diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index af0a4e863..485bfd8c5 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -1,6 +1,6 @@ name: 🐛 Bug report description: Create a report to help us improve -labels: ["Bug"] +labels: bug body: - type: textarea id: bug-description diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index c91153caa..ef50c0447 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,8 +1,5 @@ blank_issues_enabled: false contact_links: - - name: FluffyChat Community + - name: 👬 FluffyChat Community url: https://matrix.to/#/#fluffychat:matrix.org - about: Please ask and answer questions here. - - name: Report security vulnerabilities - url: https://matrix.to/#/@krille:janian.de - about: Please report security vulnerabilities here. + about: Please ask and answer questions here. \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml index a29949d66..4007c8837 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.yml +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -1,6 +1,6 @@ name: 💡 Feature Request description: Suggest an idea for this project -labels: ["Enhancement"] +labels: enhancement body: - type: textarea id: feature-description diff --git a/.github/ISSUE_TEMPLATE/test_report.md b/.github/ISSUE_TEMPLATE/test_report.md new file mode 100644 index 000000000..9a7ed7028 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/test_report.md @@ -0,0 +1,41 @@ +--- +name: 📝 Test +about: A detailed protocol for testing all features +title: 'Test Report' +labels: test +--- + +1. App receives push notifications over Firebase Cloud Messaging when it is in background/terminated: + - [ ] Android + - [ ] iOS +2. App receives push notifications over Unified Push when it is in background/terminated: + - [ ] Android +3. Notifications for rooms, which are not in foreground, are working: + - [ ] Web + - [ ] Linux +4. QR Code scanner can still scan links to start a new chat: + - [ ] Android + - [ ] iOS +5. Recording and playing voice messages works: + - [ ] Android + - [ ] iOS + - [ ] Web (play only) +6. Sending and downloading files/images works: + - [ ] Android + - [ ] iOS + - [ ] Web + - [ ] Linux +7. Sharing texts/files/images from other apps to FluffyChat works: + - [ ] Android + - [ ] iOS +8. Login with single sign on works: + - [ ] Android + - [ ] iOS + - [ ] Web + - [ ] Linux +9. Test if the app lock works as intended and appears on opening/resuming the app: + - [ ] Android + - [ ] iOS +10. Drag&Drop to send a file into a chat still works: + - [ ] Web + - [ ] Linux diff --git a/.github/workflows/auto_merge.yaml b/.github/workflows/auto_merge.yaml deleted file mode 100644 index 2dab06c40..000000000 --- a/.github/workflows/auto_merge.yaml +++ /dev/null @@ -1,16 +0,0 @@ -name: Auto merge - -on: pull_request_target - -jobs: - auto-approve: - runs-on: ubuntu-latest - permissions: - pull-requests: write - if: github.actor == 'dependabot[bot]' || github.actor == 'weblate' - steps: - - uses: hmarr/auto-approve-action@v3 - - name: automerge - uses: "pascalgn/automerge-action@v0.15.6" - env: - GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" diff --git a/.github/workflows/issue_pr_management.yaml b/.github/workflows/issue_pr_management.yaml new file mode 100644 index 000000000..490c9a91c --- /dev/null +++ b/.github/workflows/issue_pr_management.yaml @@ -0,0 +1,26 @@ +name: Close Inactive Issues And PRs +on: + schedule: + - cron: "30 1 * * *" + +jobs: + close-issues: + runs-on: ubuntu-latest + permissions: + issues: write + pull-requests: write + steps: + - uses: actions/stale@v5 + with: + days-before-issue-stale: 30 + days-before-issue-close: 14 + stale-issue-label: "stale" + stale-issue-message: "This issue is stale because it has been open for 30 days with no activity." + close-issue-message: "This issue was closed because it has been inactive for 14 days since being marked as stale." + stale-pr-message: "This pull request is stale because it has been open for 30 days with no activity." + close-pr-message: "This pull request was closed because it has been inactive for 14 days since being marked as stale." + days-before-pr-stale: 30 + days-before-pr-close: 14 + exempt-milestones: true + exempt-assignees: krille-chan + repo-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/main_deploy.yaml b/.github/workflows/main_deploy.yaml index f8603f30e..4800aa0c5 100644 --- a/.github/workflows/main_deploy.yaml +++ b/.github/workflows/main_deploy.yaml @@ -5,13 +5,14 @@ on: branches: - main -concurrency: - group: main_deploy - cancel-in-progress: true - +env: + # Setting an environment variable with the value of a configuration variable + WEB_APP_ENV: ${{ vars.WEB_APP_ENV }} + jobs: deploy_web: runs-on: ubuntu-latest + environment: staging steps: - uses: actions/checkout@v2 - run: cat .github/workflows/versions.env >> $GITHUB_ENV @@ -25,56 +26,33 @@ jobs: - name: Prepare web run: ./scripts/prepare-web.sh - name: Build Release Web - run: flutter build web --release --verbose --source-maps --base-href "/web/" + run: ./scripts/build-web.sh - name: Build Website run: | - cd docs && npx tailwindcss -o ./tailwind.css --minify && cd .. - mv docs public - mv repo public || true - mv build/web/ public/web - echo "fluffychat.im" > ./public/CNAME + mv build/web public + touch public/.env + echo "$WEB_APP_ENV" >> public/.env - name: Deploy to GitHub Pages uses: peaceiris/actions-gh-pages@v3 with: personal_token: ${{ secrets.PAGES_DEPLOY_TOKEN }} publish_dir: ./public publish_branch: gh-pages + # cname: app.staging.pangea.chat - deploy_playstore_internal: + update_sentry: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - run: cat .github/workflows/versions.env >> $GITHUB_ENV - - uses: actions/setup-java@v1 + - uses: actions/checkout@v3 with: - java-version: ${{ env.JAVA_VERSION }} - - uses: subosito/flutter-action@v2 - with: - flutter-version: ${{ env.FLUTTER_VERSION }} - cache: true - - name: Set up Ruby - uses: ruby/setup-ruby@v1 - with: - ruby-version: 2.7 - - name: Install Fastlane - run: gem install fastlane -NV - - name: Apply Google Services Patch - run: git apply ./scripts/enable-android-google-services.patch - - run: flutter pub get - - name: Prepare Android Release Build + fetch-depth: 0 + + - name: Create Sentry release + uses: getsentry/action-release@v1 env: - FDROID_KEY: ${{ secrets.FDROID_KEY }} - FDROID_KEY_PASS: ${{ secrets.FDROID_KEY_PASS }} - PLAYSTORE_DEPLOY_KEY: ${{ secrets.PLAYSTORE_DEPLOY_KEY }} - run: ./scripts/prepare-android-release.sh - - name: Build Android Release - run: flutter build appbundle --target-platform android-arm,android-arm64,android-x64 - - name: Deploy Android Release - run: | - mkdir -p build/android - cp build/app/outputs/bundle/release/app-release.aab build/android/ - cd android - bundle install - bundle update fastlane - bundle exec fastlane deploy_internal_test - cd .. + SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} + SENTRY_ORG: ${{ secrets.SENTRY_ORG }} + SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }} + # SENTRY_URL: https://sentry.io/ + with: + environment: staging diff --git a/.github/workflows/old.yml b/.github/workflows/old.yml new file mode 100644 index 000000000..a701797de --- /dev/null +++ b/.github/workflows/old.yml @@ -0,0 +1,110 @@ +name: Old Release Workflow + +on: + push: + branches: + - master-unused + +concurrency: + group: release_workflow + cancel-in-progress: true + +jobs: + build_staging: + runs-on: ubuntu-latest + environment: staging + steps: + - uses: actions/checkout@v2 + - run: cat .github/workflows/versions.env >> $GITHUB_ENV + - run: echo "$WEB_APP_ENV" > .env + + - name: Set up Flutter + uses: subosito/flutter-action@v2 + with: + flutter-version: ${{ env.FLUTTER_VERSION }} + + - name: Prepare web + run: ./scripts/prepare-web.sh + + - name: Build web + run: ./scripts/build-web.sh + + - name: Upload artifacts + uses: actions/upload-artifact@v2 + with: + name: web-artifact + path: ./build/web + + upload_sentry: + runs-on: ubuntu-latest + needs: build_staging + + steps: + - uses: actions/checkout@v2 + - run: cat .github/workflows/versions.env >> $GITHUB_ENV + - run: echo "$WEB_APP_ENV" > .env + - name: Build web + run: ./scripts/upload-sentry.sh + + deploy_staging: + runs-on: ubuntu-latest + needs: build_staging + + steps: + - uses: actions/checkout@v2 + - run: cat .github/workflows/versions.env >> $GITHUB_ENV + - run: echo "$WEB_APP_ENV" > .env + - name: Set up AWS CLI + uses: aws-actions/configure-aws-credentials@v2 + with: + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + aws-region: ${{ secrets.AWS_DEFAULT_REGION }} + + - name: Download all workflow run artifacts + uses: actions/download-artifact@v3 + + build_production: + runs-on: ubuntu-latest + environment: production + steps: + - uses: actions/checkout@v2 + - run: cat .github/workflows/versions.env >> $GITHUB_ENV + - run: echo "$WEB_APP_ENV" > .env + + - name: Set up Flutter + uses: subosito/flutter-action@v2 + with: + flutter-version: ${{ env.FLUTTER_VERSION }} + + - name: Prepare web + run: ./scripts/prepare-web.sh + + - name: Build web + run: ./scripts/build-web.sh + + - name: Upload artifacts + uses: actions/upload-artifact@v2 + with: + name: web-artifact + path: ./build/web + + deploy_production: + environment: production + runs-on: ubuntu-latest + needs: build_production + + steps: + - uses: actions/checkout@v2 + - run: cat .github/workflows/versions.env >> $GITHUB_ENV + - run: echo "$WEB_APP_ENV" > .env + + - name: Download all workflow run artifacts + uses: actions/download-artifact@v3 + + - name: Set up AWS CLI + uses: aws-actions/configure-aws-credentials@v2 + with: + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + aws-region: ${{ secrets.AWS_DEFAULT_REGION }} diff --git a/.github/workflows/process_tags.yaml b/.github/workflows/process_tags.yaml new file mode 100644 index 000000000..ef9a4b137 --- /dev/null +++ b/.github/workflows/process_tags.yaml @@ -0,0 +1,28 @@ +on: + push: + tags: + - "v*" + - "rc*" + +name: Process Tags + +jobs: + build: + name: Create Release + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Get Changelog Entry + id: changelog_reader + uses: mindsers/changelog-reader-action@v2 + - name: Create Release + id: create_release + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ github.ref }} + release_name: Release ${{ github.ref }} + body: ${{ steps.changelog_reader.outputs.changes }} + draft: false + prerelease: ${{ startsWith(github.ref, 'rc') }} diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index e8b4af2bb..e26c8f2fa 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -25,22 +25,22 @@ jobs: - name: Prepare web run: ./scripts/prepare-web.sh - name: Build Release Web - run: flutter build web --release --source-maps + run: flutter build web --dart-define=FLUTTER_WEB_CANVASKIT_URL=canvaskit/ --release --source-maps - name: Create archive - run: tar -czf fluffychat-web.tar.gz build/web/ + run: tar -czf pangeachat-web.tar.gz build/web/ - name: Upload Web Build uses: actions/upload-artifact@v2 with: name: Web Build - path: fluffychat-web.tar.gz + path: pangeachat-web.tar.gz - name: Upload to release uses: actions/upload-release-asset@v1 env: GITHUB_TOKEN: ${{ secrets.PAGES_DEPLOY_TOKEN }} with: upload_url: ${{ github.event.release.upload_url }} - asset_path: fluffychat-web.tar.gz - asset_name: fluffychat-web.tar.gz + asset_path: pangeachat-web.tar.gz + asset_name: pangeachat-web.tar.gz asset_content_type: application/gzip build_apk: @@ -57,6 +57,10 @@ jobs: cache: true - name: Apply Google Services Patch run: git apply ./scripts/enable-android-google-services.patch + - name: Remove Emoji Font + run: | + rm -rf fonts/NotoEmoji + yq -i 'del( .flutter.fonts[] | select(.family == "NotoEmoji") )' pubspec.yaml - run: flutter pub get - name: Prepare Android Release Build env: @@ -120,6 +124,10 @@ jobs: run: gem install fastlane -NV - name: Apply Google Services Patch run: git apply ./scripts/enable-android-google-services.patch + - name: Remove Emoji Font + run: | + rm -rf fonts/NotoEmoji + yq -i 'del( .flutter.fonts[] | select(.family == "NotoEmoji") )' pubspec.yaml - run: flutter pub get - name: Prepare Android Release Build env: diff --git a/.github/workflows/versions.env b/.github/workflows/versions.env index 30e7fdfb8..2fd07e8a9 100644 --- a/.github/workflows/versions.env +++ b/.github/workflows/versions.env @@ -1,2 +1,2 @@ -FLUTTER_VERSION=3.13.7 +FLUTTER_VERSION=3.16.0 JAVA_VERSION=17 \ No newline at end of file diff --git a/.gitignore b/.gitignore index 0ce56e79e..ef7038f03 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,8 @@ .history .svn/ prime +*.env +!/public/.env # libolm package /assets/js/package @@ -36,6 +38,9 @@ prime .pub/ /build/ +# Gitlab runner locally +/builds/ + # Web related docs/tailwind.css @@ -53,6 +58,7 @@ lib/l10n_old ios/Flutter/.last_build_id ios/Podfile.lock ios/Runner.ipa +scripts/.credentials /windows/out /winuwp/out @@ -60,3 +66,5 @@ ios/Runner.ipa /macos/out .vs olm + +needed-translations.txt diff --git a/.metadata b/.metadata index 9a6ebb3f7..9b7605951 100644 --- a/.metadata +++ b/.metadata @@ -1,7 +1,7 @@ # This file tracks properties of this Flutter project. # Used by Flutter tool to assess capabilities and perform upgrades etc. # -# This file should be version controlled and should not be manually edited. +# This file should be version controlled. version: revision: "efbf63d9c66b9f6ec30e9ad4611189aa80003d31" @@ -15,9 +15,24 @@ migration: - platform: root create_revision: efbf63d9c66b9f6ec30e9ad4611189aa80003d31 base_revision: efbf63d9c66b9f6ec30e9ad4611189aa80003d31 + - platform: android + create_revision: efbf63d9c66b9f6ec30e9ad4611189aa80003d31 + base_revision: efbf63d9c66b9f6ec30e9ad4611189aa80003d31 + - platform: ios + create_revision: efbf63d9c66b9f6ec30e9ad4611189aa80003d31 + base_revision: efbf63d9c66b9f6ec30e9ad4611189aa80003d31 - platform: linux create_revision: efbf63d9c66b9f6ec30e9ad4611189aa80003d31 base_revision: efbf63d9c66b9f6ec30e9ad4611189aa80003d31 + - platform: macos + create_revision: efbf63d9c66b9f6ec30e9ad4611189aa80003d31 + base_revision: efbf63d9c66b9f6ec30e9ad4611189aa80003d31 + - platform: web + create_revision: efbf63d9c66b9f6ec30e9ad4611189aa80003d31 + base_revision: efbf63d9c66b9f6ec30e9ad4611189aa80003d31 + - platform: windows + create_revision: efbf63d9c66b9f6ec30e9ad4611189aa80003d31 + base_revision: efbf63d9c66b9f6ec30e9ad4611189aa80003d31 # User provided section diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 000000000..12f26c9a3 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,71 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "pangea-chat", + "request": "launch", + "type": "dart", + // "args": [ + // "-d", + // "chrome", + // "--web-port", + // "49632" + // ], + }, + { + "name": "pangea-chat (profile mode)", + "request": "launch", + "type": "dart", + "flutterMode": "profile" + }, + { + "name": "pangea-chat (release mode)", + "request": "launch", + "type": "dart", + "flutterMode": "release" + }, + { + "name": "pangea_choreographer", + "cwd": "pangea_packages\\pangea_choreographer", + "request": "launch", + "type": "dart" + }, + { + "name": "pangea_choreographer (profile mode)", + "cwd": "pangea_packages\\pangea_choreographer", + "request": "launch", + "type": "dart", + "flutterMode": "profile" + }, + { + "name": "pangea_choreographer (release mode)", + "cwd": "pangea_packages\\pangea_choreographer", + "request": "launch", + "type": "dart", + "flutterMode": "release" + }, + { + "name": "pangea_language", + "cwd": "pangea_packages\\pangea_language", + "request": "launch", + "type": "dart" + }, + { + "name": "pangea_language (profile mode)", + "cwd": "pangea_packages\\pangea_language", + "request": "launch", + "type": "dart", + "flutterMode": "profile" + }, + { + "name": "pangea_language (release mode)", + "cwd": "pangea_packages\\pangea_language", + "request": "launch", + "type": "dart", + "flutterMode": "release" + } + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..dd15e28ee --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,9 @@ +{ + "dart.previewLsp": true, + "editor.codeActionsOnSave": { + "source.fixAll": true, + "source.organizeImports": true, + "source.sortMembers": false + }, + "editor.formatOnSave": true +} \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 69dd95a8c..f8f042378 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,67 @@ +## v1.15.1 +- feat: Make all text in chat selectable on desktop (krille-chan) +- chore: Add border to images in timeline (krille-chan) +- chore: added android audio sharing intent (Aryan Arora) +- fix: Dockerfile: install jq in the builder image (David Douard) +- fix: Cannot pin messages of other users (Krille) +- fix: Emojipicker flickering because noRecent (krille-chan) +- fix: LoadProfileBottomSheet accessing disposed outerContext (Aryan Arora) +- fix: More stable scroll up to event (krille-chan) +- fix: Properly capitalize Linux window title (kramo) +- fix: Remove failed to sent events (krille-chan) +- fix: Routing glitch when using SSO on desktop (krille-chan) +- fix: SSO with no identity providers (krille-chan) +- refactor: Do not init client in background mode on Android (krille-chan) +- refactor: Store and fix missing persistence of some values (krille-chan) +- Translated using Weblate (Arabic) (Rex_sa) +- Translated using Weblate (Basque) (xabirequejo) +- Translated using Weblate (Chinese (Simplified)) (Eric) +- Translated using Weblate (Czech) (Vojtěch Fošnár) +- Translated using Weblate (Dutch) (Jelv) +- Translated using Weblate (Estonian) (Priit Jõerüüt) +- Translated using Weblate (Finnish) (Aminda Suomalainen) +- Translated using Weblate (German) (Haui) +- Translated using Weblate (Ukrainian) (Ihor Hordiichuk) + +## v1.15.0 +- feat: Add experimental todo list for rooms (krille-chan) +- feat: better scroll to last read message handling (krille-chan) +- build: Add appid suffix to android debug builds (krille-chan) +- build: Download canvaskit on build for flutter web (krille-chan) +- build: Update to Flutter 3.13.9 (krille-chan) +- chore: Add descriptions in the areYouSure dialogs for better UX (krille-chan) +- chore: Adjust bitrate for smaller voice messages (krille-chan) +- chore: Change way how to seek in audioplayer (Krille) +- chore: Limit image file and video picker until we have a background service (krille-chan) +- chore: Minor design fixes (Krille) +- design: Make incoming messages color more light (krille-chan) +- design: Make key verification an adaptive dialog (krille-chan) +- design: Make own chat bubble primary color for better contrast (krille-chan) +- fix: Create chat dialog crashes sometimes and power level textfield does not validate input (krille-chan) +- fix: Remove uncompatible dependencies connectivity_plus and wakelock (Krille) +- fix: Use correct localization for redactedBy (krille-chan) +- fix: noFCM warning dialog (krille-chan) +- fix: render tg-forward as blockquote style (krille-chan) +- fix: Archive does not update its state +- refactor: Change audio codec to opus where supported to have better compatibility with Element (Krille) +- refactor: Make file dialog adaptive and adjust design (krille-chan) +- refactor: Preload notification sound on web (Krille) +- refactor: Remove unused config (krille-chan) +- refactor: Remove unused config params (krille-chan) +- refactor: Update FutureLoadingDialog (krille-chan) +- refactor: use locally hosted canvaskit instead of calling google (root) +- Translated using Weblate (Arabic) (Rex_sa) +- Translated using Weblate (Basque) (xabirequejo) +- Translated using Weblate (Chinese (Simplified)) (Eric) +- Translated using Weblate (Croatian) (Milo Ivir) +- Translated using Weblate (German) (Christian) +- Translated using Weblate (German) (Ettore Atalan) +- Translated using Weblate (Hungarian) (H Tamás) +- Translated using Weblate (Polish) (Tomasz W) +- Translated using Weblate (Russian) (v1s7) +- Translated using Weblate (Slovak) (Jozef Gaal) +- Translated using Weblate (Thai) (Amy/Atius) + ## v1.14.5 - Hotfix iOS crashes on start - Hotfix cannot reset applock diff --git a/Dockerfile b/Dockerfile index 7a696ce54..e5416091c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,11 +1,11 @@ FROM ghcr.io/cirruslabs/flutter as builder -RUN sudo apt update && sudo apt install curl -y +RUN sudo apt update && sudo apt install curl jq -y COPY . /app WORKDIR /app RUN ./scripts/prepare-web.sh RUN flutter pub get -RUN flutter build web --release --source-maps +RUN flutter build web --dart-define=FLUTTER_WEB_CANVASKIT_URL=canvaskit/ --release --source-maps FROM docker.io/nginx:alpine RUN rm -rf /usr/share/nginx/html -COPY --from=builder /app/build/web /usr/share/nginx/html \ No newline at end of file +COPY --from=builder /app/build/web /usr/share/nginx/html diff --git a/README.md b/README.md index f7986baa7..3c2b5d9b6 100644 --- a/README.md +++ b/README.md @@ -66,4 +66,4 @@ Please visit the [Wiki](https://github.com/krille-chan/fluffychat/wiki) for buil * WoodenBeaver sound theme for the notification sound. -* The Matrix Foundation for making and maintaining the [emoji translations](https://github.com/matrix-org/matrix-doc/blob/main/data-definitions/sas-emoji.json) used for emoji verification, licensed Apache 2.0 +* The Matrix Foundation for making and maintaining the [emoji translations](https://github.com/matrix-org/matrix-spec/blob/main/data-definitions/sas-emoji.json) used for emoji verification, licensed Apache 2.0 diff --git a/TRANSLATORS_GUIDE.md b/TRANSLATORS_GUIDE.md new file mode 100644 index 000000000..d5bc4f8fe --- /dev/null +++ b/TRANSLATORS_GUIDE.md @@ -0,0 +1,35 @@ +# Translators Guide + +There are 3 main types of strings to be translated. + +## Simple +``` +Add new friend +``` +They are just plain text and are to be translated in full. + +## Placeholder +``` +{username} changed their avatar +``` +Contains one or more words surrounded by curly brackets "`{}`". Anything outside of the curly brackets is to be translated as normal, but the words in the curly brackets are **NOT** to be translated. In the above example "`{username}`" will be replaced by the users actual username by FluffyChat. + +## Plural + +- {count,plural, =1{**1 more event**} other{{count} **more events**}} + +This is the most complicated string type, the parts in bold are the only parts that need translating in this string. You can identify plural strings by seeing the pattern `{word,plural,` at the start. `=1` and `other` are "selectors" so you can have multiple different translations for different quantities. `other` is the only required selector and will be chosen if the count does not match any other selectors. + +Selector | Matches +---|--- +=0 | a count of exactly 0 +=1 | a count of exactly 1 +=2 | a count of exactly 2 +other | any number unless it matches a more specific rule + +There is also "few" and "many", but they seem to have language specific meaning. + +Also the selectors do not need to match the English version such as your language may not even use different words for when there is more than one of something so: + - {count,plural, other{{count} \}} + +could be a perfectly resonable way to translate. diff --git a/android/app/build.gradle b/android/app/build.gradle index 923f82e0a..bc33501d7 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -22,6 +22,7 @@ if (flutterVersionName == null) { } apply plugin: 'com.android.application' +apply plugin: 'com.google.gms.google-services' apply plugin: 'kotlin-android' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" @@ -32,7 +33,7 @@ if (keystorePropertiesFile.exists()) { } android { - compileSdkVersion 33 + compileSdkVersion 34 sourceSets { main.java.srcDirs += 'src/main/kotlin' @@ -43,7 +44,7 @@ android { } defaultConfig { - applicationId "chat.fluffy.fluffychat" + applicationId "com.talktolearn.chat" minSdkVersion 19 targetSdkVersion 33 versionCode flutterVersionCode.toInteger() @@ -65,11 +66,20 @@ android { buildTypes { debug { signingConfig signingConfigs.debug + applicationIdSuffix "" + versionNameSuffix "" } release { signingConfig signingConfigs.release } } + // https://stackoverflow.com/a/77494454/8222484 + packagingOptions { + pickFirst 'lib/x86/libc++_shared.so' + pickFirst 'lib/x86_64/libc++_shared.so' + pickFirst 'lib/armeabi-v7a/libc++_shared.so' + pickFirst 'lib/arm64-v8a/libc++_shared.so' + } } flutter { diff --git a/android/app/google-services.json b/android/app/google-services.json index e33988c40..565c634cb 100644 --- a/android/app/google-services.json +++ b/android/app/google-services.json @@ -1,40 +1,40 @@ { "project_info": { - "project_number": "865731724731", - "project_id": "fluffychat-ef3e8", - "storage_bucket": "fluffychat-ef3e8.appspot.com" + "project_number": "545984292675", + "project_id": "pangea-chat-936ee", + "storage_bucket": "pangea-chat-936ee.appspot.com" }, "client": [ { "client_info": { - "mobilesdk_app_id": "1:865731724731:android:ec427b3b1dcd4a1e64309e", + "mobilesdk_app_id": "1:545984292675:android:d808acce7a80c20bb931f6", "android_client_info": { - "package_name": "chat.fluffy.fluffychat" + "package_name": "com.talktolearn.chat" } }, "oauth_client": [ { - "client_id": "865731724731-od6969v178ul9970elgacpt936v5t7qg.apps.googleusercontent.com", + "client_id": "545984292675-2amsnoan1mt6lec1fld1a7eagu6gej7o.apps.googleusercontent.com", "client_type": 3 } ], "api_key": [ { - "current_key": "AIzaSyBLdZpGSPjcinikB4lAU6awW_h88NG17Sg" + "current_key": "AIzaSyAyWBbl83WXzbVr6txyCmlUsZhpWomQfdg" } ], "services": { "appinvite_service": { "other_platform_oauth_client": [ { - "client_id": "865731724731-od6969v178ul9970elgacpt936v5t7qg.apps.googleusercontent.com", + "client_id": "545984292675-2amsnoan1mt6lec1fld1a7eagu6gej7o.apps.googleusercontent.com", "client_type": 3 }, { - "client_id": "865731724731-ofdr7e6m04murgb1bvchlj9oaos0q5i3.apps.googleusercontent.com", + "client_id": "545984292675-f5p76l3h9sibsonrct7a8l9ca3c69at0.apps.googleusercontent.com", "client_type": 2, "ios_info": { - "bundle_id": "im.fluffychat.app" + "bundle_id": "com.talktolearn.chat" } } ] diff --git a/android/app/src/debug/AndroidManifest.xml b/android/app/src/debug/AndroidManifest.xml deleted file mode 100644 index 4a2a1f5d7..000000000 --- a/android/app/src/debug/AndroidManifest.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index f57cee1b7..9e52b2a59 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -1,6 +1,6 @@ + package="com.talktolearn.chat" android:installLocation="auto"> + + + - + @@ -95,6 +99,11 @@ + + + + + - + - + + diff --git a/android/app/src/main/kotlin/com/talktolearn/chat/FcmPushService.kt b/android/app/src/main/kotlin/com/talktolearn/chat/FcmPushService.kt new file mode 100644 index 000000000..ad301c9f0 --- /dev/null +++ b/android/app/src/main/kotlin/com/talktolearn/chat/FcmPushService.kt @@ -0,0 +1,36 @@ +/*package com.talktolearn.chat + +import com.famedly.fcm_shared_isolate.FcmSharedIsolateService + +import com.talktolearn.chat.MainActivity + +import io.flutter.embedding.android.FlutterActivity +import io.flutter.embedding.engine.FlutterEngine +import io.flutter.view.FlutterMain +import io.flutter.embedding.engine.dart.DartExecutor.DartEntrypoint + +import android.content.Context +import android.os.Bundle +import android.util.Log +import android.view.WindowManager + +class FcmPushService : FcmSharedIsolateService() { + override fun getEngine(): FlutterEngine { + return provideEngine(getApplicationContext()) + } + + companion object { + fun provideEngine(context: Context): FlutterEngine { + var engine = MainActivity.engine + if (engine == null) { + engine = MainActivity.provideEngine(context) + engine.getLocalizationPlugin().sendLocalesToFlutter( + context.getResources().getConfiguration()) + engine.getDartExecutor().executeDartEntrypoint( + DartEntrypoint.createDefault()) + } + return engine + } + } +} +*/ \ No newline at end of file diff --git a/android/app/src/main/kotlin/com/talktolearn/chat/MainActivity.kt b/android/app/src/main/kotlin/com/talktolearn/chat/MainActivity.kt new file mode 100644 index 000000000..77d3c6e32 --- /dev/null +++ b/android/app/src/main/kotlin/com/talktolearn/chat/MainActivity.kt @@ -0,0 +1,33 @@ +package com.talktolearn.chat + +import io.flutter.embedding.android.FlutterActivity +import io.flutter.embedding.engine.FlutterEngine + +import android.content.Context +import androidx.multidex.MultiDex + +class MainActivity : FlutterActivity() { + + override fun attachBaseContext(base: Context) { + super.attachBaseContext(base) + MultiDex.install(this) + } + + + override fun provideFlutterEngine(context: Context): FlutterEngine? { + return provideEngine(this) + } + + override fun configureFlutterEngine(flutterEngine: FlutterEngine) { + // do nothing, because the engine was been configured in provideEngine + } + + companion object { + var engine: FlutterEngine? = null + fun provideEngine(context: Context): FlutterEngine { + val eng = engine ?: FlutterEngine(context, emptyArray(), true, false) + engine = eng + return eng + } + } +} diff --git a/android/app/src/main/kotlin/com/talktolearn/chat/UnifiedPushService.kt b/android/app/src/main/kotlin/com/talktolearn/chat/UnifiedPushService.kt new file mode 100644 index 000000000..3c1696e65 --- /dev/null +++ b/android/app/src/main/kotlin/com/talktolearn/chat/UnifiedPushService.kt @@ -0,0 +1,23 @@ +package com.talktolearn.chat + +import io.flutter.embedding.engine.FlutterEngine +import io.flutter.embedding.engine.dart.DartExecutor +import org.unifiedpush.flutter.connector.UnifiedPushReceiver + +import android.content.Context + +class UnifiedPushReceiver : UnifiedPushReceiver() { + override fun getEngine(context: Context): FlutterEngine { + var engine = MainActivity.engine + if (engine == null) { + engine = MainActivity.provideEngine(context) + engine.localizationPlugin.sendLocalesToFlutter( + context.resources.configuration + ) + engine.dartExecutor.executeDartEntrypoint( + DartExecutor.DartEntrypoint.createDefault() + ) + } + return engine + } +} \ No newline at end of file diff --git a/android/app/src/main/res/drawable-anydpi-v24/notifications_icon.xml b/android/app/src/main/res/drawable-anydpi-v24/notifications_icon.xml deleted file mode 100644 index 21b574637..000000000 --- a/android/app/src/main/res/drawable-anydpi-v24/notifications_icon.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - diff --git a/android/app/src/main/res/drawable-hdpi/android12splash.png b/android/app/src/main/res/drawable-hdpi/android12splash.png new file mode 100644 index 000000000..f6ae6153e Binary files /dev/null and b/android/app/src/main/res/drawable-hdpi/android12splash.png differ diff --git a/android/app/src/main/res/drawable-hdpi/splash.png b/android/app/src/main/res/drawable-hdpi/splash.png index 965713319..f6ae6153e 100644 Binary files a/android/app/src/main/res/drawable-hdpi/splash.png and b/android/app/src/main/res/drawable-hdpi/splash.png differ diff --git a/android/app/src/main/res/drawable-mdpi/android12splash.png b/android/app/src/main/res/drawable-mdpi/android12splash.png new file mode 100644 index 000000000..69a8a0d54 Binary files /dev/null and b/android/app/src/main/res/drawable-mdpi/android12splash.png differ diff --git a/android/app/src/main/res/drawable-mdpi/splash.png b/android/app/src/main/res/drawable-mdpi/splash.png index f4c0bdb92..69a8a0d54 100644 Binary files a/android/app/src/main/res/drawable-mdpi/splash.png and b/android/app/src/main/res/drawable-mdpi/splash.png differ diff --git a/android/app/src/main/res/drawable-night-hdpi/android12splash.png b/android/app/src/main/res/drawable-night-hdpi/android12splash.png new file mode 100644 index 000000000..f6ae6153e Binary files /dev/null and b/android/app/src/main/res/drawable-night-hdpi/android12splash.png differ diff --git a/android/app/src/main/res/drawable-night-mdpi/android12splash.png b/android/app/src/main/res/drawable-night-mdpi/android12splash.png new file mode 100644 index 000000000..69a8a0d54 Binary files /dev/null and b/android/app/src/main/res/drawable-night-mdpi/android12splash.png differ diff --git a/android/app/src/main/res/drawable-night-xhdpi/android12splash.png b/android/app/src/main/res/drawable-night-xhdpi/android12splash.png new file mode 100644 index 000000000..70f8839f7 Binary files /dev/null and b/android/app/src/main/res/drawable-night-xhdpi/android12splash.png differ diff --git a/android/app/src/main/res/drawable-night-xxhdpi/android12splash.png b/android/app/src/main/res/drawable-night-xxhdpi/android12splash.png new file mode 100644 index 000000000..e72e0fefe Binary files /dev/null and b/android/app/src/main/res/drawable-night-xxhdpi/android12splash.png differ diff --git a/android/app/src/main/res/drawable-night-xxxhdpi/android12splash.png b/android/app/src/main/res/drawable-night-xxxhdpi/android12splash.png new file mode 100644 index 000000000..00445e742 Binary files /dev/null and b/android/app/src/main/res/drawable-night-xxxhdpi/android12splash.png differ diff --git a/android/app/src/main/res/drawable-xhdpi/android12splash.png b/android/app/src/main/res/drawable-xhdpi/android12splash.png new file mode 100644 index 000000000..70f8839f7 Binary files /dev/null and b/android/app/src/main/res/drawable-xhdpi/android12splash.png differ diff --git a/android/app/src/main/res/drawable-xhdpi/splash.png b/android/app/src/main/res/drawable-xhdpi/splash.png index dafa3b707..70f8839f7 100644 Binary files a/android/app/src/main/res/drawable-xhdpi/splash.png and b/android/app/src/main/res/drawable-xhdpi/splash.png differ diff --git a/android/app/src/main/res/drawable-xxhdpi/android12splash.png b/android/app/src/main/res/drawable-xxhdpi/android12splash.png new file mode 100644 index 000000000..e72e0fefe Binary files /dev/null and b/android/app/src/main/res/drawable-xxhdpi/android12splash.png differ diff --git a/android/app/src/main/res/drawable-xxhdpi/splash.png b/android/app/src/main/res/drawable-xxhdpi/splash.png index b627f5280..e72e0fefe 100644 Binary files a/android/app/src/main/res/drawable-xxhdpi/splash.png and b/android/app/src/main/res/drawable-xxhdpi/splash.png differ diff --git a/android/app/src/main/res/drawable-xxxhdpi/android12splash.png b/android/app/src/main/res/drawable-xxxhdpi/android12splash.png new file mode 100644 index 000000000..00445e742 Binary files /dev/null and b/android/app/src/main/res/drawable-xxxhdpi/android12splash.png differ diff --git a/android/app/src/main/res/drawable-xxxhdpi/splash.png b/android/app/src/main/res/drawable-xxxhdpi/splash.png index 0d1d2a74d..00445e742 100644 Binary files a/android/app/src/main/res/drawable-xxxhdpi/splash.png and b/android/app/src/main/res/drawable-xxxhdpi/splash.png differ diff --git a/android/app/src/main/res/drawable/ic_launcher_monochrome.xml b/android/app/src/main/res/drawable/ic_launcher_monochrome.xml deleted file mode 100644 index f0b10e7d6..000000000 --- a/android/app/src/main/res/drawable/ic_launcher_monochrome.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - diff --git a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml deleted file mode 100644 index 1084c2408..000000000 --- a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png index 54dd74b56..b729d12ce 100644 Binary files a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png index 6fc0dcbfb..6b2fd5a7c 100644 Binary files a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png index dd6dcadac..06eda9ce7 100644 Binary files a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png index ea5d85515..a195b46a8 100644 Binary files a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png index 8d4f59224..6c985b40f 100644 Binary files a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/values-night-v31/styles.xml b/android/app/src/main/res/values-night-v31/styles.xml new file mode 100644 index 000000000..2d5909b1b --- /dev/null +++ b/android/app/src/main/res/values-night-v31/styles.xml @@ -0,0 +1,19 @@ + + + + + + + \ No newline at end of file diff --git a/android/app/src/main/res/values-night/styles.xml b/android/app/src/main/res/values-night/styles.xml index 7c806c658..0398fe499 100644 --- a/android/app/src/main/res/values-night/styles.xml +++ b/android/app/src/main/res/values-night/styles.xml @@ -5,6 +5,7 @@ @drawable/launch_background + false false + + + + \ No newline at end of file diff --git a/android/app/src/profile/AndroidManifest.xml b/android/app/src/profile/AndroidManifest.xml deleted file mode 100644 index 4a2a1f5d7..000000000 --- a/android/app/src/profile/AndroidManifest.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - diff --git a/android/build.gradle b/android/build.gradle index a8c597ff1..94a04851d 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -8,7 +8,7 @@ buildscript { dependencies { classpath 'com.android.tools.build:gradle:7.1.2' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - //classpath 'com.google.gms:google-services:4.3.8' + classpath 'com.google.gms:google-services:4.3.13' } } diff --git a/android/fastlane/Appfile b/android/fastlane/Appfile index 872e07850..cc33cdc7d 100644 --- a/android/fastlane/Appfile +++ b/android/fastlane/Appfile @@ -1,2 +1,2 @@ json_key_file("keys.json") # Path to the json secret file - Follow https://docs.fastlane.tools/actions/supply/#setup to get one -package_name("chat.fluffy.fluffychat") # e.g. com.krausefx.app +package_name("com.talktolearn.chat") # e.g. com.krausefx.app diff --git a/android/fastlane/metadata/android/en-US/changelogs/50 (0.22.1).txt b/android/fastlane/metadata/android/en-US/changelogs/50 (0.22.1).txt new file mode 100644 index 000000000..10f77f4f9 --- /dev/null +++ b/android/fastlane/metadata/android/en-US/changelogs/50 (0.22.1).txt @@ -0,0 +1 @@ +Check out https://gitlab.com/ChristianPauly/fluffychat-flutter/-/blob/main/CHANGELOG.md for the changelog. \ No newline at end of file diff --git a/appimage/AppRun b/appimage/AppRun old mode 100755 new mode 100644 diff --git a/assets/colors.png b/assets/colors.png new file mode 100644 index 000000000..27c996adb Binary files /dev/null and b/assets/colors.png differ diff --git a/assets/encryption.png b/assets/encryption.png new file mode 100644 index 000000000..af2ba3c24 Binary files /dev/null and b/assets/encryption.png differ diff --git a/assets/l10n/intl_ar.arb b/assets/l10n/intl_ar.arb index 0fe4b02d1..4aca37af8 100644 --- a/assets/l10n/intl_ar.arb +++ b/assets/l10n/intl_ar.arb @@ -771,7 +771,7 @@ "type": "text", "placeholders": {} }, - "noGoogleServicesWarning": "يبدو أنك لا تستخدم خدمات غوغل على هاتفك. هذا قرار جيد للحفاظ على خصوصيتك! من أجل استلام الإشعارات في FluffyChat نقترح استخدام https://microg.org أو https://unifiedpush.org.", + "noGoogleServicesWarning": "يبدو أن خدمة Firebase Cloud Messaging غير متاحة على جهازك. لمواصلة تلقي الإشعارات، نوصي بتثبيت ntfy. باستخدام ntfy أو أي مزود خدمة Unified Push آخر، يمكنك تلقي إشعارات الدفع بطريقة آمنة للبيانات. يمكنك تنزيل ntfy من PlayStore أو من F-Droid.", "@noGoogleServicesWarning": { "type": "text", "placeholders": {} @@ -2619,5 +2619,45 @@ "placeholders": { "seconds": {} } - } + }, + "hasKnocked": "لقد طرق {user}", + "@hasKnocked": { + "placeholders": { + "user": {} + } + }, + "pleaseEnterANumber": "الرجاء إدخال رقم أكبر من 0", + "@pleaseEnterANumber": {}, + "banUserDescription": "سيتم حظر المستخدم من الدردشة ولن يتمكن من الدخول إلى الدردشة مرة أخرى حتى يتم رفع الحظر عنه.", + "@banUserDescription": {}, + "removeDevicesDescription": "سيتم تسجيل خروجك من هذا الجهاز ولن تتمكن بعد ذلك من تلقي الرسائل.", + "@removeDevicesDescription": {}, + "unbanUserDescription": "سيتمكن المستخدم من الدخول إلى الدردشة مرة أخرى إذا حاول.", + "@unbanUserDescription": {}, + "todoLists": "(اختباري) لقوائم المهام", + "@todoLists": {}, + "editTodo": "تعديل المهام", + "@editTodo": {}, + "pushNotificationsNotAvailable": "دفع الإخطارات غير متوفرة", + "@pushNotificationsNotAvailable": {}, + "pleaseAddATitle": "يرجى إضافة عنوان", + "@pleaseAddATitle": {}, + "makeAdminDescription": "بمجرد تعيين هذا المستخدم كمسؤول، قد لا تتمكن من التراجع عن هذا لأنه سيكون لديه نفس الأذونات التي تتمتع بها.", + "@makeAdminDescription": {}, + "noTodosYet": "لم تتم إضافة أي مهام إلى هذه الدردشة حتى الآن. أنشئ أول ما يجب عليك فعله وابدأ في التعاون مع الآخرين. 📝", + "@noTodosYet": {}, + "archiveRoomDescription": "سيتم نقل الدردشة إلى الأرشيف. سيتمكن المستخدمون الآخرون من رؤية أنك غادرت الدردشة.", + "@archiveRoomDescription": {}, + "todosUnencrypted": "يرجى ملاحظة أن جميع المهام مرئية للجميع في الدردشة وليست مشفرة تمامًا.", + "@todosUnencrypted": {}, + "newTodo": "ما يجب القيام به جديد", + "@newTodo": {}, + "learnMore": "تعلم المزيد", + "@learnMore": {}, + "todoListChangedError": "عفوًا... لقد تم تغيير قائمة المهام أثناء قيامك بتحريرها.", + "@todoListChangedError": {}, + "roomUpgradeDescription": "سيتم بعد ذلك إعادة إنشاء الدردشة باستخدام إصدار الغرفة الجديد. سيتم إخطار جميع المشاركين بأنهم بحاجة إلى التبديل إلى الدردشة الجديدة. يمكنك معرفة المزيد حول إصدارات الغرف على https://spec.matrix.org/latest/rooms/", + "@roomUpgradeDescription": {}, + "kickUserDescription": "يتم طرد المستخدم من الدردشة ولكن لا يتم حظره. في الدردشات العامة، يمكن للمستخدم الانضمام مرة أخرى في أي وقت.", + "@kickUserDescription": {} } diff --git a/assets/l10n/intl_bn.arb b/assets/l10n/intl_bn.arb index fedac9000..dd7d6c29b 100644 --- a/assets/l10n/intl_bn.arb +++ b/assets/l10n/intl_bn.arb @@ -1,25 +1,2621 @@ { - "@@last_modified": "2021-08-14 12:41:10.154280", - "about": "সম্পর্কে", - "@about": { - "type": "text", - "placeholders": {} - }, - "accept": "স্বীকার করি", - "@accept": { - "type": "text", - "placeholders": {} - }, - "acceptedTheInvitation": "{username} আমন্ত্রণ গ্রহণ করেছে", - "@acceptedTheInvitation": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "account": "অ্যাকাউন্ট", - "@account": { - "type": "text", - "placeholders": {} + "@@last_modified": "2021-08-14 12:41:10.154280", + "about": "সম্পর্কে", + "@about": { + "type": "text", + "placeholders": {} + }, + "accept": "স্বীকার করি", + "@accept": { + "type": "text", + "placeholders": {} + }, + "acceptedTheInvitation": "{username} আমন্ত্রণ গ্রহণ করেছে", + "@acceptedTheInvitation": { + "type": "text", + "placeholders": { + "username": {} } -} \ No newline at end of file + }, + "account": "অ্যাকাউন্ট", + "@account": { + "type": "text", + "placeholders": {} + }, + "showPassword": "", + "@showPassword": { + "type": "text", + "placeholders": {} + }, + "hugContent": "", + "@hugContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "darkTheme": "", + "@darkTheme": { + "type": "text", + "placeholders": {} + }, + "passphraseOrKey": "", + "@passphraseOrKey": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourPassword": "", + "@pleaseEnterYourPassword": { + "type": "text", + "placeholders": {} + }, + "theyMatch": "", + "@theyMatch": { + "type": "text", + "placeholders": {} + }, + "connect": "", + "@connect": { + "type": "text", + "placeholders": {} + }, + "jumpToLastReadMessage": "", + "@jumpToLastReadMessage": {}, + "allRooms": "", + "@allRooms": { + "type": "text", + "placeholders": {} + }, + "obtainingLocation": "", + "@obtainingLocation": { + "type": "text", + "placeholders": {} + }, + "whoCanSeeMyStories": "", + "@whoCanSeeMyStories": {}, + "commandHint_cuddle": "", + "@commandHint_cuddle": {}, + "chats": "", + "@chats": { + "type": "text", + "placeholders": {} + }, + "widgetVideo": "", + "@widgetVideo": {}, + "dismiss": "", + "@dismiss": {}, + "unknownDevice": "", + "@unknownDevice": { + "type": "text", + "placeholders": {} + }, + "emoteShortcode": "", + "@emoteShortcode": { + "type": "text", + "placeholders": {} + }, + "noEncryptionForPublicRooms": "", + "@noEncryptionForPublicRooms": { + "type": "text", + "placeholders": {} + }, + "admin": "", + "@admin": { + "type": "text", + "placeholders": {} + }, + "reportErrorDescription": "", + "@reportErrorDescription": {}, + "directChats": "", + "@directChats": { + "type": "text", + "placeholders": {} + }, + "setPermissionsLevel": "", + "@setPermissionsLevel": { + "type": "text", + "placeholders": {} + }, + "inviteContactToGroup": "", + "@inviteContactToGroup": { + "type": "text", + "placeholders": { + "groupName": {} + } + }, + "addAccount": "", + "@addAccount": {}, + "close": "", + "@close": { + "type": "text", + "placeholders": {} + }, + "configureChat": "", + "@configureChat": { + "type": "text", + "placeholders": {} + }, + "seenByUserAndUser": "", + "@seenByUserAndUser": { + "type": "text", + "placeholders": { + "username": {}, + "username2": {} + } + }, + "chatHasBeenAddedToThisSpace": "", + "@chatHasBeenAddedToThisSpace": {}, + "reply": "", + "@reply": { + "type": "text", + "placeholders": {} + }, + "currentlyActive": "", + "@currentlyActive": { + "type": "text", + "placeholders": {} + }, + "removeYourAvatar": "", + "@removeYourAvatar": { + "type": "text", + "placeholders": {} + }, + "unsupportedAndroidVersion": "", + "@unsupportedAndroidVersion": {}, + "enterASpacepName": "", + "@enterASpacepName": {}, + "device": "", + "@device": { + "type": "text", + "placeholders": {} + }, + "blockDevice": "", + "@blockDevice": { + "type": "text", + "placeholders": {} + }, + "commandHint_html": "", + "@commandHint_html": { + "type": "text", + "description": "Usage hint for the command /html" + }, + "widgetJitsi": "", + "@widgetJitsi": {}, + "youAreNoLongerParticipatingInThisChat": "", + "@youAreNoLongerParticipatingInThisChat": { + "type": "text", + "placeholders": {} + }, + "encryption": "", + "@encryption": { + "type": "text", + "placeholders": {} + }, + "messageType": "", + "@messageType": {}, + "noEmailWarning": "", + "@noEmailWarning": {}, + "indexedDbErrorLong": "", + "@indexedDbErrorLong": {}, + "oneClientLoggedOut": "", + "@oneClientLoggedOut": {}, + "toggleMuted": "", + "@toggleMuted": { + "type": "text", + "placeholders": {} + }, + "kicked": "", + "@kicked": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "title": "", + "@title": { + "description": "Title for the application", + "type": "text", + "placeholders": {} + }, + "changeTheNameOfTheGroup": "", + "@changeTheNameOfTheGroup": { + "type": "text", + "placeholders": {} + }, + "changedTheChatAvatar": "", + "@changedTheChatAvatar": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "verifySuccess": "", + "@verifySuccess": { + "type": "text", + "placeholders": {} + }, + "sendFile": "", + "@sendFile": { + "type": "text", + "placeholders": {} + }, + "newVerificationRequest": "", + "@newVerificationRequest": { + "type": "text", + "placeholders": {} + }, + "startFirstChat": "", + "@startFirstChat": {}, + "callingAccount": "", + "@callingAccount": {}, + "requestPermission": "", + "@requestPermission": { + "type": "text", + "placeholders": {} + }, + "sentAPicture": "", + "@sentAPicture": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "invited": "", + "@invited": { + "type": "text", + "placeholders": {} + }, + "setColorTheme": "", + "@setColorTheme": {}, + "nextAccount": "", + "@nextAccount": {}, + "commandHint_create": "", + "@commandHint_create": { + "type": "text", + "description": "Usage hint for the command /create" + }, + "youAreInvitedToThisChat": "", + "@youAreInvitedToThisChat": { + "type": "text", + "placeholders": {} + }, + "singlesignon": "", + "@singlesignon": { + "type": "text", + "placeholders": {} + }, + "warning": "", + "@warning": { + "type": "text", + "placeholders": {} + }, + "password": "", + "@password": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterAMatrixIdentifier": "", + "@pleaseEnterAMatrixIdentifier": { + "type": "text", + "placeholders": {} + }, + "allSpaces": "", + "@allSpaces": {}, + "supposedMxid": "", + "@supposedMxid": { + "type": "text", + "placeholders": { + "mxid": {} + } + }, + "editDisplayname": "", + "@editDisplayname": { + "type": "text", + "placeholders": {} + }, + "user": "", + "@user": {}, + "roomVersion": "", + "@roomVersion": { + "type": "text", + "placeholders": {} + }, + "sentAFile": "", + "@sentAFile": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "videoCall": "", + "@videoCall": { + "type": "text", + "placeholders": {} + }, + "youAcceptedTheInvitation": "", + "@youAcceptedTheInvitation": {}, + "banFromChat": "", + "@banFromChat": { + "type": "text", + "placeholders": {} + }, + "noMatrixServer": "", + "@noMatrixServer": { + "type": "text", + "placeholders": { + "server1": {}, + "server2": {} + } + }, + "userAndOthersAreTyping": "", + "@userAndOthersAreTyping": { + "type": "text", + "placeholders": { + "username": {}, + "count": {} + } + }, + "youInvitedBy": "", + "@youInvitedBy": { + "placeholders": { + "user": {} + } + }, + "userIsTyping": "", + "@userIsTyping": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "openAppToReadMessages": "", + "@openAppToReadMessages": { + "type": "text", + "placeholders": {} + }, + "sentAVideo": "", + "@sentAVideo": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "banUserDescription": "", + "@banUserDescription": {}, + "inviteContact": "", + "@inviteContact": { + "type": "text", + "placeholders": {} + }, + "requests": "", + "@requests": {}, + "askSSSSSign": "", + "@askSSSSSign": { + "type": "text", + "placeholders": {} + }, + "widgetEtherpad": "", + "@widgetEtherpad": {}, + "waitingPartnerAcceptRequest": "", + "@waitingPartnerAcceptRequest": { + "type": "text", + "placeholders": {} + }, + "remove": "", + "@remove": { + "type": "text", + "placeholders": {} + }, + "writeAMessage": "", + "@writeAMessage": { + "type": "text", + "placeholders": {} + }, + "changeTheme": "", + "@changeTheme": { + "type": "text", + "placeholders": {} + }, + "stories": "", + "@stories": {}, + "id": "", + "@id": { + "type": "text", + "placeholders": {} + }, + "addToStory": "", + "@addToStory": {}, + "removeDevicesDescription": "", + "@removeDevicesDescription": {}, + "changedTheChatDescriptionTo": "", + "@changedTheChatDescriptionTo": { + "type": "text", + "placeholders": { + "username": {}, + "description": {} + } + }, + "countParticipants": "", + "@countParticipants": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "separateChatTypes": "", + "@separateChatTypes": { + "type": "text", + "placeholders": {} + }, + "tryAgain": "", + "@tryAgain": {}, + "areGuestsAllowedToJoin": "", + "@areGuestsAllowedToJoin": { + "type": "text", + "placeholders": {} + }, + "blocked": "", + "@blocked": { + "type": "text", + "placeholders": {} + }, + "youKickedAndBanned": "", + "@youKickedAndBanned": { + "placeholders": { + "user": {} + } + }, + "dateWithoutYear": "", + "@dateWithoutYear": { + "type": "text", + "placeholders": { + "month": {}, + "day": {} + } + }, + "showDirectChatsInSpaces": "", + "@showDirectChatsInSpaces": { + "type": "text", + "placeholders": {} + }, + "removeDevice": "", + "@removeDevice": { + "type": "text", + "placeholders": {} + }, + "youCannotInviteYourself": "", + "@youCannotInviteYourself": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterValidEmail": "", + "@pleaseEnterValidEmail": {}, + "unbanUserDescription": "", + "@unbanUserDescription": {}, + "todoLists": "", + "@todoLists": {}, + "userAndUserAreTyping": "", + "@userAndUserAreTyping": { + "type": "text", + "placeholders": { + "username": {}, + "username2": {} + } + }, + "pleaseClickOnLink": "", + "@pleaseClickOnLink": { + "type": "text", + "placeholders": {} + }, + "saveFile": "", + "@saveFile": { + "type": "text", + "placeholders": {} + }, + "sendOnEnter": "", + "@sendOnEnter": {}, + "seenByUserAndCountOthers": "", + "@seenByUserAndCountOthers": { + "type": "text", + "placeholders": { + "username": {}, + "count": {} + } + }, + "answeredTheCall": "", + "@answeredTheCall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "youRejectedTheInvitation": "", + "@youRejectedTheInvitation": {}, + "otherCallingPermissions": "", + "@otherCallingPermissions": {}, + "messagesStyle": "", + "@messagesStyle": {}, + "couldNotDecryptMessage": "", + "@couldNotDecryptMessage": { + "type": "text", + "placeholders": { + "error": {} + } + }, + "invitedUsersOnly": "", + "@invitedUsersOnly": { + "type": "text", + "placeholders": {} + }, + "link": "", + "@link": {}, + "widgetUrlError": "", + "@widgetUrlError": {}, + "emailOrUsername": "", + "@emailOrUsername": {}, + "newSpaceDescription": "", + "@newSpaceDescription": {}, + "chatDescription": "", + "@chatDescription": {}, + "callingAccountDetails": "", + "@callingAccountDetails": {}, + "next": "", + "@next": { + "type": "text", + "placeholders": {} + }, + "pleaseFollowInstructionsOnWeb": "", + "@pleaseFollowInstructionsOnWeb": { + "type": "text", + "placeholders": {} + }, + "changedTheGuestAccessRules": "", + "@changedTheGuestAccessRules": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "pleaseChooseAtLeastChars": "", + "@pleaseChooseAtLeastChars": { + "type": "text", + "placeholders": { + "min": {} + } + }, + "dateWithYear": "", + "@dateWithYear": { + "type": "text", + "placeholders": { + "year": {}, + "month": {}, + "day": {} + } + }, + "editRoomAliases": "", + "@editRoomAliases": { + "type": "text", + "placeholders": {} + }, + "enterSpace": "", + "@enterSpace": {}, + "encryptThisChat": "", + "@encryptThisChat": {}, + "fileName": "", + "@fileName": { + "type": "text", + "placeholders": {} + }, + "unavailable": "", + "@unavailable": { + "type": "text", + "placeholders": {} + }, + "previousAccount": "", + "@previousAccount": {}, + "publicRooms": "", + "@publicRooms": { + "type": "text", + "placeholders": {} + }, + "fromTheInvitation": "", + "@fromTheInvitation": { + "type": "text", + "placeholders": {} + }, + "sendMessages": "", + "@sendMessages": { + "type": "text", + "placeholders": {} + }, + "incorrectPassphraseOrKey": "", + "@incorrectPassphraseOrKey": { + "type": "text", + "placeholders": {} + }, + "emoteWarnNeedToPick": "", + "@emoteWarnNeedToPick": { + "type": "text", + "placeholders": {} + }, + "reopenChat": "", + "@reopenChat": {}, + "pleaseEnterRecoveryKey": "", + "@pleaseEnterRecoveryKey": {}, + "create": "", + "@create": { + "type": "text", + "placeholders": {} + }, + "toggleFavorite": "", + "@toggleFavorite": { + "type": "text", + "placeholders": {} + }, + "no": "", + "@no": { + "type": "text", + "placeholders": {} + }, + "alias": "", + "@alias": { + "type": "text", + "placeholders": {} + }, + "widgetNameError": "", + "@widgetNameError": {}, + "inoffensive": "", + "@inoffensive": { + "type": "text", + "placeholders": {} + }, + "unpin": "", + "@unpin": { + "type": "text", + "placeholders": {} + }, + "addToBundle": "", + "@addToBundle": {}, + "reportMessage": "", + "@reportMessage": { + "type": "text", + "placeholders": {} + }, + "spaceIsPublic": "", + "@spaceIsPublic": { + "type": "text", + "placeholders": {} + }, + "addWidget": "", + "@addWidget": {}, + "all": "", + "@all": { + "type": "text", + "placeholders": {} + }, + "removeAllOtherDevices": "", + "@removeAllOtherDevices": { + "type": "text", + "placeholders": {} + }, + "unblockDevice": "", + "@unblockDevice": { + "type": "text", + "placeholders": {} + }, + "countFiles": "", + "@countFiles": { + "placeholders": { + "count": {} + } + }, + "noKeyForThisMessage": "", + "@noKeyForThisMessage": {}, + "enableEncryptionWarning": "", + "@enableEncryptionWarning": { + "type": "text", + "placeholders": {} + }, + "inviteText": "", + "@inviteText": { + "type": "text", + "placeholders": { + "username": {}, + "link": {} + } + }, + "shareLocation": "", + "@shareLocation": { + "type": "text", + "placeholders": {} + }, + "reason": "", + "@reason": { + "type": "text", + "placeholders": {} + }, + "commandHint_markasgroup": "", + "@commandHint_markasgroup": {}, + "editTodo": "", + "@editTodo": {}, + "errorObtainingLocation": "", + "@errorObtainingLocation": { + "type": "text", + "placeholders": { + "error": {} + } + }, + "hydrateTor": "", + "@hydrateTor": {}, + "pushNotificationsNotAvailable": "", + "@pushNotificationsNotAvailable": {}, + "passwordRecovery": "", + "@passwordRecovery": { + "type": "text", + "placeholders": {} + }, + "storeInAppleKeyChain": "", + "@storeInAppleKeyChain": {}, + "replaceRoomWithNewerVersion": "", + "@replaceRoomWithNewerVersion": { + "type": "text", + "placeholders": {} + }, + "hydrate": "", + "@hydrate": {}, + "invalidServerName": "", + "@invalidServerName": {}, + "chatPermissions": "", + "@chatPermissions": {}, + "voiceMessage": "", + "@voiceMessage": { + "type": "text", + "placeholders": {} + }, + "badServerLoginTypesException": "", + "@badServerLoginTypesException": { + "type": "text", + "placeholders": { + "serverVersions": {}, + "supportedVersions": {} + } + }, + "wipeChatBackup": "", + "@wipeChatBackup": { + "type": "text", + "placeholders": {} + }, + "cantOpenUri": "", + "@cantOpenUri": { + "type": "text", + "placeholders": { + "uri": {} + } + }, + "sender": "", + "@sender": {}, + "storeInAndroidKeystore": "", + "@storeInAndroidKeystore": {}, + "optionalGroupName": "", + "@optionalGroupName": { + "type": "text", + "placeholders": {} + }, + "hideRedactedEvents": "", + "@hideRedactedEvents": { + "type": "text", + "placeholders": {} + }, + "online": "", + "@online": { + "type": "text", + "placeholders": {} + }, + "signInWithPassword": "", + "@signInWithPassword": {}, + "pleaseAddATitle": "", + "@pleaseAddATitle": {}, + "updateNow": "", + "@updateNow": {}, + "ignoredUsers": "", + "@ignoredUsers": { + "type": "text", + "placeholders": {} + }, + "lastActiveAgo": "", + "@lastActiveAgo": { + "type": "text", + "placeholders": { + "localizedTimeShort": {} + } + }, + "changedTheGuestAccessRulesTo": "", + "@changedTheGuestAccessRulesTo": { + "type": "text", + "placeholders": { + "username": {}, + "rules": {} + } + }, + "weSentYouAnEmail": "", + "@weSentYouAnEmail": { + "type": "text", + "placeholders": {} + }, + "offensive": "", + "@offensive": { + "type": "text", + "placeholders": {} + }, + "needPantalaimonWarning": "", + "@needPantalaimonWarning": { + "type": "text", + "placeholders": {} + }, + "makeAdminDescription": "", + "@makeAdminDescription": {}, + "edit": "", + "@edit": { + "type": "text", + "placeholders": {} + }, + "loadMore": "", + "@loadMore": { + "type": "text", + "placeholders": {} + }, + "noEmotesFound": "", + "@noEmotesFound": { + "type": "text", + "placeholders": {} + }, + "synchronizingPleaseWait": "", + "@synchronizingPleaseWait": { + "type": "text", + "placeholders": {} + }, + "transferFromAnotherDevice": "", + "@transferFromAnotherDevice": { + "type": "text", + "placeholders": {} + }, + "passwordHasBeenChanged": "", + "@passwordHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "pushRules": "", + "@pushRules": { + "type": "text", + "placeholders": {} + }, + "goToTheNewRoom": "", + "@goToTheNewRoom": { + "type": "text", + "placeholders": {} + }, + "commandHint_clearcache": "", + "@commandHint_clearcache": { + "type": "text", + "description": "Usage hint for the command /clearcache" + }, + "loadingPleaseWait": "", + "@loadingPleaseWait": { + "type": "text", + "placeholders": {} + }, + "copy": "", + "@copy": { + "type": "text", + "placeholders": {} + }, + "saveKeyManuallyDescription": "", + "@saveKeyManuallyDescription": {}, + "none": "", + "@none": { + "type": "text", + "placeholders": {} + }, + "editBundlesForAccount": "", + "@editBundlesForAccount": {}, + "renderRichContent": "", + "@renderRichContent": { + "type": "text", + "placeholders": {} + }, + "enableEncryption": "", + "@enableEncryption": { + "type": "text", + "placeholders": {} + }, + "whyIsThisMessageEncrypted": "", + "@whyIsThisMessageEncrypted": {}, + "rejectedTheInvitation": "", + "@rejectedTheInvitation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "setChatDescription": "", + "@setChatDescription": {}, + "userLeftTheChat": "", + "@userLeftTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "spaceName": "", + "@spaceName": { + "type": "text", + "placeholders": {} + }, + "importFromZipFile": "", + "@importFromZipFile": {}, + "discover": "", + "@discover": { + "type": "text", + "placeholders": {} + }, + "toggleUnread": "", + "@toggleUnread": { + "type": "text", + "placeholders": {} + }, + "or": "", + "@or": { + "type": "text", + "placeholders": {} + }, + "dehydrateWarning": "", + "@dehydrateWarning": {}, + "sendOriginal": "", + "@sendOriginal": { + "type": "text", + "placeholders": {} + }, + "noOtherDevicesFound": "", + "@noOtherDevicesFound": {}, + "whoIsAllowedToJoinThisGroup": "", + "@whoIsAllowedToJoinThisGroup": { + "type": "text", + "placeholders": {} + }, + "emptyChat": "", + "@emptyChat": { + "type": "text", + "placeholders": {} + }, + "seenByUser": "", + "@seenByUser": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "yourChatBackupHasBeenSetUp": "", + "@yourChatBackupHasBeenSetUp": {}, + "addDescription": "", + "@addDescription": {}, + "chatBackup": "", + "@chatBackup": { + "type": "text", + "placeholders": {} + }, + "redactedBy": "", + "@redactedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "submit": "", + "@submit": { + "type": "text", + "placeholders": {} + }, + "videoCallsBetaWarning": "", + "@videoCallsBetaWarning": {}, + "unmuteChat": "", + "@unmuteChat": { + "type": "text", + "placeholders": {} + }, + "createdTheChat": "", + "@createdTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "redactedAnEvent": "", + "@redactedAnEvent": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "autoplayImages": "", + "@autoplayImages": { + "type": "text", + "placeholder": {} + }, + "storyPrivacyWarning": "", + "@storyPrivacyWarning": {}, + "compareEmojiMatch": "", + "@compareEmojiMatch": { + "type": "text", + "placeholders": {} + }, + "matrixWidgets": "", + "@matrixWidgets": {}, + "participant": "", + "@participant": { + "type": "text", + "placeholders": {} + }, + "logInTo": "", + "@logInTo": { + "type": "text", + "placeholders": { + "homeserver": {} + } + }, + "yes": "", + "@yes": { + "type": "text", + "placeholders": {} + }, + "containsDisplayName": "", + "@containsDisplayName": { + "type": "text", + "placeholders": {} + }, + "signInWith": "", + "@signInWith": { + "type": "text", + "placeholders": { + "provider": {} + } + }, + "username": "", + "@username": { + "type": "text", + "placeholders": {} + }, + "changedTheRoomAliases": "", + "@changedTheRoomAliases": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "updateAvailable": "", + "@updateAvailable": {}, + "fileIsTooBigForServer": "", + "@fileIsTooBigForServer": {}, + "homeserver": "", + "@homeserver": {}, + "help": "", + "@help": { + "type": "text", + "placeholders": {} + }, + "noTodosYet": "", + "@noTodosYet": {}, + "chatDetails": "", + "@chatDetails": { + "type": "text", + "placeholders": {} + }, + "people": "", + "@people": { + "type": "text", + "placeholders": {} + }, + "changedTheHistoryVisibilityTo": "", + "@changedTheHistoryVisibilityTo": { + "type": "text", + "placeholders": { + "username": {}, + "rules": {} + } + }, + "leftTheChat": "", + "@leftTheChat": { + "type": "text", + "placeholders": {} + }, + "verified": "", + "@verified": { + "type": "text", + "placeholders": {} + }, + "repeatPassword": "", + "@repeatPassword": {}, + "setStatus": "", + "@setStatus": { + "type": "text", + "placeholders": {} + }, + "groupWith": "", + "@groupWith": { + "type": "text", + "placeholders": { + "displayname": {} + } + }, + "callingPermissions": "", + "@callingPermissions": {}, + "delete": "", + "@delete": { + "type": "text", + "placeholders": {} + }, + "newMessageInFluffyChat": "", + "@newMessageInFluffyChat": { + "type": "text", + "placeholders": {} + }, + "readUpToHere": "", + "@readUpToHere": {}, + "start": "", + "@start": {}, + "bubbleSize": "", + "@bubbleSize": { + "type": "text", + "placeholders": {} + }, + "downloadFile": "", + "@downloadFile": { + "type": "text", + "placeholders": {} + }, + "deviceId": "", + "@deviceId": { + "type": "text", + "placeholders": {} + }, + "register": "", + "@register": { + "type": "text", + "placeholders": {} + }, + "unlockOldMessages": "", + "@unlockOldMessages": {}, + "identity": "", + "@identity": { + "type": "text", + "placeholders": {} + }, + "numChats": "", + "@numChats": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "changedTheJoinRulesTo": "", + "@changedTheJoinRulesTo": { + "type": "text", + "placeholders": { + "username": {}, + "joinRules": {} + } + }, + "ignore": "", + "@ignore": { + "type": "text", + "placeholders": {} + }, + "whatIsGoingOn": "", + "@whatIsGoingOn": {}, + "recording": "", + "@recording": { + "type": "text", + "placeholders": {} + }, + "changedTheChatPermissions": "", + "@changedTheChatPermissions": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changeWallpaper": "", + "@changeWallpaper": { + "type": "text", + "placeholders": {} + }, + "moderator": "", + "@moderator": { + "type": "text", + "placeholders": {} + }, + "optionalRedactReason": "", + "@optionalRedactReason": {}, + "waitingPartnerEmoji": "", + "@waitingPartnerEmoji": { + "type": "text", + "placeholders": {} + }, + "channelCorruptedDecryptError": "", + "@channelCorruptedDecryptError": { + "type": "text", + "placeholders": {} + }, + "tryToSendAgain": "", + "@tryToSendAgain": { + "type": "text", + "placeholders": {} + }, + "guestsCanJoin": "", + "@guestsCanJoin": { + "type": "text", + "placeholders": {} + }, + "copyToClipboard": "", + "@copyToClipboard": { + "type": "text", + "placeholders": {} + }, + "dehydrate": "", + "@dehydrate": {}, + "locationPermissionDeniedNotice": "", + "@locationPermissionDeniedNotice": { + "type": "text", + "placeholders": {} + }, + "send": "", + "@send": { + "type": "text", + "placeholders": {} + }, + "hasWithdrawnTheInvitationFor": "", + "@hasWithdrawnTheInvitationFor": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "visibleForAllParticipants": "", + "@visibleForAllParticipants": { + "type": "text", + "placeholders": {} + }, + "noRoomsFound": "", + "@noRoomsFound": { + "type": "text", + "placeholders": {} + }, + "banned": "", + "@banned": { + "type": "text", + "placeholders": {} + }, + "sendAsText": "", + "@sendAsText": { + "type": "text" + }, + "inviteForMe": "", + "@inviteForMe": { + "type": "text", + "placeholders": {} + }, + "archiveRoomDescription": "", + "@archiveRoomDescription": {}, + "exportEmotePack": "", + "@exportEmotePack": {}, + "changedTheChatNameTo": "", + "@changedTheChatNameTo": { + "type": "text", + "placeholders": { + "username": {}, + "chatname": {} + } + }, + "sendSticker": "", + "@sendSticker": { + "type": "text", + "placeholders": {} + }, + "switchToAccount": "", + "@switchToAccount": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "commandInvalid": "", + "@commandInvalid": { + "type": "text" + }, + "setAsCanonicalAlias": "", + "@setAsCanonicalAlias": { + "type": "text", + "placeholders": {} + }, + "whyDoYouWantToReportThis": "", + "@whyDoYouWantToReportThis": { + "type": "text", + "placeholders": {} + }, + "locationDisabledNotice": "", + "@locationDisabledNotice": { + "type": "text", + "placeholders": {} + }, + "letsStart": "", + "@letsStart": {}, + "removedBy": "", + "@removedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheRoomInvitationLink": "", + "@changedTheRoomInvitationLink": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "newChat": "", + "@newChat": { + "type": "text", + "placeholders": {} + }, + "notifications": "", + "@notifications": { + "type": "text", + "placeholders": {} + }, + "commandHint_plain": "", + "@commandHint_plain": { + "type": "text", + "description": "Usage hint for the command /plain" + }, + "emoteSettings": "", + "@emoteSettings": { + "type": "text", + "placeholders": {} + }, + "experimentalVideoCalls": "", + "@experimentalVideoCalls": {}, + "savedEmotePack": "", + "@savedEmotePack": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "openCamera": "", + "@openCamera": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterRecoveryKeyDescription": "", + "@pleaseEnterRecoveryKeyDescription": {}, + "guestsAreForbidden": "", + "@guestsAreForbidden": { + "type": "text", + "placeholders": {} + }, + "mention": "", + "@mention": { + "type": "text", + "placeholders": {} + }, + "openInMaps": "", + "@openInMaps": { + "type": "text", + "placeholders": {} + }, + "withTheseAddressesRecoveryDescription": "", + "@withTheseAddressesRecoveryDescription": { + "type": "text", + "placeholders": {} + }, + "inviteContactToGroupQuestion": "", + "@inviteContactToGroupQuestion": {}, + "emoteExists": "", + "@emoteExists": { + "type": "text", + "placeholders": {} + }, + "redactedByBecause": "", + "@redactedByBecause": { + "type": "text", + "placeholders": { + "username": {}, + "reason": {} + } + }, + "isTyping": "", + "@isTyping": { + "type": "text", + "placeholders": {} + }, + "youHaveWithdrawnTheInvitationFor": "", + "@youHaveWithdrawnTheInvitationFor": { + "placeholders": { + "user": {} + } + }, + "chat": "", + "@chat": { + "type": "text", + "placeholders": {} + }, + "group": "", + "@group": { + "type": "text", + "placeholders": {} + }, + "leave": "", + "@leave": { + "type": "text", + "placeholders": {} + }, + "skip": "", + "@skip": { + "type": "text", + "placeholders": {} + }, + "appearOnTopDetails": "", + "@appearOnTopDetails": {}, + "roomHasBeenUpgraded": "", + "@roomHasBeenUpgraded": { + "type": "text", + "placeholders": {} + }, + "enterRoom": "", + "@enterRoom": {}, + "enableEmotesGlobally": "", + "@enableEmotesGlobally": { + "type": "text", + "placeholders": {} + }, + "areYouSure": "", + "@areYouSure": { + "type": "text", + "placeholders": {} + }, + "ignoreListDescription": "", + "@ignoreListDescription": { + "type": "text", + "placeholders": {} + }, + "pleaseChooseAPasscode": "", + "@pleaseChooseAPasscode": { + "type": "text", + "placeholders": {} + }, + "noPasswordRecoveryDescription": "", + "@noPasswordRecoveryDescription": { + "type": "text", + "placeholders": {} + }, + "changedTheProfileAvatar": "", + "@changedTheProfileAvatar": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "allChats": "", + "@allChats": { + "type": "text", + "placeholders": {} + }, + "reportUser": "", + "@reportUser": {}, + "commandHint_send": "", + "@commandHint_send": { + "type": "text", + "description": "Usage hint for the command /send" + }, + "onlineKeyBackupEnabled": "", + "@onlineKeyBackupEnabled": { + "type": "text", + "placeholders": {} + }, + "unbannedUser": "", + "@unbannedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "confirmEventUnpin": "", + "@confirmEventUnpin": {}, + "badServerVersionsException": "", + "@badServerVersionsException": { + "type": "text", + "placeholders": { + "serverVersions": {}, + "supportedVersions": {} + } + }, + "youInvitedUser": "", + "@youInvitedUser": { + "placeholders": { + "user": {} + } + }, + "kickedAndBanned": "", + "@kickedAndBanned": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "noConnectionToTheServer": "", + "@noConnectionToTheServer": { + "type": "text", + "placeholders": {} + }, + "fileHasBeenSavedAt": "", + "@fileHasBeenSavedAt": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "license": "", + "@license": { + "type": "text", + "placeholders": {} + }, + "addToSpace": "", + "@addToSpace": {}, + "importZipFile": "", + "@importZipFile": {}, + "anyoneCanKnock": "", + "@anyoneCanKnock": {}, + "commandMissing": "", + "@commandMissing": { + "type": "text", + "placeholders": { + "command": {} + }, + "description": "State that {command} is not a valid /command." + }, + "redactMessageDescription": "", + "@redactMessageDescription": {}, + "rejoin": "", + "@rejoin": { + "type": "text", + "placeholders": {} + }, + "recoveryKey": "", + "@recoveryKey": {}, + "redactMessage": "", + "@redactMessage": { + "type": "text", + "placeholders": {} + }, + "forward": "", + "@forward": { + "type": "text", + "placeholders": {} + }, + "commandHint_discardsession": "", + "@commandHint_discardsession": { + "type": "text", + "description": "Usage hint for the command /discardsession" + }, + "invalidInput": "", + "@invalidInput": {}, + "chooseAStrongPassword": "", + "@chooseAStrongPassword": { + "type": "text", + "placeholders": {} + }, + "hideUnknownEvents": "", + "@hideUnknownEvents": { + "type": "text", + "placeholders": {} + }, + "todosUnencrypted": "", + "@todosUnencrypted": {}, + "dehydrateTorLong": "", + "@dehydrateTorLong": {}, + "yourPublicKey": "", + "@yourPublicKey": { + "type": "text", + "placeholders": {} + }, + "tooManyRequestsWarning": "", + "@tooManyRequestsWarning": { + "type": "text", + "placeholders": {} + }, + "invitedUser": "", + "@invitedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "kickFromChat": "", + "@kickFromChat": { + "type": "text", + "placeholders": {} + }, + "commandHint_myroomnick": "", + "@commandHint_myroomnick": { + "type": "text", + "description": "Usage hint for the command /myroomnick" + }, + "offline": "", + "@offline": { + "type": "text", + "placeholders": {} + }, + "replyHasBeenSent": "", + "@replyHasBeenSent": {}, + "noPermission": "", + "@noPermission": { + "type": "text", + "placeholders": {} + }, + "doNotShowAgain": "", + "@doNotShowAgain": {}, + "activatedEndToEndEncryption": "", + "@activatedEndToEndEncryption": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "report": "", + "@report": {}, + "status": "", + "@status": { + "type": "text", + "placeholders": {} + }, + "deny": "", + "@deny": { + "type": "text", + "placeholders": {} + }, + "compareNumbersMatch": "", + "@compareNumbersMatch": { + "type": "text", + "placeholders": {} + }, + "groupIsPublic": "", + "@groupIsPublic": { + "type": "text", + "placeholders": {} + }, + "verifyStart": "", + "@verifyStart": { + "type": "text", + "placeholders": {} + }, + "yourStory": "", + "@yourStory": {}, + "memberChanges": "", + "@memberChanges": { + "type": "text", + "placeholders": {} + }, + "joinRoom": "", + "@joinRoom": { + "type": "text", + "placeholders": {} + }, + "ignoreUsername": "", + "@ignoreUsername": { + "type": "text", + "placeholders": {} + }, + "unverified": "", + "@unverified": {}, + "fluffychat": "", + "@fluffychat": { + "type": "text", + "placeholders": {} + }, + "howOffensiveIsThisContent": "", + "@howOffensiveIsThisContent": { + "type": "text", + "placeholders": {} + }, + "serverRequiresEmail": "", + "@serverRequiresEmail": {}, + "hideUnimportantStateEvents": "", + "@hideUnimportantStateEvents": {}, + "screenSharingTitle": "", + "@screenSharingTitle": {}, + "widgetCustom": "", + "@widgetCustom": {}, + "sentCallInformations": "", + "@sentCallInformations": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "addToSpaceDescription": "", + "@addToSpaceDescription": {}, + "googlyEyesContent": "", + "@googlyEyesContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "whoCanSeeMyStoriesDesc": "", + "@whoCanSeeMyStoriesDesc": {}, + "youBannedUser": "", + "@youBannedUser": { + "placeholders": { + "user": {} + } + }, + "theyDontMatch": "", + "@theyDontMatch": { + "type": "text", + "placeholders": {} + }, + "unsubscribeStories": "", + "@unsubscribeStories": {}, + "youHaveBeenBannedFromThisChat": "", + "@youHaveBeenBannedFromThisChat": { + "type": "text", + "placeholders": {} + }, + "displaynameHasBeenChanged": "", + "@displaynameHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "loginWithOneClick": "", + "@loginWithOneClick": {}, + "addChatDescription": "", + "@addChatDescription": {}, + "sentAnAudio": "", + "@sentAnAudio": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "editRoomAvatar": "", + "@editRoomAvatar": { + "type": "text", + "placeholders": {} + }, + "encrypted": "", + "@encrypted": { + "type": "text", + "placeholders": {} + }, + "commandHint_leave": "", + "@commandHint_leave": { + "type": "text", + "description": "Usage hint for the command /leave" + }, + "commandHint_myroomavatar": "", + "@commandHint_myroomavatar": { + "type": "text", + "description": "Usage hint for the command /myroomavatar" + }, + "cancel": "", + "@cancel": { + "type": "text", + "placeholders": {} + }, + "hasKnocked": "", + "@hasKnocked": { + "placeholders": { + "user": {} + } + }, + "publish": "", + "@publish": {}, + "openLinkInBrowser": "", + "@openLinkInBrowser": {}, + "clearArchive": "", + "@clearArchive": {}, + "appLock": "", + "@appLock": { + "type": "text", + "placeholders": {} + }, + "commandHint_react": "", + "@commandHint_react": { + "type": "text", + "description": "Usage hint for the command /react" + }, + "changedTheHistoryVisibility": "", + "@changedTheHistoryVisibility": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "commandHint_me": "", + "@commandHint_me": { + "type": "text", + "description": "Usage hint for the command /me" + }, + "pleaseEnterYourUsername": "", + "@pleaseEnterYourUsername": { + "type": "text", + "placeholders": {} + }, + "messageInfo": "", + "@messageInfo": {}, + "disableEncryptionWarning": "", + "@disableEncryptionWarning": {}, + "directChat": "", + "@directChat": {}, + "noOneCanJoin": "", + "@noOneCanJoin": {}, + "encryptionNotEnabled": "", + "@encryptionNotEnabled": { + "type": "text", + "placeholders": {} + }, + "wrongPinEntered": "", + "@wrongPinEntered": { + "type": "text", + "placeholders": { + "seconds": {} + } + }, + "sendTypingNotifications": "", + "@sendTypingNotifications": {}, + "lightTheme": "", + "@lightTheme": { + "type": "text", + "placeholders": {} + }, + "inviteGroupChat": "", + "@inviteGroupChat": {}, + "appearOnTop": "", + "@appearOnTop": {}, + "invitePrivateChat": "", + "@invitePrivateChat": {}, + "verifyTitle": "", + "@verifyTitle": { + "type": "text", + "placeholders": {} + }, + "foregroundServiceRunning": "", + "@foregroundServiceRunning": {}, + "enterAnEmailAddress": "", + "@enterAnEmailAddress": { + "type": "text", + "placeholders": {} + }, + "voiceCall": "", + "@voiceCall": {}, + "commandHint_kick": "", + "@commandHint_kick": { + "type": "text", + "description": "Usage hint for the command /kick" + }, + "copiedToClipboard": "", + "@copiedToClipboard": { + "type": "text", + "placeholders": {} + }, + "createNewSpace": "", + "@createNewSpace": { + "type": "text", + "placeholders": {} + }, + "commandHint_unban": "", + "@commandHint_unban": { + "type": "text", + "description": "Usage hint for the command /unban" + }, + "unknownEncryptionAlgorithm": "", + "@unknownEncryptionAlgorithm": { + "type": "text", + "placeholders": {} + }, + "commandHint_ban": "", + "@commandHint_ban": { + "type": "text", + "description": "Usage hint for the command /ban" + }, + "importEmojis": "", + "@importEmojis": {}, + "confirm": "", + "@confirm": { + "type": "text", + "placeholders": {} + }, + "wasDirectChatDisplayName": "", + "@wasDirectChatDisplayName": { + "type": "text", + "placeholders": { + "oldDisplayName": {} + } + }, + "noChatDescriptionYet": "", + "@noChatDescriptionYet": {}, + "defaultPermissionLevel": "", + "@defaultPermissionLevel": { + "type": "text", + "placeholders": {} + }, + "newTodo": "", + "@newTodo": {}, + "removeFromBundle": "", + "@removeFromBundle": {}, + "numUsersTyping": "", + "@numUsersTyping": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "fontSize": "", + "@fontSize": { + "type": "text", + "placeholders": {} + }, + "whoCanPerformWhichAction": "", + "@whoCanPerformWhichAction": { + "type": "text", + "placeholders": {} + }, + "confirmMatrixId": "", + "@confirmMatrixId": {}, + "learnMore": "", + "@learnMore": {}, + "iHaveClickedOnLink": "", + "@iHaveClickedOnLink": { + "type": "text", + "placeholders": {} + }, + "you": "", + "@you": { + "type": "text", + "placeholders": {} + }, + "notAnImage": "", + "@notAnImage": {}, + "users": "", + "@users": {}, + "openGallery": "", + "@openGallery": {}, + "chatDescriptionHasBeenChanged": "", + "@chatDescriptionHasBeenChanged": {}, + "search": "", + "@search": { + "type": "text", + "placeholders": {} + }, + "newGroup": "", + "@newGroup": {}, + "bundleName": "", + "@bundleName": {}, + "dehydrateTor": "", + "@dehydrateTor": {}, + "todoListChangedError": "", + "@todoListChangedError": {}, + "removeFromSpace": "", + "@removeFromSpace": {}, + "enterInviteLinkOrMatrixId": "", + "@enterInviteLinkOrMatrixId": {}, + "dateAndTimeOfDay": "", + "@dateAndTimeOfDay": { + "type": "text", + "placeholders": { + "date": {}, + "timeOfDay": {} + } + }, + "commandHint_op": "", + "@commandHint_op": { + "type": "text", + "description": "Usage hint for the command /op" + }, + "commandHint_join": "", + "@commandHint_join": { + "type": "text", + "description": "Usage hint for the command /join" + }, + "sourceCode": "", + "@sourceCode": { + "type": "text", + "placeholders": {} + }, + "enterAGroupName": "", + "@enterAGroupName": { + "type": "text", + "placeholders": {} + }, + "roomUpgradeDescription": "", + "@roomUpgradeDescription": {}, + "commandHint_invite": "", + "@commandHint_invite": { + "type": "text", + "description": "Usage hint for the command /invite" + }, + "userSentUnknownEvent": "", + "@userSentUnknownEvent": { + "type": "text", + "placeholders": { + "username": {}, + "type": {} + } + }, + "scanQrCode": "", + "@scanQrCode": {}, + "logout": "", + "@logout": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterANumber": "", + "@pleaseEnterANumber": {}, + "contactHasBeenInvitedToTheGroup": "", + "@contactHasBeenInvitedToTheGroup": { + "type": "text", + "placeholders": {} + }, + "youKicked": "", + "@youKicked": { + "placeholders": { + "user": {} + } + }, + "areYouSureYouWantToLogout": "", + "@areYouSureYouWantToLogout": { + "type": "text", + "placeholders": {} + }, + "changedTheJoinRules": "", + "@changedTheJoinRules": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "profileNotFound": "", + "@profileNotFound": {}, + "jump": "", + "@jump": {}, + "groups": "", + "@groups": { + "type": "text", + "placeholders": {} + }, + "reactedWith": "", + "@reactedWith": { + "type": "text", + "placeholders": { + "sender": {}, + "reaction": {} + } + }, + "bannedUser": "", + "@bannedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "sorryThatsNotPossible": "", + "@sorryThatsNotPossible": {}, + "storyFrom": "", + "@storyFrom": { + "type": "text", + "placeholders": { + "date": {}, + "body": {} + } + }, + "videoWithSize": "", + "@videoWithSize": { + "type": "text", + "placeholders": { + "size": {} + } + }, + "oopsSomethingWentWrong": "", + "@oopsSomethingWentWrong": { + "type": "text", + "placeholders": {} + }, + "loadCountMoreParticipants": "", + "@loadCountMoreParticipants": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "shareInviteLink": "", + "@shareInviteLink": {}, + "commandHint_markasdm": "", + "@commandHint_markasdm": {}, + "recoveryKeyLost": "", + "@recoveryKeyLost": {}, + "cuddleContent": "", + "@cuddleContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "askVerificationRequest": "", + "@askVerificationRequest": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "containsUserName": "", + "@containsUserName": { + "type": "text", + "placeholders": {} + }, + "messages": "", + "@messages": { + "type": "text", + "placeholders": {} + }, + "login": "", + "@login": { + "type": "text", + "placeholders": {} + }, + "deviceKeys": "", + "@deviceKeys": {}, + "waitingPartnerNumbers": "", + "@waitingPartnerNumbers": { + "type": "text", + "placeholders": {} + }, + "noGoogleServicesWarning": "", + "@noGoogleServicesWarning": { + "type": "text", + "placeholders": {} + }, + "everythingReady": "", + "@everythingReady": { + "type": "text", + "placeholders": {} + }, + "addEmail": "", + "@addEmail": { + "type": "text", + "placeholders": {} + }, + "emoteKeyboardNoRecents": "", + "@emoteKeyboardNoRecents": { + "type": "text", + "placeholders": {} + }, + "setCustomEmotes": "", + "@setCustomEmotes": { + "type": "text", + "placeholders": {} + }, + "startedACall": "", + "@startedACall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "emoteInvalid": "", + "@emoteInvalid": { + "type": "text", + "placeholders": {} + }, + "systemTheme": "", + "@systemTheme": { + "type": "text", + "placeholders": {} + }, + "messageWillBeRemovedWarning": "", + "@messageWillBeRemovedWarning": { + "type": "text", + "placeholders": {} + }, + "endToEndEncryption": "", + "@endToEndEncryption": {}, + "notificationsEnabledForThisAccount": "", + "@notificationsEnabledForThisAccount": { + "type": "text", + "placeholders": {} + }, + "deleteMessage": "", + "@deleteMessage": { + "type": "text", + "placeholders": {} + }, + "visibilityOfTheChatHistory": "", + "@visibilityOfTheChatHistory": { + "type": "text", + "placeholders": {} + }, + "settings": "", + "@settings": { + "type": "text", + "placeholders": {} + }, + "setTheme": "", + "@setTheme": {}, + "changeTheHomeserver": "", + "@changeTheHomeserver": { + "type": "text", + "placeholders": {} + }, + "youJoinedTheChat": "", + "@youJoinedTheChat": {}, + "wallpaper": "", + "@wallpaper": { + "type": "text", + "placeholders": {} + }, + "openVideoCamera": "", + "@openVideoCamera": { + "type": "text", + "placeholders": {} + }, + "play": "", + "@play": { + "type": "text", + "placeholders": { + "fileName": {} + } + }, + "chatBackupDescription": "", + "@chatBackupDescription": { + "type": "text", + "placeholders": {} + }, + "changeDeviceName": "", + "@changeDeviceName": { + "type": "text", + "placeholders": {} + }, + "lastSeenLongTimeAgo": "", + "@lastSeenLongTimeAgo": { + "type": "text", + "placeholders": {} + }, + "passwordForgotten": "", + "@passwordForgotten": { + "type": "text", + "placeholders": {} + }, + "statusExampleMessage": "", + "@statusExampleMessage": { + "type": "text", + "placeholders": {} + }, + "thisUserHasNotPostedAnythingYet": "", + "@thisUserHasNotPostedAnythingYet": {}, + "security": "", + "@security": { + "type": "text", + "placeholders": {} + }, + "markAsRead": "", + "@markAsRead": {}, + "sendAudio": "", + "@sendAudio": { + "type": "text", + "placeholders": {} + }, + "widgetName": "", + "@widgetName": {}, + "sentASticker": "", + "@sentASticker": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "errorAddingWidget": "", + "@errorAddingWidget": {}, + "commandHint_dm": "", + "@commandHint_dm": { + "type": "text", + "description": "Usage hint for the command /dm" + }, + "commandHint_hug": "", + "@commandHint_hug": {}, + "replace": "", + "@replace": {}, + "reject": "", + "@reject": { + "type": "text", + "placeholders": {} + }, + "editBlockedServers": "", + "@editBlockedServers": { + "type": "text", + "placeholders": {} + }, + "oopsPushError": "", + "@oopsPushError": { + "type": "text", + "placeholders": {} + }, + "youUnbannedUser": "", + "@youUnbannedUser": { + "placeholders": { + "user": {} + } + }, + "deactivateAccountWarning": "", + "@deactivateAccountWarning": { + "type": "text", + "placeholders": {} + }, + "archive": "", + "@archive": { + "type": "text", + "placeholders": {} + }, + "joinedTheChat": "", + "@joinedTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "visibleForEveryone": "", + "@visibleForEveryone": { + "type": "text", + "placeholders": {} + }, + "pleaseEnter4Digits": "", + "@pleaseEnter4Digits": { + "type": "text", + "placeholders": {} + }, + "newSpace": "", + "@newSpace": {}, + "changePassword": "", + "@changePassword": { + "type": "text", + "placeholders": {} + }, + "devices": "", + "@devices": { + "type": "text", + "placeholders": {} + }, + "unknownEvent": "", + "@unknownEvent": { + "type": "text", + "placeholders": { + "type": {} + } + }, + "emojis": "", + "@emojis": {}, + "signUp": "", + "@signUp": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourPin": "", + "@pleaseEnterYourPin": { + "type": "text", + "placeholders": {} + }, + "pleaseChoose": "", + "@pleaseChoose": { + "type": "text", + "placeholders": {} + }, + "share": "", + "@share": { + "type": "text", + "placeholders": {} + }, + "commandHint_googly": "", + "@commandHint_googly": {}, + "pleaseTryAgainLaterOrChooseDifferentServer": "", + "@pleaseTryAgainLaterOrChooseDifferentServer": {}, + "createGroup": "", + "@createGroup": {}, + "privacy": "", + "@privacy": { + "type": "text", + "placeholders": {} + }, + "changeYourAvatar": "", + "@changeYourAvatar": { + "type": "text", + "placeholders": {} + }, + "sendImage": "", + "@sendImage": { + "type": "text", + "placeholders": {} + }, + "hydrateTorLong": "", + "@hydrateTorLong": {}, + "time": "", + "@time": {}, + "enterYourHomeserver": "", + "@enterYourHomeserver": { + "type": "text", + "placeholders": {} + }, + "botMessages": "", + "@botMessages": { + "type": "text", + "placeholders": {} + }, + "contentHasBeenReported": "", + "@contentHasBeenReported": { + "type": "text", + "placeholders": {} + }, + "custom": "", + "@custom": {}, + "noBackupWarning": "", + "@noBackupWarning": {}, + "fromJoining": "", + "@fromJoining": { + "type": "text", + "placeholders": {} + }, + "verify": "", + "@verify": { + "type": "text", + "placeholders": {} + }, + "sendVideo": "", + "@sendVideo": { + "type": "text", + "placeholders": {} + }, + "editWidgets": "", + "@editWidgets": {}, + "storeInSecureStorageDescription": "", + "@storeInSecureStorageDescription": {}, + "openChat": "", + "@openChat": {}, + "kickUserDescription": "", + "@kickUserDescription": {}, + "sendAMessage": "", + "@sendAMessage": { + "type": "text", + "placeholders": {} + }, + "pin": "", + "@pin": { + "type": "text", + "placeholders": {} + }, + "importNow": "", + "@importNow": {}, + "deleteAccount": "", + "@deleteAccount": { + "type": "text", + "placeholders": {} + }, + "setInvitationLink": "", + "@setInvitationLink": { + "type": "text", + "placeholders": {} + }, + "pinMessage": "", + "@pinMessage": {}, + "muteChat": "", + "@muteChat": { + "type": "text", + "placeholders": {} + }, + "invite": "", + "@invite": {}, + "enableMultiAccounts": "", + "@enableMultiAccounts": {}, + "chooseAUsername": "", + "@chooseAUsername": { + "type": "text", + "placeholders": {} + }, + "anyoneCanJoin": "", + "@anyoneCanJoin": { + "type": "text", + "placeholders": {} + }, + "emotePacks": "", + "@emotePacks": { + "type": "text", + "placeholders": {} + }, + "makeSureTheIdentifierIsValid": "", + "@makeSureTheIdentifierIsValid": { + "type": "text", + "placeholders": {} + }, + "continueWith": "", + "@continueWith": {}, + "indexedDbErrorTitle": "", + "@indexedDbErrorTitle": {}, + "pleaseChooseAUsername": "", + "@pleaseChooseAUsername": { + "type": "text", + "placeholders": {} + }, + "endedTheCall": "", + "@endedTheCall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "unsupportedAndroidVersionLong": "", + "@unsupportedAndroidVersionLong": {}, + "storeSecurlyOnThisDevice": "", + "@storeSecurlyOnThisDevice": {}, + "ok": "", + "@ok": { + "type": "text", + "placeholders": {} + }, + "passwordsDoNotMatch": "", + "@passwordsDoNotMatch": {}, + "sharedTheLocation": "", + "@sharedTheLocation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "unbanFromChat": "", + "@unbanFromChat": { + "type": "text", + "placeholders": {} + }, + "iUnderstand": "", + "@iUnderstand": {}, + "screenSharingDetail": "", + "@screenSharingDetail": {}, + "changedTheDisplaynameTo": "", + "@changedTheDisplaynameTo": { + "type": "text", + "placeholders": { + "username": {}, + "displayname": {} + } + }, + "unreadChats": "", + "@unreadChats": { + "type": "text", + "placeholders": { + "unreadCount": {} + } + }, + "pickImage": "", + "@pickImage": { + "type": "text", + "placeholders": {} + }, + "placeCall": "", + "@placeCall": {}, + "extremeOffensive": "", + "@extremeOffensive": { + "type": "text", + "placeholders": {} + } +} diff --git a/assets/l10n/intl_bo.arb b/assets/l10n/intl_bo.arb index 9e26dfeeb..d138084cf 100644 --- a/assets/l10n/intl_bo.arb +++ b/assets/l10n/intl_bo.arb @@ -1 +1,2620 @@ -{} \ No newline at end of file +{ + "showPassword": "", + "@showPassword": { + "type": "text", + "placeholders": {} + }, + "hugContent": "", + "@hugContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "darkTheme": "", + "@darkTheme": { + "type": "text", + "placeholders": {} + }, + "passphraseOrKey": "", + "@passphraseOrKey": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourPassword": "", + "@pleaseEnterYourPassword": { + "type": "text", + "placeholders": {} + }, + "theyMatch": "", + "@theyMatch": { + "type": "text", + "placeholders": {} + }, + "connect": "", + "@connect": { + "type": "text", + "placeholders": {} + }, + "jumpToLastReadMessage": "", + "@jumpToLastReadMessage": {}, + "allRooms": "", + "@allRooms": { + "type": "text", + "placeholders": {} + }, + "obtainingLocation": "", + "@obtainingLocation": { + "type": "text", + "placeholders": {} + }, + "whoCanSeeMyStories": "", + "@whoCanSeeMyStories": {}, + "commandHint_cuddle": "", + "@commandHint_cuddle": {}, + "chats": "", + "@chats": { + "type": "text", + "placeholders": {} + }, + "widgetVideo": "", + "@widgetVideo": {}, + "dismiss": "", + "@dismiss": {}, + "unknownDevice": "", + "@unknownDevice": { + "type": "text", + "placeholders": {} + }, + "emoteShortcode": "", + "@emoteShortcode": { + "type": "text", + "placeholders": {} + }, + "noEncryptionForPublicRooms": "", + "@noEncryptionForPublicRooms": { + "type": "text", + "placeholders": {} + }, + "admin": "", + "@admin": { + "type": "text", + "placeholders": {} + }, + "reportErrorDescription": "", + "@reportErrorDescription": {}, + "directChats": "", + "@directChats": { + "type": "text", + "placeholders": {} + }, + "setPermissionsLevel": "", + "@setPermissionsLevel": { + "type": "text", + "placeholders": {} + }, + "inviteContactToGroup": "", + "@inviteContactToGroup": { + "type": "text", + "placeholders": { + "groupName": {} + } + }, + "addAccount": "", + "@addAccount": {}, + "close": "", + "@close": { + "type": "text", + "placeholders": {} + }, + "configureChat": "", + "@configureChat": { + "type": "text", + "placeholders": {} + }, + "seenByUserAndUser": "", + "@seenByUserAndUser": { + "type": "text", + "placeholders": { + "username": {}, + "username2": {} + } + }, + "chatHasBeenAddedToThisSpace": "", + "@chatHasBeenAddedToThisSpace": {}, + "reply": "", + "@reply": { + "type": "text", + "placeholders": {} + }, + "currentlyActive": "", + "@currentlyActive": { + "type": "text", + "placeholders": {} + }, + "removeYourAvatar": "", + "@removeYourAvatar": { + "type": "text", + "placeholders": {} + }, + "unsupportedAndroidVersion": "", + "@unsupportedAndroidVersion": {}, + "enterASpacepName": "", + "@enterASpacepName": {}, + "device": "", + "@device": { + "type": "text", + "placeholders": {} + }, + "blockDevice": "", + "@blockDevice": { + "type": "text", + "placeholders": {} + }, + "commandHint_html": "", + "@commandHint_html": { + "type": "text", + "description": "Usage hint for the command /html" + }, + "widgetJitsi": "", + "@widgetJitsi": {}, + "youAreNoLongerParticipatingInThisChat": "", + "@youAreNoLongerParticipatingInThisChat": { + "type": "text", + "placeholders": {} + }, + "encryption": "", + "@encryption": { + "type": "text", + "placeholders": {} + }, + "messageType": "", + "@messageType": {}, + "noEmailWarning": "", + "@noEmailWarning": {}, + "indexedDbErrorLong": "", + "@indexedDbErrorLong": {}, + "oneClientLoggedOut": "", + "@oneClientLoggedOut": {}, + "toggleMuted": "", + "@toggleMuted": { + "type": "text", + "placeholders": {} + }, + "unsupportedAndroidVersionLong": "", + "@unsupportedAndroidVersionLong": {}, + "kicked": "", + "@kicked": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "title": "", + "@title": { + "description": "Title for the application", + "type": "text", + "placeholders": {} + }, + "changeTheNameOfTheGroup": "", + "@changeTheNameOfTheGroup": { + "type": "text", + "placeholders": {} + }, + "changedTheChatAvatar": "", + "@changedTheChatAvatar": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "verifySuccess": "", + "@verifySuccess": { + "type": "text", + "placeholders": {} + }, + "sendFile": "", + "@sendFile": { + "type": "text", + "placeholders": {} + }, + "newVerificationRequest": "", + "@newVerificationRequest": { + "type": "text", + "placeholders": {} + }, + "startFirstChat": "", + "@startFirstChat": {}, + "callingAccount": "", + "@callingAccount": {}, + "requestPermission": "", + "@requestPermission": { + "type": "text", + "placeholders": {} + }, + "sentAPicture": "", + "@sentAPicture": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "invited": "", + "@invited": { + "type": "text", + "placeholders": {} + }, + "changedTheDisplaynameTo": "", + "@changedTheDisplaynameTo": { + "type": "text", + "placeholders": { + "username": {}, + "displayname": {} + } + }, + "setColorTheme": "", + "@setColorTheme": {}, + "nextAccount": "", + "@nextAccount": {}, + "commandHint_create": "", + "@commandHint_create": { + "type": "text", + "description": "Usage hint for the command /create" + }, + "youAreInvitedToThisChat": "", + "@youAreInvitedToThisChat": { + "type": "text", + "placeholders": {} + }, + "singlesignon": "", + "@singlesignon": { + "type": "text", + "placeholders": {} + }, + "warning": "", + "@warning": { + "type": "text", + "placeholders": {} + }, + "password": "", + "@password": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterAMatrixIdentifier": "", + "@pleaseEnterAMatrixIdentifier": { + "type": "text", + "placeholders": {} + }, + "allSpaces": "", + "@allSpaces": {}, + "supposedMxid": "", + "@supposedMxid": { + "type": "text", + "placeholders": { + "mxid": {} + } + }, + "editDisplayname": "", + "@editDisplayname": { + "type": "text", + "placeholders": {} + }, + "user": "", + "@user": {}, + "roomVersion": "", + "@roomVersion": { + "type": "text", + "placeholders": {} + }, + "sentAFile": "", + "@sentAFile": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "videoCall": "", + "@videoCall": { + "type": "text", + "placeholders": {} + }, + "youAcceptedTheInvitation": "", + "@youAcceptedTheInvitation": {}, + "banFromChat": "", + "@banFromChat": { + "type": "text", + "placeholders": {} + }, + "noMatrixServer": "", + "@noMatrixServer": { + "type": "text", + "placeholders": { + "server1": {}, + "server2": {} + } + }, + "userAndOthersAreTyping": "", + "@userAndOthersAreTyping": { + "type": "text", + "placeholders": { + "username": {}, + "count": {} + } + }, + "youInvitedBy": "", + "@youInvitedBy": { + "placeholders": { + "user": {} + } + }, + "userIsTyping": "", + "@userIsTyping": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "openAppToReadMessages": "", + "@openAppToReadMessages": { + "type": "text", + "placeholders": {} + }, + "sentAVideo": "", + "@sentAVideo": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "banUserDescription": "", + "@banUserDescription": {}, + "inviteContact": "", + "@inviteContact": { + "type": "text", + "placeholders": {} + }, + "requests": "", + "@requests": {}, + "askSSSSSign": "", + "@askSSSSSign": { + "type": "text", + "placeholders": {} + }, + "widgetEtherpad": "", + "@widgetEtherpad": {}, + "waitingPartnerAcceptRequest": "", + "@waitingPartnerAcceptRequest": { + "type": "text", + "placeholders": {} + }, + "remove": "", + "@remove": { + "type": "text", + "placeholders": {} + }, + "writeAMessage": "", + "@writeAMessage": { + "type": "text", + "placeholders": {} + }, + "changeTheme": "", + "@changeTheme": { + "type": "text", + "placeholders": {} + }, + "stories": "", + "@stories": {}, + "id": "", + "@id": { + "type": "text", + "placeholders": {} + }, + "addToStory": "", + "@addToStory": {}, + "removeDevicesDescription": "", + "@removeDevicesDescription": {}, + "changedTheChatDescriptionTo": "", + "@changedTheChatDescriptionTo": { + "type": "text", + "placeholders": { + "username": {}, + "description": {} + } + }, + "countParticipants": "", + "@countParticipants": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "separateChatTypes": "", + "@separateChatTypes": { + "type": "text", + "placeholders": {} + }, + "tryAgain": "", + "@tryAgain": {}, + "areGuestsAllowedToJoin": "", + "@areGuestsAllowedToJoin": { + "type": "text", + "placeholders": {} + }, + "blocked": "", + "@blocked": { + "type": "text", + "placeholders": {} + }, + "youKickedAndBanned": "", + "@youKickedAndBanned": { + "placeholders": { + "user": {} + } + }, + "dateWithoutYear": "", + "@dateWithoutYear": { + "type": "text", + "placeholders": { + "month": {}, + "day": {} + } + }, + "showDirectChatsInSpaces": "", + "@showDirectChatsInSpaces": { + "type": "text", + "placeholders": {} + }, + "removeDevice": "", + "@removeDevice": { + "type": "text", + "placeholders": {} + }, + "youCannotInviteYourself": "", + "@youCannotInviteYourself": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterValidEmail": "", + "@pleaseEnterValidEmail": {}, + "unbanUserDescription": "", + "@unbanUserDescription": {}, + "todoLists": "", + "@todoLists": {}, + "userAndUserAreTyping": "", + "@userAndUserAreTyping": { + "type": "text", + "placeholders": { + "username": {}, + "username2": {} + } + }, + "pleaseClickOnLink": "", + "@pleaseClickOnLink": { + "type": "text", + "placeholders": {} + }, + "saveFile": "", + "@saveFile": { + "type": "text", + "placeholders": {} + }, + "sendOnEnter": "", + "@sendOnEnter": {}, + "seenByUserAndCountOthers": "", + "@seenByUserAndCountOthers": { + "type": "text", + "placeholders": { + "username": {}, + "count": {} + } + }, + "pickImage": "", + "@pickImage": { + "type": "text", + "placeholders": {} + }, + "answeredTheCall": "", + "@answeredTheCall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "youRejectedTheInvitation": "", + "@youRejectedTheInvitation": {}, + "otherCallingPermissions": "", + "@otherCallingPermissions": {}, + "messagesStyle": "", + "@messagesStyle": {}, + "couldNotDecryptMessage": "", + "@couldNotDecryptMessage": { + "type": "text", + "placeholders": { + "error": {} + } + }, + "invitedUsersOnly": "", + "@invitedUsersOnly": { + "type": "text", + "placeholders": {} + }, + "link": "", + "@link": {}, + "widgetUrlError": "", + "@widgetUrlError": {}, + "emailOrUsername": "", + "@emailOrUsername": {}, + "newSpaceDescription": "", + "@newSpaceDescription": {}, + "chatDescription": "", + "@chatDescription": {}, + "callingAccountDetails": "", + "@callingAccountDetails": {}, + "next": "", + "@next": { + "type": "text", + "placeholders": {} + }, + "pleaseFollowInstructionsOnWeb": "", + "@pleaseFollowInstructionsOnWeb": { + "type": "text", + "placeholders": {} + }, + "changedTheGuestAccessRules": "", + "@changedTheGuestAccessRules": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "pleaseChooseAtLeastChars": "", + "@pleaseChooseAtLeastChars": { + "type": "text", + "placeholders": { + "min": {} + } + }, + "dateWithYear": "", + "@dateWithYear": { + "type": "text", + "placeholders": { + "year": {}, + "month": {}, + "day": {} + } + }, + "editRoomAliases": "", + "@editRoomAliases": { + "type": "text", + "placeholders": {} + }, + "enterSpace": "", + "@enterSpace": {}, + "encryptThisChat": "", + "@encryptThisChat": {}, + "fileName": "", + "@fileName": { + "type": "text", + "placeholders": {} + }, + "unavailable": "", + "@unavailable": { + "type": "text", + "placeholders": {} + }, + "previousAccount": "", + "@previousAccount": {}, + "publicRooms": "", + "@publicRooms": { + "type": "text", + "placeholders": {} + }, + "fromTheInvitation": "", + "@fromTheInvitation": { + "type": "text", + "placeholders": {} + }, + "sendMessages": "", + "@sendMessages": { + "type": "text", + "placeholders": {} + }, + "incorrectPassphraseOrKey": "", + "@incorrectPassphraseOrKey": { + "type": "text", + "placeholders": {} + }, + "emoteWarnNeedToPick": "", + "@emoteWarnNeedToPick": { + "type": "text", + "placeholders": {} + }, + "reopenChat": "", + "@reopenChat": {}, + "pleaseEnterRecoveryKey": "", + "@pleaseEnterRecoveryKey": {}, + "create": "", + "@create": { + "type": "text", + "placeholders": {} + }, + "toggleFavorite": "", + "@toggleFavorite": { + "type": "text", + "placeholders": {} + }, + "no": "", + "@no": { + "type": "text", + "placeholders": {} + }, + "alias": "", + "@alias": { + "type": "text", + "placeholders": {} + }, + "widgetNameError": "", + "@widgetNameError": {}, + "inoffensive": "", + "@inoffensive": { + "type": "text", + "placeholders": {} + }, + "unpin": "", + "@unpin": { + "type": "text", + "placeholders": {} + }, + "addToBundle": "", + "@addToBundle": {}, + "reportMessage": "", + "@reportMessage": { + "type": "text", + "placeholders": {} + }, + "spaceIsPublic": "", + "@spaceIsPublic": { + "type": "text", + "placeholders": {} + }, + "addWidget": "", + "@addWidget": {}, + "all": "", + "@all": { + "type": "text", + "placeholders": {} + }, + "removeAllOtherDevices": "", + "@removeAllOtherDevices": { + "type": "text", + "placeholders": {} + }, + "unblockDevice": "", + "@unblockDevice": { + "type": "text", + "placeholders": {} + }, + "countFiles": "", + "@countFiles": { + "placeholders": { + "count": {} + } + }, + "noKeyForThisMessage": "", + "@noKeyForThisMessage": {}, + "enableEncryptionWarning": "", + "@enableEncryptionWarning": { + "type": "text", + "placeholders": {} + }, + "inviteText": "", + "@inviteText": { + "type": "text", + "placeholders": { + "username": {}, + "link": {} + } + }, + "shareLocation": "", + "@shareLocation": { + "type": "text", + "placeholders": {} + }, + "reason": "", + "@reason": { + "type": "text", + "placeholders": {} + }, + "commandHint_markasgroup": "", + "@commandHint_markasgroup": {}, + "editTodo": "", + "@editTodo": {}, + "errorObtainingLocation": "", + "@errorObtainingLocation": { + "type": "text", + "placeholders": { + "error": {} + } + }, + "hydrateTor": "", + "@hydrateTor": {}, + "pushNotificationsNotAvailable": "", + "@pushNotificationsNotAvailable": {}, + "passwordRecovery": "", + "@passwordRecovery": { + "type": "text", + "placeholders": {} + }, + "storeInAppleKeyChain": "", + "@storeInAppleKeyChain": {}, + "replaceRoomWithNewerVersion": "", + "@replaceRoomWithNewerVersion": { + "type": "text", + "placeholders": {} + }, + "hydrate": "", + "@hydrate": {}, + "invalidServerName": "", + "@invalidServerName": {}, + "chatPermissions": "", + "@chatPermissions": {}, + "voiceMessage": "", + "@voiceMessage": { + "type": "text", + "placeholders": {} + }, + "badServerLoginTypesException": "", + "@badServerLoginTypesException": { + "type": "text", + "placeholders": { + "serverVersions": {}, + "supportedVersions": {} + } + }, + "wipeChatBackup": "", + "@wipeChatBackup": { + "type": "text", + "placeholders": {} + }, + "cantOpenUri": "", + "@cantOpenUri": { + "type": "text", + "placeholders": { + "uri": {} + } + }, + "sender": "", + "@sender": {}, + "storeInAndroidKeystore": "", + "@storeInAndroidKeystore": {}, + "optionalGroupName": "", + "@optionalGroupName": { + "type": "text", + "placeholders": {} + }, + "hideRedactedEvents": "", + "@hideRedactedEvents": { + "type": "text", + "placeholders": {} + }, + "online": "", + "@online": { + "type": "text", + "placeholders": {} + }, + "signInWithPassword": "", + "@signInWithPassword": {}, + "pleaseAddATitle": "", + "@pleaseAddATitle": {}, + "updateNow": "", + "@updateNow": {}, + "ignoredUsers": "", + "@ignoredUsers": { + "type": "text", + "placeholders": {} + }, + "lastActiveAgo": "", + "@lastActiveAgo": { + "type": "text", + "placeholders": { + "localizedTimeShort": {} + } + }, + "changedTheGuestAccessRulesTo": "", + "@changedTheGuestAccessRulesTo": { + "type": "text", + "placeholders": { + "username": {}, + "rules": {} + } + }, + "weSentYouAnEmail": "", + "@weSentYouAnEmail": { + "type": "text", + "placeholders": {} + }, + "offensive": "", + "@offensive": { + "type": "text", + "placeholders": {} + }, + "needPantalaimonWarning": "", + "@needPantalaimonWarning": { + "type": "text", + "placeholders": {} + }, + "makeAdminDescription": "", + "@makeAdminDescription": {}, + "edit": "", + "@edit": { + "type": "text", + "placeholders": {} + }, + "loadMore": "", + "@loadMore": { + "type": "text", + "placeholders": {} + }, + "noEmotesFound": "", + "@noEmotesFound": { + "type": "text", + "placeholders": {} + }, + "synchronizingPleaseWait": "", + "@synchronizingPleaseWait": { + "type": "text", + "placeholders": {} + }, + "transferFromAnotherDevice": "", + "@transferFromAnotherDevice": { + "type": "text", + "placeholders": {} + }, + "passwordHasBeenChanged": "", + "@passwordHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "pushRules": "", + "@pushRules": { + "type": "text", + "placeholders": {} + }, + "goToTheNewRoom": "", + "@goToTheNewRoom": { + "type": "text", + "placeholders": {} + }, + "commandHint_clearcache": "", + "@commandHint_clearcache": { + "type": "text", + "description": "Usage hint for the command /clearcache" + }, + "loadingPleaseWait": "", + "@loadingPleaseWait": { + "type": "text", + "placeholders": {} + }, + "copy": "", + "@copy": { + "type": "text", + "placeholders": {} + }, + "saveKeyManuallyDescription": "", + "@saveKeyManuallyDescription": {}, + "none": "", + "@none": { + "type": "text", + "placeholders": {} + }, + "editBundlesForAccount": "", + "@editBundlesForAccount": {}, + "renderRichContent": "", + "@renderRichContent": { + "type": "text", + "placeholders": {} + }, + "enableEncryption": "", + "@enableEncryption": { + "type": "text", + "placeholders": {} + }, + "whyIsThisMessageEncrypted": "", + "@whyIsThisMessageEncrypted": {}, + "unreadChats": "", + "@unreadChats": { + "type": "text", + "placeholders": { + "unreadCount": {} + } + }, + "rejectedTheInvitation": "", + "@rejectedTheInvitation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "setChatDescription": "", + "@setChatDescription": {}, + "userLeftTheChat": "", + "@userLeftTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "spaceName": "", + "@spaceName": { + "type": "text", + "placeholders": {} + }, + "importFromZipFile": "", + "@importFromZipFile": {}, + "discover": "", + "@discover": { + "type": "text", + "placeholders": {} + }, + "toggleUnread": "", + "@toggleUnread": { + "type": "text", + "placeholders": {} + }, + "or": "", + "@or": { + "type": "text", + "placeholders": {} + }, + "dehydrateWarning": "", + "@dehydrateWarning": {}, + "sendOriginal": "", + "@sendOriginal": { + "type": "text", + "placeholders": {} + }, + "noOtherDevicesFound": "", + "@noOtherDevicesFound": {}, + "whoIsAllowedToJoinThisGroup": "", + "@whoIsAllowedToJoinThisGroup": { + "type": "text", + "placeholders": {} + }, + "emptyChat": "", + "@emptyChat": { + "type": "text", + "placeholders": {} + }, + "seenByUser": "", + "@seenByUser": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "storeSecurlyOnThisDevice": "", + "@storeSecurlyOnThisDevice": {}, + "yourChatBackupHasBeenSetUp": "", + "@yourChatBackupHasBeenSetUp": {}, + "addDescription": "", + "@addDescription": {}, + "chatBackup": "", + "@chatBackup": { + "type": "text", + "placeholders": {} + }, + "redactedBy": "", + "@redactedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "submit": "", + "@submit": { + "type": "text", + "placeholders": {} + }, + "videoCallsBetaWarning": "", + "@videoCallsBetaWarning": {}, + "unmuteChat": "", + "@unmuteChat": { + "type": "text", + "placeholders": {} + }, + "createdTheChat": "", + "@createdTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "redactedAnEvent": "", + "@redactedAnEvent": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "autoplayImages": "", + "@autoplayImages": { + "type": "text", + "placeholder": {} + }, + "storyPrivacyWarning": "", + "@storyPrivacyWarning": {}, + "compareEmojiMatch": "", + "@compareEmojiMatch": { + "type": "text", + "placeholders": {} + }, + "matrixWidgets": "", + "@matrixWidgets": {}, + "participant": "", + "@participant": { + "type": "text", + "placeholders": {} + }, + "logInTo": "", + "@logInTo": { + "type": "text", + "placeholders": { + "homeserver": {} + } + }, + "yes": "", + "@yes": { + "type": "text", + "placeholders": {} + }, + "containsDisplayName": "", + "@containsDisplayName": { + "type": "text", + "placeholders": {} + }, + "signInWith": "", + "@signInWith": { + "type": "text", + "placeholders": { + "provider": {} + } + }, + "username": "", + "@username": { + "type": "text", + "placeholders": {} + }, + "changedTheRoomAliases": "", + "@changedTheRoomAliases": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "updateAvailable": "", + "@updateAvailable": {}, + "fileIsTooBigForServer": "", + "@fileIsTooBigForServer": {}, + "homeserver": "", + "@homeserver": {}, + "help": "", + "@help": { + "type": "text", + "placeholders": {} + }, + "noTodosYet": "", + "@noTodosYet": {}, + "chatDetails": "", + "@chatDetails": { + "type": "text", + "placeholders": {} + }, + "people": "", + "@people": { + "type": "text", + "placeholders": {} + }, + "changedTheHistoryVisibilityTo": "", + "@changedTheHistoryVisibilityTo": { + "type": "text", + "placeholders": { + "username": {}, + "rules": {} + } + }, + "leftTheChat": "", + "@leftTheChat": { + "type": "text", + "placeholders": {} + }, + "verified": "", + "@verified": { + "type": "text", + "placeholders": {} + }, + "repeatPassword": "", + "@repeatPassword": {}, + "setStatus": "", + "@setStatus": { + "type": "text", + "placeholders": {} + }, + "groupWith": "", + "@groupWith": { + "type": "text", + "placeholders": { + "displayname": {} + } + }, + "callingPermissions": "", + "@callingPermissions": {}, + "delete": "", + "@delete": { + "type": "text", + "placeholders": {} + }, + "newMessageInFluffyChat": "", + "@newMessageInFluffyChat": { + "type": "text", + "placeholders": {} + }, + "readUpToHere": "", + "@readUpToHere": {}, + "start": "", + "@start": {}, + "bubbleSize": "", + "@bubbleSize": { + "type": "text", + "placeholders": {} + }, + "downloadFile": "", + "@downloadFile": { + "type": "text", + "placeholders": {} + }, + "deviceId": "", + "@deviceId": { + "type": "text", + "placeholders": {} + }, + "register": "", + "@register": { + "type": "text", + "placeholders": {} + }, + "unlockOldMessages": "", + "@unlockOldMessages": {}, + "identity": "", + "@identity": { + "type": "text", + "placeholders": {} + }, + "numChats": "", + "@numChats": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "changedTheJoinRulesTo": "", + "@changedTheJoinRulesTo": { + "type": "text", + "placeholders": { + "username": {}, + "joinRules": {} + } + }, + "ignore": "", + "@ignore": { + "type": "text", + "placeholders": {} + }, + "whatIsGoingOn": "", + "@whatIsGoingOn": {}, + "recording": "", + "@recording": { + "type": "text", + "placeholders": {} + }, + "changedTheChatPermissions": "", + "@changedTheChatPermissions": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changeWallpaper": "", + "@changeWallpaper": { + "type": "text", + "placeholders": {} + }, + "moderator": "", + "@moderator": { + "type": "text", + "placeholders": {} + }, + "optionalRedactReason": "", + "@optionalRedactReason": {}, + "acceptedTheInvitation": "", + "@acceptedTheInvitation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "waitingPartnerEmoji": "", + "@waitingPartnerEmoji": { + "type": "text", + "placeholders": {} + }, + "channelCorruptedDecryptError": "", + "@channelCorruptedDecryptError": { + "type": "text", + "placeholders": {} + }, + "tryToSendAgain": "", + "@tryToSendAgain": { + "type": "text", + "placeholders": {} + }, + "guestsCanJoin": "", + "@guestsCanJoin": { + "type": "text", + "placeholders": {} + }, + "ok": "", + "@ok": { + "type": "text", + "placeholders": {} + }, + "copyToClipboard": "", + "@copyToClipboard": { + "type": "text", + "placeholders": {} + }, + "dehydrate": "", + "@dehydrate": {}, + "locationPermissionDeniedNotice": "", + "@locationPermissionDeniedNotice": { + "type": "text", + "placeholders": {} + }, + "send": "", + "@send": { + "type": "text", + "placeholders": {} + }, + "hasWithdrawnTheInvitationFor": "", + "@hasWithdrawnTheInvitationFor": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "visibleForAllParticipants": "", + "@visibleForAllParticipants": { + "type": "text", + "placeholders": {} + }, + "noRoomsFound": "", + "@noRoomsFound": { + "type": "text", + "placeholders": {} + }, + "banned": "", + "@banned": { + "type": "text", + "placeholders": {} + }, + "sendAsText": "", + "@sendAsText": { + "type": "text" + }, + "inviteForMe": "", + "@inviteForMe": { + "type": "text", + "placeholders": {} + }, + "archiveRoomDescription": "", + "@archiveRoomDescription": {}, + "exportEmotePack": "", + "@exportEmotePack": {}, + "changedTheChatNameTo": "", + "@changedTheChatNameTo": { + "type": "text", + "placeholders": { + "username": {}, + "chatname": {} + } + }, + "sendSticker": "", + "@sendSticker": { + "type": "text", + "placeholders": {} + }, + "account": "", + "@account": { + "type": "text", + "placeholders": {} + }, + "switchToAccount": "", + "@switchToAccount": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "commandInvalid": "", + "@commandInvalid": { + "type": "text" + }, + "setAsCanonicalAlias": "", + "@setAsCanonicalAlias": { + "type": "text", + "placeholders": {} + }, + "whyDoYouWantToReportThis": "", + "@whyDoYouWantToReportThis": { + "type": "text", + "placeholders": {} + }, + "locationDisabledNotice": "", + "@locationDisabledNotice": { + "type": "text", + "placeholders": {} + }, + "letsStart": "", + "@letsStart": {}, + "placeCall": "", + "@placeCall": {}, + "removedBy": "", + "@removedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheRoomInvitationLink": "", + "@changedTheRoomInvitationLink": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "newChat": "", + "@newChat": { + "type": "text", + "placeholders": {} + }, + "notifications": "", + "@notifications": { + "type": "text", + "placeholders": {} + }, + "commandHint_plain": "", + "@commandHint_plain": { + "type": "text", + "description": "Usage hint for the command /plain" + }, + "emoteSettings": "", + "@emoteSettings": { + "type": "text", + "placeholders": {} + }, + "experimentalVideoCalls": "", + "@experimentalVideoCalls": {}, + "savedEmotePack": "", + "@savedEmotePack": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "openCamera": "", + "@openCamera": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterRecoveryKeyDescription": "", + "@pleaseEnterRecoveryKeyDescription": {}, + "guestsAreForbidden": "", + "@guestsAreForbidden": { + "type": "text", + "placeholders": {} + }, + "mention": "", + "@mention": { + "type": "text", + "placeholders": {} + }, + "openInMaps": "", + "@openInMaps": { + "type": "text", + "placeholders": {} + }, + "withTheseAddressesRecoveryDescription": "", + "@withTheseAddressesRecoveryDescription": { + "type": "text", + "placeholders": {} + }, + "inviteContactToGroupQuestion": "", + "@inviteContactToGroupQuestion": {}, + "emoteExists": "", + "@emoteExists": { + "type": "text", + "placeholders": {} + }, + "redactedByBecause": "", + "@redactedByBecause": { + "type": "text", + "placeholders": { + "username": {}, + "reason": {} + } + }, + "isTyping": "", + "@isTyping": { + "type": "text", + "placeholders": {} + }, + "youHaveWithdrawnTheInvitationFor": "", + "@youHaveWithdrawnTheInvitationFor": { + "placeholders": { + "user": {} + } + }, + "chat": "", + "@chat": { + "type": "text", + "placeholders": {} + }, + "group": "", + "@group": { + "type": "text", + "placeholders": {} + }, + "leave": "", + "@leave": { + "type": "text", + "placeholders": {} + }, + "skip": "", + "@skip": { + "type": "text", + "placeholders": {} + }, + "appearOnTopDetails": "", + "@appearOnTopDetails": {}, + "roomHasBeenUpgraded": "", + "@roomHasBeenUpgraded": { + "type": "text", + "placeholders": {} + }, + "enterRoom": "", + "@enterRoom": {}, + "enableEmotesGlobally": "", + "@enableEmotesGlobally": { + "type": "text", + "placeholders": {} + }, + "areYouSure": "", + "@areYouSure": { + "type": "text", + "placeholders": {} + }, + "ignoreListDescription": "", + "@ignoreListDescription": { + "type": "text", + "placeholders": {} + }, + "pleaseChooseAPasscode": "", + "@pleaseChooseAPasscode": { + "type": "text", + "placeholders": {} + }, + "noPasswordRecoveryDescription": "", + "@noPasswordRecoveryDescription": { + "type": "text", + "placeholders": {} + }, + "changedTheProfileAvatar": "", + "@changedTheProfileAvatar": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "allChats": "", + "@allChats": { + "type": "text", + "placeholders": {} + }, + "reportUser": "", + "@reportUser": {}, + "passwordsDoNotMatch": "", + "@passwordsDoNotMatch": {}, + "sharedTheLocation": "", + "@sharedTheLocation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "commandHint_send": "", + "@commandHint_send": { + "type": "text", + "description": "Usage hint for the command /send" + }, + "onlineKeyBackupEnabled": "", + "@onlineKeyBackupEnabled": { + "type": "text", + "placeholders": {} + }, + "unbannedUser": "", + "@unbannedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "confirmEventUnpin": "", + "@confirmEventUnpin": {}, + "badServerVersionsException": "", + "@badServerVersionsException": { + "type": "text", + "placeholders": { + "serverVersions": {}, + "supportedVersions": {} + } + }, + "youInvitedUser": "", + "@youInvitedUser": { + "placeholders": { + "user": {} + } + }, + "kickedAndBanned": "", + "@kickedAndBanned": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "noConnectionToTheServer": "", + "@noConnectionToTheServer": { + "type": "text", + "placeholders": {} + }, + "fileHasBeenSavedAt": "", + "@fileHasBeenSavedAt": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "license": "", + "@license": { + "type": "text", + "placeholders": {} + }, + "addToSpace": "", + "@addToSpace": {}, + "unbanFromChat": "", + "@unbanFromChat": { + "type": "text", + "placeholders": {} + }, + "importZipFile": "", + "@importZipFile": {}, + "anyoneCanKnock": "", + "@anyoneCanKnock": {}, + "commandMissing": "", + "@commandMissing": { + "type": "text", + "placeholders": { + "command": {} + }, + "description": "State that {command} is not a valid /command." + }, + "redactMessageDescription": "", + "@redactMessageDescription": {}, + "rejoin": "", + "@rejoin": { + "type": "text", + "placeholders": {} + }, + "recoveryKey": "", + "@recoveryKey": {}, + "redactMessage": "", + "@redactMessage": { + "type": "text", + "placeholders": {} + }, + "forward": "", + "@forward": { + "type": "text", + "placeholders": {} + }, + "commandHint_discardsession": "", + "@commandHint_discardsession": { + "type": "text", + "description": "Usage hint for the command /discardsession" + }, + "invalidInput": "", + "@invalidInput": {}, + "about": "", + "@about": { + "type": "text", + "placeholders": {} + }, + "chooseAStrongPassword": "", + "@chooseAStrongPassword": { + "type": "text", + "placeholders": {} + }, + "hideUnknownEvents": "", + "@hideUnknownEvents": { + "type": "text", + "placeholders": {} + }, + "todosUnencrypted": "", + "@todosUnencrypted": {}, + "dehydrateTorLong": "", + "@dehydrateTorLong": {}, + "yourPublicKey": "", + "@yourPublicKey": { + "type": "text", + "placeholders": {} + }, + "tooManyRequestsWarning": "", + "@tooManyRequestsWarning": { + "type": "text", + "placeholders": {} + }, + "invitedUser": "", + "@invitedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "kickFromChat": "", + "@kickFromChat": { + "type": "text", + "placeholders": {} + }, + "commandHint_myroomnick": "", + "@commandHint_myroomnick": { + "type": "text", + "description": "Usage hint for the command /myroomnick" + }, + "offline": "", + "@offline": { + "type": "text", + "placeholders": {} + }, + "replyHasBeenSent": "", + "@replyHasBeenSent": {}, + "noPermission": "", + "@noPermission": { + "type": "text", + "placeholders": {} + }, + "doNotShowAgain": "", + "@doNotShowAgain": {}, + "activatedEndToEndEncryption": "", + "@activatedEndToEndEncryption": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "report": "", + "@report": {}, + "status": "", + "@status": { + "type": "text", + "placeholders": {} + }, + "deny": "", + "@deny": { + "type": "text", + "placeholders": {} + }, + "compareNumbersMatch": "", + "@compareNumbersMatch": { + "type": "text", + "placeholders": {} + }, + "groupIsPublic": "", + "@groupIsPublic": { + "type": "text", + "placeholders": {} + }, + "verifyStart": "", + "@verifyStart": { + "type": "text", + "placeholders": {} + }, + "yourStory": "", + "@yourStory": {}, + "memberChanges": "", + "@memberChanges": { + "type": "text", + "placeholders": {} + }, + "joinRoom": "", + "@joinRoom": { + "type": "text", + "placeholders": {} + }, + "ignoreUsername": "", + "@ignoreUsername": { + "type": "text", + "placeholders": {} + }, + "unverified": "", + "@unverified": {}, + "fluffychat": "", + "@fluffychat": { + "type": "text", + "placeholders": {} + }, + "howOffensiveIsThisContent": "", + "@howOffensiveIsThisContent": { + "type": "text", + "placeholders": {} + }, + "serverRequiresEmail": "", + "@serverRequiresEmail": {}, + "hideUnimportantStateEvents": "", + "@hideUnimportantStateEvents": {}, + "screenSharingTitle": "", + "@screenSharingTitle": {}, + "widgetCustom": "", + "@widgetCustom": {}, + "sentCallInformations": "", + "@sentCallInformations": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "addToSpaceDescription": "", + "@addToSpaceDescription": {}, + "googlyEyesContent": "", + "@googlyEyesContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "whoCanSeeMyStoriesDesc": "", + "@whoCanSeeMyStoriesDesc": {}, + "youBannedUser": "", + "@youBannedUser": { + "placeholders": { + "user": {} + } + }, + "theyDontMatch": "", + "@theyDontMatch": { + "type": "text", + "placeholders": {} + }, + "unsubscribeStories": "", + "@unsubscribeStories": {}, + "youHaveBeenBannedFromThisChat": "", + "@youHaveBeenBannedFromThisChat": { + "type": "text", + "placeholders": {} + }, + "displaynameHasBeenChanged": "", + "@displaynameHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "loginWithOneClick": "", + "@loginWithOneClick": {}, + "addChatDescription": "", + "@addChatDescription": {}, + "sentAnAudio": "", + "@sentAnAudio": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "editRoomAvatar": "", + "@editRoomAvatar": { + "type": "text", + "placeholders": {} + }, + "encrypted": "", + "@encrypted": { + "type": "text", + "placeholders": {} + }, + "commandHint_leave": "", + "@commandHint_leave": { + "type": "text", + "description": "Usage hint for the command /leave" + }, + "commandHint_myroomavatar": "", + "@commandHint_myroomavatar": { + "type": "text", + "description": "Usage hint for the command /myroomavatar" + }, + "cancel": "", + "@cancel": { + "type": "text", + "placeholders": {} + }, + "hasKnocked": "", + "@hasKnocked": { + "placeholders": { + "user": {} + } + }, + "publish": "", + "@publish": {}, + "openLinkInBrowser": "", + "@openLinkInBrowser": {}, + "clearArchive": "", + "@clearArchive": {}, + "appLock": "", + "@appLock": { + "type": "text", + "placeholders": {} + }, + "commandHint_react": "", + "@commandHint_react": { + "type": "text", + "description": "Usage hint for the command /react" + }, + "changedTheHistoryVisibility": "", + "@changedTheHistoryVisibility": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "commandHint_me": "", + "@commandHint_me": { + "type": "text", + "description": "Usage hint for the command /me" + }, + "pleaseEnterYourUsername": "", + "@pleaseEnterYourUsername": { + "type": "text", + "placeholders": {} + }, + "messageInfo": "", + "@messageInfo": {}, + "disableEncryptionWarning": "", + "@disableEncryptionWarning": {}, + "directChat": "", + "@directChat": {}, + "noOneCanJoin": "", + "@noOneCanJoin": {}, + "encryptionNotEnabled": "", + "@encryptionNotEnabled": { + "type": "text", + "placeholders": {} + }, + "wrongPinEntered": "", + "@wrongPinEntered": { + "type": "text", + "placeholders": { + "seconds": {} + } + }, + "sendTypingNotifications": "", + "@sendTypingNotifications": {}, + "lightTheme": "", + "@lightTheme": { + "type": "text", + "placeholders": {} + }, + "inviteGroupChat": "", + "@inviteGroupChat": {}, + "appearOnTop": "", + "@appearOnTop": {}, + "invitePrivateChat": "", + "@invitePrivateChat": {}, + "verifyTitle": "", + "@verifyTitle": { + "type": "text", + "placeholders": {} + }, + "foregroundServiceRunning": "", + "@foregroundServiceRunning": {}, + "enterAnEmailAddress": "", + "@enterAnEmailAddress": { + "type": "text", + "placeholders": {} + }, + "voiceCall": "", + "@voiceCall": {}, + "commandHint_kick": "", + "@commandHint_kick": { + "type": "text", + "description": "Usage hint for the command /kick" + }, + "copiedToClipboard": "", + "@copiedToClipboard": { + "type": "text", + "placeholders": {} + }, + "createNewSpace": "", + "@createNewSpace": { + "type": "text", + "placeholders": {} + }, + "commandHint_unban": "", + "@commandHint_unban": { + "type": "text", + "description": "Usage hint for the command /unban" + }, + "unknownEncryptionAlgorithm": "", + "@unknownEncryptionAlgorithm": { + "type": "text", + "placeholders": {} + }, + "commandHint_ban": "", + "@commandHint_ban": { + "type": "text", + "description": "Usage hint for the command /ban" + }, + "importEmojis": "", + "@importEmojis": {}, + "confirm": "", + "@confirm": { + "type": "text", + "placeholders": {} + }, + "wasDirectChatDisplayName": "", + "@wasDirectChatDisplayName": { + "type": "text", + "placeholders": { + "oldDisplayName": {} + } + }, + "noChatDescriptionYet": "", + "@noChatDescriptionYet": {}, + "defaultPermissionLevel": "", + "@defaultPermissionLevel": { + "type": "text", + "placeholders": {} + }, + "newTodo": "", + "@newTodo": {}, + "removeFromBundle": "", + "@removeFromBundle": {}, + "numUsersTyping": "", + "@numUsersTyping": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "fontSize": "", + "@fontSize": { + "type": "text", + "placeholders": {} + }, + "whoCanPerformWhichAction": "", + "@whoCanPerformWhichAction": { + "type": "text", + "placeholders": {} + }, + "confirmMatrixId": "", + "@confirmMatrixId": {}, + "learnMore": "", + "@learnMore": {}, + "iHaveClickedOnLink": "", + "@iHaveClickedOnLink": { + "type": "text", + "placeholders": {} + }, + "you": "", + "@you": { + "type": "text", + "placeholders": {} + }, + "notAnImage": "", + "@notAnImage": {}, + "users": "", + "@users": {}, + "openGallery": "", + "@openGallery": {}, + "chatDescriptionHasBeenChanged": "", + "@chatDescriptionHasBeenChanged": {}, + "search": "", + "@search": { + "type": "text", + "placeholders": {} + }, + "newGroup": "", + "@newGroup": {}, + "bundleName": "", + "@bundleName": {}, + "dehydrateTor": "", + "@dehydrateTor": {}, + "todoListChangedError": "", + "@todoListChangedError": {}, + "removeFromSpace": "", + "@removeFromSpace": {}, + "enterInviteLinkOrMatrixId": "", + "@enterInviteLinkOrMatrixId": {}, + "dateAndTimeOfDay": "", + "@dateAndTimeOfDay": { + "type": "text", + "placeholders": { + "date": {}, + "timeOfDay": {} + } + }, + "commandHint_op": "", + "@commandHint_op": { + "type": "text", + "description": "Usage hint for the command /op" + }, + "commandHint_join": "", + "@commandHint_join": { + "type": "text", + "description": "Usage hint for the command /join" + }, + "sourceCode": "", + "@sourceCode": { + "type": "text", + "placeholders": {} + }, + "enterAGroupName": "", + "@enterAGroupName": { + "type": "text", + "placeholders": {} + }, + "roomUpgradeDescription": "", + "@roomUpgradeDescription": {}, + "commandHint_invite": "", + "@commandHint_invite": { + "type": "text", + "description": "Usage hint for the command /invite" + }, + "userSentUnknownEvent": "", + "@userSentUnknownEvent": { + "type": "text", + "placeholders": { + "username": {}, + "type": {} + } + }, + "scanQrCode": "", + "@scanQrCode": {}, + "logout": "", + "@logout": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterANumber": "", + "@pleaseEnterANumber": {}, + "contactHasBeenInvitedToTheGroup": "", + "@contactHasBeenInvitedToTheGroup": { + "type": "text", + "placeholders": {} + }, + "youKicked": "", + "@youKicked": { + "placeholders": { + "user": {} + } + }, + "areYouSureYouWantToLogout": "", + "@areYouSureYouWantToLogout": { + "type": "text", + "placeholders": {} + }, + "changedTheJoinRules": "", + "@changedTheJoinRules": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "profileNotFound": "", + "@profileNotFound": {}, + "jump": "", + "@jump": {}, + "groups": "", + "@groups": { + "type": "text", + "placeholders": {} + }, + "reactedWith": "", + "@reactedWith": { + "type": "text", + "placeholders": { + "sender": {}, + "reaction": {} + } + }, + "bannedUser": "", + "@bannedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "iUnderstand": "", + "@iUnderstand": {}, + "sorryThatsNotPossible": "", + "@sorryThatsNotPossible": {}, + "storyFrom": "", + "@storyFrom": { + "type": "text", + "placeholders": { + "date": {}, + "body": {} + } + }, + "videoWithSize": "", + "@videoWithSize": { + "type": "text", + "placeholders": { + "size": {} + } + }, + "oopsSomethingWentWrong": "", + "@oopsSomethingWentWrong": { + "type": "text", + "placeholders": {} + }, + "loadCountMoreParticipants": "", + "@loadCountMoreParticipants": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "shareInviteLink": "", + "@shareInviteLink": {}, + "commandHint_markasdm": "", + "@commandHint_markasdm": {}, + "recoveryKeyLost": "", + "@recoveryKeyLost": {}, + "cuddleContent": "", + "@cuddleContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "askVerificationRequest": "", + "@askVerificationRequest": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "containsUserName": "", + "@containsUserName": { + "type": "text", + "placeholders": {} + }, + "messages": "", + "@messages": { + "type": "text", + "placeholders": {} + }, + "login": "", + "@login": { + "type": "text", + "placeholders": {} + }, + "deviceKeys": "", + "@deviceKeys": {}, + "waitingPartnerNumbers": "", + "@waitingPartnerNumbers": { + "type": "text", + "placeholders": {} + }, + "noGoogleServicesWarning": "", + "@noGoogleServicesWarning": { + "type": "text", + "placeholders": {} + }, + "everythingReady": "", + "@everythingReady": { + "type": "text", + "placeholders": {} + }, + "addEmail": "", + "@addEmail": { + "type": "text", + "placeholders": {} + }, + "emoteKeyboardNoRecents": "", + "@emoteKeyboardNoRecents": { + "type": "text", + "placeholders": {} + }, + "setCustomEmotes": "", + "@setCustomEmotes": { + "type": "text", + "placeholders": {} + }, + "startedACall": "", + "@startedACall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "emoteInvalid": "", + "@emoteInvalid": { + "type": "text", + "placeholders": {} + }, + "systemTheme": "", + "@systemTheme": { + "type": "text", + "placeholders": {} + }, + "messageWillBeRemovedWarning": "", + "@messageWillBeRemovedWarning": { + "type": "text", + "placeholders": {} + }, + "endToEndEncryption": "", + "@endToEndEncryption": {}, + "notificationsEnabledForThisAccount": "", + "@notificationsEnabledForThisAccount": { + "type": "text", + "placeholders": {} + }, + "deleteMessage": "", + "@deleteMessage": { + "type": "text", + "placeholders": {} + }, + "visibilityOfTheChatHistory": "", + "@visibilityOfTheChatHistory": { + "type": "text", + "placeholders": {} + }, + "settings": "", + "@settings": { + "type": "text", + "placeholders": {} + }, + "setTheme": "", + "@setTheme": {}, + "changeTheHomeserver": "", + "@changeTheHomeserver": { + "type": "text", + "placeholders": {} + }, + "youJoinedTheChat": "", + "@youJoinedTheChat": {}, + "wallpaper": "", + "@wallpaper": { + "type": "text", + "placeholders": {} + }, + "openVideoCamera": "", + "@openVideoCamera": { + "type": "text", + "placeholders": {} + }, + "play": "", + "@play": { + "type": "text", + "placeholders": { + "fileName": {} + } + }, + "chatBackupDescription": "", + "@chatBackupDescription": { + "type": "text", + "placeholders": {} + }, + "changeDeviceName": "", + "@changeDeviceName": { + "type": "text", + "placeholders": {} + }, + "lastSeenLongTimeAgo": "", + "@lastSeenLongTimeAgo": { + "type": "text", + "placeholders": {} + }, + "passwordForgotten": "", + "@passwordForgotten": { + "type": "text", + "placeholders": {} + }, + "statusExampleMessage": "", + "@statusExampleMessage": { + "type": "text", + "placeholders": {} + }, + "thisUserHasNotPostedAnythingYet": "", + "@thisUserHasNotPostedAnythingYet": {}, + "security": "", + "@security": { + "type": "text", + "placeholders": {} + }, + "markAsRead": "", + "@markAsRead": {}, + "sendAudio": "", + "@sendAudio": { + "type": "text", + "placeholders": {} + }, + "widgetName": "", + "@widgetName": {}, + "sentASticker": "", + "@sentASticker": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "errorAddingWidget": "", + "@errorAddingWidget": {}, + "commandHint_dm": "", + "@commandHint_dm": { + "type": "text", + "description": "Usage hint for the command /dm" + }, + "commandHint_hug": "", + "@commandHint_hug": {}, + "replace": "", + "@replace": {}, + "reject": "", + "@reject": { + "type": "text", + "placeholders": {} + }, + "extremeOffensive": "", + "@extremeOffensive": { + "type": "text", + "placeholders": {} + }, + "editBlockedServers": "", + "@editBlockedServers": { + "type": "text", + "placeholders": {} + }, + "oopsPushError": "", + "@oopsPushError": { + "type": "text", + "placeholders": {} + }, + "youUnbannedUser": "", + "@youUnbannedUser": { + "placeholders": { + "user": {} + } + }, + "deactivateAccountWarning": "", + "@deactivateAccountWarning": { + "type": "text", + "placeholders": {} + }, + "archive": "", + "@archive": { + "type": "text", + "placeholders": {} + }, + "joinedTheChat": "", + "@joinedTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "visibleForEveryone": "", + "@visibleForEveryone": { + "type": "text", + "placeholders": {} + }, + "pleaseEnter4Digits": "", + "@pleaseEnter4Digits": { + "type": "text", + "placeholders": {} + }, + "newSpace": "", + "@newSpace": {}, + "changePassword": "", + "@changePassword": { + "type": "text", + "placeholders": {} + }, + "devices": "", + "@devices": { + "type": "text", + "placeholders": {} + }, + "accept": "", + "@accept": { + "type": "text", + "placeholders": {} + }, + "unknownEvent": "", + "@unknownEvent": { + "type": "text", + "placeholders": { + "type": {} + } + }, + "emojis": "", + "@emojis": {}, + "signUp": "", + "@signUp": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourPin": "", + "@pleaseEnterYourPin": { + "type": "text", + "placeholders": {} + }, + "pleaseChoose": "", + "@pleaseChoose": { + "type": "text", + "placeholders": {} + }, + "share": "", + "@share": { + "type": "text", + "placeholders": {} + }, + "commandHint_googly": "", + "@commandHint_googly": {}, + "pleaseTryAgainLaterOrChooseDifferentServer": "", + "@pleaseTryAgainLaterOrChooseDifferentServer": {}, + "createGroup": "", + "@createGroup": {}, + "privacy": "", + "@privacy": { + "type": "text", + "placeholders": {} + }, + "changeYourAvatar": "", + "@changeYourAvatar": { + "type": "text", + "placeholders": {} + }, + "sendImage": "", + "@sendImage": { + "type": "text", + "placeholders": {} + }, + "hydrateTorLong": "", + "@hydrateTorLong": {}, + "time": "", + "@time": {}, + "enterYourHomeserver": "", + "@enterYourHomeserver": { + "type": "text", + "placeholders": {} + }, + "botMessages": "", + "@botMessages": { + "type": "text", + "placeholders": {} + }, + "contentHasBeenReported": "", + "@contentHasBeenReported": { + "type": "text", + "placeholders": {} + }, + "custom": "", + "@custom": {}, + "noBackupWarning": "", + "@noBackupWarning": {}, + "fromJoining": "", + "@fromJoining": { + "type": "text", + "placeholders": {} + }, + "verify": "", + "@verify": { + "type": "text", + "placeholders": {} + }, + "sendVideo": "", + "@sendVideo": { + "type": "text", + "placeholders": {} + }, + "editWidgets": "", + "@editWidgets": {}, + "storeInSecureStorageDescription": "", + "@storeInSecureStorageDescription": {}, + "openChat": "", + "@openChat": {}, + "kickUserDescription": "", + "@kickUserDescription": {}, + "sendAMessage": "", + "@sendAMessage": { + "type": "text", + "placeholders": {} + }, + "pin": "", + "@pin": { + "type": "text", + "placeholders": {} + }, + "importNow": "", + "@importNow": {}, + "deleteAccount": "", + "@deleteAccount": { + "type": "text", + "placeholders": {} + }, + "setInvitationLink": "", + "@setInvitationLink": { + "type": "text", + "placeholders": {} + }, + "pinMessage": "", + "@pinMessage": {}, + "screenSharingDetail": "", + "@screenSharingDetail": {}, + "muteChat": "", + "@muteChat": { + "type": "text", + "placeholders": {} + }, + "invite": "", + "@invite": {}, + "enableMultiAccounts": "", + "@enableMultiAccounts": {}, + "chooseAUsername": "", + "@chooseAUsername": { + "type": "text", + "placeholders": {} + }, + "anyoneCanJoin": "", + "@anyoneCanJoin": { + "type": "text", + "placeholders": {} + }, + "emotePacks": "", + "@emotePacks": { + "type": "text", + "placeholders": {} + }, + "makeSureTheIdentifierIsValid": "", + "@makeSureTheIdentifierIsValid": { + "type": "text", + "placeholders": {} + }, + "continueWith": "", + "@continueWith": {}, + "indexedDbErrorTitle": "", + "@indexedDbErrorTitle": {}, + "pleaseChooseAUsername": "", + "@pleaseChooseAUsername": { + "type": "text", + "placeholders": {} + }, + "endedTheCall": "", + "@endedTheCall": { + "type": "text", + "placeholders": { + "senderName": {} + } + } +} diff --git a/assets/l10n/intl_ca.arb b/assets/l10n/intl_ca.arb index 89427e877..d60cf517d 100644 --- a/assets/l10n/intl_ca.arb +++ b/assets/l10n/intl_ca.arb @@ -1,2016 +1,2658 @@ { - "@@last_modified": "2021-08-14 12:41:10.145728", - "about": "Quant a", - "@about": { - "type": "text", - "placeholders": {} - }, - "accept": "Accepta", - "@accept": { - "type": "text", - "placeholders": {} - }, - "acceptedTheInvitation": "{username} ha acceptat la invitació", - "@acceptedTheInvitation": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "account": "Compte", - "@account": { - "type": "text", - "placeholders": {} - }, - "activatedEndToEndEncryption": "{username} ha activat el xifratge d’extrem a extrem", - "@activatedEndToEndEncryption": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "addGroupDescription": "Afegeix descripció de grup", - "@addGroupDescription": { - "type": "text", - "placeholders": {} - }, - "admin": "Administració", - "@admin": { - "type": "text", - "placeholders": {} - }, - "alias": "àlies", - "@alias": { - "type": "text", - "placeholders": {} - }, - "allChats": "Tots els xats", - "@allChats": { - "type": "text", - "placeholders": {} - }, - "answeredTheCall": "{senderName} ha respost a la trucada", - "@answeredTheCall": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "anyoneCanJoin": "Qualsevol pot unir-se", - "@anyoneCanJoin": { - "type": "text", - "placeholders": {} - }, - "appLock": "Blocatge de l’aplicació", - "@appLock": { - "type": "text", - "placeholders": {} - }, - "archive": "Arxiu", - "@archive": { - "type": "text", - "placeholders": {} - }, - "areGuestsAllowedToJoin": "Accés dels usuaris convidats", - "@areGuestsAllowedToJoin": { - "type": "text", - "placeholders": {} - }, - "areYouSure": "N’esteu segur?", - "@areYouSure": { - "type": "text", - "placeholders": {} - }, - "askSSSSSign": "Per a poder donar accés a l’altra persona, introduïu la frase de seguretat o clau de recuperació.", - "@askSSSSSign": { - "type": "text", - "placeholders": {} - }, - "askVerificationRequest": "Voleu acceptar aquesta sol·licitud de verificació de: {username}?", - "@askVerificationRequest": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "banFromChat": "Veta del xat", - "@banFromChat": { - "type": "text", - "placeholders": {} - }, - "banned": "Vetat", - "@banned": { - "type": "text", - "placeholders": {} - }, - "bannedUser": "{username} ha vetat a {targetName}", - "@bannedUser": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "blockDevice": "Bloca el dispositiu", - "@blockDevice": { - "type": "text", - "placeholders": {} - }, - "botMessages": "Missatges del bot", - "@botMessages": { - "type": "text", - "placeholders": {} - }, - "cancel": "Cancel·la", - "@cancel": { - "type": "text", - "placeholders": {} - }, - "cantOpenUri": "No es pot obrir l’URI {uri}", - "@cantOpenUri": { - "type": "text", - "placeholders": { - "uri": {} - } - }, - "changeDeviceName": "Canvia el nom del dispositiu", - "@changeDeviceName": { - "type": "text", - "placeholders": {} - }, - "changedTheChatAvatar": "{username} ha canviat la imatge del xat", - "@changedTheChatAvatar": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheChatDescriptionTo": "{username} ha canviat la descripció del xat a: '{description}'", - "@changedTheChatDescriptionTo": { - "type": "text", - "placeholders": { - "username": {}, - "description": {} - } - }, - "changedTheChatNameTo": "{username} ha canviat el nom del xat a: '{chatname}'", - "@changedTheChatNameTo": { - "type": "text", - "placeholders": { - "username": {}, - "chatname": {} - } - }, - "changedTheChatPermissions": "{username} ha canviat els permisos del xat", - "@changedTheChatPermissions": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheGuestAccessRules": "{username} ha canviat les normes d’accés dels convidats", - "@changedTheGuestAccessRules": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheGuestAccessRulesTo": "{username} ha canviat les normes d’accés dels convidats a: {rules}", - "@changedTheGuestAccessRulesTo": { - "type": "text", - "placeholders": { - "username": {}, - "rules": {} - } - }, - "changedTheHistoryVisibility": "{username} ha canviat la visibilitat de l’historial", - "@changedTheHistoryVisibility": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheHistoryVisibilityTo": "{username} ha canviat la visibilitat de l’historial a: {rules}", - "@changedTheHistoryVisibilityTo": { - "type": "text", - "placeholders": { - "username": {}, - "rules": {} - } - }, - "changedTheJoinRules": "{username} ha canviat les normes d’unió", - "@changedTheJoinRules": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheJoinRulesTo": "{username} ha canviat les normes d’unió a: {joinRules}", - "@changedTheJoinRulesTo": { - "type": "text", - "placeholders": { - "username": {}, - "joinRules": {} - } - }, - "changedTheProfileAvatar": "{username} ha canviat la seva imatge de perfil", - "@changedTheProfileAvatar": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheRoomAliases": "{username} ha canviat l’àlies de la sala", - "@changedTheRoomAliases": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheRoomInvitationLink": "{username} ha canviat l’enllaç per a convidar", - "@changedTheRoomInvitationLink": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changePassword": "Canvia la contrasenya", - "@changePassword": { - "type": "text", - "placeholders": {} - }, - "changeTheHomeserver": "Canvia el servidor", - "@changeTheHomeserver": { - "type": "text", - "placeholders": {} - }, - "changeTheme": "Canvia l’estil", - "@changeTheme": { - "type": "text", - "placeholders": {} - }, - "changeTheNameOfTheGroup": "Canvia el nom del grup", - "@changeTheNameOfTheGroup": { - "type": "text", - "placeholders": {} - }, - "changeWallpaper": "Canvia el fons", - "@changeWallpaper": { - "type": "text", - "placeholders": {} - }, - "channelCorruptedDecryptError": "El xifratge s’ha corromput", - "@channelCorruptedDecryptError": { - "type": "text", - "placeholders": {} - }, - "chat": "Xat", - "@chat": { - "type": "text", - "placeholders": {} - }, - "chatDetails": "Detalls del xat", - "@chatDetails": { - "type": "text", - "placeholders": {} - }, - "chats": "Xats", - "@chats": { - "type": "text", - "placeholders": {} - }, - "chooseAStrongPassword": "Trieu una contrasenya forta", - "@chooseAStrongPassword": { - "type": "text", - "placeholders": {} - }, - "chooseAUsername": "Trieu un nom d’usuari", - "@chooseAUsername": { - "type": "text", - "placeholders": {} - }, - "close": "Tanca", - "@close": { - "type": "text", - "placeholders": {} - }, - "commandHint_html": "Envia text en format HTML", - "@commandHint_html": { - "type": "text", - "description": "Usage hint for the command /html" - }, - "commandHint_leave": "Abandona aquesta sala", - "@commandHint_leave": { - "type": "text", - "description": "Usage hint for the command /leave" - }, - "commandHint_op": "Estableix el nivell d'autoritat de l'usuari (per defecte: 50)", - "@commandHint_op": { - "type": "text", - "description": "Usage hint for the command /op" - }, - "commandHint_plain": "Envia text sense format", - "@commandHint_plain": { - "type": "text", - "description": "Usage hint for the command /plain" - }, - "commandHint_send": "Envia text", - "@commandHint_send": { - "type": "text", - "description": "Usage hint for the command /send" - }, - "compareEmojiMatch": "Compareu i assegureu-vos que els emojis següents coincideixen amb els de l’altre dispositiu:", - "@compareEmojiMatch": { - "type": "text", - "placeholders": {} - }, - "compareNumbersMatch": "Compareu i assegureu-vos que els nombres següents coincideixen amb els de l’altre dispositiu:", - "@compareNumbersMatch": { - "type": "text", - "placeholders": {} - }, - "confirm": "Confirma", - "@confirm": { - "type": "text", - "placeholders": {} - }, - "connect": "Connecta", - "@connect": { - "type": "text", - "placeholders": {} - }, - "contactHasBeenInvitedToTheGroup": "El contacte ha estat convidat al grup", - "@contactHasBeenInvitedToTheGroup": { - "type": "text", - "placeholders": {} - }, - "containsDisplayName": "Conté l'àlies", - "@containsDisplayName": { - "type": "text", - "placeholders": {} - }, - "containsUserName": "Conté el nom d’usuari", - "@containsUserName": { - "type": "text", - "placeholders": {} - }, - "copiedToClipboard": "S’ha copiat al porta-retalls", - "@copiedToClipboard": { - "type": "text", - "placeholders": {} - }, - "copy": "Copia", - "@copy": { - "type": "text", - "placeholders": {} - }, - "couldNotDecryptMessage": "No s'ha pogut desxifrar el missatge: {error}", - "@couldNotDecryptMessage": { - "type": "text", - "placeholders": { - "error": {} - } - }, - "countParticipants": "{count} participants", - "@countParticipants": { - "type": "text", - "placeholders": { - "count": {} - } - }, - "create": "Crea", - "@create": { - "type": "text", - "placeholders": {} - }, - "createdTheChat": "{username} ha creat el xat", - "@createdTheChat": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "createNewGroup": "Crea un grup nou", - "@createNewGroup": { - "type": "text", - "placeholders": {} - }, - "currentlyActive": "Actiu actualment", - "@currentlyActive": { - "type": "text", - "placeholders": {} - }, - "darkTheme": "Fosc", - "@darkTheme": { - "type": "text", - "placeholders": {} - }, - "dateAndTimeOfDay": "{date}, {timeOfDay}", - "@dateAndTimeOfDay": { - "type": "text", - "placeholders": { - "date": {}, - "timeOfDay": {} - } - }, - "dateWithoutYear": "{day}-{month}", - "@dateWithoutYear": { - "type": "text", - "placeholders": { - "month": {}, - "day": {} - } - }, - "dateWithYear": "{day}-{month}-{year}", - "@dateWithYear": { - "type": "text", - "placeholders": { - "year": {}, - "month": {}, - "day": {} - } - }, - "deactivateAccountWarning": "Es desactivarà el vostre compte d’usuari. Això no es pot desfer! Esteu segur de fer-ho?", - "@deactivateAccountWarning": { - "type": "text", - "placeholders": {} - }, - "delete": "Suprimeix", - "@delete": { - "type": "text", - "placeholders": {} - }, - "deleteAccount": "Suprimeix el compte", - "@deleteAccount": { - "type": "text", - "placeholders": {} - }, - "deleteMessage": "Suprimeix el missatge", - "@deleteMessage": { - "type": "text", - "placeholders": {} - }, - "deny": "Denega", - "@deny": { - "type": "text", - "placeholders": {} - }, - "device": "Dispositiu", - "@device": { - "type": "text", - "placeholders": {} - }, - "deviceId": "Id. de dispositiu", - "@deviceId": { - "type": "text", - "placeholders": {} - }, - "devices": "Dispositius", - "@devices": { - "type": "text", - "placeholders": {} - }, - "directChats": "Xats directes", - "@directChats": { - "type": "text", - "placeholders": {} - }, - "displaynameHasBeenChanged": "Ha canviat l'àlies", - "@displaynameHasBeenChanged": { - "type": "text", - "placeholders": {} - }, - "downloadFile": "Baixa el fitxer", - "@downloadFile": { - "type": "text", - "placeholders": {} - }, - "edit": "Edita", - "@edit": { - "type": "text", - "placeholders": {} - }, - "editDisplayname": "Edita l'àlies", - "@editDisplayname": { - "type": "text", - "placeholders": {} - }, - "emoteExists": "L'emoticona ja existeix!", - "@emoteExists": { - "type": "text", - "placeholders": {} - }, - "emoteInvalid": "Codi d'emoticona invàlid!", - "@emoteInvalid": { - "type": "text", - "placeholders": {} - }, - "emotePacks": "Paquet d'emoticones de la sala", - "@emotePacks": { - "type": "text", - "placeholders": {} - }, - "emoteSettings": "Paràmetres de les emoticones", - "@emoteSettings": { - "type": "text", - "placeholders": {} - }, - "emoteShortcode": "Codi d'emoticona", - "@emoteShortcode": { - "type": "text", - "placeholders": {} - }, - "emoteWarnNeedToPick": "Has de seleccionar un codi d'emoticona i una imatge!", - "@emoteWarnNeedToPick": { - "type": "text", - "placeholders": {} - }, - "emptyChat": "Xat buit", - "@emptyChat": { - "type": "text", - "placeholders": {} - }, - "enableEmotesGlobally": "Activa el paquet d'emoticones global", - "@enableEmotesGlobally": { - "type": "text", - "placeholders": {} - }, - "enableEncryptionWarning": "No podreu desactivar el xifratge mai més. N’esteu segur?", - "@enableEncryptionWarning": { - "type": "text", - "placeholders": {} - }, - "encrypted": "Xifrat", - "@encrypted": { - "type": "text", - "placeholders": {} - }, - "encryption": "Xifratge", - "@encryption": { - "type": "text", - "placeholders": {} - }, - "encryptionNotEnabled": "El xifratge no s’ha activat", - "@encryptionNotEnabled": { - "type": "text", - "placeholders": {} - }, - "endedTheCall": "{senderName} ha finalitzat la trucada", - "@endedTheCall": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "enterAGroupName": "Introduïu un nom de grup", - "@enterAGroupName": { - "type": "text", - "placeholders": {} - }, - "enterAnEmailAddress": "Introduïu una adreça electrònica", - "@enterAnEmailAddress": { - "type": "text", - "placeholders": {} - }, - "enterYourHomeserver": "Introdueix el teu servidor", - "@enterYourHomeserver": { - "type": "text", - "placeholders": {} - }, - "fileName": "Nom del fitxer", - "@fileName": { - "type": "text", - "placeholders": {} - }, - "fluffychat": "FluffyChat", - "@fluffychat": { - "type": "text", - "placeholders": {} - }, - "forward": "Reenvia", - "@forward": { - "type": "text", - "placeholders": {} - }, - "fromJoining": "Des de la unió", - "@fromJoining": { - "type": "text", - "placeholders": {} - }, - "fromTheInvitation": "Des de la invitació", - "@fromTheInvitation": { - "type": "text", - "placeholders": {} - }, - "group": "Grup", - "@group": { - "type": "text", - "placeholders": {} - }, - "groupDescription": "Descripció de grup", - "@groupDescription": { - "type": "text", - "placeholders": {} - }, - "groupDescriptionHasBeenChanged": "Descripció de grup canviada", - "@groupDescriptionHasBeenChanged": { - "type": "text", - "placeholders": {} - }, - "groupIsPublic": "El grup és públic", - "@groupIsPublic": { - "type": "text", - "placeholders": {} - }, - "groupWith": "Grup amb {displayname}", - "@groupWith": { - "type": "text", - "placeholders": { - "displayname": {} - } - }, - "guestsAreForbidden": "Els convidats no poden unir-se", - "@guestsAreForbidden": { - "type": "text", - "placeholders": {} - }, - "guestsCanJoin": "Els convidats es poden unir", - "@guestsCanJoin": { - "type": "text", - "placeholders": {} - }, - "hasWithdrawnTheInvitationFor": "{username} ha retirat la invitació de {targetName}", - "@hasWithdrawnTheInvitationFor": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "help": "Ajuda", - "@help": { - "type": "text", - "placeholders": {} - }, - "hideRedactedEvents": "Amaga els esdeveniments velats", - "@hideRedactedEvents": { - "type": "text", - "placeholders": {} - }, - "hideUnknownEvents": "Amaga els esdeveniments desconeguts", - "@hideUnknownEvents": { - "type": "text", - "placeholders": {} - }, - "id": "Id.", - "@id": { - "type": "text", - "placeholders": {} - }, - "identity": "Identitat", - "@identity": { - "type": "text", - "placeholders": {} - }, - "ignoredUsers": "Usuaris ignorats", - "@ignoredUsers": { - "type": "text", - "placeholders": {} - }, - "ignoreListDescription": "Pots ignorar els usuaris que et molestin. No rebràs els missatges ni les invitacions dels usuaris que es trobin a la teva llista personal d'ignorats.", - "@ignoreListDescription": { - "type": "text", - "placeholders": {} - }, - "ignoreUsername": "Ignora nom d'usuari", - "@ignoreUsername": { - "type": "text", - "placeholders": {} - }, - "iHaveClickedOnLink": "He fet clic a l'enllaç", - "@iHaveClickedOnLink": { - "type": "text", - "placeholders": {} - }, - "incorrectPassphraseOrKey": "Frase de seguretat o clau de recuperació incorrecta", - "@incorrectPassphraseOrKey": { - "type": "text", - "placeholders": {} - }, - "inviteContact": "Convida contacte", - "@inviteContact": { - "type": "text", - "placeholders": {} - }, - "inviteContactToGroup": "Convida contacte a {groupName}", - "@inviteContactToGroup": { - "type": "text", - "placeholders": { - "groupName": {} - } - }, - "invited": "Convidat", - "@invited": { - "type": "text", - "placeholders": {} - }, - "invitedUser": "{username} ha convidat a {targetName}", - "@invitedUser": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "invitedUsersOnly": "Només usuaris convidats", - "@invitedUsersOnly": { - "type": "text", - "placeholders": {} - }, - "inviteForMe": "Invitació per a mi", - "@inviteForMe": { - "type": "text", - "placeholders": {} - }, - "inviteText": "{username} t'ha convidat a FluffyChat.\n1. Instal·la FluffyChat: https://fluffychat.im\n2. Registra't o inicia sessió\n3. Obre l'enllaç d'invitació: {link}", - "@inviteText": { - "type": "text", - "placeholders": { - "username": {}, - "link": {} - } - }, - "isTyping": "escrivint…", - "@isTyping": { - "type": "text", - "placeholders": {} - }, - "joinedTheChat": "{username} s'ha unit al xat", - "@joinedTheChat": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "joinRoom": "Uneix-te a la sala", - "@joinRoom": { - "type": "text", - "placeholders": {} - }, - "kicked": "{username} ha expulsat a {targetName}", - "@kicked": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "kickedAndBanned": "{username} ha expulsat i vetat a {targetName}", - "@kickedAndBanned": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "kickFromChat": "Expulsa del xat", - "@kickFromChat": { - "type": "text", - "placeholders": {} - }, - "lastActiveAgo": "Actiu per última vegada: {localizedTimeShort}", - "@lastActiveAgo": { - "type": "text", - "placeholders": { - "localizedTimeShort": {} - } - }, - "lastSeenLongTimeAgo": "Vist va molt de temps", - "@lastSeenLongTimeAgo": { - "type": "text", - "placeholders": {} - }, - "leave": "Abandona", - "@leave": { - "type": "text", - "placeholders": {} - }, - "leftTheChat": "Ha marxat del xat", - "@leftTheChat": { - "type": "text", - "placeholders": {} - }, - "license": "Llicència", - "@license": { - "type": "text", - "placeholders": {} - }, - "lightTheme": "Clar", - "@lightTheme": { - "type": "text", - "placeholders": {} - }, - "loadCountMoreParticipants": "Carrega {count} participants més", - "@loadCountMoreParticipants": { - "type": "text", - "placeholders": { - "count": {} - } - }, - "loadingPleaseWait": "S’està carregant… Espereu.", - "@loadingPleaseWait": { - "type": "text", - "placeholders": {} - }, - "loadMore": "Carrega’n més…", - "@loadMore": { - "type": "text", - "placeholders": {} - }, - "locationDisabledNotice": "S’han desactivat els serveis d’ubicació. Activeu-los per a compartir la vostra ubicació.", - "@locationDisabledNotice": { - "type": "text", - "placeholders": {} - }, - "locationPermissionDeniedNotice": "S’ha rebutjat el permís d’ubicació. Atorgueu-lo per a poder compartir la vostra ubicació.", - "@locationPermissionDeniedNotice": { - "type": "text", - "placeholders": {} - }, - "login": "Inicia la sessió", - "@login": { - "type": "text", - "placeholders": {} - }, - "logInTo": "Inicia sessió a {homeserver}", - "@logInTo": { - "type": "text", - "placeholders": { - "homeserver": {} - } - }, - "loginWith": "Inicia la sessió amb {brand}", - "@loginWith": { - "type": "text", - "placeholders": { - "brand": {} - } - }, - "logout": "Finalitza la sessió", - "@logout": { - "type": "text", - "placeholders": {} - }, - "makeSureTheIdentifierIsValid": "Assegura't que l'identificador sigui vàlid", - "@makeSureTheIdentifierIsValid": { - "type": "text", - "placeholders": {} - }, - "memberChanges": "Canvis de participants", - "@memberChanges": { - "type": "text", - "placeholders": {} - }, - "mention": "Menciona", - "@mention": { - "type": "text", - "placeholders": {} - }, - "messageWillBeRemovedWarning": "El missatge s'eliminarà per a tots els participants", - "@messageWillBeRemovedWarning": { - "type": "text", - "placeholders": {} - }, - "moderator": "Moderador", - "@moderator": { - "type": "text", - "placeholders": {} - }, - "muteChat": "Silencia el xat", - "@muteChat": { - "type": "text", - "placeholders": {} - }, - "needPantalaimonWarning": "Tingueu en compte que, ara per ara, us cal el Pantalaimon per a poder utilitzar el xifratge d’extrem a extrem.", - "@needPantalaimonWarning": { - "type": "text", - "placeholders": {} - }, - "newMessageInFluffyChat": "Missatge nou al FluffyChat", - "@newMessageInFluffyChat": { - "type": "text", - "placeholders": {} - }, - "newVerificationRequest": "Nova sol·licitud de verificació!", - "@newVerificationRequest": { - "type": "text", - "placeholders": {} - }, - "no": "No", - "@no": { - "type": "text", - "placeholders": {} - }, - "noConnectionToTheServer": "Sense connexió al servidor", - "@noConnectionToTheServer": { - "type": "text", - "placeholders": {} - }, - "noEmotesFound": "No s’ha trobat cap emoticona. 😕", - "@noEmotesFound": { - "type": "text", - "placeholders": {} - }, - "noGoogleServicesWarning": "Sembla que no teniu els Serveis de Google al telèfon. Això és una bona decisió respecte a la vostra privadesa! Per a rebre notificacions automàtiques del FluffyChat, us recomanem utilitzar https://microg.org/ o https://unifiedpush.org/.", - "@noGoogleServicesWarning": { - "type": "text", - "placeholders": {} - }, - "none": "Cap", - "@none": { - "type": "text", - "placeholders": {} - }, - "noPasswordRecoveryDescription": "Encara no heu afegit cap mètode per a poder recuperar la contrasenya.", - "@noPasswordRecoveryDescription": { - "type": "text", - "placeholders": {} - }, - "noPermission": "Sense permís", - "@noPermission": { - "type": "text", - "placeholders": {} - }, - "noRoomsFound": "No s’ha trobat cap sala…", - "@noRoomsFound": { - "type": "text", - "placeholders": {} - }, - "notifications": "Notificacions", - "@notifications": { - "type": "text", - "placeholders": {} - }, - "notificationsEnabledForThisAccount": "Notificacions activades per a aquest compte", - "@notificationsEnabledForThisAccount": { - "type": "text", - "placeholders": {} - }, - "numUsersTyping": "{count} usuaris escrivint…", - "@numUsersTyping": { - "type": "text", - "placeholders": { - "count": {} - } - }, - "offline": "Fora de línia", - "@offline": { - "type": "text", - "placeholders": {} - }, - "ok": "D'acord", - "@ok": { - "type": "text", - "placeholders": {} - }, - "online": "En línia", - "@online": { - "type": "text", - "placeholders": {} - }, - "onlineKeyBackupEnabled": "La còpia de seguretat de claus en línia està activada", - "@onlineKeyBackupEnabled": { - "type": "text", - "placeholders": {} - }, - "oopsSomethingWentWrong": "Alguna cosa ha anat malament…", - "@oopsSomethingWentWrong": { - "type": "text", - "placeholders": {} - }, - "openAppToReadMessages": "Obre l'aplicació per llegir els missatges", - "@openAppToReadMessages": { - "type": "text", - "placeholders": {} - }, - "openCamera": "Obre la càmera", - "@openCamera": { - "type": "text", - "placeholders": {} - }, - "optionalGroupName": "(Opcional) Nom del grup", - "@optionalGroupName": { - "type": "text", - "placeholders": {} - }, - "or": "O", - "@or": { - "type": "text", - "placeholders": {} - }, - "passphraseOrKey": "contrasenya o clau de recuperació", - "@passphraseOrKey": { - "type": "text", - "placeholders": {} - }, - "password": "Contrasenya", - "@password": { - "type": "text", - "placeholders": {} - }, - "passwordForgotten": "Contrasenya oblidada", - "@passwordForgotten": { - "type": "text", - "placeholders": {} - }, - "passwordHasBeenChanged": "La contrasenya ha canviat", - "@passwordHasBeenChanged": { - "type": "text", - "placeholders": {} - }, - "passwordRecovery": "Recuperació de contrassenya", - "@passwordRecovery": { - "type": "text", - "placeholders": {} - }, - "pickImage": "Selecciona una imatge", - "@pickImage": { - "type": "text", - "placeholders": {} - }, - "pin": "Fixa", - "@pin": { - "type": "text", - "placeholders": {} - }, - "play": "Reproduir {fileName}", - "@play": { - "type": "text", - "placeholders": { - "fileName": {} - } - }, - "pleaseChooseAPasscode": "Tria un codi d'accés", - "@pleaseChooseAPasscode": { - "type": "text", - "placeholders": {} - }, - "pleaseChooseAUsername": "Tria un nom d'usuari", - "@pleaseChooseAUsername": { - "type": "text", - "placeholders": {} - }, - "pleaseClickOnLink": "Fes clic a l'enllaç del correu i, després, segueix.", - "@pleaseClickOnLink": { - "type": "text", - "placeholders": {} - }, - "pleaseEnter4Digits": "Introdueix 4 dígits o deixa-ho buit per desactivar el bloqueig.", - "@pleaseEnter4Digits": { - "type": "text", - "placeholders": {} - }, - "pleaseEnterAMatrixIdentifier": "Introdueix un identificador de Matrix.", - "@pleaseEnterAMatrixIdentifier": { - "type": "text", - "placeholders": {} - }, - "pleaseEnterYourPassword": "Introdueix la teva contrasenya", - "@pleaseEnterYourPassword": { - "type": "text", - "placeholders": {} - }, - "pleaseEnterYourUsername": "Introdueix el teu nom d'usuari", - "@pleaseEnterYourUsername": { - "type": "text", - "placeholders": {} - }, - "privacy": "Privadesa", - "@privacy": { - "type": "text", - "placeholders": {} - }, - "publicRooms": "Sales públiques", - "@publicRooms": { - "type": "text", - "placeholders": {} - }, - "pushRules": "Regles push", - "@pushRules": { - "type": "text", - "placeholders": {} - }, - "recording": "Enregistrant", - "@recording": { - "type": "text", - "placeholders": {} - }, - "redactedAnEvent": "{username} ha velat un esdeveniment", - "@redactedAnEvent": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "reject": "Rebutja", - "@reject": { - "type": "text", - "placeholders": {} - }, - "rejectedTheInvitation": "{username} ha rebutjat la invitació", - "@rejectedTheInvitation": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "rejoin": "Torna-t'hi a unir", - "@rejoin": { - "type": "text", - "placeholders": {} - }, - "remove": "Elimina", - "@remove": { - "type": "text", - "placeholders": {} - }, - "removeAllOtherDevices": "Elimina tots els altres dispositius", - "@removeAllOtherDevices": { - "type": "text", - "placeholders": {} - }, - "removedBy": "Eliminat per {username}", - "@removedBy": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "removeDevice": "Elimina dispositiu", - "@removeDevice": { - "type": "text", - "placeholders": {} - }, - "unbanFromChat": "Desfés l'expulsió", - "@unbanFromChat": { - "type": "text", - "placeholders": {} - }, - "renderRichContent": "Mostra el contingut enriquit dels missatges", - "@renderRichContent": { - "type": "text", - "placeholders": {} - }, - "reply": "Respon", - "@reply": { - "type": "text", - "placeholders": {} - }, - "requestPermission": "Sol·licita permís", - "@requestPermission": { - "type": "text", - "placeholders": {} - }, - "roomHasBeenUpgraded": "La sala s'ha actualitzat", - "@roomHasBeenUpgraded": { - "type": "text", - "placeholders": {} - }, - "security": "Seguretat", - "@security": { - "type": "text", - "placeholders": {} - }, - "seenByUser": "Vist per {username}", - "@seenByUser": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "seenByUserAndCountOthers": "{count, plural, other{Vist per {username} i {count} més}}", - "@seenByUserAndCountOthers": { - "type": "text", - "placeholders": { - "username": {}, - "count": {} - } - }, - "seenByUserAndUser": "Vist per {username} i {username2}", - "@seenByUserAndUser": { - "type": "text", - "placeholders": { - "username": {}, - "username2": {} - } - }, - "send": "Envia", - "@send": { - "type": "text", - "placeholders": {} - }, - "sendAMessage": "Envia un missatge", - "@sendAMessage": { - "type": "text", - "placeholders": {} - }, - "sendAsText": "Envia com a text", - "@sendAsText": { - "type": "text" - }, - "sendAudio": "Envia un àudio", - "@sendAudio": { - "type": "text", - "placeholders": {} - }, - "sendFile": "Envia un fitxer", - "@sendFile": { - "type": "text", - "placeholders": {} - }, - "sendImage": "Envia una imatge", - "@sendImage": { - "type": "text", - "placeholders": {} - }, - "sendOriginal": "Envia l’original", - "@sendOriginal": { - "type": "text", - "placeholders": {} - }, - "sendSticker": "Envia adhesiu", - "@sendSticker": { - "type": "text", - "placeholders": {} - }, - "sendVideo": "Envia un vídeo", - "@sendVideo": { - "type": "text", - "placeholders": {} - }, - "sentAFile": "{username} ha enviat un fitxer", - "@sentAFile": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sentAnAudio": "{username} ha enviat un àudio", - "@sentAnAudio": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sentAPicture": "{username} ha enviat una imatge", - "@sentAPicture": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sentASticker": "{username} ha enviat un adhesiu", - "@sentASticker": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sentAVideo": "{username} ha enviat un vídeo", - "@sentAVideo": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sentCallInformations": "{senderName} ha enviat informació de trucada", - "@sentCallInformations": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "setGroupDescription": "Defineix la descripció del grup", - "@setGroupDescription": { - "type": "text", - "placeholders": {} - }, - "setInvitationLink": "Defineix l’enllaç per a convidar", - "@setInvitationLink": { - "type": "text", - "placeholders": {} - }, - "setPermissionsLevel": "Defineix el nivell de permisos", - "@setPermissionsLevel": { - "type": "text", - "placeholders": {} - }, - "setStatus": "Defineix l’estat", - "@setStatus": { - "type": "text", - "placeholders": {} - }, - "settings": "Paràmetres", - "@settings": { - "type": "text", - "placeholders": {} - }, - "share": "Comparteix", - "@share": { - "type": "text", - "placeholders": {} - }, - "sharedTheLocation": "{username} n’ha compartit la ubicació", - "@sharedTheLocation": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "signUp": "Registre", - "@signUp": { - "type": "text", - "placeholders": {} - }, - "singlesignon": "Autenticació única", - "@singlesignon": { - "type": "text", - "placeholders": {} - }, - "skip": "Omet", - "@skip": { - "type": "text", - "placeholders": {} - }, - "sourceCode": "Codi font", - "@sourceCode": { - "type": "text", - "placeholders": {} - }, - "startedACall": "{senderName} ha iniciat una trucada", - "@startedACall": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "statusExampleMessage": "Com us sentiu avui?", - "@statusExampleMessage": { - "type": "text", - "placeholders": {} - }, - "submit": "Envia", - "@submit": { - "type": "text", - "placeholders": {} - }, - "systemTheme": "Sistema", - "@systemTheme": { - "type": "text", - "placeholders": {} - }, - "theyDontMatch": "No coincideixen", - "@theyDontMatch": { - "type": "text", - "placeholders": {} - }, - "theyMatch": "Coincideixen", - "@theyMatch": { - "type": "text", - "placeholders": {} - }, - "title": "FluffyChat", - "@title": { - "description": "Title for the application", - "type": "text", - "placeholders": {} - }, - "toggleUnread": "Marca com a llegit/sense llegir", - "@toggleUnread": { - "type": "text", - "placeholders": {} - }, - "tooManyRequestsWarning": "Massa sol·licituds. Torna-ho a provar més tard!", - "@tooManyRequestsWarning": { - "type": "text", - "placeholders": {} - }, - "tryToSendAgain": "Intenta tornar a enviar", - "@tryToSendAgain": { - "type": "text", - "placeholders": {} - }, - "unavailable": "No disponible", - "@unavailable": { - "type": "text", - "placeholders": {} - }, - "unbannedUser": "{username} ha tret el veto a {targetName}", - "@unbannedUser": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "unblockDevice": "Desbloqueja dispositiu", - "@unblockDevice": { - "type": "text", - "placeholders": {} - }, - "unknownDevice": "Dispositiu desconegut", - "@unknownDevice": { - "type": "text", - "placeholders": {} - }, - "unknownEncryptionAlgorithm": "L’algorisme de xifratge és desconegut", - "@unknownEncryptionAlgorithm": { - "type": "text", - "placeholders": {} - }, - "unknownEvent": "Esdeveniment desconegut '{type}'", - "@unknownEvent": { - "type": "text", - "placeholders": { - "type": {} - } - }, - "unmuteChat": "Deixa de silenciar el xat", - "@unmuteChat": { - "type": "text", - "placeholders": {} - }, - "unpin": "Deixa de fixar", - "@unpin": { - "type": "text", - "placeholders": {} - }, - "unreadChats": "{unreadCount, plural, =1{1 xat no llegit} other{{unreadCount} xats no llegits}}", - "@unreadChats": { - "type": "text", - "placeholders": { - "unreadCount": {} - } - }, - "userAndOthersAreTyping": "{username} i {count} més estan escrivint…", - "@userAndOthersAreTyping": { - "type": "text", - "placeholders": { - "username": {}, - "count": {} - } - }, - "userAndUserAreTyping": "{username} i {username2} estan escrivint…", - "@userAndUserAreTyping": { - "type": "text", - "placeholders": { - "username": {}, - "username2": {} - } - }, - "userIsTyping": "{username} està escrivint…", - "@userIsTyping": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "userLeftTheChat": "{username} ha marxat del xat", - "@userLeftTheChat": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "username": "Nom d’usuari", - "@username": { - "type": "text", - "placeholders": {} - }, - "userSentUnknownEvent": "{username} ha enviat un esdeveniment {type}", - "@userSentUnknownEvent": { - "type": "text", - "placeholders": { - "username": {}, - "type": {} - } - }, - "verify": "Verifica", - "@verify": { - "type": "text", - "placeholders": {} - }, - "verifyStart": "Inicia la verificació", - "@verifyStart": { - "type": "text", - "placeholders": {} - }, - "verifySuccess": "T'has verificat correctament!", - "@verifySuccess": { - "type": "text", - "placeholders": {} - }, - "verifyTitle": "Verificant un altre compte", - "@verifyTitle": { - "type": "text", - "placeholders": {} - }, - "videoCall": "Videotrucada", - "@videoCall": { - "type": "text", - "placeholders": {} - }, - "visibilityOfTheChatHistory": "Visibilitat de l’historial del xat", - "@visibilityOfTheChatHistory": { - "type": "text", - "placeholders": {} - }, - "visibleForAllParticipants": "Visible per a tots els participants", - "@visibleForAllParticipants": { - "type": "text", - "placeholders": {} - }, - "visibleForEveryone": "Visible per a tothom", - "@visibleForEveryone": { - "type": "text", - "placeholders": {} - }, - "voiceMessage": "Missatge de veu", - "@voiceMessage": { - "type": "text", - "placeholders": {} - }, - "waitingPartnerEmoji": "S’està esperant que l’altre accepti l’emoji…", - "@waitingPartnerEmoji": { - "type": "text", - "placeholders": {} - }, - "waitingPartnerNumbers": "S’està esperant que l’altre accepti els nombres…", - "@waitingPartnerNumbers": { - "type": "text", - "placeholders": {} - }, - "wallpaper": "Fons", - "@wallpaper": { - "type": "text", - "placeholders": {} - }, - "warning": "Atenció!", - "@warning": { - "type": "text", - "placeholders": {} - }, - "weSentYouAnEmail": "Us hem enviat un missatge de correu electrònic", - "@weSentYouAnEmail": { - "type": "text", - "placeholders": {} - }, - "whoIsAllowedToJoinThisGroup": "Qui pot unir-se a aquest grup", - "@whoIsAllowedToJoinThisGroup": { - "type": "text", - "placeholders": {} - }, - "withTheseAddressesRecoveryDescription": "Amb aquestes adreces, si ho necessiteu, podeu recuperar la vostra contrasenya.", - "@withTheseAddressesRecoveryDescription": { - "type": "text", - "placeholders": {} - }, - "writeAMessage": "Escriviu un missatge…", - "@writeAMessage": { - "type": "text", - "placeholders": {} - }, - "yes": "Sí", - "@yes": { - "type": "text", - "placeholders": {} - }, - "you": "Vós", - "@you": { - "type": "text", - "placeholders": {} - }, - "youAreInvitedToThisChat": "Us han convidat a aquest xat", - "@youAreInvitedToThisChat": { - "type": "text", - "placeholders": {} - }, - "youAreNoLongerParticipatingInThisChat": "Ja no participeu en aquest xat", - "@youAreNoLongerParticipatingInThisChat": { - "type": "text", - "placeholders": {} - }, - "youCannotInviteYourself": "No us podeu convidar a vós mateix", - "@youCannotInviteYourself": { - "type": "text", - "placeholders": {} - }, - "youHaveBeenBannedFromThisChat": "Has estat vetat d'aquest xat", - "@youHaveBeenBannedFromThisChat": { - "type": "text", - "placeholders": {} - }, - "yourPublicKey": "La vostra clau pública", - "@yourPublicKey": { - "type": "text", - "placeholders": {} - }, - "all": "Tot", - "@all": { - "type": "text", - "placeholders": {} - }, - "addToSpace": "Afegeix a un espai", - "@addToSpace": {}, - "areYouSureYouWantToLogout": "Segur que voleu finalitzar la sessió?", - "@areYouSureYouWantToLogout": { - "type": "text", - "placeholders": {} - }, - "addEmail": "Afegeix una adreça electrònica", - "@addEmail": { - "type": "text", - "placeholders": {} - }, - "commandInvalid": "L’ordre no és vàlida", - "@commandInvalid": { - "type": "text" - }, - "fontSize": "Mida de la lletra", - "@fontSize": { - "type": "text", - "placeholders": {} - }, - "goToTheNewRoom": "Ves a la sala nova", - "@goToTheNewRoom": { - "type": "text", - "placeholders": {} - }, - "next": "Següent", - "@next": { - "type": "text", - "placeholders": {} - }, - "link": "Enllaç", - "@link": {}, - "people": "Gent", - "@people": { - "type": "text", - "placeholders": {} - }, - "redactMessage": "Vela el missatge", - "@redactMessage": { - "type": "text", - "placeholders": {} - }, - "sendOnEnter": "Envia en prémer Retorn", - "@sendOnEnter": {}, - "clearArchive": "Neteja l’arxiu", - "@clearArchive": {}, - "chatBackupDescription": "La còpia de seguretat dels xats és protegida amb una clau. Assegureu-vos de no perdre-la.", - "@chatBackupDescription": { - "type": "text", - "placeholders": {} - }, - "chatHasBeenAddedToThisSpace": "El xat s’ha afegit a aquest espai", - "@chatHasBeenAddedToThisSpace": {}, - "autoplayImages": "Reprodueix automàticament enganxines i emoticones animades", - "@autoplayImages": { - "type": "text", - "placeholder": {} - }, - "chatBackup": "Còpia de seguretat del xat", - "@chatBackup": { - "type": "text", - "placeholders": {} - }, - "blocked": "Blocat", - "@blocked": { - "type": "text", - "placeholders": {} - }, - "everythingReady": "Tot és a punt!", - "@everythingReady": { - "type": "text", - "placeholders": {} - }, - "spaceName": "Nom de l’espai", - "@spaceName": { - "type": "text", - "placeholders": {} - }, - "search": "Cerca", - "@search": { - "type": "text", - "placeholders": {} - }, - "verified": "Verificat", - "@verified": { - "type": "text", - "placeholders": {} - }, - "newChat": "Xat nou", - "@newChat": { - "type": "text", - "placeholders": {} - }, - "changeYourAvatar": "Canvia l’avatar", - "@changeYourAvatar": { - "type": "text", - "placeholders": {} - }, - "ignore": "Ignora", - "@ignore": { - "type": "text", - "placeholders": {} - }, - "commandHint_react": "Envia una resposta com a reacció", - "@commandHint_react": { - "type": "text", - "description": "Usage hint for the command /react" - }, - "defaultPermissionLevel": "Nivell de permisos per defecte", - "@defaultPermissionLevel": { - "type": "text", - "placeholders": {} - }, - "extremeOffensive": "Extremadament ofensiu", - "@extremeOffensive": { - "type": "text", - "placeholders": {} - }, - "yourChatBackupHasBeenSetUp": "S’ha configurat la còpia de seguretat del xat.", - "@yourChatBackupHasBeenSetUp": {}, - "contentHasBeenReported": "El contingut s’ha denunciat als administradors del servidor", - "@contentHasBeenReported": { - "type": "text", - "placeholders": {} - }, - "enableEncryption": "Activa el xifratge", - "@enableEncryption": { - "type": "text", - "placeholders": {} - }, - "enterASpacepName": "Introduïu un nom d’espai", - "@enterASpacepName": {}, - "addAccount": "Afegeix un compte", - "@addAccount": {}, - "noEncryptionForPublicRooms": "Només podreu activar el xifratge quan la sala ja no sigui accessible públicament.", - "@noEncryptionForPublicRooms": { - "type": "text", - "placeholders": {} - }, - "roomVersion": "Versió de la sala", - "@roomVersion": { - "type": "text", - "placeholders": {} - }, - "sendMessages": "Envia missatges", - "@sendMessages": { - "type": "text", - "placeholders": {} - }, - "saveFile": "Desa el fitxer", - "@saveFile": { - "type": "text", - "placeholders": {} - }, - "pleaseFollowInstructionsOnWeb": "Seguiu les instruccions al lloc web i toqueu «Següent».", - "@pleaseFollowInstructionsOnWeb": { - "type": "text", - "placeholders": {} - }, - "reportMessage": "Denuncia el missatge", - "@reportMessage": { - "type": "text", - "placeholders": {} - }, - "setAsCanonicalAlias": "Defineix com a àlies principal", - "@setAsCanonicalAlias": { - "type": "text", - "placeholders": {} - }, - "status": "Estat", - "@status": { - "type": "text", - "placeholders": {} - }, - "toggleFavorite": "Commuta l’estat «preferit»", - "@toggleFavorite": { - "type": "text", - "placeholders": {} - }, - "toggleMuted": "Commuta l’estat «silenci»", - "@toggleMuted": { - "type": "text", - "placeholders": {} - }, - "transferFromAnotherDevice": "Transfereix des d’un altre dispositiu", - "@transferFromAnotherDevice": { - "type": "text", - "placeholders": {} - }, - "setCustomEmotes": "Defineix emoticones personalitzades", - "@setCustomEmotes": { - "type": "text", - "placeholders": {} - }, - "whoCanPerformWhichAction": "Qui pot efectuar quina acció", - "@whoCanPerformWhichAction": { - "type": "text", - "placeholders": {} - }, - "whyDoYouWantToReportThis": "Per què voleu denunciar això?", - "@whyDoYouWantToReportThis": { - "type": "text", - "placeholders": {} - }, - "wipeChatBackup": "Voleu suprimir la còpia de seguretat dels xats per a crear una clau de seguretat nova?", - "@wipeChatBackup": { - "type": "text", - "placeholders": {} - }, - "waitingPartnerAcceptRequest": "S’està esperant que l’altre accepti la sol·licitud…", - "@waitingPartnerAcceptRequest": { - "type": "text", - "placeholders": {} - }, - "unverified": "No verificat", - "@unverified": {}, - "commandHint_me": "Descriviu-vos", - "@commandHint_me": { - "type": "text", - "description": "Usage hint for the command /me" - }, - "commandMissing": "{command} no és una ordre.", - "@commandMissing": { - "type": "text", - "placeholders": { - "command": {} - }, - "description": "State that {command} is not a valid /command." - }, - "configureChat": "Configura el xat", - "@configureChat": { - "type": "text", - "placeholders": {} - }, - "copyToClipboard": "Copia al porta-retalls", - "@copyToClipboard": { - "type": "text", - "placeholders": {} - }, - "createNewSpace": "Espai nou", - "@createNewSpace": { - "type": "text", - "placeholders": {} - }, - "errorObtainingLocation": "S’ha produït un error en obtenir la ubicació: {error}", - "@errorObtainingLocation": { - "type": "text", - "placeholders": { - "error": {} - } - }, - "groups": "Grups", - "@groups": { - "type": "text", - "placeholders": {} - }, - "messages": "Missatges", - "@messages": { - "type": "text", - "placeholders": {} - }, - "showPassword": "Mostra la contrasenya", - "@showPassword": { - "type": "text", - "placeholders": {} - }, - "spaceIsPublic": "L’espai és públic", - "@spaceIsPublic": { - "type": "text", - "placeholders": {} - }, - "scanQrCode": "Escaneja un codi QR", - "@scanQrCode": {}, - "obtainingLocation": "S’està obtenint la ubicació…", - "@obtainingLocation": { - "type": "text", - "placeholders": {} - }, - "shareLocation": "Comparteix la ubicació", - "@shareLocation": { - "type": "text", - "placeholders": {} - }, - "synchronizingPleaseWait": "S’està sincronitzant… Espereu.", - "@synchronizingPleaseWait": { - "type": "text", - "placeholders": {} - }, - "reason": "Raó", - "@reason": { - "type": "text", - "placeholders": {} - }, - "changedTheDisplaynameTo": "{username} ha canviat el seu àlies a: '{displayname}'", - "@changedTheDisplaynameTo": { - "type": "text", - "placeholders": { - "username": {}, - "displayname": {} - } - }, - "howOffensiveIsThisContent": "Com d’ofensiu és aquest contingut?", - "@howOffensiveIsThisContent": { - "type": "text", - "placeholders": {} - }, - "commandHint_clearcache": "Neteja la memòria cau", - "@commandHint_clearcache": { - "type": "text", - "description": "Usage hint for the command /clearcache" - }, - "commandHint_join": "Uneix-te a la sala", - "@commandHint_join": { - "type": "text", - "description": "Usage hint for the command /join" - }, - "commandHint_kick": "Elimina l'usuari indicat d'aquesta sala", - "@commandHint_kick": { - "type": "text", - "description": "Usage hint for the command /kick" - }, - "commandHint_myroomavatar": "Establiu la imatge per a aquesta sala (per mxc-uri)", - "@commandHint_myroomavatar": { - "type": "text", - "description": "Usage hint for the command /myroomavatar" - }, - "commandHint_dm": "Inicia un xat directe\nUsa --no-encryption per desactivar l'encriptatge", - "@commandHint_dm": { - "type": "text", - "description": "Usage hint for the command /dm" - }, - "commandHint_invite": "Convida l'usuari indicat a aquesta sala", - "@commandHint_invite": { - "type": "text", - "description": "Usage hint for the command /invite" - }, - "commandHint_ban": "Prohibeix l'usuari indicat d'aquesta sala", - "@commandHint_ban": { - "type": "text", - "description": "Usage hint for the command /ban" - }, - "commandHint_create": "Crea un xat de grup buit\nUsa --no-encryption per desactivar l'encriptatge", - "@commandHint_create": { - "type": "text", - "description": "Usage hint for the command /create" - }, - "commandHint_discardsession": "Descarta la sessió", - "@commandHint_discardsession": { - "type": "text", - "description": "Usage hint for the command /discardsession" - }, - "passwordsDoNotMatch": "Les contrasenyes no coincideixen!", - "@passwordsDoNotMatch": {}, - "pleaseEnterValidEmail": "Introduïu una adreça electrònica vàlida.", - "@pleaseEnterValidEmail": {}, - "repeatPassword": "Repetiu la contrasenya", - "@repeatPassword": {}, - "pleaseChooseAtLeastChars": "Seleccioneu almenys {min} caràcters.", - "@pleaseChooseAtLeastChars": { - "type": "text", - "placeholders": { - "min": {} - } - }, - "bubbleSize": "Mida de la bombolla", - "@bubbleSize": { - "type": "text", - "placeholders": {} - }, - "commandHint_myroomnick": "Estableix el teu àlies per a aquesta sala", - "@commandHint_myroomnick": { - "type": "text", - "description": "Usage hint for the command /myroomnick" - }, - "editBlockedServers": "Edita els servidors bloquejats", - "@editBlockedServers": { - "type": "text", - "placeholders": {} - }, - "badServerLoginTypesException": "El servidor admet els inicis de sessió:\n{serverVersions}\nPerò l'aplicació només admet:\n{supportedVersions}", - "@badServerLoginTypesException": { - "type": "text", - "placeholders": { - "serverVersions": {}, - "supportedVersions": {} - } - }, - "editChatPermissions": "Edita els permisos del xat", - "@editChatPermissions": { - "type": "text", - "placeholders": {} + "@@last_modified": "2021-08-14 12:41:10.145728", + "about": "Quant a", + "@about": { + "type": "text", + "placeholders": {} + }, + "accept": "Accepta", + "@accept": { + "type": "text", + "placeholders": {} + }, + "acceptedTheInvitation": "{username} ha acceptat la invitació", + "@acceptedTheInvitation": { + "type": "text", + "placeholders": { + "username": {} } -} \ No newline at end of file + }, + "account": "Compte", + "@account": { + "type": "text", + "placeholders": {} + }, + "activatedEndToEndEncryption": "{username} ha activat el xifratge d’extrem a extrem", + "@activatedEndToEndEncryption": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "addGroupDescription": "Afegeix descripció de grup", + "@addGroupDescription": { + "type": "text", + "placeholders": {} + }, + "admin": "Administració", + "@admin": { + "type": "text", + "placeholders": {} + }, + "alias": "àlies", + "@alias": { + "type": "text", + "placeholders": {} + }, + "allChats": "Tots els xats", + "@allChats": { + "type": "text", + "placeholders": {} + }, + "answeredTheCall": "{senderName} ha respost a la trucada", + "@answeredTheCall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "anyoneCanJoin": "Qualsevol pot unir-se", + "@anyoneCanJoin": { + "type": "text", + "placeholders": {} + }, + "appLock": "Blocatge de l’aplicació", + "@appLock": { + "type": "text", + "placeholders": {} + }, + "archive": "Arxiu", + "@archive": { + "type": "text", + "placeholders": {} + }, + "areGuestsAllowedToJoin": "Accés dels usuaris convidats", + "@areGuestsAllowedToJoin": { + "type": "text", + "placeholders": {} + }, + "areYouSure": "N’esteu segur?", + "@areYouSure": { + "type": "text", + "placeholders": {} + }, + "askSSSSSign": "Per a poder donar accés a l’altra persona, introduïu la frase de seguretat o clau de recuperació.", + "@askSSSSSign": { + "type": "text", + "placeholders": {} + }, + "askVerificationRequest": "Voleu acceptar aquesta sol·licitud de verificació de: {username}?", + "@askVerificationRequest": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "banFromChat": "Veta del xat", + "@banFromChat": { + "type": "text", + "placeholders": {} + }, + "banned": "Vetat", + "@banned": { + "type": "text", + "placeholders": {} + }, + "bannedUser": "{username} ha vetat a {targetName}", + "@bannedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "blockDevice": "Bloca el dispositiu", + "@blockDevice": { + "type": "text", + "placeholders": {} + }, + "botMessages": "Missatges del bot", + "@botMessages": { + "type": "text", + "placeholders": {} + }, + "cancel": "Cancel·la", + "@cancel": { + "type": "text", + "placeholders": {} + }, + "cantOpenUri": "No es pot obrir l’URI {uri}", + "@cantOpenUri": { + "type": "text", + "placeholders": { + "uri": {} + } + }, + "changeDeviceName": "Canvia el nom del dispositiu", + "@changeDeviceName": { + "type": "text", + "placeholders": {} + }, + "changedTheChatAvatar": "{username} ha canviat la imatge del xat", + "@changedTheChatAvatar": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheChatDescriptionTo": "{username} ha canviat la descripció del xat a: '{description}'", + "@changedTheChatDescriptionTo": { + "type": "text", + "placeholders": { + "username": {}, + "description": {} + } + }, + "changedTheChatNameTo": "{username} ha canviat el nom del xat a: '{chatname}'", + "@changedTheChatNameTo": { + "type": "text", + "placeholders": { + "username": {}, + "chatname": {} + } + }, + "changedTheChatPermissions": "{username} ha canviat els permisos del xat", + "@changedTheChatPermissions": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheGuestAccessRules": "{username} ha canviat les normes d’accés dels convidats", + "@changedTheGuestAccessRules": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheGuestAccessRulesTo": "{username} ha canviat les normes d’accés dels convidats a: {rules}", + "@changedTheGuestAccessRulesTo": { + "type": "text", + "placeholders": { + "username": {}, + "rules": {} + } + }, + "changedTheHistoryVisibility": "{username} ha canviat la visibilitat de l’historial", + "@changedTheHistoryVisibility": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheHistoryVisibilityTo": "{username} ha canviat la visibilitat de l’historial a: {rules}", + "@changedTheHistoryVisibilityTo": { + "type": "text", + "placeholders": { + "username": {}, + "rules": {} + } + }, + "changedTheJoinRules": "{username} ha canviat les normes d’unió", + "@changedTheJoinRules": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheJoinRulesTo": "{username} ha canviat les normes d’unió a: {joinRules}", + "@changedTheJoinRulesTo": { + "type": "text", + "placeholders": { + "username": {}, + "joinRules": {} + } + }, + "changedTheProfileAvatar": "{username} ha canviat la seva imatge de perfil", + "@changedTheProfileAvatar": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheRoomAliases": "{username} ha canviat l’àlies de la sala", + "@changedTheRoomAliases": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheRoomInvitationLink": "{username} ha canviat l’enllaç per a convidar", + "@changedTheRoomInvitationLink": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changePassword": "Canvia la contrasenya", + "@changePassword": { + "type": "text", + "placeholders": {} + }, + "changeTheHomeserver": "Canvia el servidor", + "@changeTheHomeserver": { + "type": "text", + "placeholders": {} + }, + "changeTheme": "Canvia l’estil", + "@changeTheme": { + "type": "text", + "placeholders": {} + }, + "changeTheNameOfTheGroup": "Canvia el nom del grup", + "@changeTheNameOfTheGroup": { + "type": "text", + "placeholders": {} + }, + "changeWallpaper": "Canvia el fons", + "@changeWallpaper": { + "type": "text", + "placeholders": {} + }, + "channelCorruptedDecryptError": "El xifratge s’ha corromput", + "@channelCorruptedDecryptError": { + "type": "text", + "placeholders": {} + }, + "chat": "Xat", + "@chat": { + "type": "text", + "placeholders": {} + }, + "chatDetails": "Detalls del xat", + "@chatDetails": { + "type": "text", + "placeholders": {} + }, + "chats": "Xats", + "@chats": { + "type": "text", + "placeholders": {} + }, + "chooseAStrongPassword": "Trieu una contrasenya forta", + "@chooseAStrongPassword": { + "type": "text", + "placeholders": {} + }, + "chooseAUsername": "Trieu un nom d’usuari", + "@chooseAUsername": { + "type": "text", + "placeholders": {} + }, + "close": "Tanca", + "@close": { + "type": "text", + "placeholders": {} + }, + "commandHint_html": "Envia text en format HTML", + "@commandHint_html": { + "type": "text", + "description": "Usage hint for the command /html" + }, + "commandHint_leave": "Abandona aquesta sala", + "@commandHint_leave": { + "type": "text", + "description": "Usage hint for the command /leave" + }, + "commandHint_op": "Estableix el nivell d'autoritat de l'usuari (per defecte: 50)", + "@commandHint_op": { + "type": "text", + "description": "Usage hint for the command /op" + }, + "commandHint_plain": "Envia text sense format", + "@commandHint_plain": { + "type": "text", + "description": "Usage hint for the command /plain" + }, + "commandHint_send": "Envia text", + "@commandHint_send": { + "type": "text", + "description": "Usage hint for the command /send" + }, + "compareEmojiMatch": "Compareu i assegureu-vos que els emojis següents coincideixen amb els de l’altre dispositiu:", + "@compareEmojiMatch": { + "type": "text", + "placeholders": {} + }, + "compareNumbersMatch": "Compareu i assegureu-vos que els nombres següents coincideixen amb els de l’altre dispositiu:", + "@compareNumbersMatch": { + "type": "text", + "placeholders": {} + }, + "confirm": "Confirma", + "@confirm": { + "type": "text", + "placeholders": {} + }, + "connect": "Connecta", + "@connect": { + "type": "text", + "placeholders": {} + }, + "contactHasBeenInvitedToTheGroup": "El contacte ha estat convidat al grup", + "@contactHasBeenInvitedToTheGroup": { + "type": "text", + "placeholders": {} + }, + "containsDisplayName": "Conté l'àlies", + "@containsDisplayName": { + "type": "text", + "placeholders": {} + }, + "containsUserName": "Conté el nom d’usuari", + "@containsUserName": { + "type": "text", + "placeholders": {} + }, + "copiedToClipboard": "S’ha copiat al porta-retalls", + "@copiedToClipboard": { + "type": "text", + "placeholders": {} + }, + "copy": "Copia", + "@copy": { + "type": "text", + "placeholders": {} + }, + "couldNotDecryptMessage": "No s'ha pogut desxifrar el missatge: {error}", + "@couldNotDecryptMessage": { + "type": "text", + "placeholders": { + "error": {} + } + }, + "countParticipants": "{count} participants", + "@countParticipants": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "create": "Crea", + "@create": { + "type": "text", + "placeholders": {} + }, + "createdTheChat": "{username} ha creat el xat", + "@createdTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "createNewGroup": "Crea un grup nou", + "@createNewGroup": { + "type": "text", + "placeholders": {} + }, + "currentlyActive": "Actiu actualment", + "@currentlyActive": { + "type": "text", + "placeholders": {} + }, + "darkTheme": "Fosc", + "@darkTheme": { + "type": "text", + "placeholders": {} + }, + "dateAndTimeOfDay": "{date}, {timeOfDay}", + "@dateAndTimeOfDay": { + "type": "text", + "placeholders": { + "date": {}, + "timeOfDay": {} + } + }, + "dateWithoutYear": "{day}-{month}", + "@dateWithoutYear": { + "type": "text", + "placeholders": { + "month": {}, + "day": {} + } + }, + "dateWithYear": "{day}-{month}-{year}", + "@dateWithYear": { + "type": "text", + "placeholders": { + "year": {}, + "month": {}, + "day": {} + } + }, + "deactivateAccountWarning": "Es desactivarà el vostre compte d’usuari. Això no es pot desfer! Esteu segur de fer-ho?", + "@deactivateAccountWarning": { + "type": "text", + "placeholders": {} + }, + "delete": "Suprimeix", + "@delete": { + "type": "text", + "placeholders": {} + }, + "deleteAccount": "Suprimeix el compte", + "@deleteAccount": { + "type": "text", + "placeholders": {} + }, + "deleteMessage": "Suprimeix el missatge", + "@deleteMessage": { + "type": "text", + "placeholders": {} + }, + "deny": "Denega", + "@deny": { + "type": "text", + "placeholders": {} + }, + "device": "Dispositiu", + "@device": { + "type": "text", + "placeholders": {} + }, + "deviceId": "Id. de dispositiu", + "@deviceId": { + "type": "text", + "placeholders": {} + }, + "devices": "Dispositius", + "@devices": { + "type": "text", + "placeholders": {} + }, + "directChats": "Xats directes", + "@directChats": { + "type": "text", + "placeholders": {} + }, + "displaynameHasBeenChanged": "Ha canviat l'àlies", + "@displaynameHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "downloadFile": "Baixa el fitxer", + "@downloadFile": { + "type": "text", + "placeholders": {} + }, + "edit": "Edita", + "@edit": { + "type": "text", + "placeholders": {} + }, + "editDisplayname": "Edita l'àlies", + "@editDisplayname": { + "type": "text", + "placeholders": {} + }, + "emoteExists": "L'emoticona ja existeix!", + "@emoteExists": { + "type": "text", + "placeholders": {} + }, + "emoteInvalid": "Codi d'emoticona invàlid!", + "@emoteInvalid": { + "type": "text", + "placeholders": {} + }, + "emotePacks": "Paquet d'emoticones de la sala", + "@emotePacks": { + "type": "text", + "placeholders": {} + }, + "emoteSettings": "Paràmetres de les emoticones", + "@emoteSettings": { + "type": "text", + "placeholders": {} + }, + "emoteShortcode": "Codi d'emoticona", + "@emoteShortcode": { + "type": "text", + "placeholders": {} + }, + "emoteWarnNeedToPick": "Has de seleccionar un codi d'emoticona i una imatge!", + "@emoteWarnNeedToPick": { + "type": "text", + "placeholders": {} + }, + "emptyChat": "Xat buit", + "@emptyChat": { + "type": "text", + "placeholders": {} + }, + "enableEmotesGlobally": "Activa el paquet d'emoticones global", + "@enableEmotesGlobally": { + "type": "text", + "placeholders": {} + }, + "enableEncryptionWarning": "No podreu desactivar el xifratge mai més. N’esteu segur?", + "@enableEncryptionWarning": { + "type": "text", + "placeholders": {} + }, + "encrypted": "Xifrat", + "@encrypted": { + "type": "text", + "placeholders": {} + }, + "encryption": "Xifratge", + "@encryption": { + "type": "text", + "placeholders": {} + }, + "encryptionNotEnabled": "El xifratge no s’ha activat", + "@encryptionNotEnabled": { + "type": "text", + "placeholders": {} + }, + "endedTheCall": "{senderName} ha finalitzat la trucada", + "@endedTheCall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "enterAGroupName": "Introduïu un nom de grup", + "@enterAGroupName": { + "type": "text", + "placeholders": {} + }, + "enterAnEmailAddress": "Introduïu una adreça electrònica", + "@enterAnEmailAddress": { + "type": "text", + "placeholders": {} + }, + "enterYourHomeserver": "Introdueix el teu servidor", + "@enterYourHomeserver": { + "type": "text", + "placeholders": {} + }, + "fileName": "Nom del fitxer", + "@fileName": { + "type": "text", + "placeholders": {} + }, + "fluffychat": "FluffyChat", + "@fluffychat": { + "type": "text", + "placeholders": {} + }, + "forward": "Reenvia", + "@forward": { + "type": "text", + "placeholders": {} + }, + "fromJoining": "Des de la unió", + "@fromJoining": { + "type": "text", + "placeholders": {} + }, + "fromTheInvitation": "Des de la invitació", + "@fromTheInvitation": { + "type": "text", + "placeholders": {} + }, + "group": "Grup", + "@group": { + "type": "text", + "placeholders": {} + }, + "groupDescription": "Descripció de grup", + "@groupDescription": { + "type": "text", + "placeholders": {} + }, + "groupDescriptionHasBeenChanged": "Descripció de grup canviada", + "@groupDescriptionHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "groupIsPublic": "El grup és públic", + "@groupIsPublic": { + "type": "text", + "placeholders": {} + }, + "groupWith": "Grup amb {displayname}", + "@groupWith": { + "type": "text", + "placeholders": { + "displayname": {} + } + }, + "guestsAreForbidden": "Els convidats no poden unir-se", + "@guestsAreForbidden": { + "type": "text", + "placeholders": {} + }, + "guestsCanJoin": "Els convidats es poden unir", + "@guestsCanJoin": { + "type": "text", + "placeholders": {} + }, + "hasWithdrawnTheInvitationFor": "{username} ha retirat la invitació de {targetName}", + "@hasWithdrawnTheInvitationFor": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "help": "Ajuda", + "@help": { + "type": "text", + "placeholders": {} + }, + "hideRedactedEvents": "Amaga els esdeveniments velats", + "@hideRedactedEvents": { + "type": "text", + "placeholders": {} + }, + "hideUnknownEvents": "Amaga els esdeveniments desconeguts", + "@hideUnknownEvents": { + "type": "text", + "placeholders": {} + }, + "id": "Id.", + "@id": { + "type": "text", + "placeholders": {} + }, + "identity": "Identitat", + "@identity": { + "type": "text", + "placeholders": {} + }, + "ignoredUsers": "Usuaris ignorats", + "@ignoredUsers": { + "type": "text", + "placeholders": {} + }, + "ignoreListDescription": "Pots ignorar els usuaris que et molestin. No rebràs els missatges ni les invitacions dels usuaris que es trobin a la teva llista personal d'ignorats.", + "@ignoreListDescription": { + "type": "text", + "placeholders": {} + }, + "ignoreUsername": "Ignora nom d'usuari", + "@ignoreUsername": { + "type": "text", + "placeholders": {} + }, + "iHaveClickedOnLink": "He fet clic a l'enllaç", + "@iHaveClickedOnLink": { + "type": "text", + "placeholders": {} + }, + "incorrectPassphraseOrKey": "Frase de seguretat o clau de recuperació incorrecta", + "@incorrectPassphraseOrKey": { + "type": "text", + "placeholders": {} + }, + "inviteContact": "Convida contacte", + "@inviteContact": { + "type": "text", + "placeholders": {} + }, + "inviteContactToGroup": "Convida contacte a {groupName}", + "@inviteContactToGroup": { + "type": "text", + "placeholders": { + "groupName": {} + } + }, + "invited": "Convidat", + "@invited": { + "type": "text", + "placeholders": {} + }, + "invitedUser": "{username} ha convidat a {targetName}", + "@invitedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "invitedUsersOnly": "Només usuaris convidats", + "@invitedUsersOnly": { + "type": "text", + "placeholders": {} + }, + "inviteForMe": "Invitació per a mi", + "@inviteForMe": { + "type": "text", + "placeholders": {} + }, + "inviteText": "{username} t'ha convidat a FluffyChat.\n1. Instal·la FluffyChat: https://fluffychat.im\n2. Registra't o inicia sessió\n3. Obre l'enllaç d'invitació: {link}", + "@inviteText": { + "type": "text", + "placeholders": { + "username": {}, + "link": {} + } + }, + "isTyping": "escrivint…", + "@isTyping": { + "type": "text", + "placeholders": {} + }, + "joinedTheChat": "{username} s'ha unit al xat", + "@joinedTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "joinRoom": "Uneix-te a la sala", + "@joinRoom": { + "type": "text", + "placeholders": {} + }, + "kicked": "{username} ha expulsat a {targetName}", + "@kicked": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "kickedAndBanned": "{username} ha expulsat i vetat a {targetName}", + "@kickedAndBanned": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "kickFromChat": "Expulsa del xat", + "@kickFromChat": { + "type": "text", + "placeholders": {} + }, + "lastActiveAgo": "Actiu per última vegada: {localizedTimeShort}", + "@lastActiveAgo": { + "type": "text", + "placeholders": { + "localizedTimeShort": {} + } + }, + "lastSeenLongTimeAgo": "Vist va molt de temps", + "@lastSeenLongTimeAgo": { + "type": "text", + "placeholders": {} + }, + "leave": "Abandona", + "@leave": { + "type": "text", + "placeholders": {} + }, + "leftTheChat": "Ha marxat del xat", + "@leftTheChat": { + "type": "text", + "placeholders": {} + }, + "license": "Llicència", + "@license": { + "type": "text", + "placeholders": {} + }, + "lightTheme": "Clar", + "@lightTheme": { + "type": "text", + "placeholders": {} + }, + "loadCountMoreParticipants": "Carrega {count} participants més", + "@loadCountMoreParticipants": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "loadingPleaseWait": "S’està carregant… Espereu.", + "@loadingPleaseWait": { + "type": "text", + "placeholders": {} + }, + "loadMore": "Carrega’n més…", + "@loadMore": { + "type": "text", + "placeholders": {} + }, + "locationDisabledNotice": "S’han desactivat els serveis d’ubicació. Activeu-los per a compartir la vostra ubicació.", + "@locationDisabledNotice": { + "type": "text", + "placeholders": {} + }, + "locationPermissionDeniedNotice": "S’ha rebutjat el permís d’ubicació. Atorgueu-lo per a poder compartir la vostra ubicació.", + "@locationPermissionDeniedNotice": { + "type": "text", + "placeholders": {} + }, + "login": "Inicia la sessió", + "@login": { + "type": "text", + "placeholders": {} + }, + "logInTo": "Inicia sessió a {homeserver}", + "@logInTo": { + "type": "text", + "placeholders": { + "homeserver": {} + } + }, + "loginWith": "Inicia la sessió amb {brand}", + "@loginWith": { + "type": "text", + "placeholders": { + "brand": {} + } + }, + "logout": "Finalitza la sessió", + "@logout": { + "type": "text", + "placeholders": {} + }, + "makeSureTheIdentifierIsValid": "Assegura't que l'identificador sigui vàlid", + "@makeSureTheIdentifierIsValid": { + "type": "text", + "placeholders": {} + }, + "memberChanges": "Canvis de participants", + "@memberChanges": { + "type": "text", + "placeholders": {} + }, + "mention": "Menciona", + "@mention": { + "type": "text", + "placeholders": {} + }, + "messageWillBeRemovedWarning": "El missatge s'eliminarà per a tots els participants", + "@messageWillBeRemovedWarning": { + "type": "text", + "placeholders": {} + }, + "moderator": "Moderador", + "@moderator": { + "type": "text", + "placeholders": {} + }, + "muteChat": "Silencia el xat", + "@muteChat": { + "type": "text", + "placeholders": {} + }, + "needPantalaimonWarning": "Tingueu en compte que, ara per ara, us cal el Pantalaimon per a poder utilitzar el xifratge d’extrem a extrem.", + "@needPantalaimonWarning": { + "type": "text", + "placeholders": {} + }, + "newMessageInFluffyChat": "Missatge nou al FluffyChat", + "@newMessageInFluffyChat": { + "type": "text", + "placeholders": {} + }, + "newVerificationRequest": "Nova sol·licitud de verificació!", + "@newVerificationRequest": { + "type": "text", + "placeholders": {} + }, + "no": "No", + "@no": { + "type": "text", + "placeholders": {} + }, + "noConnectionToTheServer": "Sense connexió al servidor", + "@noConnectionToTheServer": { + "type": "text", + "placeholders": {} + }, + "noEmotesFound": "No s’ha trobat cap emoticona. 😕", + "@noEmotesFound": { + "type": "text", + "placeholders": {} + }, + "noGoogleServicesWarning": "Sembla que no teniu els Serveis de Google al telèfon. Això és una bona decisió respecte a la vostra privadesa! Per a rebre notificacions automàtiques del FluffyChat, us recomanem utilitzar https://microg.org/ o https://unifiedpush.org/.", + "@noGoogleServicesWarning": { + "type": "text", + "placeholders": {} + }, + "none": "Cap", + "@none": { + "type": "text", + "placeholders": {} + }, + "noPasswordRecoveryDescription": "Encara no heu afegit cap mètode per a poder recuperar la contrasenya.", + "@noPasswordRecoveryDescription": { + "type": "text", + "placeholders": {} + }, + "noPermission": "Sense permís", + "@noPermission": { + "type": "text", + "placeholders": {} + }, + "noRoomsFound": "No s’ha trobat cap sala…", + "@noRoomsFound": { + "type": "text", + "placeholders": {} + }, + "notifications": "Notificacions", + "@notifications": { + "type": "text", + "placeholders": {} + }, + "notificationsEnabledForThisAccount": "Notificacions activades per a aquest compte", + "@notificationsEnabledForThisAccount": { + "type": "text", + "placeholders": {} + }, + "numUsersTyping": "{count} usuaris escrivint…", + "@numUsersTyping": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "offline": "Fora de línia", + "@offline": { + "type": "text", + "placeholders": {} + }, + "ok": "D'acord", + "@ok": { + "type": "text", + "placeholders": {} + }, + "online": "En línia", + "@online": { + "type": "text", + "placeholders": {} + }, + "onlineKeyBackupEnabled": "La còpia de seguretat de claus en línia està activada", + "@onlineKeyBackupEnabled": { + "type": "text", + "placeholders": {} + }, + "oopsSomethingWentWrong": "Alguna cosa ha anat malament…", + "@oopsSomethingWentWrong": { + "type": "text", + "placeholders": {} + }, + "openAppToReadMessages": "Obre l'aplicació per llegir els missatges", + "@openAppToReadMessages": { + "type": "text", + "placeholders": {} + }, + "openCamera": "Obre la càmera", + "@openCamera": { + "type": "text", + "placeholders": {} + }, + "optionalGroupName": "(Opcional) Nom del grup", + "@optionalGroupName": { + "type": "text", + "placeholders": {} + }, + "or": "O", + "@or": { + "type": "text", + "placeholders": {} + }, + "passphraseOrKey": "contrasenya o clau de recuperació", + "@passphraseOrKey": { + "type": "text", + "placeholders": {} + }, + "password": "Contrasenya", + "@password": { + "type": "text", + "placeholders": {} + }, + "passwordForgotten": "Contrasenya oblidada", + "@passwordForgotten": { + "type": "text", + "placeholders": {} + }, + "passwordHasBeenChanged": "La contrasenya ha canviat", + "@passwordHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "passwordRecovery": "Recuperació de contrassenya", + "@passwordRecovery": { + "type": "text", + "placeholders": {} + }, + "pickImage": "Selecciona una imatge", + "@pickImage": { + "type": "text", + "placeholders": {} + }, + "pin": "Fixa", + "@pin": { + "type": "text", + "placeholders": {} + }, + "play": "Reproduir {fileName}", + "@play": { + "type": "text", + "placeholders": { + "fileName": {} + } + }, + "pleaseChooseAPasscode": "Tria un codi d'accés", + "@pleaseChooseAPasscode": { + "type": "text", + "placeholders": {} + }, + "pleaseChooseAUsername": "Tria un nom d'usuari", + "@pleaseChooseAUsername": { + "type": "text", + "placeholders": {} + }, + "pleaseClickOnLink": "Fes clic a l'enllaç del correu i, després, segueix.", + "@pleaseClickOnLink": { + "type": "text", + "placeholders": {} + }, + "pleaseEnter4Digits": "Introdueix 4 dígits o deixa-ho buit per desactivar el bloqueig.", + "@pleaseEnter4Digits": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterAMatrixIdentifier": "Introdueix un identificador de Matrix.", + "@pleaseEnterAMatrixIdentifier": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourPassword": "Introdueix la teva contrasenya", + "@pleaseEnterYourPassword": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourUsername": "Introdueix el teu nom d'usuari", + "@pleaseEnterYourUsername": { + "type": "text", + "placeholders": {} + }, + "privacy": "Privadesa", + "@privacy": { + "type": "text", + "placeholders": {} + }, + "publicRooms": "Sales públiques", + "@publicRooms": { + "type": "text", + "placeholders": {} + }, + "pushRules": "Regles push", + "@pushRules": { + "type": "text", + "placeholders": {} + }, + "recording": "Enregistrant", + "@recording": { + "type": "text", + "placeholders": {} + }, + "redactedAnEvent": "{username} ha velat un esdeveniment", + "@redactedAnEvent": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "reject": "Rebutja", + "@reject": { + "type": "text", + "placeholders": {} + }, + "rejectedTheInvitation": "{username} ha rebutjat la invitació", + "@rejectedTheInvitation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "rejoin": "Torna-t'hi a unir", + "@rejoin": { + "type": "text", + "placeholders": {} + }, + "remove": "Elimina", + "@remove": { + "type": "text", + "placeholders": {} + }, + "removeAllOtherDevices": "Elimina tots els altres dispositius", + "@removeAllOtherDevices": { + "type": "text", + "placeholders": {} + }, + "removedBy": "Eliminat per {username}", + "@removedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "removeDevice": "Elimina dispositiu", + "@removeDevice": { + "type": "text", + "placeholders": {} + }, + "unbanFromChat": "Desfés l'expulsió", + "@unbanFromChat": { + "type": "text", + "placeholders": {} + }, + "renderRichContent": "Mostra el contingut enriquit dels missatges", + "@renderRichContent": { + "type": "text", + "placeholders": {} + }, + "reply": "Respon", + "@reply": { + "type": "text", + "placeholders": {} + }, + "requestPermission": "Sol·licita permís", + "@requestPermission": { + "type": "text", + "placeholders": {} + }, + "roomHasBeenUpgraded": "La sala s'ha actualitzat", + "@roomHasBeenUpgraded": { + "type": "text", + "placeholders": {} + }, + "security": "Seguretat", + "@security": { + "type": "text", + "placeholders": {} + }, + "seenByUser": "Vist per {username}", + "@seenByUser": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "seenByUserAndCountOthers": "{count, plural, other{Vist per {username} i {count} més}}", + "@seenByUserAndCountOthers": { + "type": "text", + "placeholders": { + "username": {}, + "count": {} + } + }, + "seenByUserAndUser": "Vist per {username} i {username2}", + "@seenByUserAndUser": { + "type": "text", + "placeholders": { + "username": {}, + "username2": {} + } + }, + "send": "Envia", + "@send": { + "type": "text", + "placeholders": {} + }, + "sendAMessage": "Envia un missatge", + "@sendAMessage": { + "type": "text", + "placeholders": {} + }, + "sendAsText": "Envia com a text", + "@sendAsText": { + "type": "text" + }, + "sendAudio": "Envia un àudio", + "@sendAudio": { + "type": "text", + "placeholders": {} + }, + "sendFile": "Envia un fitxer", + "@sendFile": { + "type": "text", + "placeholders": {} + }, + "sendImage": "Envia una imatge", + "@sendImage": { + "type": "text", + "placeholders": {} + }, + "sendOriginal": "Envia l’original", + "@sendOriginal": { + "type": "text", + "placeholders": {} + }, + "sendSticker": "Envia adhesiu", + "@sendSticker": { + "type": "text", + "placeholders": {} + }, + "sendVideo": "Envia un vídeo", + "@sendVideo": { + "type": "text", + "placeholders": {} + }, + "sentAFile": "{username} ha enviat un fitxer", + "@sentAFile": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sentAnAudio": "{username} ha enviat un àudio", + "@sentAnAudio": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sentAPicture": "{username} ha enviat una imatge", + "@sentAPicture": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sentASticker": "{username} ha enviat un adhesiu", + "@sentASticker": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sentAVideo": "{username} ha enviat un vídeo", + "@sentAVideo": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sentCallInformations": "{senderName} ha enviat informació de trucada", + "@sentCallInformations": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "setGroupDescription": "Defineix la descripció del grup", + "@setGroupDescription": { + "type": "text", + "placeholders": {} + }, + "setInvitationLink": "Defineix l’enllaç per a convidar", + "@setInvitationLink": { + "type": "text", + "placeholders": {} + }, + "setPermissionsLevel": "Defineix el nivell de permisos", + "@setPermissionsLevel": { + "type": "text", + "placeholders": {} + }, + "setStatus": "Defineix l’estat", + "@setStatus": { + "type": "text", + "placeholders": {} + }, + "settings": "Paràmetres", + "@settings": { + "type": "text", + "placeholders": {} + }, + "share": "Comparteix", + "@share": { + "type": "text", + "placeholders": {} + }, + "sharedTheLocation": "{username} n’ha compartit la ubicació", + "@sharedTheLocation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "signUp": "Registre", + "@signUp": { + "type": "text", + "placeholders": {} + }, + "singlesignon": "Autenticació única", + "@singlesignon": { + "type": "text", + "placeholders": {} + }, + "skip": "Omet", + "@skip": { + "type": "text", + "placeholders": {} + }, + "sourceCode": "Codi font", + "@sourceCode": { + "type": "text", + "placeholders": {} + }, + "startedACall": "{senderName} ha iniciat una trucada", + "@startedACall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "statusExampleMessage": "Com us sentiu avui?", + "@statusExampleMessage": { + "type": "text", + "placeholders": {} + }, + "submit": "Envia", + "@submit": { + "type": "text", + "placeholders": {} + }, + "systemTheme": "Sistema", + "@systemTheme": { + "type": "text", + "placeholders": {} + }, + "theyDontMatch": "No coincideixen", + "@theyDontMatch": { + "type": "text", + "placeholders": {} + }, + "theyMatch": "Coincideixen", + "@theyMatch": { + "type": "text", + "placeholders": {} + }, + "title": "FluffyChat", + "@title": { + "description": "Title for the application", + "type": "text", + "placeholders": {} + }, + "toggleUnread": "Marca com a llegit/sense llegir", + "@toggleUnread": { + "type": "text", + "placeholders": {} + }, + "tooManyRequestsWarning": "Massa sol·licituds. Torna-ho a provar més tard!", + "@tooManyRequestsWarning": { + "type": "text", + "placeholders": {} + }, + "tryToSendAgain": "Intenta tornar a enviar", + "@tryToSendAgain": { + "type": "text", + "placeholders": {} + }, + "unavailable": "No disponible", + "@unavailable": { + "type": "text", + "placeholders": {} + }, + "unbannedUser": "{username} ha tret el veto a {targetName}", + "@unbannedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "unblockDevice": "Desbloqueja dispositiu", + "@unblockDevice": { + "type": "text", + "placeholders": {} + }, + "unknownDevice": "Dispositiu desconegut", + "@unknownDevice": { + "type": "text", + "placeholders": {} + }, + "unknownEncryptionAlgorithm": "L’algorisme de xifratge és desconegut", + "@unknownEncryptionAlgorithm": { + "type": "text", + "placeholders": {} + }, + "unknownEvent": "Esdeveniment desconegut '{type}'", + "@unknownEvent": { + "type": "text", + "placeholders": { + "type": {} + } + }, + "unmuteChat": "Deixa de silenciar el xat", + "@unmuteChat": { + "type": "text", + "placeholders": {} + }, + "unpin": "Deixa de fixar", + "@unpin": { + "type": "text", + "placeholders": {} + }, + "unreadChats": "{unreadCount, plural, =1{1 xat no llegit} other{{unreadCount} xats no llegits}}", + "@unreadChats": { + "type": "text", + "placeholders": { + "unreadCount": {} + } + }, + "userAndOthersAreTyping": "{username} i {count} més estan escrivint…", + "@userAndOthersAreTyping": { + "type": "text", + "placeholders": { + "username": {}, + "count": {} + } + }, + "userAndUserAreTyping": "{username} i {username2} estan escrivint…", + "@userAndUserAreTyping": { + "type": "text", + "placeholders": { + "username": {}, + "username2": {} + } + }, + "userIsTyping": "{username} està escrivint…", + "@userIsTyping": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "userLeftTheChat": "{username} ha marxat del xat", + "@userLeftTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "username": "Nom d’usuari", + "@username": { + "type": "text", + "placeholders": {} + }, + "userSentUnknownEvent": "{username} ha enviat un esdeveniment {type}", + "@userSentUnknownEvent": { + "type": "text", + "placeholders": { + "username": {}, + "type": {} + } + }, + "verify": "Verifica", + "@verify": { + "type": "text", + "placeholders": {} + }, + "verifyStart": "Inicia la verificació", + "@verifyStart": { + "type": "text", + "placeholders": {} + }, + "verifySuccess": "T'has verificat correctament!", + "@verifySuccess": { + "type": "text", + "placeholders": {} + }, + "verifyTitle": "Verificant un altre compte", + "@verifyTitle": { + "type": "text", + "placeholders": {} + }, + "videoCall": "Videotrucada", + "@videoCall": { + "type": "text", + "placeholders": {} + }, + "visibilityOfTheChatHistory": "Visibilitat de l’historial del xat", + "@visibilityOfTheChatHistory": { + "type": "text", + "placeholders": {} + }, + "visibleForAllParticipants": "Visible per a tots els participants", + "@visibleForAllParticipants": { + "type": "text", + "placeholders": {} + }, + "visibleForEveryone": "Visible per a tothom", + "@visibleForEveryone": { + "type": "text", + "placeholders": {} + }, + "voiceMessage": "Missatge de veu", + "@voiceMessage": { + "type": "text", + "placeholders": {} + }, + "waitingPartnerEmoji": "S’està esperant que l’altre accepti l’emoji…", + "@waitingPartnerEmoji": { + "type": "text", + "placeholders": {} + }, + "waitingPartnerNumbers": "S’està esperant que l’altre accepti els nombres…", + "@waitingPartnerNumbers": { + "type": "text", + "placeholders": {} + }, + "wallpaper": "Fons", + "@wallpaper": { + "type": "text", + "placeholders": {} + }, + "warning": "Atenció!", + "@warning": { + "type": "text", + "placeholders": {} + }, + "weSentYouAnEmail": "Us hem enviat un missatge de correu electrònic", + "@weSentYouAnEmail": { + "type": "text", + "placeholders": {} + }, + "whoIsAllowedToJoinThisGroup": "Qui pot unir-se a aquest grup", + "@whoIsAllowedToJoinThisGroup": { + "type": "text", + "placeholders": {} + }, + "withTheseAddressesRecoveryDescription": "Amb aquestes adreces, si ho necessiteu, podeu recuperar la vostra contrasenya.", + "@withTheseAddressesRecoveryDescription": { + "type": "text", + "placeholders": {} + }, + "writeAMessage": "Escriviu un missatge…", + "@writeAMessage": { + "type": "text", + "placeholders": {} + }, + "yes": "Sí", + "@yes": { + "type": "text", + "placeholders": {} + }, + "you": "Vós", + "@you": { + "type": "text", + "placeholders": {} + }, + "youAreInvitedToThisChat": "Us han convidat a aquest xat", + "@youAreInvitedToThisChat": { + "type": "text", + "placeholders": {} + }, + "youAreNoLongerParticipatingInThisChat": "Ja no participeu en aquest xat", + "@youAreNoLongerParticipatingInThisChat": { + "type": "text", + "placeholders": {} + }, + "youCannotInviteYourself": "No us podeu convidar a vós mateix", + "@youCannotInviteYourself": { + "type": "text", + "placeholders": {} + }, + "youHaveBeenBannedFromThisChat": "Has estat vetat d'aquest xat", + "@youHaveBeenBannedFromThisChat": { + "type": "text", + "placeholders": {} + }, + "yourPublicKey": "La vostra clau pública", + "@yourPublicKey": { + "type": "text", + "placeholders": {} + }, + "all": "Tot", + "@all": { + "type": "text", + "placeholders": {} + }, + "addToSpace": "Afegeix a un espai", + "@addToSpace": {}, + "areYouSureYouWantToLogout": "Segur que voleu finalitzar la sessió?", + "@areYouSureYouWantToLogout": { + "type": "text", + "placeholders": {} + }, + "addEmail": "Afegeix una adreça electrònica", + "@addEmail": { + "type": "text", + "placeholders": {} + }, + "commandInvalid": "L’ordre no és vàlida", + "@commandInvalid": { + "type": "text" + }, + "fontSize": "Mida de la lletra", + "@fontSize": { + "type": "text", + "placeholders": {} + }, + "goToTheNewRoom": "Ves a la sala nova", + "@goToTheNewRoom": { + "type": "text", + "placeholders": {} + }, + "next": "Següent", + "@next": { + "type": "text", + "placeholders": {} + }, + "link": "Enllaç", + "@link": {}, + "people": "Gent", + "@people": { + "type": "text", + "placeholders": {} + }, + "redactMessage": "Vela el missatge", + "@redactMessage": { + "type": "text", + "placeholders": {} + }, + "sendOnEnter": "Envia en prémer Retorn", + "@sendOnEnter": {}, + "clearArchive": "Neteja l’arxiu", + "@clearArchive": {}, + "chatBackupDescription": "La còpia de seguretat dels xats és protegida amb una clau. Assegureu-vos de no perdre-la.", + "@chatBackupDescription": { + "type": "text", + "placeholders": {} + }, + "chatHasBeenAddedToThisSpace": "El xat s’ha afegit a aquest espai", + "@chatHasBeenAddedToThisSpace": {}, + "autoplayImages": "Reprodueix automàticament enganxines i emoticones animades", + "@autoplayImages": { + "type": "text", + "placeholder": {} + }, + "chatBackup": "Còpia de seguretat del xat", + "@chatBackup": { + "type": "text", + "placeholders": {} + }, + "blocked": "Blocat", + "@blocked": { + "type": "text", + "placeholders": {} + }, + "everythingReady": "Tot és a punt!", + "@everythingReady": { + "type": "text", + "placeholders": {} + }, + "spaceName": "Nom de l’espai", + "@spaceName": { + "type": "text", + "placeholders": {} + }, + "search": "Cerca", + "@search": { + "type": "text", + "placeholders": {} + }, + "verified": "Verificat", + "@verified": { + "type": "text", + "placeholders": {} + }, + "newChat": "Xat nou", + "@newChat": { + "type": "text", + "placeholders": {} + }, + "changeYourAvatar": "Canvia l’avatar", + "@changeYourAvatar": { + "type": "text", + "placeholders": {} + }, + "ignore": "Ignora", + "@ignore": { + "type": "text", + "placeholders": {} + }, + "commandHint_react": "Envia una resposta com a reacció", + "@commandHint_react": { + "type": "text", + "description": "Usage hint for the command /react" + }, + "defaultPermissionLevel": "Nivell de permisos per defecte", + "@defaultPermissionLevel": { + "type": "text", + "placeholders": {} + }, + "extremeOffensive": "Extremadament ofensiu", + "@extremeOffensive": { + "type": "text", + "placeholders": {} + }, + "yourChatBackupHasBeenSetUp": "S’ha configurat la còpia de seguretat del xat.", + "@yourChatBackupHasBeenSetUp": {}, + "contentHasBeenReported": "El contingut s’ha denunciat als administradors del servidor", + "@contentHasBeenReported": { + "type": "text", + "placeholders": {} + }, + "enableEncryption": "Activa el xifratge", + "@enableEncryption": { + "type": "text", + "placeholders": {} + }, + "enterASpacepName": "Introduïu un nom d’espai", + "@enterASpacepName": {}, + "addAccount": "Afegeix un compte", + "@addAccount": {}, + "noEncryptionForPublicRooms": "Només podreu activar el xifratge quan la sala ja no sigui accessible públicament.", + "@noEncryptionForPublicRooms": { + "type": "text", + "placeholders": {} + }, + "roomVersion": "Versió de la sala", + "@roomVersion": { + "type": "text", + "placeholders": {} + }, + "sendMessages": "Envia missatges", + "@sendMessages": { + "type": "text", + "placeholders": {} + }, + "saveFile": "Desa el fitxer", + "@saveFile": { + "type": "text", + "placeholders": {} + }, + "pleaseFollowInstructionsOnWeb": "Seguiu les instruccions al lloc web i toqueu «Següent».", + "@pleaseFollowInstructionsOnWeb": { + "type": "text", + "placeholders": {} + }, + "reportMessage": "Denuncia el missatge", + "@reportMessage": { + "type": "text", + "placeholders": {} + }, + "setAsCanonicalAlias": "Defineix com a àlies principal", + "@setAsCanonicalAlias": { + "type": "text", + "placeholders": {} + }, + "status": "Estat", + "@status": { + "type": "text", + "placeholders": {} + }, + "toggleFavorite": "Commuta l’estat «preferit»", + "@toggleFavorite": { + "type": "text", + "placeholders": {} + }, + "toggleMuted": "Commuta l’estat «silenci»", + "@toggleMuted": { + "type": "text", + "placeholders": {} + }, + "transferFromAnotherDevice": "Transfereix des d’un altre dispositiu", + "@transferFromAnotherDevice": { + "type": "text", + "placeholders": {} + }, + "setCustomEmotes": "Defineix emoticones personalitzades", + "@setCustomEmotes": { + "type": "text", + "placeholders": {} + }, + "whoCanPerformWhichAction": "Qui pot efectuar quina acció", + "@whoCanPerformWhichAction": { + "type": "text", + "placeholders": {} + }, + "whyDoYouWantToReportThis": "Per què voleu denunciar això?", + "@whyDoYouWantToReportThis": { + "type": "text", + "placeholders": {} + }, + "wipeChatBackup": "Voleu suprimir la còpia de seguretat dels xats per a crear una clau de seguretat nova?", + "@wipeChatBackup": { + "type": "text", + "placeholders": {} + }, + "waitingPartnerAcceptRequest": "S’està esperant que l’altre accepti la sol·licitud…", + "@waitingPartnerAcceptRequest": { + "type": "text", + "placeholders": {} + }, + "unverified": "No verificat", + "@unverified": {}, + "commandHint_me": "Descriviu-vos", + "@commandHint_me": { + "type": "text", + "description": "Usage hint for the command /me" + }, + "commandMissing": "{command} no és una ordre.", + "@commandMissing": { + "type": "text", + "placeholders": { + "command": {} + }, + "description": "State that {command} is not a valid /command." + }, + "configureChat": "Configura el xat", + "@configureChat": { + "type": "text", + "placeholders": {} + }, + "copyToClipboard": "Copia al porta-retalls", + "@copyToClipboard": { + "type": "text", + "placeholders": {} + }, + "createNewSpace": "Espai nou", + "@createNewSpace": { + "type": "text", + "placeholders": {} + }, + "errorObtainingLocation": "S’ha produït un error en obtenir la ubicació: {error}", + "@errorObtainingLocation": { + "type": "text", + "placeholders": { + "error": {} + } + }, + "groups": "Grups", + "@groups": { + "type": "text", + "placeholders": {} + }, + "messages": "Missatges", + "@messages": { + "type": "text", + "placeholders": {} + }, + "showPassword": "Mostra la contrasenya", + "@showPassword": { + "type": "text", + "placeholders": {} + }, + "spaceIsPublic": "L’espai és públic", + "@spaceIsPublic": { + "type": "text", + "placeholders": {} + }, + "scanQrCode": "Escaneja un codi QR", + "@scanQrCode": {}, + "obtainingLocation": "S’està obtenint la ubicació…", + "@obtainingLocation": { + "type": "text", + "placeholders": {} + }, + "shareLocation": "Comparteix la ubicació", + "@shareLocation": { + "type": "text", + "placeholders": {} + }, + "synchronizingPleaseWait": "S’està sincronitzant… Espereu.", + "@synchronizingPleaseWait": { + "type": "text", + "placeholders": {} + }, + "reason": "Raó", + "@reason": { + "type": "text", + "placeholders": {} + }, + "changedTheDisplaynameTo": "{username} ha canviat el seu àlies a: '{displayname}'", + "@changedTheDisplaynameTo": { + "type": "text", + "placeholders": { + "username": {}, + "displayname": {} + } + }, + "howOffensiveIsThisContent": "Com d’ofensiu és aquest contingut?", + "@howOffensiveIsThisContent": { + "type": "text", + "placeholders": {} + }, + "commandHint_clearcache": "Neteja la memòria cau", + "@commandHint_clearcache": { + "type": "text", + "description": "Usage hint for the command /clearcache" + }, + "commandHint_join": "Uneix-te a la sala", + "@commandHint_join": { + "type": "text", + "description": "Usage hint for the command /join" + }, + "commandHint_kick": "Elimina l'usuari indicat d'aquesta sala", + "@commandHint_kick": { + "type": "text", + "description": "Usage hint for the command /kick" + }, + "commandHint_myroomavatar": "Establiu la imatge per a aquesta sala (per mxc-uri)", + "@commandHint_myroomavatar": { + "type": "text", + "description": "Usage hint for the command /myroomavatar" + }, + "commandHint_dm": "Inicia un xat directe\nUsa --no-encryption per desactivar l'encriptatge", + "@commandHint_dm": { + "type": "text", + "description": "Usage hint for the command /dm" + }, + "commandHint_invite": "Convida l'usuari indicat a aquesta sala", + "@commandHint_invite": { + "type": "text", + "description": "Usage hint for the command /invite" + }, + "commandHint_ban": "Prohibeix l'usuari indicat d'aquesta sala", + "@commandHint_ban": { + "type": "text", + "description": "Usage hint for the command /ban" + }, + "commandHint_create": "Crea un xat de grup buit\nUsa --no-encryption per desactivar l'encriptatge", + "@commandHint_create": { + "type": "text", + "description": "Usage hint for the command /create" + }, + "commandHint_discardsession": "Descarta la sessió", + "@commandHint_discardsession": { + "type": "text", + "description": "Usage hint for the command /discardsession" + }, + "passwordsDoNotMatch": "Les contrasenyes no coincideixen!", + "@passwordsDoNotMatch": {}, + "pleaseEnterValidEmail": "Introduïu una adreça electrònica vàlida.", + "@pleaseEnterValidEmail": {}, + "repeatPassword": "Repetiu la contrasenya", + "@repeatPassword": {}, + "pleaseChooseAtLeastChars": "Seleccioneu almenys {min} caràcters.", + "@pleaseChooseAtLeastChars": { + "type": "text", + "placeholders": { + "min": {} + } + }, + "bubbleSize": "Mida de la bombolla", + "@bubbleSize": { + "type": "text", + "placeholders": {} + }, + "commandHint_myroomnick": "Estableix el teu àlies per a aquesta sala", + "@commandHint_myroomnick": { + "type": "text", + "description": "Usage hint for the command /myroomnick" + }, + "editBlockedServers": "Edita els servidors bloquejats", + "@editBlockedServers": { + "type": "text", + "placeholders": {} + }, + "badServerLoginTypesException": "El servidor admet els inicis de sessió:\n{serverVersions}\nPerò l'aplicació només admet:\n{supportedVersions}", + "@badServerLoginTypesException": { + "type": "text", + "placeholders": { + "serverVersions": {}, + "supportedVersions": {} + } + }, + "editChatPermissions": "Edita els permisos del xat", + "@editChatPermissions": { + "type": "text", + "placeholders": {} + }, + "hugContent": "", + "@hugContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "jumpToLastReadMessage": "", + "@jumpToLastReadMessage": {}, + "allRooms": "", + "@allRooms": { + "type": "text", + "placeholders": {} + }, + "whoCanSeeMyStories": "", + "@whoCanSeeMyStories": {}, + "commandHint_cuddle": "", + "@commandHint_cuddle": {}, + "widgetVideo": "", + "@widgetVideo": {}, + "dismiss": "", + "@dismiss": {}, + "reportErrorDescription": "", + "@reportErrorDescription": {}, + "removeYourAvatar": "", + "@removeYourAvatar": { + "type": "text", + "placeholders": {} + }, + "unsupportedAndroidVersion": "", + "@unsupportedAndroidVersion": {}, + "widgetJitsi": "", + "@widgetJitsi": {}, + "messageType": "", + "@messageType": {}, + "noEmailWarning": "", + "@noEmailWarning": {}, + "indexedDbErrorLong": "", + "@indexedDbErrorLong": {}, + "oneClientLoggedOut": "", + "@oneClientLoggedOut": {}, + "startFirstChat": "", + "@startFirstChat": {}, + "callingAccount": "", + "@callingAccount": {}, + "setColorTheme": "", + "@setColorTheme": {}, + "nextAccount": "", + "@nextAccount": {}, + "allSpaces": "", + "@allSpaces": {}, + "supposedMxid": "", + "@supposedMxid": { + "type": "text", + "placeholders": { + "mxid": {} + } + }, + "user": "", + "@user": {}, + "youAcceptedTheInvitation": "", + "@youAcceptedTheInvitation": {}, + "noMatrixServer": "", + "@noMatrixServer": { + "type": "text", + "placeholders": { + "server1": {}, + "server2": {} + } + }, + "youInvitedBy": "", + "@youInvitedBy": { + "placeholders": { + "user": {} + } + }, + "banUserDescription": "", + "@banUserDescription": {}, + "requests": "", + "@requests": {}, + "widgetEtherpad": "", + "@widgetEtherpad": {}, + "stories": "", + "@stories": {}, + "addToStory": "", + "@addToStory": {}, + "removeDevicesDescription": "", + "@removeDevicesDescription": {}, + "separateChatTypes": "", + "@separateChatTypes": { + "type": "text", + "placeholders": {} + }, + "tryAgain": "", + "@tryAgain": {}, + "youKickedAndBanned": "", + "@youKickedAndBanned": { + "placeholders": { + "user": {} + } + }, + "showDirectChatsInSpaces": "", + "@showDirectChatsInSpaces": { + "type": "text", + "placeholders": {} + }, + "unbanUserDescription": "", + "@unbanUserDescription": {}, + "todoLists": "", + "@todoLists": {}, + "youRejectedTheInvitation": "", + "@youRejectedTheInvitation": {}, + "otherCallingPermissions": "", + "@otherCallingPermissions": {}, + "messagesStyle": "", + "@messagesStyle": {}, + "widgetUrlError": "", + "@widgetUrlError": {}, + "emailOrUsername": "", + "@emailOrUsername": {}, + "newSpaceDescription": "", + "@newSpaceDescription": {}, + "chatDescription": "", + "@chatDescription": {}, + "callingAccountDetails": "", + "@callingAccountDetails": {}, + "editRoomAliases": "", + "@editRoomAliases": { + "type": "text", + "placeholders": {} + }, + "enterSpace": "", + "@enterSpace": {}, + "encryptThisChat": "", + "@encryptThisChat": {}, + "previousAccount": "", + "@previousAccount": {}, + "reopenChat": "", + "@reopenChat": {}, + "pleaseEnterRecoveryKey": "", + "@pleaseEnterRecoveryKey": {}, + "widgetNameError": "", + "@widgetNameError": {}, + "inoffensive": "", + "@inoffensive": { + "type": "text", + "placeholders": {} + }, + "addToBundle": "", + "@addToBundle": {}, + "addWidget": "", + "@addWidget": {}, + "countFiles": "", + "@countFiles": { + "placeholders": { + "count": {} + } + }, + "noKeyForThisMessage": "", + "@noKeyForThisMessage": {}, + "commandHint_markasgroup": "", + "@commandHint_markasgroup": {}, + "editTodo": "", + "@editTodo": {}, + "hydrateTor": "", + "@hydrateTor": {}, + "pushNotificationsNotAvailable": "", + "@pushNotificationsNotAvailable": {}, + "storeInAppleKeyChain": "", + "@storeInAppleKeyChain": {}, + "replaceRoomWithNewerVersion": "", + "@replaceRoomWithNewerVersion": { + "type": "text", + "placeholders": {} + }, + "hydrate": "", + "@hydrate": {}, + "invalidServerName": "", + "@invalidServerName": {}, + "chatPermissions": "", + "@chatPermissions": {}, + "sender": "", + "@sender": {}, + "storeInAndroidKeystore": "", + "@storeInAndroidKeystore": {}, + "signInWithPassword": "", + "@signInWithPassword": {}, + "pleaseAddATitle": "", + "@pleaseAddATitle": {}, + "updateNow": "", + "@updateNow": {}, + "offensive": "", + "@offensive": { + "type": "text", + "placeholders": {} + }, + "makeAdminDescription": "", + "@makeAdminDescription": {}, + "saveKeyManuallyDescription": "", + "@saveKeyManuallyDescription": {}, + "editBundlesForAccount": "", + "@editBundlesForAccount": {}, + "whyIsThisMessageEncrypted": "", + "@whyIsThisMessageEncrypted": {}, + "setChatDescription": "", + "@setChatDescription": {}, + "importFromZipFile": "", + "@importFromZipFile": {}, + "dehydrateWarning": "", + "@dehydrateWarning": {}, + "noOtherDevicesFound": "", + "@noOtherDevicesFound": {}, + "addDescription": "", + "@addDescription": {}, + "redactedBy": "", + "@redactedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "videoCallsBetaWarning": "", + "@videoCallsBetaWarning": {}, + "storyPrivacyWarning": "", + "@storyPrivacyWarning": {}, + "matrixWidgets": "", + "@matrixWidgets": {}, + "participant": "", + "@participant": { + "type": "text", + "placeholders": {} + }, + "signInWith": "", + "@signInWith": { + "type": "text", + "placeholders": { + "provider": {} + } + }, + "updateAvailable": "", + "@updateAvailable": {}, + "fileIsTooBigForServer": "", + "@fileIsTooBigForServer": {}, + "homeserver": "", + "@homeserver": {}, + "noTodosYet": "", + "@noTodosYet": {}, + "callingPermissions": "", + "@callingPermissions": {}, + "readUpToHere": "", + "@readUpToHere": {}, + "start": "", + "@start": {}, + "register": "", + "@register": { + "type": "text", + "placeholders": {} + }, + "unlockOldMessages": "", + "@unlockOldMessages": {}, + "numChats": "", + "@numChats": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "whatIsGoingOn": "", + "@whatIsGoingOn": {}, + "optionalRedactReason": "", + "@optionalRedactReason": {}, + "dehydrate": "", + "@dehydrate": {}, + "archiveRoomDescription": "", + "@archiveRoomDescription": {}, + "exportEmotePack": "", + "@exportEmotePack": {}, + "switchToAccount": "", + "@switchToAccount": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "letsStart": "", + "@letsStart": {}, + "experimentalVideoCalls": "", + "@experimentalVideoCalls": {}, + "savedEmotePack": "", + "@savedEmotePack": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "pleaseEnterRecoveryKeyDescription": "", + "@pleaseEnterRecoveryKeyDescription": {}, + "openInMaps": "", + "@openInMaps": { + "type": "text", + "placeholders": {} + }, + "inviteContactToGroupQuestion": "", + "@inviteContactToGroupQuestion": {}, + "redactedByBecause": "", + "@redactedByBecause": { + "type": "text", + "placeholders": { + "username": {}, + "reason": {} + } + }, + "youHaveWithdrawnTheInvitationFor": "", + "@youHaveWithdrawnTheInvitationFor": { + "placeholders": { + "user": {} + } + }, + "appearOnTopDetails": "", + "@appearOnTopDetails": {}, + "enterRoom": "", + "@enterRoom": {}, + "reportUser": "", + "@reportUser": {}, + "confirmEventUnpin": "", + "@confirmEventUnpin": {}, + "badServerVersionsException": "", + "@badServerVersionsException": { + "type": "text", + "placeholders": { + "serverVersions": {}, + "supportedVersions": {} + } + }, + "youInvitedUser": "", + "@youInvitedUser": { + "placeholders": { + "user": {} + } + }, + "fileHasBeenSavedAt": "", + "@fileHasBeenSavedAt": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "importZipFile": "", + "@importZipFile": {}, + "anyoneCanKnock": "", + "@anyoneCanKnock": {}, + "redactMessageDescription": "", + "@redactMessageDescription": {}, + "recoveryKey": "", + "@recoveryKey": {}, + "invalidInput": "", + "@invalidInput": {}, + "todosUnencrypted": "", + "@todosUnencrypted": {}, + "dehydrateTorLong": "", + "@dehydrateTorLong": {}, + "replyHasBeenSent": "", + "@replyHasBeenSent": {}, + "doNotShowAgain": "", + "@doNotShowAgain": {}, + "report": "", + "@report": {}, + "yourStory": "", + "@yourStory": {}, + "serverRequiresEmail": "", + "@serverRequiresEmail": {}, + "hideUnimportantStateEvents": "", + "@hideUnimportantStateEvents": {}, + "screenSharingTitle": "", + "@screenSharingTitle": {}, + "widgetCustom": "", + "@widgetCustom": {}, + "addToSpaceDescription": "", + "@addToSpaceDescription": {}, + "googlyEyesContent": "", + "@googlyEyesContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "whoCanSeeMyStoriesDesc": "", + "@whoCanSeeMyStoriesDesc": {}, + "youBannedUser": "", + "@youBannedUser": { + "placeholders": { + "user": {} + } + }, + "unsubscribeStories": "", + "@unsubscribeStories": {}, + "loginWithOneClick": "", + "@loginWithOneClick": {}, + "addChatDescription": "", + "@addChatDescription": {}, + "editRoomAvatar": "", + "@editRoomAvatar": { + "type": "text", + "placeholders": {} + }, + "hasKnocked": "", + "@hasKnocked": { + "placeholders": { + "user": {} + } + }, + "publish": "", + "@publish": {}, + "openLinkInBrowser": "", + "@openLinkInBrowser": {}, + "messageInfo": "", + "@messageInfo": {}, + "disableEncryptionWarning": "", + "@disableEncryptionWarning": {}, + "directChat": "", + "@directChat": {}, + "noOneCanJoin": "", + "@noOneCanJoin": {}, + "wrongPinEntered": "", + "@wrongPinEntered": { + "type": "text", + "placeholders": { + "seconds": {} + } + }, + "sendTypingNotifications": "", + "@sendTypingNotifications": {}, + "inviteGroupChat": "", + "@inviteGroupChat": {}, + "appearOnTop": "", + "@appearOnTop": {}, + "invitePrivateChat": "", + "@invitePrivateChat": {}, + "foregroundServiceRunning": "", + "@foregroundServiceRunning": {}, + "voiceCall": "", + "@voiceCall": {}, + "commandHint_unban": "", + "@commandHint_unban": { + "type": "text", + "description": "Usage hint for the command /unban" + }, + "importEmojis": "", + "@importEmojis": {}, + "wasDirectChatDisplayName": "", + "@wasDirectChatDisplayName": { + "type": "text", + "placeholders": { + "oldDisplayName": {} + } + }, + "noChatDescriptionYet": "", + "@noChatDescriptionYet": {}, + "newTodo": "", + "@newTodo": {}, + "removeFromBundle": "", + "@removeFromBundle": {}, + "confirmMatrixId": "", + "@confirmMatrixId": {}, + "learnMore": "", + "@learnMore": {}, + "notAnImage": "", + "@notAnImage": {}, + "users": "", + "@users": {}, + "openGallery": "", + "@openGallery": {}, + "chatDescriptionHasBeenChanged": "", + "@chatDescriptionHasBeenChanged": {}, + "newGroup": "", + "@newGroup": {}, + "bundleName": "", + "@bundleName": {}, + "dehydrateTor": "", + "@dehydrateTor": {}, + "todoListChangedError": "", + "@todoListChangedError": {}, + "removeFromSpace": "", + "@removeFromSpace": {}, + "enterInviteLinkOrMatrixId": "", + "@enterInviteLinkOrMatrixId": {}, + "roomUpgradeDescription": "", + "@roomUpgradeDescription": {}, + "pleaseEnterANumber": "", + "@pleaseEnterANumber": {}, + "youKicked": "", + "@youKicked": { + "placeholders": { + "user": {} + } + }, + "profileNotFound": "", + "@profileNotFound": {}, + "jump": "", + "@jump": {}, + "reactedWith": "", + "@reactedWith": { + "type": "text", + "placeholders": { + "sender": {}, + "reaction": {} + } + }, + "sorryThatsNotPossible": "", + "@sorryThatsNotPossible": {}, + "storyFrom": "", + "@storyFrom": { + "type": "text", + "placeholders": { + "date": {}, + "body": {} + } + }, + "videoWithSize": "", + "@videoWithSize": { + "type": "text", + "placeholders": { + "size": {} + } + }, + "shareInviteLink": "", + "@shareInviteLink": {}, + "commandHint_markasdm": "", + "@commandHint_markasdm": {}, + "recoveryKeyLost": "", + "@recoveryKeyLost": {}, + "cuddleContent": "", + "@cuddleContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "deviceKeys": "", + "@deviceKeys": {}, + "emoteKeyboardNoRecents": "", + "@emoteKeyboardNoRecents": { + "type": "text", + "placeholders": {} + }, + "endToEndEncryption": "", + "@endToEndEncryption": {}, + "setTheme": "", + "@setTheme": {}, + "youJoinedTheChat": "", + "@youJoinedTheChat": {}, + "openVideoCamera": "", + "@openVideoCamera": { + "type": "text", + "placeholders": {} + }, + "thisUserHasNotPostedAnythingYet": "", + "@thisUserHasNotPostedAnythingYet": {}, + "markAsRead": "", + "@markAsRead": {}, + "widgetName": "", + "@widgetName": {}, + "errorAddingWidget": "", + "@errorAddingWidget": {}, + "commandHint_hug": "", + "@commandHint_hug": {}, + "replace": "", + "@replace": {}, + "oopsPushError": "", + "@oopsPushError": { + "type": "text", + "placeholders": {} + }, + "youUnbannedUser": "", + "@youUnbannedUser": { + "placeholders": { + "user": {} + } + }, + "newSpace": "", + "@newSpace": {}, + "emojis": "", + "@emojis": {}, + "pleaseEnterYourPin": "", + "@pleaseEnterYourPin": { + "type": "text", + "placeholders": {} + }, + "pleaseChoose": "", + "@pleaseChoose": { + "type": "text", + "placeholders": {} + }, + "commandHint_googly": "", + "@commandHint_googly": {}, + "pleaseTryAgainLaterOrChooseDifferentServer": "", + "@pleaseTryAgainLaterOrChooseDifferentServer": {}, + "createGroup": "", + "@createGroup": {}, + "hydrateTorLong": "", + "@hydrateTorLong": {}, + "time": "", + "@time": {}, + "custom": "", + "@custom": {}, + "noBackupWarning": "", + "@noBackupWarning": {}, + "editWidgets": "", + "@editWidgets": {}, + "storeInSecureStorageDescription": "", + "@storeInSecureStorageDescription": {}, + "openChat": "", + "@openChat": {}, + "kickUserDescription": "", + "@kickUserDescription": {}, + "importNow": "", + "@importNow": {}, + "pinMessage": "", + "@pinMessage": {}, + "invite": "", + "@invite": {}, + "enableMultiAccounts": "", + "@enableMultiAccounts": {}, + "continueWith": "", + "@continueWith": {}, + "indexedDbErrorTitle": "", + "@indexedDbErrorTitle": {}, + "discover": "", + "@discover": { + "type": "text", + "placeholders": {} + }, + "unsupportedAndroidVersionLong": "", + "@unsupportedAndroidVersionLong": {}, + "storeSecurlyOnThisDevice": "", + "@storeSecurlyOnThisDevice": {}, + "iUnderstand": "", + "@iUnderstand": {}, + "screenSharingDetail": "", + "@screenSharingDetail": {}, + "placeCall": "", + "@placeCall": {} +} diff --git a/assets/l10n/intl_cs.arb b/assets/l10n/intl_cs.arb index 3067b3e02..1414bb3d1 100644 --- a/assets/l10n/intl_cs.arb +++ b/assets/l10n/intl_cs.arb @@ -2343,7 +2343,7 @@ "@notAnImage": {}, "importNow": "Importovat nyní", "@importNow": {}, - "redactedByBecause": "Redigováno uživatelem {username} s důvodem: \"{reason}\"", + "redactedByBecause": "Smazáno uživatelem {username} s důvodem: \"{reason}\"", "@redactedByBecause": { "type": "text", "placeholders": { @@ -2415,7 +2415,7 @@ "@jumpToLastReadMessage": {}, "signInWithPassword": "Přihlásit se pomocí hesla", "@signInWithPassword": {}, - "redactedBy": "Redigováno uživatelem {username}", + "redactedBy": "Smazáno uživatelem {username}", "@redactedBy": { "type": "text", "placeholders": { @@ -2432,9 +2432,9 @@ "@noOneCanJoin": {}, "tryAgain": "Zkuste to znovu", "@tryAgain": {}, - "redactMessageDescription": "Tato zpráva bude skryta pro všechny účastníky konverzace. Tuto akci nelze vzít zpět.", + "redactMessageDescription": "Tato zpráva bude smazána pro všechny účastníky konverzace. Tuto akci nelze vzít zpět.", "@redactMessageDescription": {}, - "optionalRedactReason": "(Nepovinné) Důvod redakce této zprávy…", + "optionalRedactReason": "(Nepovinné) Důvod smazání této zprávy…", "@optionalRedactReason": {}, "messagesStyle": "Zprávy:", "@messagesStyle": {}, @@ -2566,5 +2566,96 @@ } }, "requests": "Žádosti", - "@requests": {} + "@requests": {}, + "reportErrorDescription": "", + "@reportErrorDescription": {}, + "banUserDescription": "", + "@banUserDescription": {}, + "removeDevicesDescription": "", + "@removeDevicesDescription": {}, + "unbanUserDescription": "", + "@unbanUserDescription": {}, + "todoLists": "", + "@todoLists": {}, + "editTodo": "", + "@editTodo": {}, + "pushNotificationsNotAvailable": "", + "@pushNotificationsNotAvailable": {}, + "pleaseAddATitle": "", + "@pleaseAddATitle": {}, + "makeAdminDescription": "", + "@makeAdminDescription": {}, + "noTodosYet": "", + "@noTodosYet": {}, + "archiveRoomDescription": "", + "@archiveRoomDescription": {}, + "savedEmotePack": "", + "@savedEmotePack": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "invalidInput": "", + "@invalidInput": {}, + "todosUnencrypted": "", + "@todosUnencrypted": {}, + "report": "", + "@report": {}, + "hasKnocked": "", + "@hasKnocked": { + "placeholders": { + "user": {} + } + }, + "wrongPinEntered": "", + "@wrongPinEntered": { + "type": "text", + "placeholders": { + "seconds": {} + } + }, + "inviteGroupChat": "", + "@inviteGroupChat": {}, + "invitePrivateChat": "", + "@invitePrivateChat": {}, + "newTodo": "", + "@newTodo": {}, + "learnMore": "", + "@learnMore": {}, + "todoListChangedError": "", + "@todoListChangedError": {}, + "roomUpgradeDescription": "", + "@roomUpgradeDescription": {}, + "pleaseEnterANumber": "", + "@pleaseEnterANumber": {}, + "emoteKeyboardNoRecents": "", + "@emoteKeyboardNoRecents": { + "type": "text", + "placeholders": {} + }, + "kickUserDescription": "", + "@kickUserDescription": {}, + "invite": "", + "@invite": {}, + "indexedDbErrorLong": "", + "@indexedDbErrorLong": {}, + "callingAccount": "", + "@callingAccount": {}, + "enterSpace": "", + "@enterSpace": {}, + "noKeyForThisMessage": "", + "@noKeyForThisMessage": {}, + "readUpToHere": "", + "@readUpToHere": {}, + "appearOnTopDetails": "", + "@appearOnTopDetails": {}, + "enterRoom": "", + "@enterRoom": {}, + "hideUnimportantStateEvents": "", + "@hideUnimportantStateEvents": {}, + "noBackupWarning": "", + "@noBackupWarning": {}, + "indexedDbErrorTitle": "", + "@indexedDbErrorTitle": {} } diff --git a/assets/l10n/intl_de.arb b/assets/l10n/intl_de.arb index 077f0efd3..e472d80ec 100644 --- a/assets/l10n/intl_de.arb +++ b/assets/l10n/intl_de.arb @@ -1159,7 +1159,7 @@ "type": "text", "placeholders": {} }, - "noGoogleServicesWarning": "Es sieht so aus, als hättest du keine Google-Dienste auf deinem Gerät. Das ist eine gute Entscheidung für deine Privatsphäre! Um Push-Benachrichtigungen in FluffyChat zu erhalten, empfehlen wir die Verwendung von microG https://microg.org/ oder Unified Push https://unifiedpush.org/.", + "noGoogleServicesWarning": "Firebase Cloud Messaging scheint auf deinem Gerät nicht verfügbar zu sein. Um trotzdem Push-Benachrichtigungen zu erhalten, empfehlen wir die Installation von ntfy. Mit ntfy oder einem anderen Unified Push Anbieter kannst du Push-Benachrichtigungen datensicher empfangen. Du kannst ntfy im PlayStore oder bei F-Droid herunterladen.", "@noGoogleServicesWarning": { "type": "text", "placeholders": {} @@ -1888,7 +1888,7 @@ "type": "text", "placeholders": {} }, - "verify": "Bestätigen", + "verify": "Verifizieren", "@verify": { "type": "text", "placeholders": {} @@ -2211,7 +2211,7 @@ "@openChat": {}, "confirmEventUnpin": "Möchtest du das Ereignis wirklich dauerhaft lösen?", "@confirmEventUnpin": {}, - "dismiss": "Ablehnen", + "dismiss": "Verwerfen", "@dismiss": {}, "switchToAccount": "Zu Konto {number} wechseln", "@switchToAccount": { @@ -2607,5 +2607,57 @@ "invitePrivateChat": "📨 Einladungen zum privaten Chat", "@invitePrivateChat": {}, "invalidInput": "Ungültige Eingabe!", - "@invalidInput": {} + "@invalidInput": {}, + "hasKnocked": "{user} hat angeklopft", + "@hasKnocked": { + "placeholders": { + "user": {} + } + }, + "wrongPinEntered": "Falsche PIN eingegeben! Bitte in {seconds} Sekunden erneut versuchen ...", + "@wrongPinEntered": { + "type": "text", + "placeholders": { + "seconds": {} + } + }, + "pleaseEnterANumber": "Bitte eine Zahl größer 0 eingeben", + "@pleaseEnterANumber": {}, + "emoteKeyboardNoRecents": "Kürzlich verwendete Emotes werden hier angezeigt ...", + "@emoteKeyboardNoRecents": { + "type": "text", + "placeholders": {} + }, + "banUserDescription": "Der Benutzer wird aus dem Chat gebannt und kann den Chat erst wieder betreten, wenn die Verbannung aufgehoben wird.", + "@banUserDescription": {}, + "removeDevicesDescription": "Du wirst von diesem Gerät abgemeldet und kannst dann dort keine Nachrichten mehr empfangen.", + "@removeDevicesDescription": {}, + "unbanUserDescription": "Der Benutzer kann den Chat dann wieder betreten, wenn er es versucht.", + "@unbanUserDescription": {}, + "todoLists": "(Beta) Aufgabenlisten", + "@todoLists": {}, + "editTodo": "Aufgabe bearbeiten", + "@editTodo": {}, + "pushNotificationsNotAvailable": "Push-Benachrichtigungen nicht verfügbar", + "@pushNotificationsNotAvailable": {}, + "pleaseAddATitle": "Bitte einen Titel hinzufügen", + "@pleaseAddATitle": {}, + "makeAdminDescription": "Sobald du diesen Benutzer zum Administrator gemacht hast, kannst du das möglicherweise nicht mehr rückgängig machen, da er dann über dieselben Berechtigungen wie du verfügt.", + "@makeAdminDescription": {}, + "noTodosYet": "Zu diesem Chat wurden noch keine Aufgaben hinzugefügt. Erstellen die erste Aufgabe und fange an, mit anderen zusammenzuarbeiten. 📝", + "@noTodosYet": {}, + "archiveRoomDescription": "Der Chat wird in das Archiv verschoben. Andere Benutzer können sehen, dass du den Chat verlassen hast.", + "@archiveRoomDescription": {}, + "newTodo": "Neue Aufgabe", + "@newTodo": {}, + "learnMore": "Erfahre mehr", + "@learnMore": {}, + "todoListChangedError": "Hoppla ... Die Aufgabenliste wurde geändert, während Sie sie bearbeitet haben.", + "@todoListChangedError": {}, + "roomUpgradeDescription": "Der Chat wird dann mit der neuen Raumversion neu erstellt. Alle Teilnehmer werden benachrichtigt, dass sie zum neuen Chat wechseln müssen. Mehr über Raumversionen erfährst du unter https://spec.matrix.org/latest/rooms/", + "@roomUpgradeDescription": {}, + "kickUserDescription": "Der Benutzer wird aus dem Chat geworfen, aber nicht gebannt. In öffentlichen Chats kann der Benutzer jederzeit wieder beitreten.", + "@kickUserDescription": {}, + "todosUnencrypted": "Bitte beachte, dass Todos für jeden im Chat sichtbar und nicht Ende zu Ende verschlüsselt sind.", + "@todosUnencrypted": {} } diff --git a/assets/l10n/intl_el.arb b/assets/l10n/intl_el.arb index 0967ef424..d138084cf 100644 --- a/assets/l10n/intl_el.arb +++ b/assets/l10n/intl_el.arb @@ -1 +1,2620 @@ -{} +{ + "showPassword": "", + "@showPassword": { + "type": "text", + "placeholders": {} + }, + "hugContent": "", + "@hugContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "darkTheme": "", + "@darkTheme": { + "type": "text", + "placeholders": {} + }, + "passphraseOrKey": "", + "@passphraseOrKey": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourPassword": "", + "@pleaseEnterYourPassword": { + "type": "text", + "placeholders": {} + }, + "theyMatch": "", + "@theyMatch": { + "type": "text", + "placeholders": {} + }, + "connect": "", + "@connect": { + "type": "text", + "placeholders": {} + }, + "jumpToLastReadMessage": "", + "@jumpToLastReadMessage": {}, + "allRooms": "", + "@allRooms": { + "type": "text", + "placeholders": {} + }, + "obtainingLocation": "", + "@obtainingLocation": { + "type": "text", + "placeholders": {} + }, + "whoCanSeeMyStories": "", + "@whoCanSeeMyStories": {}, + "commandHint_cuddle": "", + "@commandHint_cuddle": {}, + "chats": "", + "@chats": { + "type": "text", + "placeholders": {} + }, + "widgetVideo": "", + "@widgetVideo": {}, + "dismiss": "", + "@dismiss": {}, + "unknownDevice": "", + "@unknownDevice": { + "type": "text", + "placeholders": {} + }, + "emoteShortcode": "", + "@emoteShortcode": { + "type": "text", + "placeholders": {} + }, + "noEncryptionForPublicRooms": "", + "@noEncryptionForPublicRooms": { + "type": "text", + "placeholders": {} + }, + "admin": "", + "@admin": { + "type": "text", + "placeholders": {} + }, + "reportErrorDescription": "", + "@reportErrorDescription": {}, + "directChats": "", + "@directChats": { + "type": "text", + "placeholders": {} + }, + "setPermissionsLevel": "", + "@setPermissionsLevel": { + "type": "text", + "placeholders": {} + }, + "inviteContactToGroup": "", + "@inviteContactToGroup": { + "type": "text", + "placeholders": { + "groupName": {} + } + }, + "addAccount": "", + "@addAccount": {}, + "close": "", + "@close": { + "type": "text", + "placeholders": {} + }, + "configureChat": "", + "@configureChat": { + "type": "text", + "placeholders": {} + }, + "seenByUserAndUser": "", + "@seenByUserAndUser": { + "type": "text", + "placeholders": { + "username": {}, + "username2": {} + } + }, + "chatHasBeenAddedToThisSpace": "", + "@chatHasBeenAddedToThisSpace": {}, + "reply": "", + "@reply": { + "type": "text", + "placeholders": {} + }, + "currentlyActive": "", + "@currentlyActive": { + "type": "text", + "placeholders": {} + }, + "removeYourAvatar": "", + "@removeYourAvatar": { + "type": "text", + "placeholders": {} + }, + "unsupportedAndroidVersion": "", + "@unsupportedAndroidVersion": {}, + "enterASpacepName": "", + "@enterASpacepName": {}, + "device": "", + "@device": { + "type": "text", + "placeholders": {} + }, + "blockDevice": "", + "@blockDevice": { + "type": "text", + "placeholders": {} + }, + "commandHint_html": "", + "@commandHint_html": { + "type": "text", + "description": "Usage hint for the command /html" + }, + "widgetJitsi": "", + "@widgetJitsi": {}, + "youAreNoLongerParticipatingInThisChat": "", + "@youAreNoLongerParticipatingInThisChat": { + "type": "text", + "placeholders": {} + }, + "encryption": "", + "@encryption": { + "type": "text", + "placeholders": {} + }, + "messageType": "", + "@messageType": {}, + "noEmailWarning": "", + "@noEmailWarning": {}, + "indexedDbErrorLong": "", + "@indexedDbErrorLong": {}, + "oneClientLoggedOut": "", + "@oneClientLoggedOut": {}, + "toggleMuted": "", + "@toggleMuted": { + "type": "text", + "placeholders": {} + }, + "unsupportedAndroidVersionLong": "", + "@unsupportedAndroidVersionLong": {}, + "kicked": "", + "@kicked": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "title": "", + "@title": { + "description": "Title for the application", + "type": "text", + "placeholders": {} + }, + "changeTheNameOfTheGroup": "", + "@changeTheNameOfTheGroup": { + "type": "text", + "placeholders": {} + }, + "changedTheChatAvatar": "", + "@changedTheChatAvatar": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "verifySuccess": "", + "@verifySuccess": { + "type": "text", + "placeholders": {} + }, + "sendFile": "", + "@sendFile": { + "type": "text", + "placeholders": {} + }, + "newVerificationRequest": "", + "@newVerificationRequest": { + "type": "text", + "placeholders": {} + }, + "startFirstChat": "", + "@startFirstChat": {}, + "callingAccount": "", + "@callingAccount": {}, + "requestPermission": "", + "@requestPermission": { + "type": "text", + "placeholders": {} + }, + "sentAPicture": "", + "@sentAPicture": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "invited": "", + "@invited": { + "type": "text", + "placeholders": {} + }, + "changedTheDisplaynameTo": "", + "@changedTheDisplaynameTo": { + "type": "text", + "placeholders": { + "username": {}, + "displayname": {} + } + }, + "setColorTheme": "", + "@setColorTheme": {}, + "nextAccount": "", + "@nextAccount": {}, + "commandHint_create": "", + "@commandHint_create": { + "type": "text", + "description": "Usage hint for the command /create" + }, + "youAreInvitedToThisChat": "", + "@youAreInvitedToThisChat": { + "type": "text", + "placeholders": {} + }, + "singlesignon": "", + "@singlesignon": { + "type": "text", + "placeholders": {} + }, + "warning": "", + "@warning": { + "type": "text", + "placeholders": {} + }, + "password": "", + "@password": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterAMatrixIdentifier": "", + "@pleaseEnterAMatrixIdentifier": { + "type": "text", + "placeholders": {} + }, + "allSpaces": "", + "@allSpaces": {}, + "supposedMxid": "", + "@supposedMxid": { + "type": "text", + "placeholders": { + "mxid": {} + } + }, + "editDisplayname": "", + "@editDisplayname": { + "type": "text", + "placeholders": {} + }, + "user": "", + "@user": {}, + "roomVersion": "", + "@roomVersion": { + "type": "text", + "placeholders": {} + }, + "sentAFile": "", + "@sentAFile": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "videoCall": "", + "@videoCall": { + "type": "text", + "placeholders": {} + }, + "youAcceptedTheInvitation": "", + "@youAcceptedTheInvitation": {}, + "banFromChat": "", + "@banFromChat": { + "type": "text", + "placeholders": {} + }, + "noMatrixServer": "", + "@noMatrixServer": { + "type": "text", + "placeholders": { + "server1": {}, + "server2": {} + } + }, + "userAndOthersAreTyping": "", + "@userAndOthersAreTyping": { + "type": "text", + "placeholders": { + "username": {}, + "count": {} + } + }, + "youInvitedBy": "", + "@youInvitedBy": { + "placeholders": { + "user": {} + } + }, + "userIsTyping": "", + "@userIsTyping": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "openAppToReadMessages": "", + "@openAppToReadMessages": { + "type": "text", + "placeholders": {} + }, + "sentAVideo": "", + "@sentAVideo": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "banUserDescription": "", + "@banUserDescription": {}, + "inviteContact": "", + "@inviteContact": { + "type": "text", + "placeholders": {} + }, + "requests": "", + "@requests": {}, + "askSSSSSign": "", + "@askSSSSSign": { + "type": "text", + "placeholders": {} + }, + "widgetEtherpad": "", + "@widgetEtherpad": {}, + "waitingPartnerAcceptRequest": "", + "@waitingPartnerAcceptRequest": { + "type": "text", + "placeholders": {} + }, + "remove": "", + "@remove": { + "type": "text", + "placeholders": {} + }, + "writeAMessage": "", + "@writeAMessage": { + "type": "text", + "placeholders": {} + }, + "changeTheme": "", + "@changeTheme": { + "type": "text", + "placeholders": {} + }, + "stories": "", + "@stories": {}, + "id": "", + "@id": { + "type": "text", + "placeholders": {} + }, + "addToStory": "", + "@addToStory": {}, + "removeDevicesDescription": "", + "@removeDevicesDescription": {}, + "changedTheChatDescriptionTo": "", + "@changedTheChatDescriptionTo": { + "type": "text", + "placeholders": { + "username": {}, + "description": {} + } + }, + "countParticipants": "", + "@countParticipants": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "separateChatTypes": "", + "@separateChatTypes": { + "type": "text", + "placeholders": {} + }, + "tryAgain": "", + "@tryAgain": {}, + "areGuestsAllowedToJoin": "", + "@areGuestsAllowedToJoin": { + "type": "text", + "placeholders": {} + }, + "blocked": "", + "@blocked": { + "type": "text", + "placeholders": {} + }, + "youKickedAndBanned": "", + "@youKickedAndBanned": { + "placeholders": { + "user": {} + } + }, + "dateWithoutYear": "", + "@dateWithoutYear": { + "type": "text", + "placeholders": { + "month": {}, + "day": {} + } + }, + "showDirectChatsInSpaces": "", + "@showDirectChatsInSpaces": { + "type": "text", + "placeholders": {} + }, + "removeDevice": "", + "@removeDevice": { + "type": "text", + "placeholders": {} + }, + "youCannotInviteYourself": "", + "@youCannotInviteYourself": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterValidEmail": "", + "@pleaseEnterValidEmail": {}, + "unbanUserDescription": "", + "@unbanUserDescription": {}, + "todoLists": "", + "@todoLists": {}, + "userAndUserAreTyping": "", + "@userAndUserAreTyping": { + "type": "text", + "placeholders": { + "username": {}, + "username2": {} + } + }, + "pleaseClickOnLink": "", + "@pleaseClickOnLink": { + "type": "text", + "placeholders": {} + }, + "saveFile": "", + "@saveFile": { + "type": "text", + "placeholders": {} + }, + "sendOnEnter": "", + "@sendOnEnter": {}, + "seenByUserAndCountOthers": "", + "@seenByUserAndCountOthers": { + "type": "text", + "placeholders": { + "username": {}, + "count": {} + } + }, + "pickImage": "", + "@pickImage": { + "type": "text", + "placeholders": {} + }, + "answeredTheCall": "", + "@answeredTheCall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "youRejectedTheInvitation": "", + "@youRejectedTheInvitation": {}, + "otherCallingPermissions": "", + "@otherCallingPermissions": {}, + "messagesStyle": "", + "@messagesStyle": {}, + "couldNotDecryptMessage": "", + "@couldNotDecryptMessage": { + "type": "text", + "placeholders": { + "error": {} + } + }, + "invitedUsersOnly": "", + "@invitedUsersOnly": { + "type": "text", + "placeholders": {} + }, + "link": "", + "@link": {}, + "widgetUrlError": "", + "@widgetUrlError": {}, + "emailOrUsername": "", + "@emailOrUsername": {}, + "newSpaceDescription": "", + "@newSpaceDescription": {}, + "chatDescription": "", + "@chatDescription": {}, + "callingAccountDetails": "", + "@callingAccountDetails": {}, + "next": "", + "@next": { + "type": "text", + "placeholders": {} + }, + "pleaseFollowInstructionsOnWeb": "", + "@pleaseFollowInstructionsOnWeb": { + "type": "text", + "placeholders": {} + }, + "changedTheGuestAccessRules": "", + "@changedTheGuestAccessRules": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "pleaseChooseAtLeastChars": "", + "@pleaseChooseAtLeastChars": { + "type": "text", + "placeholders": { + "min": {} + } + }, + "dateWithYear": "", + "@dateWithYear": { + "type": "text", + "placeholders": { + "year": {}, + "month": {}, + "day": {} + } + }, + "editRoomAliases": "", + "@editRoomAliases": { + "type": "text", + "placeholders": {} + }, + "enterSpace": "", + "@enterSpace": {}, + "encryptThisChat": "", + "@encryptThisChat": {}, + "fileName": "", + "@fileName": { + "type": "text", + "placeholders": {} + }, + "unavailable": "", + "@unavailable": { + "type": "text", + "placeholders": {} + }, + "previousAccount": "", + "@previousAccount": {}, + "publicRooms": "", + "@publicRooms": { + "type": "text", + "placeholders": {} + }, + "fromTheInvitation": "", + "@fromTheInvitation": { + "type": "text", + "placeholders": {} + }, + "sendMessages": "", + "@sendMessages": { + "type": "text", + "placeholders": {} + }, + "incorrectPassphraseOrKey": "", + "@incorrectPassphraseOrKey": { + "type": "text", + "placeholders": {} + }, + "emoteWarnNeedToPick": "", + "@emoteWarnNeedToPick": { + "type": "text", + "placeholders": {} + }, + "reopenChat": "", + "@reopenChat": {}, + "pleaseEnterRecoveryKey": "", + "@pleaseEnterRecoveryKey": {}, + "create": "", + "@create": { + "type": "text", + "placeholders": {} + }, + "toggleFavorite": "", + "@toggleFavorite": { + "type": "text", + "placeholders": {} + }, + "no": "", + "@no": { + "type": "text", + "placeholders": {} + }, + "alias": "", + "@alias": { + "type": "text", + "placeholders": {} + }, + "widgetNameError": "", + "@widgetNameError": {}, + "inoffensive": "", + "@inoffensive": { + "type": "text", + "placeholders": {} + }, + "unpin": "", + "@unpin": { + "type": "text", + "placeholders": {} + }, + "addToBundle": "", + "@addToBundle": {}, + "reportMessage": "", + "@reportMessage": { + "type": "text", + "placeholders": {} + }, + "spaceIsPublic": "", + "@spaceIsPublic": { + "type": "text", + "placeholders": {} + }, + "addWidget": "", + "@addWidget": {}, + "all": "", + "@all": { + "type": "text", + "placeholders": {} + }, + "removeAllOtherDevices": "", + "@removeAllOtherDevices": { + "type": "text", + "placeholders": {} + }, + "unblockDevice": "", + "@unblockDevice": { + "type": "text", + "placeholders": {} + }, + "countFiles": "", + "@countFiles": { + "placeholders": { + "count": {} + } + }, + "noKeyForThisMessage": "", + "@noKeyForThisMessage": {}, + "enableEncryptionWarning": "", + "@enableEncryptionWarning": { + "type": "text", + "placeholders": {} + }, + "inviteText": "", + "@inviteText": { + "type": "text", + "placeholders": { + "username": {}, + "link": {} + } + }, + "shareLocation": "", + "@shareLocation": { + "type": "text", + "placeholders": {} + }, + "reason": "", + "@reason": { + "type": "text", + "placeholders": {} + }, + "commandHint_markasgroup": "", + "@commandHint_markasgroup": {}, + "editTodo": "", + "@editTodo": {}, + "errorObtainingLocation": "", + "@errorObtainingLocation": { + "type": "text", + "placeholders": { + "error": {} + } + }, + "hydrateTor": "", + "@hydrateTor": {}, + "pushNotificationsNotAvailable": "", + "@pushNotificationsNotAvailable": {}, + "passwordRecovery": "", + "@passwordRecovery": { + "type": "text", + "placeholders": {} + }, + "storeInAppleKeyChain": "", + "@storeInAppleKeyChain": {}, + "replaceRoomWithNewerVersion": "", + "@replaceRoomWithNewerVersion": { + "type": "text", + "placeholders": {} + }, + "hydrate": "", + "@hydrate": {}, + "invalidServerName": "", + "@invalidServerName": {}, + "chatPermissions": "", + "@chatPermissions": {}, + "voiceMessage": "", + "@voiceMessage": { + "type": "text", + "placeholders": {} + }, + "badServerLoginTypesException": "", + "@badServerLoginTypesException": { + "type": "text", + "placeholders": { + "serverVersions": {}, + "supportedVersions": {} + } + }, + "wipeChatBackup": "", + "@wipeChatBackup": { + "type": "text", + "placeholders": {} + }, + "cantOpenUri": "", + "@cantOpenUri": { + "type": "text", + "placeholders": { + "uri": {} + } + }, + "sender": "", + "@sender": {}, + "storeInAndroidKeystore": "", + "@storeInAndroidKeystore": {}, + "optionalGroupName": "", + "@optionalGroupName": { + "type": "text", + "placeholders": {} + }, + "hideRedactedEvents": "", + "@hideRedactedEvents": { + "type": "text", + "placeholders": {} + }, + "online": "", + "@online": { + "type": "text", + "placeholders": {} + }, + "signInWithPassword": "", + "@signInWithPassword": {}, + "pleaseAddATitle": "", + "@pleaseAddATitle": {}, + "updateNow": "", + "@updateNow": {}, + "ignoredUsers": "", + "@ignoredUsers": { + "type": "text", + "placeholders": {} + }, + "lastActiveAgo": "", + "@lastActiveAgo": { + "type": "text", + "placeholders": { + "localizedTimeShort": {} + } + }, + "changedTheGuestAccessRulesTo": "", + "@changedTheGuestAccessRulesTo": { + "type": "text", + "placeholders": { + "username": {}, + "rules": {} + } + }, + "weSentYouAnEmail": "", + "@weSentYouAnEmail": { + "type": "text", + "placeholders": {} + }, + "offensive": "", + "@offensive": { + "type": "text", + "placeholders": {} + }, + "needPantalaimonWarning": "", + "@needPantalaimonWarning": { + "type": "text", + "placeholders": {} + }, + "makeAdminDescription": "", + "@makeAdminDescription": {}, + "edit": "", + "@edit": { + "type": "text", + "placeholders": {} + }, + "loadMore": "", + "@loadMore": { + "type": "text", + "placeholders": {} + }, + "noEmotesFound": "", + "@noEmotesFound": { + "type": "text", + "placeholders": {} + }, + "synchronizingPleaseWait": "", + "@synchronizingPleaseWait": { + "type": "text", + "placeholders": {} + }, + "transferFromAnotherDevice": "", + "@transferFromAnotherDevice": { + "type": "text", + "placeholders": {} + }, + "passwordHasBeenChanged": "", + "@passwordHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "pushRules": "", + "@pushRules": { + "type": "text", + "placeholders": {} + }, + "goToTheNewRoom": "", + "@goToTheNewRoom": { + "type": "text", + "placeholders": {} + }, + "commandHint_clearcache": "", + "@commandHint_clearcache": { + "type": "text", + "description": "Usage hint for the command /clearcache" + }, + "loadingPleaseWait": "", + "@loadingPleaseWait": { + "type": "text", + "placeholders": {} + }, + "copy": "", + "@copy": { + "type": "text", + "placeholders": {} + }, + "saveKeyManuallyDescription": "", + "@saveKeyManuallyDescription": {}, + "none": "", + "@none": { + "type": "text", + "placeholders": {} + }, + "editBundlesForAccount": "", + "@editBundlesForAccount": {}, + "renderRichContent": "", + "@renderRichContent": { + "type": "text", + "placeholders": {} + }, + "enableEncryption": "", + "@enableEncryption": { + "type": "text", + "placeholders": {} + }, + "whyIsThisMessageEncrypted": "", + "@whyIsThisMessageEncrypted": {}, + "unreadChats": "", + "@unreadChats": { + "type": "text", + "placeholders": { + "unreadCount": {} + } + }, + "rejectedTheInvitation": "", + "@rejectedTheInvitation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "setChatDescription": "", + "@setChatDescription": {}, + "userLeftTheChat": "", + "@userLeftTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "spaceName": "", + "@spaceName": { + "type": "text", + "placeholders": {} + }, + "importFromZipFile": "", + "@importFromZipFile": {}, + "discover": "", + "@discover": { + "type": "text", + "placeholders": {} + }, + "toggleUnread": "", + "@toggleUnread": { + "type": "text", + "placeholders": {} + }, + "or": "", + "@or": { + "type": "text", + "placeholders": {} + }, + "dehydrateWarning": "", + "@dehydrateWarning": {}, + "sendOriginal": "", + "@sendOriginal": { + "type": "text", + "placeholders": {} + }, + "noOtherDevicesFound": "", + "@noOtherDevicesFound": {}, + "whoIsAllowedToJoinThisGroup": "", + "@whoIsAllowedToJoinThisGroup": { + "type": "text", + "placeholders": {} + }, + "emptyChat": "", + "@emptyChat": { + "type": "text", + "placeholders": {} + }, + "seenByUser": "", + "@seenByUser": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "storeSecurlyOnThisDevice": "", + "@storeSecurlyOnThisDevice": {}, + "yourChatBackupHasBeenSetUp": "", + "@yourChatBackupHasBeenSetUp": {}, + "addDescription": "", + "@addDescription": {}, + "chatBackup": "", + "@chatBackup": { + "type": "text", + "placeholders": {} + }, + "redactedBy": "", + "@redactedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "submit": "", + "@submit": { + "type": "text", + "placeholders": {} + }, + "videoCallsBetaWarning": "", + "@videoCallsBetaWarning": {}, + "unmuteChat": "", + "@unmuteChat": { + "type": "text", + "placeholders": {} + }, + "createdTheChat": "", + "@createdTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "redactedAnEvent": "", + "@redactedAnEvent": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "autoplayImages": "", + "@autoplayImages": { + "type": "text", + "placeholder": {} + }, + "storyPrivacyWarning": "", + "@storyPrivacyWarning": {}, + "compareEmojiMatch": "", + "@compareEmojiMatch": { + "type": "text", + "placeholders": {} + }, + "matrixWidgets": "", + "@matrixWidgets": {}, + "participant": "", + "@participant": { + "type": "text", + "placeholders": {} + }, + "logInTo": "", + "@logInTo": { + "type": "text", + "placeholders": { + "homeserver": {} + } + }, + "yes": "", + "@yes": { + "type": "text", + "placeholders": {} + }, + "containsDisplayName": "", + "@containsDisplayName": { + "type": "text", + "placeholders": {} + }, + "signInWith": "", + "@signInWith": { + "type": "text", + "placeholders": { + "provider": {} + } + }, + "username": "", + "@username": { + "type": "text", + "placeholders": {} + }, + "changedTheRoomAliases": "", + "@changedTheRoomAliases": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "updateAvailable": "", + "@updateAvailable": {}, + "fileIsTooBigForServer": "", + "@fileIsTooBigForServer": {}, + "homeserver": "", + "@homeserver": {}, + "help": "", + "@help": { + "type": "text", + "placeholders": {} + }, + "noTodosYet": "", + "@noTodosYet": {}, + "chatDetails": "", + "@chatDetails": { + "type": "text", + "placeholders": {} + }, + "people": "", + "@people": { + "type": "text", + "placeholders": {} + }, + "changedTheHistoryVisibilityTo": "", + "@changedTheHistoryVisibilityTo": { + "type": "text", + "placeholders": { + "username": {}, + "rules": {} + } + }, + "leftTheChat": "", + "@leftTheChat": { + "type": "text", + "placeholders": {} + }, + "verified": "", + "@verified": { + "type": "text", + "placeholders": {} + }, + "repeatPassword": "", + "@repeatPassword": {}, + "setStatus": "", + "@setStatus": { + "type": "text", + "placeholders": {} + }, + "groupWith": "", + "@groupWith": { + "type": "text", + "placeholders": { + "displayname": {} + } + }, + "callingPermissions": "", + "@callingPermissions": {}, + "delete": "", + "@delete": { + "type": "text", + "placeholders": {} + }, + "newMessageInFluffyChat": "", + "@newMessageInFluffyChat": { + "type": "text", + "placeholders": {} + }, + "readUpToHere": "", + "@readUpToHere": {}, + "start": "", + "@start": {}, + "bubbleSize": "", + "@bubbleSize": { + "type": "text", + "placeholders": {} + }, + "downloadFile": "", + "@downloadFile": { + "type": "text", + "placeholders": {} + }, + "deviceId": "", + "@deviceId": { + "type": "text", + "placeholders": {} + }, + "register": "", + "@register": { + "type": "text", + "placeholders": {} + }, + "unlockOldMessages": "", + "@unlockOldMessages": {}, + "identity": "", + "@identity": { + "type": "text", + "placeholders": {} + }, + "numChats": "", + "@numChats": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "changedTheJoinRulesTo": "", + "@changedTheJoinRulesTo": { + "type": "text", + "placeholders": { + "username": {}, + "joinRules": {} + } + }, + "ignore": "", + "@ignore": { + "type": "text", + "placeholders": {} + }, + "whatIsGoingOn": "", + "@whatIsGoingOn": {}, + "recording": "", + "@recording": { + "type": "text", + "placeholders": {} + }, + "changedTheChatPermissions": "", + "@changedTheChatPermissions": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changeWallpaper": "", + "@changeWallpaper": { + "type": "text", + "placeholders": {} + }, + "moderator": "", + "@moderator": { + "type": "text", + "placeholders": {} + }, + "optionalRedactReason": "", + "@optionalRedactReason": {}, + "acceptedTheInvitation": "", + "@acceptedTheInvitation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "waitingPartnerEmoji": "", + "@waitingPartnerEmoji": { + "type": "text", + "placeholders": {} + }, + "channelCorruptedDecryptError": "", + "@channelCorruptedDecryptError": { + "type": "text", + "placeholders": {} + }, + "tryToSendAgain": "", + "@tryToSendAgain": { + "type": "text", + "placeholders": {} + }, + "guestsCanJoin": "", + "@guestsCanJoin": { + "type": "text", + "placeholders": {} + }, + "ok": "", + "@ok": { + "type": "text", + "placeholders": {} + }, + "copyToClipboard": "", + "@copyToClipboard": { + "type": "text", + "placeholders": {} + }, + "dehydrate": "", + "@dehydrate": {}, + "locationPermissionDeniedNotice": "", + "@locationPermissionDeniedNotice": { + "type": "text", + "placeholders": {} + }, + "send": "", + "@send": { + "type": "text", + "placeholders": {} + }, + "hasWithdrawnTheInvitationFor": "", + "@hasWithdrawnTheInvitationFor": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "visibleForAllParticipants": "", + "@visibleForAllParticipants": { + "type": "text", + "placeholders": {} + }, + "noRoomsFound": "", + "@noRoomsFound": { + "type": "text", + "placeholders": {} + }, + "banned": "", + "@banned": { + "type": "text", + "placeholders": {} + }, + "sendAsText": "", + "@sendAsText": { + "type": "text" + }, + "inviteForMe": "", + "@inviteForMe": { + "type": "text", + "placeholders": {} + }, + "archiveRoomDescription": "", + "@archiveRoomDescription": {}, + "exportEmotePack": "", + "@exportEmotePack": {}, + "changedTheChatNameTo": "", + "@changedTheChatNameTo": { + "type": "text", + "placeholders": { + "username": {}, + "chatname": {} + } + }, + "sendSticker": "", + "@sendSticker": { + "type": "text", + "placeholders": {} + }, + "account": "", + "@account": { + "type": "text", + "placeholders": {} + }, + "switchToAccount": "", + "@switchToAccount": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "commandInvalid": "", + "@commandInvalid": { + "type": "text" + }, + "setAsCanonicalAlias": "", + "@setAsCanonicalAlias": { + "type": "text", + "placeholders": {} + }, + "whyDoYouWantToReportThis": "", + "@whyDoYouWantToReportThis": { + "type": "text", + "placeholders": {} + }, + "locationDisabledNotice": "", + "@locationDisabledNotice": { + "type": "text", + "placeholders": {} + }, + "letsStart": "", + "@letsStart": {}, + "placeCall": "", + "@placeCall": {}, + "removedBy": "", + "@removedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheRoomInvitationLink": "", + "@changedTheRoomInvitationLink": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "newChat": "", + "@newChat": { + "type": "text", + "placeholders": {} + }, + "notifications": "", + "@notifications": { + "type": "text", + "placeholders": {} + }, + "commandHint_plain": "", + "@commandHint_plain": { + "type": "text", + "description": "Usage hint for the command /plain" + }, + "emoteSettings": "", + "@emoteSettings": { + "type": "text", + "placeholders": {} + }, + "experimentalVideoCalls": "", + "@experimentalVideoCalls": {}, + "savedEmotePack": "", + "@savedEmotePack": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "openCamera": "", + "@openCamera": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterRecoveryKeyDescription": "", + "@pleaseEnterRecoveryKeyDescription": {}, + "guestsAreForbidden": "", + "@guestsAreForbidden": { + "type": "text", + "placeholders": {} + }, + "mention": "", + "@mention": { + "type": "text", + "placeholders": {} + }, + "openInMaps": "", + "@openInMaps": { + "type": "text", + "placeholders": {} + }, + "withTheseAddressesRecoveryDescription": "", + "@withTheseAddressesRecoveryDescription": { + "type": "text", + "placeholders": {} + }, + "inviteContactToGroupQuestion": "", + "@inviteContactToGroupQuestion": {}, + "emoteExists": "", + "@emoteExists": { + "type": "text", + "placeholders": {} + }, + "redactedByBecause": "", + "@redactedByBecause": { + "type": "text", + "placeholders": { + "username": {}, + "reason": {} + } + }, + "isTyping": "", + "@isTyping": { + "type": "text", + "placeholders": {} + }, + "youHaveWithdrawnTheInvitationFor": "", + "@youHaveWithdrawnTheInvitationFor": { + "placeholders": { + "user": {} + } + }, + "chat": "", + "@chat": { + "type": "text", + "placeholders": {} + }, + "group": "", + "@group": { + "type": "text", + "placeholders": {} + }, + "leave": "", + "@leave": { + "type": "text", + "placeholders": {} + }, + "skip": "", + "@skip": { + "type": "text", + "placeholders": {} + }, + "appearOnTopDetails": "", + "@appearOnTopDetails": {}, + "roomHasBeenUpgraded": "", + "@roomHasBeenUpgraded": { + "type": "text", + "placeholders": {} + }, + "enterRoom": "", + "@enterRoom": {}, + "enableEmotesGlobally": "", + "@enableEmotesGlobally": { + "type": "text", + "placeholders": {} + }, + "areYouSure": "", + "@areYouSure": { + "type": "text", + "placeholders": {} + }, + "ignoreListDescription": "", + "@ignoreListDescription": { + "type": "text", + "placeholders": {} + }, + "pleaseChooseAPasscode": "", + "@pleaseChooseAPasscode": { + "type": "text", + "placeholders": {} + }, + "noPasswordRecoveryDescription": "", + "@noPasswordRecoveryDescription": { + "type": "text", + "placeholders": {} + }, + "changedTheProfileAvatar": "", + "@changedTheProfileAvatar": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "allChats": "", + "@allChats": { + "type": "text", + "placeholders": {} + }, + "reportUser": "", + "@reportUser": {}, + "passwordsDoNotMatch": "", + "@passwordsDoNotMatch": {}, + "sharedTheLocation": "", + "@sharedTheLocation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "commandHint_send": "", + "@commandHint_send": { + "type": "text", + "description": "Usage hint for the command /send" + }, + "onlineKeyBackupEnabled": "", + "@onlineKeyBackupEnabled": { + "type": "text", + "placeholders": {} + }, + "unbannedUser": "", + "@unbannedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "confirmEventUnpin": "", + "@confirmEventUnpin": {}, + "badServerVersionsException": "", + "@badServerVersionsException": { + "type": "text", + "placeholders": { + "serverVersions": {}, + "supportedVersions": {} + } + }, + "youInvitedUser": "", + "@youInvitedUser": { + "placeholders": { + "user": {} + } + }, + "kickedAndBanned": "", + "@kickedAndBanned": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "noConnectionToTheServer": "", + "@noConnectionToTheServer": { + "type": "text", + "placeholders": {} + }, + "fileHasBeenSavedAt": "", + "@fileHasBeenSavedAt": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "license": "", + "@license": { + "type": "text", + "placeholders": {} + }, + "addToSpace": "", + "@addToSpace": {}, + "unbanFromChat": "", + "@unbanFromChat": { + "type": "text", + "placeholders": {} + }, + "importZipFile": "", + "@importZipFile": {}, + "anyoneCanKnock": "", + "@anyoneCanKnock": {}, + "commandMissing": "", + "@commandMissing": { + "type": "text", + "placeholders": { + "command": {} + }, + "description": "State that {command} is not a valid /command." + }, + "redactMessageDescription": "", + "@redactMessageDescription": {}, + "rejoin": "", + "@rejoin": { + "type": "text", + "placeholders": {} + }, + "recoveryKey": "", + "@recoveryKey": {}, + "redactMessage": "", + "@redactMessage": { + "type": "text", + "placeholders": {} + }, + "forward": "", + "@forward": { + "type": "text", + "placeholders": {} + }, + "commandHint_discardsession": "", + "@commandHint_discardsession": { + "type": "text", + "description": "Usage hint for the command /discardsession" + }, + "invalidInput": "", + "@invalidInput": {}, + "about": "", + "@about": { + "type": "text", + "placeholders": {} + }, + "chooseAStrongPassword": "", + "@chooseAStrongPassword": { + "type": "text", + "placeholders": {} + }, + "hideUnknownEvents": "", + "@hideUnknownEvents": { + "type": "text", + "placeholders": {} + }, + "todosUnencrypted": "", + "@todosUnencrypted": {}, + "dehydrateTorLong": "", + "@dehydrateTorLong": {}, + "yourPublicKey": "", + "@yourPublicKey": { + "type": "text", + "placeholders": {} + }, + "tooManyRequestsWarning": "", + "@tooManyRequestsWarning": { + "type": "text", + "placeholders": {} + }, + "invitedUser": "", + "@invitedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "kickFromChat": "", + "@kickFromChat": { + "type": "text", + "placeholders": {} + }, + "commandHint_myroomnick": "", + "@commandHint_myroomnick": { + "type": "text", + "description": "Usage hint for the command /myroomnick" + }, + "offline": "", + "@offline": { + "type": "text", + "placeholders": {} + }, + "replyHasBeenSent": "", + "@replyHasBeenSent": {}, + "noPermission": "", + "@noPermission": { + "type": "text", + "placeholders": {} + }, + "doNotShowAgain": "", + "@doNotShowAgain": {}, + "activatedEndToEndEncryption": "", + "@activatedEndToEndEncryption": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "report": "", + "@report": {}, + "status": "", + "@status": { + "type": "text", + "placeholders": {} + }, + "deny": "", + "@deny": { + "type": "text", + "placeholders": {} + }, + "compareNumbersMatch": "", + "@compareNumbersMatch": { + "type": "text", + "placeholders": {} + }, + "groupIsPublic": "", + "@groupIsPublic": { + "type": "text", + "placeholders": {} + }, + "verifyStart": "", + "@verifyStart": { + "type": "text", + "placeholders": {} + }, + "yourStory": "", + "@yourStory": {}, + "memberChanges": "", + "@memberChanges": { + "type": "text", + "placeholders": {} + }, + "joinRoom": "", + "@joinRoom": { + "type": "text", + "placeholders": {} + }, + "ignoreUsername": "", + "@ignoreUsername": { + "type": "text", + "placeholders": {} + }, + "unverified": "", + "@unverified": {}, + "fluffychat": "", + "@fluffychat": { + "type": "text", + "placeholders": {} + }, + "howOffensiveIsThisContent": "", + "@howOffensiveIsThisContent": { + "type": "text", + "placeholders": {} + }, + "serverRequiresEmail": "", + "@serverRequiresEmail": {}, + "hideUnimportantStateEvents": "", + "@hideUnimportantStateEvents": {}, + "screenSharingTitle": "", + "@screenSharingTitle": {}, + "widgetCustom": "", + "@widgetCustom": {}, + "sentCallInformations": "", + "@sentCallInformations": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "addToSpaceDescription": "", + "@addToSpaceDescription": {}, + "googlyEyesContent": "", + "@googlyEyesContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "whoCanSeeMyStoriesDesc": "", + "@whoCanSeeMyStoriesDesc": {}, + "youBannedUser": "", + "@youBannedUser": { + "placeholders": { + "user": {} + } + }, + "theyDontMatch": "", + "@theyDontMatch": { + "type": "text", + "placeholders": {} + }, + "unsubscribeStories": "", + "@unsubscribeStories": {}, + "youHaveBeenBannedFromThisChat": "", + "@youHaveBeenBannedFromThisChat": { + "type": "text", + "placeholders": {} + }, + "displaynameHasBeenChanged": "", + "@displaynameHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "loginWithOneClick": "", + "@loginWithOneClick": {}, + "addChatDescription": "", + "@addChatDescription": {}, + "sentAnAudio": "", + "@sentAnAudio": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "editRoomAvatar": "", + "@editRoomAvatar": { + "type": "text", + "placeholders": {} + }, + "encrypted": "", + "@encrypted": { + "type": "text", + "placeholders": {} + }, + "commandHint_leave": "", + "@commandHint_leave": { + "type": "text", + "description": "Usage hint for the command /leave" + }, + "commandHint_myroomavatar": "", + "@commandHint_myroomavatar": { + "type": "text", + "description": "Usage hint for the command /myroomavatar" + }, + "cancel": "", + "@cancel": { + "type": "text", + "placeholders": {} + }, + "hasKnocked": "", + "@hasKnocked": { + "placeholders": { + "user": {} + } + }, + "publish": "", + "@publish": {}, + "openLinkInBrowser": "", + "@openLinkInBrowser": {}, + "clearArchive": "", + "@clearArchive": {}, + "appLock": "", + "@appLock": { + "type": "text", + "placeholders": {} + }, + "commandHint_react": "", + "@commandHint_react": { + "type": "text", + "description": "Usage hint for the command /react" + }, + "changedTheHistoryVisibility": "", + "@changedTheHistoryVisibility": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "commandHint_me": "", + "@commandHint_me": { + "type": "text", + "description": "Usage hint for the command /me" + }, + "pleaseEnterYourUsername": "", + "@pleaseEnterYourUsername": { + "type": "text", + "placeholders": {} + }, + "messageInfo": "", + "@messageInfo": {}, + "disableEncryptionWarning": "", + "@disableEncryptionWarning": {}, + "directChat": "", + "@directChat": {}, + "noOneCanJoin": "", + "@noOneCanJoin": {}, + "encryptionNotEnabled": "", + "@encryptionNotEnabled": { + "type": "text", + "placeholders": {} + }, + "wrongPinEntered": "", + "@wrongPinEntered": { + "type": "text", + "placeholders": { + "seconds": {} + } + }, + "sendTypingNotifications": "", + "@sendTypingNotifications": {}, + "lightTheme": "", + "@lightTheme": { + "type": "text", + "placeholders": {} + }, + "inviteGroupChat": "", + "@inviteGroupChat": {}, + "appearOnTop": "", + "@appearOnTop": {}, + "invitePrivateChat": "", + "@invitePrivateChat": {}, + "verifyTitle": "", + "@verifyTitle": { + "type": "text", + "placeholders": {} + }, + "foregroundServiceRunning": "", + "@foregroundServiceRunning": {}, + "enterAnEmailAddress": "", + "@enterAnEmailAddress": { + "type": "text", + "placeholders": {} + }, + "voiceCall": "", + "@voiceCall": {}, + "commandHint_kick": "", + "@commandHint_kick": { + "type": "text", + "description": "Usage hint for the command /kick" + }, + "copiedToClipboard": "", + "@copiedToClipboard": { + "type": "text", + "placeholders": {} + }, + "createNewSpace": "", + "@createNewSpace": { + "type": "text", + "placeholders": {} + }, + "commandHint_unban": "", + "@commandHint_unban": { + "type": "text", + "description": "Usage hint for the command /unban" + }, + "unknownEncryptionAlgorithm": "", + "@unknownEncryptionAlgorithm": { + "type": "text", + "placeholders": {} + }, + "commandHint_ban": "", + "@commandHint_ban": { + "type": "text", + "description": "Usage hint for the command /ban" + }, + "importEmojis": "", + "@importEmojis": {}, + "confirm": "", + "@confirm": { + "type": "text", + "placeholders": {} + }, + "wasDirectChatDisplayName": "", + "@wasDirectChatDisplayName": { + "type": "text", + "placeholders": { + "oldDisplayName": {} + } + }, + "noChatDescriptionYet": "", + "@noChatDescriptionYet": {}, + "defaultPermissionLevel": "", + "@defaultPermissionLevel": { + "type": "text", + "placeholders": {} + }, + "newTodo": "", + "@newTodo": {}, + "removeFromBundle": "", + "@removeFromBundle": {}, + "numUsersTyping": "", + "@numUsersTyping": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "fontSize": "", + "@fontSize": { + "type": "text", + "placeholders": {} + }, + "whoCanPerformWhichAction": "", + "@whoCanPerformWhichAction": { + "type": "text", + "placeholders": {} + }, + "confirmMatrixId": "", + "@confirmMatrixId": {}, + "learnMore": "", + "@learnMore": {}, + "iHaveClickedOnLink": "", + "@iHaveClickedOnLink": { + "type": "text", + "placeholders": {} + }, + "you": "", + "@you": { + "type": "text", + "placeholders": {} + }, + "notAnImage": "", + "@notAnImage": {}, + "users": "", + "@users": {}, + "openGallery": "", + "@openGallery": {}, + "chatDescriptionHasBeenChanged": "", + "@chatDescriptionHasBeenChanged": {}, + "search": "", + "@search": { + "type": "text", + "placeholders": {} + }, + "newGroup": "", + "@newGroup": {}, + "bundleName": "", + "@bundleName": {}, + "dehydrateTor": "", + "@dehydrateTor": {}, + "todoListChangedError": "", + "@todoListChangedError": {}, + "removeFromSpace": "", + "@removeFromSpace": {}, + "enterInviteLinkOrMatrixId": "", + "@enterInviteLinkOrMatrixId": {}, + "dateAndTimeOfDay": "", + "@dateAndTimeOfDay": { + "type": "text", + "placeholders": { + "date": {}, + "timeOfDay": {} + } + }, + "commandHint_op": "", + "@commandHint_op": { + "type": "text", + "description": "Usage hint for the command /op" + }, + "commandHint_join": "", + "@commandHint_join": { + "type": "text", + "description": "Usage hint for the command /join" + }, + "sourceCode": "", + "@sourceCode": { + "type": "text", + "placeholders": {} + }, + "enterAGroupName": "", + "@enterAGroupName": { + "type": "text", + "placeholders": {} + }, + "roomUpgradeDescription": "", + "@roomUpgradeDescription": {}, + "commandHint_invite": "", + "@commandHint_invite": { + "type": "text", + "description": "Usage hint for the command /invite" + }, + "userSentUnknownEvent": "", + "@userSentUnknownEvent": { + "type": "text", + "placeholders": { + "username": {}, + "type": {} + } + }, + "scanQrCode": "", + "@scanQrCode": {}, + "logout": "", + "@logout": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterANumber": "", + "@pleaseEnterANumber": {}, + "contactHasBeenInvitedToTheGroup": "", + "@contactHasBeenInvitedToTheGroup": { + "type": "text", + "placeholders": {} + }, + "youKicked": "", + "@youKicked": { + "placeholders": { + "user": {} + } + }, + "areYouSureYouWantToLogout": "", + "@areYouSureYouWantToLogout": { + "type": "text", + "placeholders": {} + }, + "changedTheJoinRules": "", + "@changedTheJoinRules": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "profileNotFound": "", + "@profileNotFound": {}, + "jump": "", + "@jump": {}, + "groups": "", + "@groups": { + "type": "text", + "placeholders": {} + }, + "reactedWith": "", + "@reactedWith": { + "type": "text", + "placeholders": { + "sender": {}, + "reaction": {} + } + }, + "bannedUser": "", + "@bannedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "iUnderstand": "", + "@iUnderstand": {}, + "sorryThatsNotPossible": "", + "@sorryThatsNotPossible": {}, + "storyFrom": "", + "@storyFrom": { + "type": "text", + "placeholders": { + "date": {}, + "body": {} + } + }, + "videoWithSize": "", + "@videoWithSize": { + "type": "text", + "placeholders": { + "size": {} + } + }, + "oopsSomethingWentWrong": "", + "@oopsSomethingWentWrong": { + "type": "text", + "placeholders": {} + }, + "loadCountMoreParticipants": "", + "@loadCountMoreParticipants": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "shareInviteLink": "", + "@shareInviteLink": {}, + "commandHint_markasdm": "", + "@commandHint_markasdm": {}, + "recoveryKeyLost": "", + "@recoveryKeyLost": {}, + "cuddleContent": "", + "@cuddleContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "askVerificationRequest": "", + "@askVerificationRequest": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "containsUserName": "", + "@containsUserName": { + "type": "text", + "placeholders": {} + }, + "messages": "", + "@messages": { + "type": "text", + "placeholders": {} + }, + "login": "", + "@login": { + "type": "text", + "placeholders": {} + }, + "deviceKeys": "", + "@deviceKeys": {}, + "waitingPartnerNumbers": "", + "@waitingPartnerNumbers": { + "type": "text", + "placeholders": {} + }, + "noGoogleServicesWarning": "", + "@noGoogleServicesWarning": { + "type": "text", + "placeholders": {} + }, + "everythingReady": "", + "@everythingReady": { + "type": "text", + "placeholders": {} + }, + "addEmail": "", + "@addEmail": { + "type": "text", + "placeholders": {} + }, + "emoteKeyboardNoRecents": "", + "@emoteKeyboardNoRecents": { + "type": "text", + "placeholders": {} + }, + "setCustomEmotes": "", + "@setCustomEmotes": { + "type": "text", + "placeholders": {} + }, + "startedACall": "", + "@startedACall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "emoteInvalid": "", + "@emoteInvalid": { + "type": "text", + "placeholders": {} + }, + "systemTheme": "", + "@systemTheme": { + "type": "text", + "placeholders": {} + }, + "messageWillBeRemovedWarning": "", + "@messageWillBeRemovedWarning": { + "type": "text", + "placeholders": {} + }, + "endToEndEncryption": "", + "@endToEndEncryption": {}, + "notificationsEnabledForThisAccount": "", + "@notificationsEnabledForThisAccount": { + "type": "text", + "placeholders": {} + }, + "deleteMessage": "", + "@deleteMessage": { + "type": "text", + "placeholders": {} + }, + "visibilityOfTheChatHistory": "", + "@visibilityOfTheChatHistory": { + "type": "text", + "placeholders": {} + }, + "settings": "", + "@settings": { + "type": "text", + "placeholders": {} + }, + "setTheme": "", + "@setTheme": {}, + "changeTheHomeserver": "", + "@changeTheHomeserver": { + "type": "text", + "placeholders": {} + }, + "youJoinedTheChat": "", + "@youJoinedTheChat": {}, + "wallpaper": "", + "@wallpaper": { + "type": "text", + "placeholders": {} + }, + "openVideoCamera": "", + "@openVideoCamera": { + "type": "text", + "placeholders": {} + }, + "play": "", + "@play": { + "type": "text", + "placeholders": { + "fileName": {} + } + }, + "chatBackupDescription": "", + "@chatBackupDescription": { + "type": "text", + "placeholders": {} + }, + "changeDeviceName": "", + "@changeDeviceName": { + "type": "text", + "placeholders": {} + }, + "lastSeenLongTimeAgo": "", + "@lastSeenLongTimeAgo": { + "type": "text", + "placeholders": {} + }, + "passwordForgotten": "", + "@passwordForgotten": { + "type": "text", + "placeholders": {} + }, + "statusExampleMessage": "", + "@statusExampleMessage": { + "type": "text", + "placeholders": {} + }, + "thisUserHasNotPostedAnythingYet": "", + "@thisUserHasNotPostedAnythingYet": {}, + "security": "", + "@security": { + "type": "text", + "placeholders": {} + }, + "markAsRead": "", + "@markAsRead": {}, + "sendAudio": "", + "@sendAudio": { + "type": "text", + "placeholders": {} + }, + "widgetName": "", + "@widgetName": {}, + "sentASticker": "", + "@sentASticker": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "errorAddingWidget": "", + "@errorAddingWidget": {}, + "commandHint_dm": "", + "@commandHint_dm": { + "type": "text", + "description": "Usage hint for the command /dm" + }, + "commandHint_hug": "", + "@commandHint_hug": {}, + "replace": "", + "@replace": {}, + "reject": "", + "@reject": { + "type": "text", + "placeholders": {} + }, + "extremeOffensive": "", + "@extremeOffensive": { + "type": "text", + "placeholders": {} + }, + "editBlockedServers": "", + "@editBlockedServers": { + "type": "text", + "placeholders": {} + }, + "oopsPushError": "", + "@oopsPushError": { + "type": "text", + "placeholders": {} + }, + "youUnbannedUser": "", + "@youUnbannedUser": { + "placeholders": { + "user": {} + } + }, + "deactivateAccountWarning": "", + "@deactivateAccountWarning": { + "type": "text", + "placeholders": {} + }, + "archive": "", + "@archive": { + "type": "text", + "placeholders": {} + }, + "joinedTheChat": "", + "@joinedTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "visibleForEveryone": "", + "@visibleForEveryone": { + "type": "text", + "placeholders": {} + }, + "pleaseEnter4Digits": "", + "@pleaseEnter4Digits": { + "type": "text", + "placeholders": {} + }, + "newSpace": "", + "@newSpace": {}, + "changePassword": "", + "@changePassword": { + "type": "text", + "placeholders": {} + }, + "devices": "", + "@devices": { + "type": "text", + "placeholders": {} + }, + "accept": "", + "@accept": { + "type": "text", + "placeholders": {} + }, + "unknownEvent": "", + "@unknownEvent": { + "type": "text", + "placeholders": { + "type": {} + } + }, + "emojis": "", + "@emojis": {}, + "signUp": "", + "@signUp": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourPin": "", + "@pleaseEnterYourPin": { + "type": "text", + "placeholders": {} + }, + "pleaseChoose": "", + "@pleaseChoose": { + "type": "text", + "placeholders": {} + }, + "share": "", + "@share": { + "type": "text", + "placeholders": {} + }, + "commandHint_googly": "", + "@commandHint_googly": {}, + "pleaseTryAgainLaterOrChooseDifferentServer": "", + "@pleaseTryAgainLaterOrChooseDifferentServer": {}, + "createGroup": "", + "@createGroup": {}, + "privacy": "", + "@privacy": { + "type": "text", + "placeholders": {} + }, + "changeYourAvatar": "", + "@changeYourAvatar": { + "type": "text", + "placeholders": {} + }, + "sendImage": "", + "@sendImage": { + "type": "text", + "placeholders": {} + }, + "hydrateTorLong": "", + "@hydrateTorLong": {}, + "time": "", + "@time": {}, + "enterYourHomeserver": "", + "@enterYourHomeserver": { + "type": "text", + "placeholders": {} + }, + "botMessages": "", + "@botMessages": { + "type": "text", + "placeholders": {} + }, + "contentHasBeenReported": "", + "@contentHasBeenReported": { + "type": "text", + "placeholders": {} + }, + "custom": "", + "@custom": {}, + "noBackupWarning": "", + "@noBackupWarning": {}, + "fromJoining": "", + "@fromJoining": { + "type": "text", + "placeholders": {} + }, + "verify": "", + "@verify": { + "type": "text", + "placeholders": {} + }, + "sendVideo": "", + "@sendVideo": { + "type": "text", + "placeholders": {} + }, + "editWidgets": "", + "@editWidgets": {}, + "storeInSecureStorageDescription": "", + "@storeInSecureStorageDescription": {}, + "openChat": "", + "@openChat": {}, + "kickUserDescription": "", + "@kickUserDescription": {}, + "sendAMessage": "", + "@sendAMessage": { + "type": "text", + "placeholders": {} + }, + "pin": "", + "@pin": { + "type": "text", + "placeholders": {} + }, + "importNow": "", + "@importNow": {}, + "deleteAccount": "", + "@deleteAccount": { + "type": "text", + "placeholders": {} + }, + "setInvitationLink": "", + "@setInvitationLink": { + "type": "text", + "placeholders": {} + }, + "pinMessage": "", + "@pinMessage": {}, + "screenSharingDetail": "", + "@screenSharingDetail": {}, + "muteChat": "", + "@muteChat": { + "type": "text", + "placeholders": {} + }, + "invite": "", + "@invite": {}, + "enableMultiAccounts": "", + "@enableMultiAccounts": {}, + "chooseAUsername": "", + "@chooseAUsername": { + "type": "text", + "placeholders": {} + }, + "anyoneCanJoin": "", + "@anyoneCanJoin": { + "type": "text", + "placeholders": {} + }, + "emotePacks": "", + "@emotePacks": { + "type": "text", + "placeholders": {} + }, + "makeSureTheIdentifierIsValid": "", + "@makeSureTheIdentifierIsValid": { + "type": "text", + "placeholders": {} + }, + "continueWith": "", + "@continueWith": {}, + "indexedDbErrorTitle": "", + "@indexedDbErrorTitle": {}, + "pleaseChooseAUsername": "", + "@pleaseChooseAUsername": { + "type": "text", + "placeholders": {} + }, + "endedTheCall": "", + "@endedTheCall": { + "type": "text", + "placeholders": { + "senderName": {} + } + } +} diff --git a/assets/l10n/intl_en.arb b/assets/l10n/intl_en.arb index 78a315041..5dc8cd899 100644 --- a/assets/l10n/intl_en.arb +++ b/assets/l10n/intl_en.arb @@ -55,6 +55,11 @@ "type": "text", "placeholders": {} }, + "accountInformation": "Account information", + "@accountInformation": { + "type": "text", + "placeholders": {} + }, "activatedEndToEndEncryption": "🔐 {username} activated end to end encryption", "@activatedEndToEndEncryption": { "type": "text", @@ -76,7 +81,16 @@ "mxid": {} } }, - "addChatDescription": "Add a chat description", + "addGroupDescription": "Add a chat description", + "@addGroupDescription": { + "type": "text", + "placeholders": {} + }, + "addNewFriend": "Add new friend", + "@addNewFriend": { + "type": "text", + "placeholders": {} + }, "addToSpace": "Add to space", "@addToSpace": {}, "admin": "Admin", @@ -99,6 +113,11 @@ "type": "text", "placeholders": {} }, + "alreadyHaveAnAccount": "Already have an account?", + "@alreadyHaveAnAccount": { + "type": "text", + "placeholders": {} + }, "commandHint_googly": "Send some googly eyes", "commandHint_cuddle": "Send a cuddle", "commandHint_hug": "Send a hug", @@ -187,7 +206,7 @@ }, "sendTypingNotifications": "Send typing notifications", "@sendTypingNotifications": {}, - "sendOnEnter": "Send on enter", + "sendOnEnter": "Always send on enter", "@sendOnEnter": {}, "badServerVersionsException": "The homeserver supports the Spec versions:\n{serverVersions}\nBut this app supports only {supportedVersions}", "@badServerVersionsException": { @@ -371,7 +390,7 @@ "type": "text", "placeholders": {} }, - "changeTheNameOfTheGroup": "Change the name of the group", + "changeTheNameOfTheGroup": "Change the name of the chat", "@changeTheNameOfTheGroup": { "type": "text", "placeholders": {} @@ -415,11 +434,12 @@ }, "chatHasBeenAddedToThisSpace": "Chat has been added to this space", "@chatHasBeenAddedToThisSpace": {}, - "chats": "Chats", + "chats": "Group Chats", "@chats": { "type": "text", "placeholders": {} }, + "classes": "Classes", "chooseAStrongPassword": "Choose a strong password", "@chooseAStrongPassword": { "type": "text", @@ -563,7 +583,7 @@ "type": "text", "placeholders": {} }, - "connect": "Connect", + "connect": "Start", "@connect": { "type": "text", "placeholders": {} @@ -583,7 +603,7 @@ "type": "text", "placeholders": {} }, - "contentHasBeenReported": "The content has been reported to the server admins", + "contentHasBeenReported": "The content has been reported", "@contentHasBeenReported": { "type": "text", "placeholders": {} @@ -630,7 +650,12 @@ } }, "createGroup": "Create group", - "createNewSpace": "New space", + "createNewSpace": "Create an exchange space", + "createNewGroup": "Create a new chat", + "@createNewGroup": { + "type": "text", + "placeholders": {} + }, "@createNewSpace": { "type": "text", "placeholders": {} @@ -751,6 +776,11 @@ "placeholders": {} }, "chatPermissions": "Chat permissions", + "editChatPermissions": "Edit chat permissions", + "@editChatPermissions": { + "type": "text", + "placeholders": {} + }, "editDisplayname": "Edit displayname", "@editDisplayname": { "type": "text", @@ -843,7 +873,7 @@ "senderName": {} } }, - "enterAGroupName": "Enter a group name", + "enterAGroupName": "Enter a chat name", "@enterAGroupName": { "type": "text", "placeholders": {} @@ -853,7 +883,7 @@ "type": "text", "placeholders": {} }, - "enterASpacepName": "Enter a space name", + "enterASpacepName": "Enter a name", "@enterASpacepName": {}, "homeserver": "Homeserver", "@homeserver": {}, @@ -914,7 +944,7 @@ "type": "text", "placeholders": {} }, - "group": "Group", + "group": "Chat", "@group": { "type": "text", "placeholders": {} @@ -922,16 +952,26 @@ "chatDescription": "Chat description", "chatDescriptionHasBeenChanged": "Chat description changed", "groupIsPublic": "Group is public", + "groupDescription": "Chat description", + "@groupDescription": { + "type": "text", + "placeholders": {} + }, + "groupDescriptionHasBeenChanged": "Chat description changed", + "@groupDescriptionHasBeenChanged": { + "type": "text", + "placeholders": {} + }, "@groupIsPublic": { "type": "text", "placeholders": {} }, - "groups": "Groups", + "groups": "Chats", "@groups": { "type": "text", "placeholders": {} }, - "groupWith": "Group with {displayname}", + "groupWith": "Chat with {displayname}", "@groupWith": { "type": "text", "placeholders": { @@ -986,22 +1026,22 @@ "type": "text", "placeholders": {} }, - "ignore": "Ignore", + "ignore": "Block", "@ignore": { "type": "text", "placeholders": {} }, - "ignoredUsers": "Ignored users", + "ignoredUsers": "Blocked users", "@ignoredUsers": { "type": "text", "placeholders": {} }, - "ignoreListDescription": "You can ignore users who are disturbing you. You won't be able to receive any messages or room invites from the users on your personal ignore list.", + "ignoreListDescription": "You can block users who are disturbing you. You won't be able to receive any messages or invites from the users on your personal block list.", "@ignoreListDescription": { "type": "text", "placeholders": {} }, - "ignoreUsername": "Ignore username", + "ignoreUsername": "Block username", "@ignoreUsername": { "type": "text", "placeholders": {} @@ -1016,7 +1056,7 @@ "type": "text", "placeholders": {} }, - "inoffensive": "Inoffensive", + "inoffensive": "Slightly offensive", "@inoffensive": { "type": "text", "placeholders": {} @@ -1035,12 +1075,6 @@ } }, "inviteContactToGroup": "Invite contact to {groupName}", - "@inviteContactToGroup": { - "type": "text", - "placeholders": { - "groupName": {} - } - }, "noChatDescriptionYet": "No chat description created yet.", "anyoneCanKnock": "Anyone can knock", "noOneCanJoin": "No one can join", @@ -1290,7 +1324,7 @@ "type": "text", "placeholders": {} }, - "noGoogleServicesWarning": "It seems that you have no google services on your phone. That's a good decision for your privacy! To receive push notifications in FluffyChat we recommend using https://microg.org/ or https://unifiedpush.org/.", + "noGoogleServicesWarning": "Firebase Cloud Messaging doesn't appear to be available on your device. To still receive push notifications, we recommend installing ntfy. With ntfy or another Unified Push provider you can receive push notifications in a data secure way. You can download ntfy from the PlayStore or from F-Droid.", "@noGoogleServicesWarning": { "type": "text", "placeholders": {} @@ -1421,7 +1455,7 @@ "@link": {}, "serverRequiresEmail": "This server needs to validate your email address for registration.", "@serverRequiresEmail": {}, - "optionalGroupName": "(Optional) Group name", + "optionalGroupName": "(Optional) Chat name", "@optionalGroupName": { "type": "text", "placeholders": {} @@ -1898,7 +1932,7 @@ "type": "text", "placeholders": {} }, - "spaceName": "Space name", + "spaceName": "Name", "@spaceName": { "type": "text", "placeholders": {} @@ -2164,7 +2198,7 @@ "type": "text", "placeholders": {} }, - "whoIsAllowedToJoinThisGroup": "Who is allowed to join this group", + "whoIsAllowedToJoinThisGroup": "Who is allowed to join this chat", "@whoIsAllowedToJoinThisGroup": { "type": "text", "placeholders": {} @@ -2402,6 +2436,12 @@ "user": {} } }, + "hasKnocked": "{user} has knocked", + "@hasKnocked": { + "placeholders": { + "user": {} + } + }, "noEmailWarning": "Please enter a valid email address. Otherwise you won't be able to reset your password. If you don't want to, tap again on the button to continue.", "@noEmailWarning": {}, "stories": "Stories", @@ -2452,9 +2492,9 @@ "@whyIsThisMessageEncrypted": {}, "noKeyForThisMessage": "This can happen if the message was sent before you have signed in to your account at this device.\n\nIt is also possible that the sender has blocked your device or something went wrong with the internet connection.\n\nAre you able to read the message on another session? Then you can transfer the message from it! Go to Settings > Devices and make sure that your devices have verified each other. When you open the room the next time and both sessions are in the foreground, the keys will be transmitted automatically.\n\nDo you not want to lose the keys when logging out or switching devices? Make sure that you have enabled the chat backup in the settings.", "@noKeyForThisMessage": {}, - "newGroup": "New group", + "newGroup": "New chat", "@newGroup": {}, - "newSpace": "New space", + "newSpace": "New class", "@newSpace": {}, "enterSpace": "Enter space", "@enterSpace": {}, @@ -2487,7 +2527,7 @@ "letsStart": "Let's start", "enterInviteLinkOrMatrixId": "Enter invite link or Matrix ID...", "reopenChat": "Reopen chat", - "noBackupWarning": "Warning! Without enabling chat backup, you will lose access to your encrypted messages. It is highly recommended to enable the chat backup first before logging out.", + "noBackupWarning": "Don't forget your password!", "noOtherDevicesFound": "No other devices found", "fileIsTooBigForServer": "The server reports that the file is too large to be sent.", "fileHasBeenSavedAt": "File has been saved at {path}", @@ -2513,19 +2553,1390 @@ "provider": {} } }, - "profileNotFound": "The user could not be found on the server. Maybe there is a connection problem or the user doesn't exist.", - "setTheme": "Set theme:", - "setColorTheme": "Set color theme:", - "invite": "Invite", - "requests": "Requests", - "inviteGroupChat": "📨 Invite group chat", - "invitePrivateChat": "📨 Invite private chat", - "invalidInput": "Invalid input!", - "wrongPinEntered": "Wrong pin entered! Try again in {seconds} seconds...", - "@wrongPinEntered": { + "profileNotFound": "The user could not be found on the server. Maybe there is a connection problem or the user doesn't exist.", + "setTheme": "Set theme:", + "setColorTheme": "Set color theme:", + "invite": "Invite", + "requests": "Requests", + "inviteGroupChat": "📨 Invite group chat", + "invitePrivateChat": "📨 Invite private chat", + "invalidInput": "Invalid input!", + "wrongPinEntered": "Wrong pin entered! Try again in {seconds} seconds...", + "@wrongPinEntered": { + "type": "text", + "placeholders": { + "seconds": {} + } + }, + "pleaseEnterANumber": "Please enter a number greater than 0", + "archiveRoomDescription": "The chat will be moved to the archive. Other users will be able to see that you have left the chat.", + "roomUpgradeDescription": "The chat will then be recreated with the new room version. All participants will be notified that they need to switch to the new chat. You can find out more about room versions at https://spec.matrix.org/latest/rooms/", + "allCorrect": "That's how I would say it! Nice!", + "newWayAllGood": "That's not how I would have said it but it looks good!", + "othersAreBetter": "Hm, there might be a better way to say that.", + "holdForInfo": "Click and hold for word info.", + "greenFeedback": "That's what I would put!", + "yellowFeedback": "Hm, you can try that and see if it works! To use this word, just click it again.", + "redFeedback": "I don't think that's right...", + "customInputFeedbackChoice": "You wrote it in. Nice!", + "itInstructionsTitle": "I can help you translate!", + "itInstructionsBody": "You can click and hold choices for word info.", + "toggleLanguages": "Toggle the language of selected messages.", + "classWelcomeChat": "Welcome Chat", + "@classWelcomeChat": { + "type": "text", + "placeholders": {} + }, + "deleteSpace": "Delete Space", + "deleteGroup": "Delete Group Chat", + "areYouSureDeleteClass": "Are you sure you want to delete this space?", + "areYouSureDeleteGroup": "Are you sure you want to delete this group chat?", + "cannotBeReversed": "This action cannot be reversed", + "enterDeletedClassName": "Enter space name to confirm:", + "incorrectClassName": "Incorrect Space Name", + "oneday": "Last 24 hours", + "@oneday": { + "type": "text", + "placeholders": {} + }, + "oneweek": "Last 7 days", + "@oneweek": { + "type": "text", + "placeholders": {} + }, + "onemonth": "Past month", + "@onemonth": { + "type": "text", + "placeholders": {} + }, + "sixmonth": "Past 6 months", + "@sixmonth": { + "type": "text", + "placeholders": {} + }, + "oneyear": "Past year", + "@oneyear": { + "type": "text", + "placeholders": {} + }, + "gaTooltip": "L2 use with grammar assistance", + "taTooltip": "L2 use with translation assistance", + "unTooltip": "Other", + "interactiveTranslatorSliderHeader": "Interactive Translator", + "interactiveGrammarSliderHeader": "Interactive Grammar Checker", + "interactiveTranslatorNotAllowed": "Disabled", + "@interactiveTranslatorNotAllowed": { + "type": "text", + "placeholders": {} + }, + "interactiveTranslatorAllowed": "Student Choice", + "@interactiveTranslatorAllowed": { + "type": "text", + "placeholders": {} + }, + "interactiveTranslatorRequired": "Required", + "@interactiveTranslatorRequired": { + "type": "text", + "placeholders": {} + }, + "interactiveTranslatorNotAllowedDesc": "Translation assistance is disabled in space group chats for all participants. This restriction does not apply to Class/Exchange Admin or direct chats.", + "@interactiveTranslatorNotAllowedDesc": { + "type": "text", + "placeholders": {} + }, + "interactiveTranslatorAllowedDesc": "Students can choose whether to use translation assistance in space group chats in Settings > Learning Settings.", + "@interactiveTranslatorAllowedDesc": { + "type": "text", + "placeholders": {} + }, + "interactiveTranslatorRequiredDesc": "Students cannot turn off translation assistance. They can choose not to accept the translation suggestions. This restriction does not apply to Class/Exchange or direct chats.", + "@interactiveTranslatorRequiredDesc": { + "type": "text", + "placeholders": {} + }, + "notYetSet": "Not yet set", + "@notYetSet": { + "type": "text", + "placeholders": {} + }, + "multiLingualClass": "Multilingual Class", + "classAnalytics": "Class Analytics", + "@classAnalytics": { + "type": "text", + "placeholders": {} + }, + "allClasses": "All Classes", + "@allClasses": { + "type": "text", + "placeholders": {} + }, + "myLearning": "My Analytics", + "@myLearning": { + "type": "text", + "placeholders": {} + }, + "allChatsAndClasses": "All chats and spaces", + "timeOfLastMessage": "Time of last sent message", + "totalMessages": "Total messages sent", + "waTooltip": "L2 use without assistance", + "changeDateRange": "Change date range", + "numberOfStudents": "Number of Students", + "@numberOfStudents": { + "type": "text", + "placeholders": {} + }, + "classDescription": "Description", + "@classDescription": { + "type": "text", + "placeholders": {} + }, + "classDescriptionDesc": "Set a description", + "@classDescriptionDesc": { + "type": "text", + "placeholders": {} + }, + "requestToEnroll": "Request to Enroll", + "@requestToEnroll": { + "type": "text", + "placeholders": {} + }, + "requestAnExchange": "Request an Exchange", + "@requestAnExchange": { + "type": "text", + "placeholders": {} + }, + "findLanguageExchange": "Find a class exchange partner", + "@findLanguageExchange": { + "type": "text", + "placeholders": {} + }, + "classAnalyticsDesc": "Detailed information on student engagement and language use", + "@classAnalyticsDesc": { + "type": "text", + "placeholders": {} + }, + "addStudents": "Add students", + "@addStudents": { + "type": "text", + "placeholders": {} + }, + "copyClassLink": "Copy invite link", + "@copyClassLink": { + "type": "text", + "placeholders": {} + }, + "copyClassLinkDesc": "Clicking this link will take students to the app, direct them to make an account and they will automatically join this space.", + "@copyClassLink": { + "type": "text", + "placeholders": {} + }, + "copyClassCode": "Copy invite code", + "inviteStudentByUserName": "Invite student by username", + "@inviteStudentByUserName": { + "type": "text", + "placeholders": {} + }, + "classSettings": "Class Settings", + "@classSettings": { + "type": "text", + "placeholders": {} + }, + "classSettingsDesc": "Edit class languages and proficiency level.", + "@classSettingsDesc": { + "type": "text", + "placeholders": {} + }, + "selectClassRoomDominantLanguage": "What is the base language of your class?", + "@selectClassRoomDominantLanguage": { + "type": "text", + "placeholders": {} + }, + "selectTargetLanguage": "What language are you teaching?", + "@selectTargetLanguage": { + "type": "text", + "placeholders": {} + }, + "whatIsYourClassLanguageLevel": "What is the average language level of your class?", + "@whatIsYourClassLanguageLevel": { + "type": "text", + "placeholders": {} + }, + "studentPermissions": "Student Permissions", + "@studentPermissions": { + "type": "text", + "placeholders": {} + }, + "interactiveTranslator": "Translation assistance", + "@interactiveTranslator": { + "type": "text", + "placeholders": {} + }, + "oneToOneChatsWithinClass": "Private Chats within Space", + "@oneToOneChatsWithinClass": { + "type": "text", + "placeholders": {} + }, + "oneToOneChatsWithinClassDesc": "If you allow private chats, students can initiate and use private chats with other space participants. Otherwise, they can only participate in groups chats.", + "@oneToOneChatsWithinClassDesc": { + "type": "text", + "placeholders": {} + }, + "createGroupChats": "Create Group Chats", + "@createGroupChats": { + "type": "text", + "placeholders": {} + }, + "createGroupChatsDesc": "Toggle this on to allow students to create group chats within the class/exchange space.", + "@createGroupChatsDesc": { + "type": "text", + "placeholders": {} + }, + "shareVideo": "Share Video", + "@shareVideo": { + "type": "text", + "placeholders": {} + }, + "shareVideoDesc": "Toggle this on to allow students to share videos in chats.", + "@shareVideoDesc": { + "type": "text", + "placeholders": {} + }, + "sharePhotos": "Share Photos", + "@sharePhotos": { + "type": "text", + "placeholders": {} + }, + "sharePhotosDesc": "Toggle this on to allow students to share photos in chats.", + "@sharePhotosDesc": { + "type": "text", + "placeholders": {} + }, + "shareFiles": "Share Files", + "@shareFiles": { + "type": "text", + "placeholders": {} + }, + "shareFilesDesc": "Toggle this on to allow students to share files in chats.", + "@shareFilesDesc": { + "type": "text", + "placeholders": {} + }, + "shareLocationDesc": "Toggle this on to allow students to share location in chats.", + "@shareLocationDesc": { + "type": "text", + "placeholders": {} + }, + "selectLanguageLevel": "Select language level", + "@selectLanguageLevel": { + "type": "text", + "placeholders": {} + }, + "noIdenticalLanguages": "Please choose different base and target languages", + "@noIdenticalLanguages": { + "type": "text", + "placeholders": {} + }, + "iWantALanguagePartnerFrom": "Is from:", + "@iWantALanguagePartnerFrom": { + "type": "text", + "placeholders": {} + }, + "worldWide": "Worldwide", + "@worldWide": { + "type": "text", + "placeholders": {} + }, + "noResults": "No results! Try broadening your search.", + "@noResults": { + "type": "text", + "placeholders": {} + }, + "searchBy": "Search by country and languages", + "@searchBy": { + "type": "text", + "placeholders": {} + }, + "iWantAConversationPartner": "I want a conversation partner who", + "@iWantAConversationPartner": { + "type": "text", + "placeholders": {} + }, + "iWantALanguagePartnerWhoSpeaks": "Speaks:", + "@iWantALanguagePartnerWhoSpeaks": { + "type": "text", + "placeholders": {} + }, + "iWantALanguagePartnerWhoIsLearning": "Is learning:", + "@iWantALanguagePartnerWhoIsLearning": { + "type": "text", + "placeholders": {} + }, + "yourBirthdayPlease": "Pangea Chat serves schools and other learning communities, ages 13 and up, around the world.\n\nIn order to protect our young learners, we ask our users to verify their age before connecting to our community.\n\nBefore you can search Pangea Chat for classes, rooms, and new friends, you must verify you are 18 or older.", + "@yourBirthdayPlease": { + "type": "text", + "placeholders": {} + }, + "invalidDob": "Invalid Date of Birth", + "@invalidDob": { + "type": "text", + "placeholders": {} + }, + "enterYourDob": "Enter your Date of Birth", + "@enterYourDob": { + "type": "text", + "placeholders": {} + }, + "getStarted": "Get Started", + "@getStarted": { + "type": "text", + "placeholders": {} + }, + "mustBe13": "User should be 13 years old", + "@mustBe13": { + "type": "text", + "placeholders": {} + }, + "yourBirthdayPleaseShort": "Please provide your date of birth", + "@yourBirthdayPleaseShort": { + "type": "text", + "placeholders": {} + }, + "errorPleaseRefresh": "We're looking into it! Please reload and try again.", + "@errorPleaseRefresh": { + "type": "text", + "placeholders": {} + }, + "joinWithClassCode": "Join class or exchange", + "@joinWithClassCode": { + "type": "text", + "placeholders": {} + }, + "joinWithClassCodeDesc": "Connect to a class or exchange space with the 6-digit invite code provided by the space administrator.", + "@joinWithClassCodeDesc": { + "type": "text", + "placeholders": {} + }, + "joinWithClassCodeHint": "Enter invite code", + "@joinWithClassCodeHint": { + "type": "text", + "placeholders": {} + }, + "unableToFindClass": "We are unable to find the class or exchange. Please double-check the information with the space administrator. If you are still experiencing an issue, please contact support@pangea.chat.", + "@unableToFindClass": { + "type": "text", + "placeholders": {} + }, + "languageLevelPreA1": "True Beginner (Pre A1)", + "@languageLevelPreA1": { + "type": "text", + "placeholders": {} + }, + "languageLevelA1": "Beginner (A1)", + "@languageLevelA1": { + "type": "text", + "placeholders": {} + }, + "languageLevelA2": "Elementary (A2)", + "@languageLevelA2": { + "type": "text", + "placeholders": {} + }, + "languageLevelB1": "Intermediate (B1)", + "@languageLevelB1": { + "type": "text", + "placeholders": {} + }, + "languageLevelB2": "Upper Intermediate (B2)", + "@languageLevelB2": { + "type": "text", + "placeholders": {} + }, + "languageLevelC1": "Advanced (C1)", + "@languageLevelC1": { + "type": "text", + "placeholders": {} + }, + "languageLevelC2": "Mastery (C2)", + "@languageLevelC2": { + "type": "text", + "placeholders": {} + }, + "changeTheNameOfTheClass": "Change the name", + "@changeTheNameOfTheClass": { + "type": "text", + "placeholders": {} + }, + "changeTheNameOfTheChat": "Change the name of the chat", + "@changeTheNameOfTheChat": { + "type": "text", + "placeholders": {} + }, + "welcomeToYourNewClass": "Welcome! 🙂", + "@welcomeToYourNewClass": { + "type": "text", + "placeholders": {} + }, + "welcomeToClass": "Welcome! 🙂\n- Try joining a chat!\n- Have fun chatting!", + "@welcomeToClass": { + "type": "text", + "placeholders": {} + }, + "welcomeToPangea18Plus": "Welcome to Pangea Chat! 🙂\nWhat's next?\nCreate or join a class!\nOr search for a conversation partner!", + "@welcomeToPangea18Plus": { + "type": "text", + "placeholders": {} + }, + "welcomeToPangeaMinor": "Welcome to Pangea Chat! 🙂\nWhat's next?\nJoin a class!\nAsk your teacher for an invite code.", + "@welcomeToPangeaMinor": { + "type": "text", + "placeholders": {} + }, + "findALanguagePartner": "Find a conversation partner", + "@findALanguagePartner": { + "type": "text", + "placeholders": {} + }, + "setToPublicSettingsTitle": "Want to find a conversation partner?", + "@setToPublicSettingsTitle": { + "type": "text", + "placeholders": {} + }, + "setToPublicSettingsDesc": "Before you can search for a conversation parter, you must set your profile visibility to public.", + "@setToPublicSettingsDesc": { + "type": "text", + "placeholders": {} + }, + "accountSettings": "Account settings", + "@accountSettings": { + "type": "text", + "placeholders": {} + }, + "unableToFindClassCode": "Unable to find code.", + "@unableToFindClassCode": { + "type": "text", + "placeholders": {} + }, + "askPangeaBot": "Ask Pangea Bot for a contextual definition.", + "sorryNoResults": "Sorry, no results.", + "@sorryNoResults": { + "type": "text", + "placeholders": {} + }, + "ignoreInThisText": "Ignore", + "@ignoreInThisText": { + "type": "text", + "placeholders": {} + }, + "helpMeTranslate": "Help me translate!", + "@helpMeTranslate": { + "type": "text", + "placeholders": {} + }, + "needsItShortMessage": "Try interactive translation!", + "needsIGCShortMessage": "Try interactive grammar assistance!", + "@needsItShortMessage": { + "type": "text", + "placeholders": {} + }, + "needsItMessage": "This message has too many words in your base language.", + "@needsItMessage": { + "type": "text", + "placeholders": {} + }, + "needsIgcMessage": "This message has a grammar error.", + "tokenTranslationTitle": "A word is in your base language.", + "@tokenTranslationTitle": { + "type": "text", + "placeholders": {} + }, + "spanTranslationDesc": "See possible translations below.", + "@spanTranslationDesc": { + "type": "text", + "placeholders": {} + }, + "spanTranslationTitle": "Some words are in your base language.", + "@spanTranslationTitle": { + "type": "text", + "placeholders": {} + }, + "l1SpanAndGrammarTitle": "Outside target language", + "l1SpanAndGrammarDesc": "This could in your base language or it could be a grammar error.", + "otherTitle": "You have an error.", + "@otherTitle": { + "type": "text", + "placeholders": {} + }, + "otherDesc": "See possible corrections below.", + "@otherDesc": { + "type": "text", + "placeholders": {} + }, + "countryInformation": "My country", + "@countryInformation": { + "type": "text", + "placeholders": {} + }, + "myLanguages": "My base and target language", + "@myLanguages": { + "type": "text", + "placeholders": {} + }, + "targetLanguage": "Target Language", + "@targetLanguage": { + "type": "text", + "placeholders": {} + }, + "sourceLanguage": "Base language", + "@sourceLanguage": { + "type": "text", + "placeholders": {} + }, + "languagesISpeak": "Languages I speak", + "@languagesISpeak": { + "type": "text", + "placeholders": {} + }, + "updateLanguage": "My languages", + "@updateLanguage": { + "type": "text", + "placeholders": {} + }, + "whatLanguageYouWantToLearn": "What language do you want to learn?", + "@whatLanguageYouWantToLearn": { + "type": "text", + "placeholders": {} + }, + "whatIsYourBaseLanguage": "What is your base language? \n\nInteractive translation is only available for English and Spanish.", + "@whatIsYourBaseLanguage": { + "type": "text", + "placeholders": {} + }, + "saveChanges": "Save changes", + "@saveChanges": { + "type": "text", + "placeholders": {} + }, + "publicProfileTitle": "Public Profile", + "@publicProfileTitle": { + "type": "text", + "placeholders": {} + }, + "publicProfileDesc": "Your profile must be public in order to search or be found as a conversation partner.", + "@publicProfileDesc": { + "type": "text", + "placeholders": {} + }, + "error502504Title": "Wow, there are a lot of students online!", + "@error502504Title": { + "type": "text", + "placeholders": {} + }, + "error502504Desc": "Translation and grammar tools may be slow or unavailable while the Pangea bots catch up.", + "@error502504Desc": { + "type": "text", + "placeholders": {} + }, + "error404Title": "Translation error!", + "@error404Title": { + "type": "text", + "placeholders": {} + }, + "error404Desc": "Pangea Bot isn't sure how to translate that...", + "@error404Desc": { + "type": "text", + "placeholders": {} + }, + "errorDisableIT": "Translation assistance is turned off.", + "errorDisableIGC": "Grammar assistance is turned off.", + "errorDisableLanguageAssistance": "Translation assistance and grammar assistance are turned off.", + "errorDisableITUserDesc": "Click here to update translation assistance settings", + "errorDisableIGCUserDesc": "Click here to update grammar assistance settings", + "errorDisableLanguageAssistanceUserDesc": "Click here to update translation assistance and grammar assistance settings", + "errorDisableITClassDesc": "Translation assistance is turned off for the space that this chat is in.", + "errorDisableIGCClassDesc": "Grammar assistance is turned off for the space that this chat is in.", + "errorDisableLanguageAssistanceClassDesc": "Translation assistance and grammar assistance are turned off for the space that this chat is in.", + "itIsDisabled": "Interactive Translation is disabled", + "igcIsDisabled": "Interactive Grammar Checking is disabled", + "goToLearningSettings": "Go to Learning Settings", + "error405Title": "Languages not set", + "error405Desc": "Please set your languages in Settings > Learning Settings", + "loginOrSignup": "Sign in with", + "@loginOrSignup": { + "type": "text", + "placeholders": {} + }, + "iAgreeToThe": "I agree to the ", + "@iAgreeToThe": { + "type": "text", + "placeholders": {} + }, + "termsAndConditions": "Terms and Conditions", + "@termsAndConditions": { + "type": "text", + "placeholders": {} + }, + "andCertifyIAmAtLeast13YearsOfAge": " and certify I am at least 13 years of age.", + "@andCertifyIAmAtLeast13YearsOfAge": { + "type": "text", + "placeholders": {} + }, + "error502504Title": "Wow, there are a lot of students online!", + "@error502504Title": { + "type": "text", + "placeholders": {} + }, + "error502504Desc": "Translation and grammar tools may be slow or unavailable while the Pangea bots catch up.", + "@error502504Desc": { + "type": "text", + "placeholders": {} + }, + "error404Title": "Translation error!", + "@error404Title": { + "type": "text", + "placeholders": {} + }, + "error404Desc": "Pangea Bot isn't sure how to translate that...", + "@error404Desc": { + "type": "text", + "placeholders": {} + }, + "errorPleaseRefresh": "We're looking into it! Please reload and try again.", + "@errorPleaseRefresh": { + "type": "text", + "placeholders": {} + }, + "findAClass": "Find a class (coming soon)", + "toggleIT": "Interactive Translation", + "@toggleIT": { + "type": "text", + "placeholders": {} + }, + "toggleIGC": "Interactive Grammar Checking", + "@toggleIGC": { + "type": "text", + "placeholders": {} + }, + "toggleToolSettingsDescription": "Here you can toggle your individual language tool settings. For chats within a space, the space settings will take precedence and may override these settings.", + "connectedToStaging": "You are connected to the staging server.", + "@connectedToStaging": { + "type": "text", + "placeholders": {} + }, + "learningSettings": "Learning Settings", + "classNameRequired": "Please enter a space name", + "@classNameRequired": { + "type": "text", + "placeholders": {} + }, + "sendVoiceNotes": "Send Voice Notes", + "@sendVoiceNotes": { + "type": "text", + "placeholders": {} + }, + "sendVoiceNotesDesc": "Toggle this on to allow students to send voice notes in chats.", + "@sendVoiceNotesDesc": { + "type": "text", + "placeholders": {} + }, + "chatTopic": "Chat topic", + "@chatTopic": { + "type": "text", + "placeholders": {} + }, + "chatTopicDesc": "Set a chat topic", + "@chatTopicDesc": { + "type": "text", + "placeholders": {} + }, + "classDescription": "Space Description", + "@classDescription": { + "type": "text", + "placeholders": {} + }, + "inviteStudentByUserNameDesc": "If your student already has an account, you can search for them.", + "@inviteStudentByUserNameDesc": { + "type": "text", + "placeholders": {} + }, + "classRoster": "Participants", + "@classRoster": { + "type": "text", + "placeholders": {} + }, + "almostPerfect": "That seems right! Here's what I would have said.", + "prettyGood": "Pretty good! Here's what I would have said.", + "letMeThink": "Hmm, let's see how you did!", + "clickMessageTitle": "Select messages for language help!", + "clickMessageBody": "Messages always show in your target language but you can select them to access definitions and translations!", + "understandingMessagesTitle": "Definitions and translations!", + "addToClass": "Add this chat to ", + "understandingMessagesBody": "Click underlined words for definitions. Translate with message options (upper right).", + "allDone": "All done!", + "vocab": "Vocabulary", + + "low": "We have evidence the user does not understand these words.", + "medium": "These words have been used. It is unclear if the words are fully understood or not.", + "high": "We have evidence the user understands these words.", + "unknownProficiency": "These words have not been used in Pangea Chat.", + "changeView": "Switch views.", + "clearAll": "Clear all words?", + "generateVocabulary": "Generate vocabulary from title and description", + "generatePrompts": "Generate prompts", + "subscribe": "Subscribe", + "getAccess": "Unlock learning tools", + "subscriptionDesc": "Messaging is free! Subscribe to unlock interactive translation, grammar checking and learning analytics.", + "subscriptionManagement": "Subscription Management", + "currentSubscription": "Current Subscription", + "changeSubscription": "Change your subscription", + "cancelSubscription": "Cancel your subscription", + "selectYourPlan": "Select Your Plan", + "subsciptionPlatformTooltip": "Please login to your original device to manage your subscription plan", + "subscriptionManagementUnavailable": "Subscription management not available", + "paymentMethod": "Payment Method", + "paymentHistory": "Payment History", + "emptyChatDownloadWarning": "Cannot download empty chat", + "appUpdateAvailable": "Update Available", + "update": "Update", + "updateDesc": "You can now update this app from {localVersion} to {storeVersion}", + "@updateDesc": { + "type": "text", + "placeholders": { + "storeVersion": {}, + "localVersion": {} + } + }, + "maybeLater": "Maybe Later", + "mainMenu": "Main Menu", + "toggleImmersionMode": "Immersion Mode", + "toggleImmersionModeDesc": "When enabled, all messages are displayed in your target language and you can click the message to access definitions and translations.", + "itToggleDescription": "This language learning tool will identify words in your base language and help you translate them to your target language. Though rare, the AI can make translation errors.", + "igcToggleDescription": "This language learning tool will identify common spelling, grammar and punctuation errors in your message and suggest corrections. Though rare, the AI can make correction errors.", + "sendOnEnterDescription": "Turn this off to be able to add line spaces in messages. When the toggle is off on the browser app, you can press Shift + Enter to start a new line. When the toggle is off on mobile apps, just Enter will start a new line.", + "alreadyInClass": "You are already in this space.", + "pleaseLoginFirst": "Please login or sign up first and then you will be added to your class/exchange space.", + "originalMessage": "Original Message", + "sentMessage": "Sent Message", + "useType": "Use Type", + "notAvailable": "Not Available", + "taAndGaTooltip": "L2 use with translation assistance and grammar assistance", + "definitionsToolName": "Word Definitions", + "messageTranslationsToolName": "Message Translations", + "definitionsToolDescription": "When enabled, words underlined in blue can be clicked for definitions. Click messages to access definitions.", + "translationsToolDescrption": "When enabled, click a message and the translation icon to see a message in your base language.", + "welcomeBack": "Welcome back! If you were part of the 2023-2024 pilot, please contact us for your special pilot subscription. If you are a teacher who has (or whose institution has) purchased licenses for your class, contact us for your teacher subscription.", + "classExchanges": "Exchanges", + "createNewClass": "New class space", + "newExchange": "New exchange space", + "kickAllStudents": "Kick All Students", + "kickAllStudentsConfirmation": "Are you sure you want to kick all students?", + "inviteAllStudents": "Invite All Students", + "inviteAllStudentsConfirmation": "Are you sure you want to invite all students?", + "inviteStudentsFromOtherClasses": "Invite students from other spaces", + "inviteUsersFromPangea": "Add teachers", + "allExchanges": "All Exchanges", + "redeemPromoCode": "Redeem Promo Code", + "enterPromoCode": "Enter Promo Code", + "downloadTxtFile": "Download Text File", + "downloadCSVFile": "Download CSV File", + "promotionalSubscriptionDesc": "You currently have a lifetime promotional subscription. Message support@pangea.chat for help changing your subscription.", + "originalSubscriptionPlatform": "Subscription purchased through", + "oneWeekTrial": "One Week Trial", + "creatingSpacePleaseWait": "Creating space. Please wait...", + "downloadXLSXFile": "Download Excel File", + "abDisplayName": "Abkhaz", + "aaDisplayName": "Afar", + "afDisplayName": "Afrikaans", + "akDisplayName": "Akan", + "sqDisplayName": "Albanian", + "amDisplayName": "Amharic", + "arDisplayName": "Arabic", + "anDisplayName": "Aragonese", + "hyDisplayName": "Armenian", + "asDisplayName": "Assamese", + "avDisplayName": "Avaric", + "aeDisplayName": "Avestan", + "ayDisplayName": "Aymara", + "azDisplayName": "Azerbaijani", + "bmDisplayName": "Bambara", + "baDisplayName": "Bashkir", + "euDisplayName": "Basque", + "beDisplayName": "Belarusian", + "bnDisplayName": "Bengali", + "bhDisplayName": "Bihari", + "biDisplayName": "Bislama", + "bsDisplayName": "Bosnian", + "brDisplayName": "Breton", + "bgDisplayName": "Bulgarian", + "myDisplayName": "Burmese", + "caDisplayName": "Catalan, Valencian", + "chDisplayName": "Chamorro", + "ceDisplayName": "Chechen", + "nyDisplayName": "Chichewa, Chewa, Nyanja", + "zhDisplayName": "Chinese", + "cvDisplayName": "Chuvash", + "kwDisplayName": "Cornish", + "coDisplayName": "Corsican", + "crDisplayName": "Cree", + "hrDisplayName": "Croatian", + "csDisplayName": "Czech", + "daDisplayName": "Danish", + "dvDisplayName": "Divehi; Dhivehi; Maldivian;", + "nlDisplayName": "Dutch", + "enDisplayName": "English", + "eoDisplayName": "Esperanto", + "etDisplayName": "Estonian", + "eeDisplayName": "Ewe", + "foDisplayName": "Faroese", + "fjDisplayName": "Fijian", + "fiDisplayName": "Finnish", + "frDisplayName": "French", + "ffDisplayName": "Fula; Fulah; Pulaar; Pular", + "glDisplayName": "Galician", + "kaDisplayName": "Georgian", + "deDisplayName": "German", + "elDisplayName": "Greek, Modern", + "gnDisplayName": "Guaraní", + "guDisplayName": "Gujarati", + "htDisplayName": "Haitian, Haitian Creole", + "haDisplayName": "Hausa", + "heDisplayName": "Hebrew (modern)", + "hzDisplayName": "Herero", + "hiDisplayName": "Hindi", + "hoDisplayName": "Hiri Motu", + "huDisplayName": "Hungarian", + "iaDisplayName": "Interlingua", + "idDisplayName": "Indonesian", + "ieDisplayName": "Interlingue", + "gaDisplayName": "Irish", + "igDisplayName": "Igbo", + "ikDisplayName": "Inupiaq", + "ioDisplayName": "Ido", + "isDisplayName": "Icelandic", + "itDisplayName": "Italian", + "iuDisplayName": "Inuktitut", + "jaDisplayName": "Japanese", + "jvDisplayName": "Javanese", + "klDisplayName": "Kalaallisut, Greenlandic", + "knDisplayName": "Kannada", + "krDisplayName": "Kanuri", + "ksDisplayName": "Kashmiri", + "kkDisplayName": "Kazakh", + "kmDisplayName": "Khmer", + "kiDisplayName": "Kikuyu, Gikuyu", + "rwDisplayName": "Kinyarwanda", + "kyDisplayName": "Kirghiz, Kyrgyz", + "kvDisplayName": "Komi", + "kgDisplayName": "Kongo", + "koDisplayName": "Korean", + "kuDisplayName": "Kurdish", + "kjDisplayName": "Kwanyama, Kuanyama", + "laDisplayName": "Latin", + "lbDisplayName": "Luxembourgish, Letzeburgesch", + "lgDisplayName": "Luganda", + "liDisplayName": "Limburgish, Limburgan, Limburger", + "lnDisplayName": "Lingala", + "loDisplayName": "Lao", + "ltDisplayName": "Lithuanian", + "luDisplayName": "Luba-Katanga", + "lvDisplayName": "Latvian", + "gvDisplayName": "Manx", + "mkDisplayName": "Macedonian", + "mgDisplayName": "Malagasy", + "msDisplayName": "Malay", + "mlDisplayName": "Malayalam", + "mtDisplayName": "Maltese", + "miDisplayName": "Māori", + "mrDisplayName": "Marathi (Marāṭhī)", + "mhDisplayName": "Marshallese", + "mnDisplayName": "Mongolian", + "naDisplayName": "Nauru", + "nvDisplayName": "Navajo, Navaho", + "nbDisplayName": "Norwegian Bokmål", + "ndDisplayName": "North Ndebele", + "neDisplayName": "Nepali", + "ngDisplayName": "Ndonga", + "nnDisplayName": "Norwegian Nynorsk", + "noDisplayName": "Norwegian", + "iiDisplayName": "Nuosu", + "nrDisplayName": "South Ndebele", + "ocDisplayName": "Occitan", + "ojDisplayName": "Ojibwe, Ojibwa", + "cuDisplayName": "Old Church Slavonic, Church Slavic, Church Slavonic, Old Bulgarian, Old Slavonic", + "omDisplayName": "Oromo", + "orDisplayName": "Oriya", + "osDisplayName": "Ossetian, Ossetic", + "paDisplayName": "Panjabi, Punjabi", + "piDisplayName": "Pāli", + "faDisplayName": "Persian", + "plDisplayName": "Polish", + "psDisplayName": "Pashto, Pushto", + "ptDisplayName": "Portuguese", + "quDisplayName": "Quechua", + "rmDisplayName": "Romansh", + "rnDisplayName": "Kirundi", + "roDisplayName": "Romanian, Moldavian, Moldovan", + "ruDisplayName": "Russian", + "saDisplayName": "Sanskrit (Saṁskṛta)", + "scDisplayName": "Sardinian", + "sdDisplayName": "Sindhi", + "seDisplayName": "Northern Sami", + "smDisplayName": "Samoan", + "sgDisplayName": "Sango", + "srDisplayName": "Serbian", + "gdDisplayName": "Scottish Gaelic, Gaelic", + "snDisplayName": "Shona", + "siDisplayName": "Sinhala, Sinhalese", + "skDisplayName": "Slovak", + "slDisplayName": "Slovene", + "soDisplayName": "Somali", + "stDisplayName": "Southern Sotho", + "esDisplayName": "Spanish", + "suDisplayName": "Sundanese", + "swDisplayName": "Swahili", + "ssDisplayName": "Swati", + "svDisplayName": "Swedish", + "taDisplayName": "Tamil", + "teDisplayName": "Telugu", + "tgDisplayName": "Tajik", + "thDisplayName": "Thai", + "tiDisplayName": "Tigrinya", + "boDisplayName": "Tibetan Standard, Tibetan, Central", + "tkDisplayName": "Turkmen", + "tlDisplayName": "Tagalog", + "tnDisplayName": "Tswana", + "toDisplayName": "Tonga (Tonga Islands)", + "trDisplayName": "Turkish", + "tsDisplayName": "Tsonga", + "ttDisplayName": "Tatar", + "twDisplayName": "Twi", + "tyDisplayName": "Tahitian", + "ugDisplayName": "Uighur, Uyghur", + "ukDisplayName": "Ukrainian", + "urDisplayName": "Urdu", + "uzDisplayName": "Uzbek", + "veDisplayName": "Venda", + "viDisplayName": "Vietnamese", + "voDisplayName": "Volapük", + "waDisplayName": "Walloon", + "cyDisplayName": "Welsh", + "woDisplayName": "Wolof", + "fyDisplayName": "Western Frisian", + "xhDisplayName": "Xhosa", + "yiDisplayName": "Yiddish", + "yoDisplayName": "Yoruba", + "zaDisplayName": "Zhuang, Chuang", + "unkDisplayName": "Unknown", + "zuDisplayName": "Zulu", + "hawDisplayName": "Hawaiian", + "hmnDisplayName": "Hmong", + "multiDisplayName": "Multi", + "cebDisplayName": "Cebuano", + "dzDisplayName": "Dzongkha", + "iwDisplayName": "Hebrew", + "jwDisplayName": "Javanese", + "moDisplayName": "Moldavian", + "shDisplayName": "Serbo-Croatian", + "wwCountryDisplayName": "World Wide", + "afCountryDisplayName": "Afghanistan", + "axCountryDisplayName": "Aland Islands", + "alCountryDisplayName": "Albania", + "dzCountryDisplayName": "Algeria", + "asCountryDisplayName": "American Samoa", + "adCountryDisplayName": "Andorra", + "aoCountryDisplayName": "Angola", + "aiCountryDisplayName": "Anguilla", + "agCountryDisplayName": "Antigua and Barbuda", + "arCountryDisplayName": "Argentina", + "amCountryDisplayName": "Armenia", + "awCountryDisplayName": "Aruba", + "acCountryDisplayName": "Ascension Island", + "auCountryDisplayName": "Australia", + "atCountryDisplayName": "Austria", + "azCountryDisplayName": "Azerbaijan", + "bsCountryDisplayName": "Bahamas", + "bhCountryDisplayName": "Bahrain", + "bdCountryDisplayName": "Bangladesh", + "bbCountryDisplayName": "Barbados", + "byCountryDisplayName": "Belarus", + "beCountryDisplayName": "Belgium", + "bzCountryDisplayName": "Belize", + "bjCountryDisplayName": "Benin", + "bmCountryDisplayName": "Bermuda", + "btCountryDisplayName": "Bhutan", + "boCountryDisplayName": "Bolivia", + "baCountryDisplayName": "Bosnia and Herzegovina", + "bwCountryDisplayName": "Botswana", + "brCountryDisplayName": "Brazil", + "ioCountryDisplayName": "British Indian Ocean Territory", + "vgCountryDisplayName": "British Virgin Islands", + "bnCountryDisplayName": "Brunei", + "bgCountryDisplayName": "Bulgaria", + "bfCountryDisplayName": "Burkina Faso", + "biCountryDisplayName": "Burundi", + "khCountryDisplayName": "Cambodia", + "cmCountryDisplayName": "Cameroon", + "caCountryDisplayName": "Canada", + "cvCountryDisplayName": "Cape Verde", + "bqCountryDisplayName": "Caribbean Netherlands", + "kyCountryDisplayName": "Cayman Islands", + "cfCountryDisplayName": "Central African Republic", + "tdCountryDisplayName": "Chad", + "clCountryDisplayName": "Chile", + "cnCountryDisplayName": "China", + "cxCountryDisplayName": "Christmas Island", + "ccCountryDisplayName": "Cocos [Keeling] Islands", + "coCountryDisplayName": "Colombia", + "kmCountryDisplayName": "Comoros", + "cdCountryDisplayName": "Democratic Republic Congo", + "cgCountryDisplayName": "Republic of Congo", + "ckCountryDisplayName": "Cook Islands", + "crCountryDisplayName": "Costa Rica", + "ciCountryDisplayName": "Côte d'Ivoire", + "hrCountryDisplayName": "Croatia", + "cuCountryDisplayName": "Cuba", + "cwCountryDisplayName": "Curaçao", + "cyCountryDisplayName": "Cyprus", + "czCountryDisplayName": "Czech Republic", + "dkCountryDisplayName": "Denmark", + "djCountryDisplayName": "Djibouti", + "dmCountryDisplayName": "Dominica", + "doCountryDisplayName": "Dominican Republic", + "tlCountryDisplayName": "East Timor", + "ecCountryDisplayName": "Ecuador", + "egCountryDisplayName": "Egypt", + "svCountryDisplayName": "El Salvador", + "gqCountryDisplayName": "Equatorial Guinea", + "erCountryDisplayName": "Eritrea", + "eeCountryDisplayName": "Estonia", + "szCountryDisplayName": "Eswatini", + "etCountryDisplayName": "Ethiopia", + "fkCountryDisplayName": "Falkland Islands", + "foCountryDisplayName": "Faroe Islands", + "fjCountryDisplayName": "Fiji", + "fiCountryDisplayName": "Finland", + "frCountryDisplayName": "France", + "gfCountryDisplayName": "French Guiana", + "pfCountryDisplayName": "French Polynesia", + "gaCountryDisplayName": "Gabon", + "gmCountryDisplayName": "Gambia", + "geCountryDisplayName": "Georgia", + "deCountryDisplayName": "Germany", + "ghCountryDisplayName": "Ghana", + "giCountryDisplayName": "Gibraltar", + "grCountryDisplayName": "Greece", + "glCountryDisplayName": "Greenland", + "gdCountryDisplayName": "Grenada", + "gpCountryDisplayName": "Guadeloupe", + "guCountryDisplayName": "Guam", + "gtCountryDisplayName": "Guatemala", + "ggCountryDisplayName": "Guernsey", + "gnCountryDisplayName": "Guinea Conakry", + "gwCountryDisplayName": "Guinea-Bissau", + "gyCountryDisplayName": "Guyana", + "htCountryDisplayName": "Haiti", + "hmCountryDisplayName": "Heard Island and McDonald Islands", + "hnCountryDisplayName": "Honduras", + "hkCountryDisplayName": "Hong Kong", + "huCountryDisplayName": "Hungary", + "isCountryDisplayName": "Iceland", + "inCountryDisplayName": "India", + "idCountryDisplayName": "Indonesia", + "irCountryDisplayName": "Iran", + "iqCountryDisplayName": "Iraq", + "ieCountryDisplayName": "Ireland", + "imCountryDisplayName": "Isle of Man", + "ilCountryDisplayName": "Israel", + "itCountryDisplayName": "Italy", + "jmCountryDisplayName": "Jamaica", + "jpCountryDisplayName": "Japan", + "jeCountryDisplayName": "Jersey", + "joCountryDisplayName": "Jordan", + "kzCountryDisplayName": "Kazakhstan", + "keCountryDisplayName": "Kenya", + "kiCountryDisplayName": "Kiribati", + "xkCountryDisplayName": "Kosovo", + "kwCountryDisplayName": "Kuwait", + "kgCountryDisplayName": "Kyrgyzstan", + "laCountryDisplayName": "Laos", + "lvCountryDisplayName": "Latvia", + "lbCountryDisplayName": "Lebanon", + "lsCountryDisplayName": "Lesotho", + "lrCountryDisplayName": "Liberia", + "lyCountryDisplayName": "Libya", + "liCountryDisplayName": "Liechtenstein", + "ltCountryDisplayName": "Lithuania", + "luCountryDisplayName": "Luxembourg", + "moCountryDisplayName": "Macau", + "mkCountryDisplayName": "Macedonia", + "mgCountryDisplayName": "Madagascar", + "mwCountryDisplayName": "Malawi", + "myCountryDisplayName": "Malaysia", + "mvCountryDisplayName": "Maldives", + "mlCountryDisplayName": "Mali", + "mtCountryDisplayName": "Malta", + "mhCountryDisplayName": "Marshall Islands", + "mqCountryDisplayName": "Martinique", + "mrCountryDisplayName": "Mauritania", + "muCountryDisplayName": "Mauritius", + "ytCountryDisplayName": "Mayotte", + "mxCountryDisplayName": "Mexico", + "fmCountryDisplayName": "Micronesia", + "mdCountryDisplayName": "Moldova", + "mcCountryDisplayName": "Monaco", + "mnCountryDisplayName": "Mongolia", + "meCountryDisplayName": "Montenegro", + "msCountryDisplayName": "Montserrat", + "maCountryDisplayName": "Morocco", + "mzCountryDisplayName": "Mozambique", + "mmCountryDisplayName": "Myanmar (Burma)", + "naCountryDisplayName": "Namibia", + "nrCountryDisplayName": "Nauru", + "npCountryDisplayName": "Nepal", + "nlCountryDisplayName": "Netherlands", + "ncCountryDisplayName": "New Caledonia", + "nzCountryDisplayName": "New Zealand", + "niCountryDisplayName": "Nicaragua", + "neCountryDisplayName": "Niger", + "ngCountryDisplayName": "Nigeria", + "nuCountryDisplayName": "Niue", + "nfCountryDisplayName": "Norfolk Island", + "kpCountryDisplayName": "North Korea", + "mpCountryDisplayName": "Northern Mariana Islands", + "noCountryDisplayName": "Norway", + "omCountryDisplayName": "Oman", + "pkCountryDisplayName": "Pakistan", + "pwCountryDisplayName": "Palau", + "psCountryDisplayName": "Palestinian Territories", + "paCountryDisplayName": "Panama", + "pgCountryDisplayName": "Papua New Guinea", + "pyCountryDisplayName": "Paraguay", + "peCountryDisplayName": "Peru", + "phCountryDisplayName": "Philippines", + "plCountryDisplayName": "Poland", + "ptCountryDisplayName": "Portugal", + "prCountryDisplayName": "Puerto Rico", + "qaCountryDisplayName": "Qatar", + "reCountryDisplayName": "Réunion", + "roCountryDisplayName": "Romania", + "ruCountryDisplayName": "Russia", + "rwCountryDisplayName": "Rwanda", + "blCountryDisplayName": "Saint Barthélemy", + "shCountryDisplayName": "Saint Helena", + "knCountryDisplayName": "St. Kitts", + "lcCountryDisplayName": "St. Lucia", + "mfCountryDisplayName": "Saint Martin", + "pmCountryDisplayName": "Saint Pierre and Miquelon", + "vcCountryDisplayName": "St. Vincent", + "wsCountryDisplayName": "Samoa", + "smCountryDisplayName": "San Marino", + "stCountryDisplayName": "São Tomé and Príncipe", + "saCountryDisplayName": "Saudi Arabia", + "snCountryDisplayName": "Senegal", + "rsCountryDisplayName": "Serbia", + "scCountryDisplayName": "Seychelles", + "slCountryDisplayName": "Sierra Leone", + "sgCountryDisplayName": "Singapore", + "sxCountryDisplayName": "Sint Maarten", + "skCountryDisplayName": "Slovakia", + "siCountryDisplayName": "Slovenia", + "sbCountryDisplayName": "Solomon Islands", + "soCountryDisplayName": "Somalia", + "zaCountryDisplayName": "South Africa", + "gsCountryDisplayName": "South Georgia and the South Sandwich Islands", + "krCountryDisplayName": "South Korea", + "ssCountryDisplayName": "South Sudan", + "esCountryDisplayName": "Spain", + "lkCountryDisplayName": "Sri Lanka", + "sdCountryDisplayName": "Sudan", + "srCountryDisplayName": "Suriname", + "sjCountryDisplayName": "Svalbard and Jan Mayen", + "seCountryDisplayName": "Sweden", + "chCountryDisplayName": "Switzerland", + "syCountryDisplayName": "Syria", + "twCountryDisplayName": "Taiwan", + "tjCountryDisplayName": "Tajikistan", + "tzCountryDisplayName": "Tanzania", + "thCountryDisplayName": "Thailand", + "tgCountryDisplayName": "Togo", + "tkCountryDisplayName": "Tokelau", + "toCountryDisplayName": "Tonga", + "ttCountryDisplayName": "Trinidad/Tobago", + "tnCountryDisplayName": "Tunisia", + "trCountryDisplayName": "Turkey", + "tmCountryDisplayName": "Turkmenistan", + "tcCountryDisplayName": "Turks and Caicos Islands", + "tvCountryDisplayName": "Tuvalu", + "viCountryDisplayName": "U.S. Virgin Islands", + "ugCountryDisplayName": "Uganda", + "uaCountryDisplayName": "Ukraine", + "aeCountryDisplayName": "United Arab Emirates", + "gbCountryDisplayName": "United Kingdom", + "usCountryDisplayName": "United States", + "uyCountryDisplayName": "Uruguay", + "uzCountryDisplayName": "Uzbekistan", + "vuCountryDisplayName": "Vanuatu", + "vaCountryDisplayName": "Vatican City", + "veCountryDisplayName": "Venezuela", + "vnCountryDisplayName": "Vietnam", + "wfCountryDisplayName": "Wallis and Futuna", + "ehCountryDisplayName": "Western Sahara", + "yeCountryDisplayName": "Yemen", + "zmCountryDisplayName": "Zambia", + "zwCountryDisplayName": "Zimbabwe", + "pay": "Pay", + "allPrivateChats": "All private chats in space (including with Pangea Bot)", + "unknownPrivateChat": "Unknown private chat", + "copyClassCodeDesc": "Students who are already in the app can 'Join class or exchange' via the main menu.", + "addToClass": "Add exchange to class", + "addToClassDesc": "Adding an exchange to a class will make the exchange appear within the class for students and give them access to all chats within the exchange.", + "addToClassOrExchange": "Add chat to class or exchange", + "addToClassOrExchangeDesc": + "Adding a chat to a class or exchange will make the chat appear within the class or exchange for students and give them access.", + "invitedToClassOrExchange": "{user} has invited you to join a space: {classOrExchange}! Do you wish to accept?", + "@invitedToClassOrExchange": { + "placeholders": { + "classOrExchange": {}, + "user": {} + } + }, + "decline": "Decline", + "declinedInvitation": "Declined invitation", + "acceptedInvitation": "Accepted invitation", + "youreInvited": "📩 You're invited!", + "studentPermissionsDesc": "Set permissions for this space. They will only apply to the class/exchange space. They will override individual user settings.", + "noEligibleSpaces": "There are no eligible spaces to add this to.", + "youAddedToSpace": "You added {child} to {space}", + "@youAddedToSpace": { + "placeholders": { + "child": {}, + "space": {} + } + }, + "youRemovedFromSpace": "You removed {child} from {space}", + "@youRemovedFromSpace": { + "placeholders": { + "child": {}, + "space": {} + } + }, + "invitedToChat": "{user} has invited you to join a chat: {name}! Do you wish to accept?", + "@invitedToChat": { + "placeholders": { + "name": {}, + "user": {} + } + }, + "monthlySubscription": "Monthly", + "yearlySubscription": "Yearly", + "defaultSubscription": "Pangea Chat Subscription", + "freeTrial": "Free Trial", + "grammarAnalytics": "Error Analytics", + "total": "Total: ", + "noDataFound": "No data found", + "promoSubscriptionExpirationDesc": "Your current subscription is promotional and expires on {expiration}. Message support@pangea.chat for help changing your subscription.", + "@promoSubscriptionExpirationDesc": { + "placeholders": { + "expiration": {} + } + }, + "emptyChatNameWarning": "Please enter a name for this chat", + "emptyClassNameWarning": "Please enter a name for this class", + "emptyExchangeNameWarning": "Please enter a name for this exchange", + "blurMeansTranslateTitle": "Why is the message blurred?", + "blurMeansTranslateBody": "While Immersion Mode is on, messages that are sent in your base language will be blurred while Pangea Bot translates them to your target language. Immersion Mode can be toggled in individual and class settings.", + "someErrorTitle": "Hm, something's not right", + "someErrorBody": "It could be an error or something in your base language.", + "bestCorrectionFeedback": "That's correct!", + "distractorFeedback": "That's not quite right.", + "bestAnswerFeedback": "That's correct!", + "definitionDefaultPrompt": "What does this word mean?", + "practiceDefaultPrompt": "What is the best answer?", + "correctionDefaultPrompt": "What is the best correction?", + "itStartDefaultPrompt": "Do you want help translating?", + "languageLevelWarning": "Please select a class language level", + "lockedChatWarning": "🔒 This chat has been locked", + "lockSpace": "Lock Space", + "lockChat": "Lock Chat", + "archiveSpace": "Archive Space", + "suggestTo": "Suggest to {spaceName}", + "@suggestTo": { + "placeholders": { + "spaceName": {} + } + }, + "suggestChatDesc": "Suggested chats will appear in the chat list for {spaceName}", + "@suggestToDesc": { + "placeholders": { + "spaceName": {} + } + }, + "suggestExchangeDesc": "Suggested exchanges will appear in the chat list for {spaceName}", + "@suggestToExchangeDesc": { + "placeholders": { + "spaceName": {} + } + }, + "acceptSelection": "Accept Correction", + "acceptSelectionAnyway": "Use this anyway", + "replace": "Make correction", + "makingActivity": "Making activity", + "why": "Why?", + "definition": "Definition", + "exampleSentence": "Example Sentence", + "addToClassTitle": "Add Exchange to Class", + "reportToTeacher": "Who do you want to report this message to?", + "reportMessageTitle": "{reportingUserId} has reported a message from {reportedUserId} in the chat {roomName}", + "@reportMessageTitle": { + "placeholders": { + "reportingUserId": {}, + "reportedUserId": {}, + "roomName": {} + } + }, + "reportMessageBody": "Message: {reportedMessage}\nReason: {reason}", + "@reportMessageBody": { + "placeholders": { + "reportedMessage": {}, + "reason": {} + } + }, + "noTeachersFound": "No teachers found to report to", + "pushNotificationsNotAvailable": "Push notifications not available", + "learnMore": "Learn more", + "banUserDescription": "The user will be banned from the chat and will not be able to enter the chat again until they are unbanned.", + "unbanUserDescription": "The user will be able to enter the chat again if they try.", + "kickUserDescription": "The user is kicked out of the chat but not banned. In public chats, the user can rejoin at any time.", + "makeAdminDescription": "Once you make this user admin, you may not be able to undo this as they will then have the same permissions as you.", + "pleaseEnterANumber": "Please enter a number greater than 0", + "archiveRoomDescription": "The chat will be moved to the archive. Other users will be able to see that you have left the chat.", + "roomUpgradeDescription": "The chat will then be recreated with the new room version. All participants will be notified that they need to switch to the new chat. You can find out more about room versions at https://spec.matrix.org/latest/rooms/", + "removeDevicesDescription": "You will be logged out of this device and will no longer be able to receive messages.", + "banUserDescription": "The user will be banned from the chat and will not be able to enter the chat again until they are unbanned.", + "unbanUserDescription": "The user will be able to enter the chat again if they try.", + "kickUserDescription": "The user is kicked out of the chat but not banned. In public chats, the user can rejoin at any time.", + "makeAdminDescription": "Once you make this user admin, you may not be able to undo this as they will then have the same permissions as you.", + "pushNotificationsNotAvailable": "Push notifications not available", + "learnMore": "Learn more", + "todoLists": "(Beta) Todolists", + "newTodo": "New todo", + "noTodosYet": "No todos have been added to this chat yet. Create your first todo and start cooperating with others. 📝", + "editTodo": "Edit todo", + "pleaseAddATitle": "Please add a title", + "todoListChangedError": "Oops... The todo list has been changed while you edited it.", + "todosUnencrypted": "Please notice that todos are visible by everyone in the chat and are not end to end encrypted.", + "noAddToSpacePermissions": "You can't add a chat to this space", + "alreadyInSpace": "The chat is already in this space", + "yourGlobalUserIdIs": "Your global user-ID is: ", + "noUsersFoundWithQuery": "Unfortunately no user could be found with \"{query}\". Please check whether you made a typo.", + "@noUsersFoundWithQuery": { "type": "text", "placeholders": { - "seconds": {} + "query": {} } - } + }, + "searchChatsRooms": "Search for #chats, @users...", + "groupName": "Group name", + "createGroupAndInviteUsers": "Create a group and invite users", + "groupCanBeFoundViaSearch": "Group can be found via search", + "inNoSpaces": "You are not a member of any classes or exchanges" } diff --git a/assets/l10n/intl_eo.arb b/assets/l10n/intl_eo.arb index 523374e4b..946c58f96 100644 --- a/assets/l10n/intl_eo.arb +++ b/assets/l10n/intl_eo.arb @@ -1,2036 +1,2658 @@ { - "@@last_modified": "2021-08-14 12:41:10.107750", - "about": "Prio", - "@about": { - "type": "text", - "placeholders": {} - }, - "accept": "Akcepti", - "@accept": { - "type": "text", - "placeholders": {} - }, - "acceptedTheInvitation": "{username} akceptis la inviton", - "@acceptedTheInvitation": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "account": "Konto", - "@account": { - "type": "text", - "placeholders": {} - }, - "activatedEndToEndEncryption": "{username} aktivigis tutvojan ĉifradon", - "@activatedEndToEndEncryption": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "addEmail": "Aldoni retpoŝtadreson", - "@addEmail": { - "type": "text", - "placeholders": {} - }, - "addGroupDescription": "Aldoni priskribon de grupo", - "@addGroupDescription": { - "type": "text", - "placeholders": {} - }, - "admin": "Administranto", - "@admin": { - "type": "text", - "placeholders": {} - }, - "alias": "kromnomo", - "@alias": { - "type": "text", - "placeholders": {} - }, - "all": "Ĉio", - "@all": { - "type": "text", - "placeholders": {} - }, - "allChats": "Ĉiuj babiloj", - "@allChats": { - "type": "text", - "placeholders": {} - }, - "answeredTheCall": "{senderName} respondis la vokon", - "@answeredTheCall": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "anyoneCanJoin": "Ĉiu ajn povas aliĝi", - "@anyoneCanJoin": { - "type": "text", - "placeholders": {} - }, - "appLock": "Ŝlosado", - "@appLock": { - "type": "text", - "placeholders": {} - }, - "archive": "Arĥivo", - "@archive": { - "type": "text", - "placeholders": {} - }, - "areGuestsAllowedToJoin": "Ĉu gastoj rajtas aliĝi", - "@areGuestsAllowedToJoin": { - "type": "text", - "placeholders": {} - }, - "areYouSure": "Ĉu vi certas?", - "@areYouSure": { - "type": "text", - "placeholders": {} - }, - "areYouSureYouWantToLogout": "Ĉu vi certe volas adiaŭi?", - "@areYouSureYouWantToLogout": { - "type": "text", - "placeholders": {} - }, - "askSSSSSign": "Por ke vi povu kontroli (subskribi) la alian personon, bonvolu enigi pasfrazon de via sekreta deponejo aŭ vian rehavan ŝlosilon.", - "@askSSSSSign": { - "type": "text", - "placeholders": {} - }, - "askVerificationRequest": "Ĉu akcepti ĉi tiun kontrolpeton de {username}?", - "@askVerificationRequest": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "badServerLoginTypesException": "La hejmservilo subtenas la jenajn specojn de salutoj:\n{serverVersions}\nSed ĉi tiu aplikaĵo subtenas nur:\n{supportedVersions}", - "@badServerLoginTypesException": { - "type": "text", - "placeholders": { - "serverVersions": {}, - "supportedVersions": {} - } - }, - "badServerVersionsException": "La hejmservilo subtenas la jenajn version de la specifaĵo:\n{serverVersions}\nSed ĉi tiu aplikaĵo subtenas nur {supportedVersions}", - "@badServerVersionsException": { - "type": "text", - "placeholders": { - "serverVersions": {}, - "supportedVersions": {} - } - }, - "banFromChat": "Forbari de babilo", - "@banFromChat": { - "type": "text", - "placeholders": {} - }, - "banned": "Forbarita", - "@banned": { - "type": "text", - "placeholders": {} - }, - "bannedUser": "{username} forbaris uzanton {targetName}", - "@bannedUser": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "blockDevice": "Bloki aparaton", - "@blockDevice": { - "type": "text", - "placeholders": {} - }, - "blocked": "Blokita", - "@blocked": { - "type": "text", - "placeholders": {} - }, - "botMessages": "Mesaĝoj de robotoj", - "@botMessages": { - "type": "text", - "placeholders": {} - }, - "cancel": "Nuligi", - "@cancel": { - "type": "text", - "placeholders": {} - }, - "cantOpenUri": "Ne povis malfermi URI {uri}", - "@cantOpenUri": { - "type": "text", - "placeholders": { - "uri": {} - } - }, - "changeDeviceName": "Ŝanĝi nomon de aparato", - "@changeDeviceName": { - "type": "text", - "placeholders": {} - }, - "changedTheChatAvatar": "{username} ŝanĝis bildon de la babilo", - "@changedTheChatAvatar": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheChatDescriptionTo": "{username} ŝanĝis priskribon de la babilo al: «{description}»", - "@changedTheChatDescriptionTo": { - "type": "text", - "placeholders": { - "username": {}, - "description": {} - } - }, - "changedTheChatNameTo": "{username} ŝanĝis nomon de la babilo al: «{chatname}»", - "@changedTheChatNameTo": { - "type": "text", - "placeholders": { - "username": {}, - "chatname": {} - } - }, - "changedTheChatPermissions": "{username} ŝanĝis permesojn pri la babilo", - "@changedTheChatPermissions": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheDisplaynameTo": "{username} ŝanĝis sian prezentan nomon al: {username}", - "@changedTheDisplaynameTo": { - "type": "text", - "placeholders": { - "username": {}, - "displayname": {} - } - }, - "changedTheGuestAccessRules": "{username} ŝanĝis regulojn pri aliro de gastoj", - "@changedTheGuestAccessRules": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheGuestAccessRulesTo": "{username} ŝanĝis regulojn pri aliro de gastoj al: {rules}", - "@changedTheGuestAccessRulesTo": { - "type": "text", - "placeholders": { - "username": {}, - "rules": {} - } - }, - "changedTheHistoryVisibility": "{username} ŝanĝis videblecon de la historio", - "@changedTheHistoryVisibility": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheHistoryVisibilityTo": "{username} ŝanĝis videblecon de la historio al: {rules}", - "@changedTheHistoryVisibilityTo": { - "type": "text", - "placeholders": { - "username": {}, - "rules": {} - } - }, - "changedTheJoinRules": "{username} ŝanĝis regulojn pri aliĝado", - "@changedTheJoinRules": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheJoinRulesTo": "{username} ŝanĝis regulojn pri aliĝado al: {joinRules}", - "@changedTheJoinRulesTo": { - "type": "text", - "placeholders": { - "username": {}, - "joinRules": {} - } - }, - "changedTheProfileAvatar": "{username} ŝanĝis sian profilbildon", - "@changedTheProfileAvatar": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheRoomAliases": "{username} ŝanĝis la kromnomojn de la ĉambro", - "@changedTheRoomAliases": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheRoomInvitationLink": "{username} ŝanĝis la invitan ligilon", - "@changedTheRoomInvitationLink": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changePassword": "Ŝanĝi pasvorton", - "@changePassword": { - "type": "text", - "placeholders": {} - }, - "changeTheHomeserver": "Ŝanĝi hejmservilon", - "@changeTheHomeserver": { - "type": "text", - "placeholders": {} - }, - "changeTheme": "Ŝanĝu la haŭton", - "@changeTheme": { - "type": "text", - "placeholders": {} - }, - "changeTheNameOfTheGroup": "Ŝanĝi nomon de la grupo", - "@changeTheNameOfTheGroup": { - "type": "text", - "placeholders": {} - }, - "changeWallpaper": "Ŝanĝi fonbildon", - "@changeWallpaper": { - "type": "text", - "placeholders": {} - }, - "changeYourAvatar": "Ŝanĝi vian profilbildon", - "@changeYourAvatar": { - "type": "text", - "placeholders": {} - }, - "channelCorruptedDecryptError": "La ĉifrado estas difektita", - "@channelCorruptedDecryptError": { - "type": "text", - "placeholders": {} - }, - "chat": "Babilo", - "@chat": { - "type": "text", - "placeholders": {} - }, - "chatBackup": "Savkopiado de babilo", - "@chatBackup": { - "type": "text", - "placeholders": {} - }, - "chatBackupDescription": "Via savkopio de babilo estas sekurigita per sekureca ŝlosilo. Bonvolu certigi, ke vi ne perdos ĝin.", - "@chatBackupDescription": { - "type": "text", - "placeholders": {} - }, - "chatDetails": "Detaloj pri babilo", - "@chatDetails": { - "type": "text", - "placeholders": {} - }, - "chats": "Babiloj", - "@chats": { - "type": "text", - "placeholders": {} - }, - "chooseAStrongPassword": "Elektu fortan pasvorton", - "@chooseAStrongPassword": { - "type": "text", - "placeholders": {} - }, - "chooseAUsername": "Elektu uzantonomon", - "@chooseAUsername": { - "type": "text", - "placeholders": {} - }, - "clearArchive": "Vakigi arĥivon", - "@clearArchive": {}, - "close": "Fermi", - "@close": { - "type": "text", - "placeholders": {} - }, - "commandHint_ban": "Forbari la donitan uzanton de ĉi tiu ĉambro", - "@commandHint_ban": { - "type": "text", - "description": "Usage hint for the command /ban" - }, - "commandHint_html": "Sendi tekston formatan je HTML", - "@commandHint_html": { - "type": "text", - "description": "Usage hint for the command /html" - }, - "commandHint_invite": "Inviti la donitan uzanton al ĉi tiu ĉambro", - "@commandHint_invite": { - "type": "text", - "description": "Usage hint for the command /invite" - }, - "commandHint_join": "Aliĝi al la donita ĉambro", - "@commandHint_join": { - "type": "text", - "description": "Usage hint for the command /join" - }, - "commandHint_kick": "Forigi la donitan uzanton de ĉi tiu ĉambro", - "@commandHint_kick": { - "type": "text", - "description": "Usage hint for the command /kick" - }, - "commandHint_leave": "Foriri de ĉi tiu ĉambro", - "@commandHint_leave": { - "type": "text", - "description": "Usage hint for the command /leave" - }, - "commandHint_me": "Priskribu vian agon", - "@commandHint_me": { - "type": "text", - "description": "Usage hint for the command /me" - }, - "commandHint_myroomavatar": "Agordi vian profilbildon por ĉi tiu ĉambro (laŭ mxc-uri)", - "@commandHint_myroomavatar": { - "type": "text", - "description": "Usage hint for the command /myroomavatar" - }, - "commandHint_myroomnick": "Agordi vian prezentan nomon en ĉi tiu ĉambro", - "@commandHint_myroomnick": { - "type": "text", - "description": "Usage hint for the command /myroomnick" - }, - "commandHint_op": "Agordi povnivelon de la donita uzanto (implicite: 50)", - "@commandHint_op": { - "type": "text", - "description": "Usage hint for the command /op" - }, - "commandHint_plain": "Sendi senformatan tekston", - "@commandHint_plain": { - "type": "text", - "description": "Usage hint for the command /plain" - }, - "commandHint_react": "Sendi respondon kiel reagon", - "@commandHint_react": { - "type": "text", - "description": "Usage hint for the command /react" - }, - "commandHint_unban": "Malforbari la donitan uzanton de ĉi tiu ĉambro", - "@commandHint_unban": { - "type": "text", - "description": "Usage hint for the command /unban" - }, - "commandInvalid": "Nevalida ordono", - "@commandInvalid": { - "type": "text" - }, - "commandMissing": "{command} ne estas ordono.", - "@commandMissing": { - "type": "text", - "placeholders": { - "command": {} - }, - "description": "State that {command} is not a valid /command." - }, - "compareEmojiMatch": "Komparu kaj certigu, ke la jenaj bildosignoj samas en ambaŭ aparatoj:", - "@compareEmojiMatch": { - "type": "text", - "placeholders": {} - }, - "compareNumbersMatch": "Komparu kaj certigu, ke la jenaj numeroj samas en ambaŭ aparatoj:", - "@compareNumbersMatch": { - "type": "text", - "placeholders": {} - }, - "configureChat": "Agordi babilon", - "@configureChat": { - "type": "text", - "placeholders": {} - }, - "confirm": "Konfirmi", - "@confirm": { - "type": "text", - "placeholders": {} - }, - "connect": "Konektiĝi", - "@connect": { - "type": "text", - "placeholders": {} - }, - "contactHasBeenInvitedToTheGroup": "Kontakto invitiĝis al la grupo", - "@contactHasBeenInvitedToTheGroup": { - "type": "text", - "placeholders": {} - }, - "containsDisplayName": "Enhavas prezentan nomon", - "@containsDisplayName": { - "type": "text", - "placeholders": {} - }, - "containsUserName": "Enhavas uzantonomon", - "@containsUserName": { - "type": "text", - "placeholders": {} - }, - "contentHasBeenReported": "La enhavo raportiĝis al la administrantoj de la servilo", - "@contentHasBeenReported": { - "type": "text", - "placeholders": {} - }, - "copiedToClipboard": "Kopiite al tondujo", - "@copiedToClipboard": { - "type": "text", - "placeholders": {} - }, - "copy": "Kopii", - "@copy": { - "type": "text", - "placeholders": {} - }, - "copyToClipboard": "Kopii al tondujo", - "@copyToClipboard": { - "type": "text", - "placeholders": {} - }, - "couldNotDecryptMessage": "Ne povis malĉifri mesaĝon: {error}", - "@couldNotDecryptMessage": { - "type": "text", - "placeholders": { - "error": {} - } - }, - "countParticipants": "{count} partoprenantoj", - "@countParticipants": { - "type": "text", - "placeholders": { - "count": {} - } - }, - "create": "Krei", - "@create": { - "type": "text", - "placeholders": {} - }, - "createdTheChat": "{username} kreis la babilon", - "@createdTheChat": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "createNewGroup": "Krei novan grupon", - "@createNewGroup": { - "type": "text", - "placeholders": {} - }, - "createNewSpace": "Nova aro", - "@createNewSpace": { - "type": "text", - "placeholders": {} - }, - "currentlyActive": "Nun aktiva", - "@currentlyActive": { - "type": "text", - "placeholders": {} - }, - "darkTheme": "Malhela", - "@darkTheme": { - "type": "text", - "placeholders": {} - }, - "dateAndTimeOfDay": "{date}, {timeOfDay}", - "@dateAndTimeOfDay": { - "type": "text", - "placeholders": { - "date": {}, - "timeOfDay": {} - } - }, - "dateWithoutYear": "{day}a de la {month}a", - "@dateWithoutYear": { - "type": "text", - "placeholders": { - "month": {}, - "day": {} - } - }, - "dateWithYear": "{day}a de la {month}a de {year}", - "@dateWithYear": { - "type": "text", - "placeholders": { - "year": {}, - "month": {}, - "day": {} - } - }, - "deactivateAccountWarning": "Ĉi tio malaktivigos vian konton de uzanto. Ne eblas tion malfari! Ĉu certe vi certas?", - "@deactivateAccountWarning": { - "type": "text", - "placeholders": {} - }, - "defaultPermissionLevel": "Norma nivelo de permesoj", - "@defaultPermissionLevel": { - "type": "text", - "placeholders": {} - }, - "delete": "Forigi", - "@delete": { - "type": "text", - "placeholders": {} - }, - "deleteAccount": "Forigi konton", - "@deleteAccount": { - "type": "text", - "placeholders": {} - }, - "deleteMessage": "Forigi mesaĝon", - "@deleteMessage": { - "type": "text", - "placeholders": {} - }, - "deny": "Malakcepti", - "@deny": { - "type": "text", - "placeholders": {} - }, - "device": "Aparato", - "@device": { - "type": "text", - "placeholders": {} - }, - "deviceId": "Identigilo de aparato", - "@deviceId": { - "type": "text", - "placeholders": {} - }, - "devices": "Aparatoj", - "@devices": { - "type": "text", - "placeholders": {} - }, - "directChats": "Rektaj babiloj", - "@directChats": { - "type": "text", - "placeholders": {} - }, - "displaynameHasBeenChanged": "Prezenta nomo ŝanĝiĝis", - "@displaynameHasBeenChanged": { - "type": "text", - "placeholders": {} - }, - "downloadFile": "Elŝuti dosieron", - "@downloadFile": { - "type": "text", - "placeholders": {} - }, - "edit": "Redakti", - "@edit": { - "type": "text", - "placeholders": {} - }, - "editBlockedServers": "Redakti blokitajn servilojn", - "@editBlockedServers": { - "type": "text", - "placeholders": {} - }, - "editChatPermissions": "Redakti permesojn de babilo", - "@editChatPermissions": { - "type": "text", - "placeholders": {} - }, - "editDisplayname": "Redakti prezentan nomon", - "@editDisplayname": { - "type": "text", - "placeholders": {} - }, - "editRoomAliases": "Ŝanĝi kromnomojn de ĉambro", - "@editRoomAliases": { - "type": "text", - "placeholders": {} - }, - "editRoomAvatar": "Redakti bildon de ĉambro", - "@editRoomAvatar": { - "type": "text", - "placeholders": {} - }, - "emoteExists": "Mieneto jam ekzistas!", - "@emoteExists": { - "type": "text", - "placeholders": {} - }, - "emoteInvalid": "Nevalida mallongigo de mieneto!", - "@emoteInvalid": { - "type": "text", - "placeholders": {} - }, - "emotePacks": "Mienetaroj por la ĉambro", - "@emotePacks": { - "type": "text", - "placeholders": {} - }, - "emoteSettings": "Agordoj pri mienetoj", - "@emoteSettings": { - "type": "text", - "placeholders": {} - }, - "emoteShortcode": "Mallongigo de mieneto", - "@emoteShortcode": { - "type": "text", - "placeholders": {} - }, - "emoteWarnNeedToPick": "Vi devas elekti mallongigon de mieneto kaj bildon!", - "@emoteWarnNeedToPick": { - "type": "text", - "placeholders": {} - }, - "emptyChat": "Malplena babilo", - "@emptyChat": { - "type": "text", - "placeholders": {} - }, - "enableEmotesGlobally": "Ŝalti mienetaron ĉie", - "@enableEmotesGlobally": { - "type": "text", - "placeholders": {} - }, - "enableEncryption": "Ŝalti ĉifradon", - "@enableEncryption": { - "type": "text", - "placeholders": {} - }, - "enableEncryptionWarning": "Vi ne povos malŝalti la ĉifradon. Ĉu vi certas?", - "@enableEncryptionWarning": { - "type": "text", - "placeholders": {} - }, - "encrypted": "Ĉifrite", - "@encrypted": { - "type": "text", - "placeholders": {} - }, - "encryption": "Ĉifrado", - "@encryption": { - "type": "text", - "placeholders": {} - }, - "encryptionNotEnabled": "Ĉifrado ne estas ŝaltita", - "@encryptionNotEnabled": { - "type": "text", - "placeholders": {} - }, - "endedTheCall": "{senderName} finis la vokon", - "@endedTheCall": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "enterAGroupName": "Enigu nomon de grupo", - "@enterAGroupName": { - "type": "text", - "placeholders": {} - }, - "enterAnEmailAddress": "Enigu retpoŝtadreson", - "@enterAnEmailAddress": { - "type": "text", - "placeholders": {} - }, - "enterASpacepName": "Enigi nomon de aro", - "@enterASpacepName": {}, - "enterYourHomeserver": "Enigu vian hejmservilon", - "@enterYourHomeserver": { - "type": "text", - "placeholders": {} - }, - "errorObtainingLocation": "Eraris akirado de loko: {error}", - "@errorObtainingLocation": { - "type": "text", - "placeholders": { - "error": {} - } - }, - "everythingReady": "Ĉio pretas!", - "@everythingReady": { - "type": "text", - "placeholders": {} - }, - "extremeOffensive": "Tre ofenda", - "@extremeOffensive": { - "type": "text", - "placeholders": {} - }, - "fileName": "Dosiernomo", - "@fileName": { - "type": "text", - "placeholders": {} - }, - "fluffychat": "FluffyChat", - "@fluffychat": { - "type": "text", - "placeholders": {} - }, - "fontSize": "Grandeco de tiparo", - "@fontSize": { - "type": "text", - "placeholders": {} - }, - "forward": "Plusendi", - "@forward": { - "type": "text", - "placeholders": {} - }, - "fromJoining": "Ekde aliĝo", - "@fromJoining": { - "type": "text", - "placeholders": {} - }, - "fromTheInvitation": "Ekde la invito", - "@fromTheInvitation": { - "type": "text", - "placeholders": {} - }, - "goToTheNewRoom": "Iri al la nova ĉambro", - "@goToTheNewRoom": { - "type": "text", - "placeholders": {} - }, - "group": "Grupo", - "@group": { - "type": "text", - "placeholders": {} - }, - "groupDescription": "Priskribo de grupo", - "@groupDescription": { - "type": "text", - "placeholders": {} - }, - "groupDescriptionHasBeenChanged": "Priskribo de grupo ŝanĝiĝis", - "@groupDescriptionHasBeenChanged": { - "type": "text", - "placeholders": {} - }, - "groupIsPublic": "Grupo estas publika", - "@groupIsPublic": { - "type": "text", - "placeholders": {} - }, - "groups": "Grupoj", - "@groups": { - "type": "text", - "placeholders": {} - }, - "groupWith": "Grupo kun {displayname}", - "@groupWith": { - "type": "text", - "placeholders": { - "displayname": {} - } - }, - "guestsAreForbidden": "Gastoj estas malpermesitaj", - "@guestsAreForbidden": { - "type": "text", - "placeholders": {} - }, - "guestsCanJoin": "Gastoj povas aliĝi", - "@guestsCanJoin": { - "type": "text", - "placeholders": {} - }, - "hasWithdrawnTheInvitationFor": "{username} nuligis la inviton por {targetName}", - "@hasWithdrawnTheInvitationFor": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "help": "Helpo", - "@help": { - "type": "text", - "placeholders": {} - }, - "hideRedactedEvents": "Kaŝi obskurigitajn eventojn", - "@hideRedactedEvents": { - "type": "text", - "placeholders": {} - }, - "hideUnknownEvents": "Kaŝi nekonatajn eventojn", - "@hideUnknownEvents": { - "type": "text", - "placeholders": {} - }, - "howOffensiveIsThisContent": "Kiel ofenda estas ĉi tiu enhavo?", - "@howOffensiveIsThisContent": { - "type": "text", - "placeholders": {} - }, - "id": "Identigilo", - "@id": { - "type": "text", - "placeholders": {} - }, - "identity": "Identeco", - "@identity": { - "type": "text", - "placeholders": {} - }, - "ignore": "Malatenti", - "@ignore": { - "type": "text", - "placeholders": {} - }, - "ignoredUsers": "Malatentitaj uzantoj", - "@ignoredUsers": { - "type": "text", - "placeholders": {} - }, - "ignoreListDescription": "Vi povas malatenti uzantojn, kiuj vin ĝenas. Vi ne povos ricevi mesaĝojn nek invitojn al ĉambroj de la uzantoj sur via listo de malatentatoj.", - "@ignoreListDescription": { - "type": "text", - "placeholders": {} - }, - "ignoreUsername": "Malatenti uzantonomon", - "@ignoreUsername": { - "type": "text", - "placeholders": {} - }, - "iHaveClickedOnLink": "Mi klakis la ligilon", - "@iHaveClickedOnLink": { - "type": "text", - "placeholders": {} - }, - "incorrectPassphraseOrKey": "Neĝusta pasfrazo aŭ rehava ŝlosilo", - "@incorrectPassphraseOrKey": { - "type": "text", - "placeholders": {} - }, - "inoffensive": "Neofenda", - "@inoffensive": { - "type": "text", - "placeholders": {} - }, - "inviteContact": "Inviti kontakton", - "@inviteContact": { - "type": "text", - "placeholders": {} - }, - "inviteContactToGroup": "Inviti kontakton al {groupName}", - "@inviteContactToGroup": { - "type": "text", - "placeholders": { - "groupName": {} - } - }, - "invited": "Invitita", - "@invited": { - "type": "text", - "placeholders": {} - }, - "invitedUser": "{username} invitis uzanton {targetName}", - "@invitedUser": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "invitedUsersOnly": "Nur invititoj", - "@invitedUsersOnly": { - "type": "text", - "placeholders": {} - }, - "inviteForMe": "Invito por mi", - "@inviteForMe": { - "type": "text", - "placeholders": {} - }, - "inviteText": "{username} invitis vin al FluffyChat. \n1. Instalu la aplikaĵon FluffyChat: https://fluffychat.im \n2. Registriĝu aŭ salutu \n3. Malfermu la invitan ligilon: {link}", - "@inviteText": { - "type": "text", - "placeholders": { - "username": {}, - "link": {} - } - }, - "isTyping": "tajpas…", - "@isTyping": { - "type": "text", - "placeholders": {} - }, - "joinedTheChat": "{username} aliĝis al la babilo", - "@joinedTheChat": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "joinRoom": "Aliĝi al ĉambro", - "@joinRoom": { - "type": "text", - "placeholders": {} - }, - "kicked": "{username} forpelis uzanton {targetName}", - "@kicked": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "kickedAndBanned": "{username} forpelis kaj forbaris uzanton {targetName}", - "@kickedAndBanned": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "kickFromChat": "Forpeli de babilo", - "@kickFromChat": { - "type": "text", - "placeholders": {} - }, - "lastActiveAgo": "Lastafoje aktiva: {localizedTimeShort}", - "@lastActiveAgo": { - "type": "text", - "placeholders": { - "localizedTimeShort": {} - } - }, - "lastSeenLongTimeAgo": "Vidita antaŭ longe", - "@lastSeenLongTimeAgo": { - "type": "text", - "placeholders": {} - }, - "leave": "Foriri", - "@leave": { - "type": "text", - "placeholders": {} - }, - "leftTheChat": "Foriris de la ĉambro", - "@leftTheChat": { - "type": "text", - "placeholders": {} - }, - "license": "Permesilo", - "@license": { - "type": "text", - "placeholders": {} - }, - "lightTheme": "Hela", - "@lightTheme": { - "type": "text", - "placeholders": {} - }, - "loadCountMoreParticipants": "Enlegi {count} pliajn partoprenantojn", - "@loadCountMoreParticipants": { - "type": "text", - "placeholders": { - "count": {} - } - }, - "loadingPleaseWait": "Enlegante… bonvolu atendi.", - "@loadingPleaseWait": { - "type": "text", - "placeholders": {} - }, - "loadMore": "Enlegi pli…", - "@loadMore": { - "type": "text", - "placeholders": {} - }, - "login": "Saluti", - "@login": { - "type": "text", - "placeholders": {} - }, - "logInTo": "Saluti servilon {homeserver}", - "@logInTo": { - "type": "text", - "placeholders": { - "homeserver": {} - } - }, - "loginWith": "Saluti per {brand}", - "@loginWith": { - "type": "text", - "placeholders": { - "brand": {} - } - }, - "logout": "Adiaŭi", - "@logout": { - "type": "text", - "placeholders": {} - }, - "makeSureTheIdentifierIsValid": "Certigu, ke la identigilo estas valida", - "@makeSureTheIdentifierIsValid": { - "type": "text", - "placeholders": {} - }, - "memberChanges": "Ŝanĝoj de anoj", - "@memberChanges": { - "type": "text", - "placeholders": {} - }, - "mention": "Mencii", - "@mention": { - "type": "text", - "placeholders": {} - }, - "messages": "Mesaĝoj", - "@messages": { - "type": "text", - "placeholders": {} - }, - "messageWillBeRemovedWarning": "Mesaĝo foriĝos por ĉiuj partoprenantoj", - "@messageWillBeRemovedWarning": { - "type": "text", - "placeholders": {} - }, - "moderator": "Reguligisto", - "@moderator": { - "type": "text", - "placeholders": {} - }, - "muteChat": "Silentigi babilon", - "@muteChat": { - "type": "text", - "placeholders": {} - }, - "needPantalaimonWarning": "Bonvolu scii, ke vi ankoraŭ bezonas la programon Pantalaimon por uzi tutvojan ĉifradon.", - "@needPantalaimonWarning": { - "type": "text", - "placeholders": {} - }, - "newChat": "Nova babilo", - "@newChat": { - "type": "text", - "placeholders": {} - }, - "newMessageInFluffyChat": "Nova mesaĝo en FluffyChat", - "@newMessageInFluffyChat": { - "type": "text", - "placeholders": {} - }, - "newVerificationRequest": "Nova kontrolpeto!", - "@newVerificationRequest": { - "type": "text", - "placeholders": {} - }, - "next": "Sekva", - "@next": { - "type": "text", - "placeholders": {} - }, - "no": "Ne", - "@no": { - "type": "text", - "placeholders": {} - }, - "noConnectionToTheServer": "Neniu konekto al la servilo", - "@noConnectionToTheServer": { - "type": "text", - "placeholders": {} - }, - "noEmotesFound": "Neniuj mienetoj troviĝis. 😕", - "@noEmotesFound": { - "type": "text", - "placeholders": {} - }, - "noEncryptionForPublicRooms": "Vi nur povas aktivigi ĉifradon kiam la ĉambro ne plu estas publike alirebla.", - "@noEncryptionForPublicRooms": { - "type": "text", - "placeholders": {} - }, - "noGoogleServicesWarning": "Ŝajnas, ke via telefono ne havas servojn de Google. Tio estas bona decido por via privateco! Por ricevadi pasivajn sciigojn en FluffyChat, ni rekomendas, ke vi uzu la https://microg.org/ aŭ https://unifiedpush.org/.", - "@noGoogleServicesWarning": { - "type": "text", - "placeholders": {} - }, - "none": "Neniu", - "@none": { - "type": "text", - "placeholders": {} - }, - "noPasswordRecoveryDescription": "Vi ankoraŭ ne aldonis manieron rehavi vian pasvorton.", - "@noPasswordRecoveryDescription": { - "type": "text", - "placeholders": {} - }, - "noPermission": "Neniu permeso", - "@noPermission": { - "type": "text", - "placeholders": {} - }, - "noRoomsFound": "Neniuj ĉambroj troviĝis…", - "@noRoomsFound": { - "type": "text", - "placeholders": {} - }, - "notifications": "Sciigoj", - "@notifications": { - "type": "text", - "placeholders": {} - }, - "notificationsEnabledForThisAccount": "Sciigoj ŝaltiĝis por ĉi tiu konto", - "@notificationsEnabledForThisAccount": { - "type": "text", - "placeholders": {} - }, - "numUsersTyping": "{count} uzantoj tajpas…", - "@numUsersTyping": { - "type": "text", - "placeholders": { - "count": {} - } - }, - "obtainingLocation": "Akirante lokon…", - "@obtainingLocation": { - "type": "text", - "placeholders": {} - }, - "offensive": "Ofenda", - "@offensive": { - "type": "text", - "placeholders": {} - }, - "offline": "Eksterrete", - "@offline": { - "type": "text", - "placeholders": {} - }, - "ok": "bone", - "@ok": { - "type": "text", - "placeholders": {} - }, - "online": "Enrete", - "@online": { - "type": "text", - "placeholders": {} - }, - "onlineKeyBackupEnabled": "Enreta savkopiado de ŝlosiloj estas ŝaltita", - "@onlineKeyBackupEnabled": { - "type": "text", - "placeholders": {} - }, - "oopsPushError": "Oj! Bedaŭrinde eraris la agordado de pasivaj sciigoj.", - "@oopsPushError": { - "type": "text", - "placeholders": {} - }, - "oopsSomethingWentWrong": "Oj! Io misokazis…", - "@oopsSomethingWentWrong": { - "type": "text", - "placeholders": {} - }, - "openAppToReadMessages": "Malfermu la aplikaĵon por legi mesaĝojn", - "@openAppToReadMessages": { - "type": "text", - "placeholders": {} - }, - "openCamera": "Malfermi fotilon", - "@openCamera": { - "type": "text", - "placeholders": {} - }, - "optionalGroupName": "(Malnepra) Nomo de grupo", - "@optionalGroupName": { - "type": "text", - "placeholders": {} - }, - "or": "Aŭ", - "@or": { - "type": "text", - "placeholders": {} - }, - "participant": "Partoprenanto", - "@participant": { - "type": "text", - "placeholders": {} - }, - "passphraseOrKey": "pasfrazo aŭ rehava ŝlosilo", - "@passphraseOrKey": { - "type": "text", - "placeholders": {} - }, - "password": "Pasvorto", - "@password": { - "type": "text", - "placeholders": {} - }, - "passwordForgotten": "Forgesita pasvorto", - "@passwordForgotten": { - "type": "text", - "placeholders": {} - }, - "passwordHasBeenChanged": "Pasvorto ŝanĝiĝis", - "@passwordHasBeenChanged": { - "type": "text", - "placeholders": {} - }, - "passwordRecovery": "Rehavo de pasvorto", - "@passwordRecovery": { - "type": "text", - "placeholders": {} - }, - "people": "Personoj", - "@people": { - "type": "text", - "placeholders": {} - }, - "pickImage": "Elekti bildon", - "@pickImage": { - "type": "text", - "placeholders": {} - }, - "pin": "Fiksi", - "@pin": { - "type": "text", - "placeholders": {} - }, - "play": "Ludi {fileName}", - "@play": { - "type": "text", - "placeholders": { - "fileName": {} - } - }, - "pleaseChoose": "Bonvolu elekti", - "@pleaseChoose": { - "type": "text", - "placeholders": {} - }, - "pleaseChooseAPasscode": "Bonvolu elekti paskodon", - "@pleaseChooseAPasscode": { - "type": "text", - "placeholders": {} - }, - "pleaseChooseAUsername": "Bonvolu elekti uzantonomon", - "@pleaseChooseAUsername": { - "type": "text", - "placeholders": {} - }, - "pleaseClickOnLink": "Bonvolu klaki la ligilon en la retletero kaj pluiĝi.", - "@pleaseClickOnLink": { - "type": "text", - "placeholders": {} - }, - "pleaseEnter4Digits": "Bonvolu enigi 4 ciferojn, aŭ nenion por malŝalti ŝlosadon de la aplikaĵo.", - "@pleaseEnter4Digits": { - "type": "text", - "placeholders": {} - }, - "pleaseEnterAMatrixIdentifier": "Bonvolu enigi identigilon de Matrix.", - "@pleaseEnterAMatrixIdentifier": { - "type": "text", - "placeholders": {} - }, - "pleaseEnterYourPassword": "Bonvolu enigi vian pasvorton", - "@pleaseEnterYourPassword": { - "type": "text", - "placeholders": {} - }, - "pleaseEnterYourPin": "Bonvolu enigi vian personan identigan numeron", - "@pleaseEnterYourPin": { - "type": "text", - "placeholders": {} - }, - "pleaseEnterYourUsername": "Bonvolu enigi vian uzantonomon", - "@pleaseEnterYourUsername": { - "type": "text", - "placeholders": {} - }, - "pleaseFollowInstructionsOnWeb": "Bonvolu sekvi la instrukciojn de la retejo kaj tuŝetu al «Sekva».", - "@pleaseFollowInstructionsOnWeb": { - "type": "text", - "placeholders": {} - }, - "privacy": "Privateco", - "@privacy": { - "type": "text", - "placeholders": {} - }, - "publicRooms": "Publikaj ĉambroj", - "@publicRooms": { - "type": "text", - "placeholders": {} - }, - "pushRules": "Reguloj de pasivaj sciigoj", - "@pushRules": { - "type": "text", - "placeholders": {} - }, - "reason": "Kialo", - "@reason": { - "type": "text", - "placeholders": {} - }, - "recording": "Registrante", - "@recording": { - "type": "text", - "placeholders": {} - }, - "redactedAnEvent": "{username} obskurigis eventon", - "@redactedAnEvent": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "redactMessage": "Obskurigi mesaĝon", - "@redactMessage": { - "type": "text", - "placeholders": {} - }, - "register": "Registriĝi", - "@register": { - "type": "text", - "placeholders": {} - }, - "reject": "Rifuzi", - "@reject": { - "type": "text", - "placeholders": {} - }, - "rejectedTheInvitation": "{username} rifuzis la inviton", - "@rejectedTheInvitation": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "rejoin": "Ree aliĝi", - "@rejoin": { - "type": "text", - "placeholders": {} - }, - "remove": "Forigi", - "@remove": { - "type": "text", - "placeholders": {} - }, - "removeAllOtherDevices": "Forigi ĉiujn aliajn aparatojn", - "@removeAllOtherDevices": { - "type": "text", - "placeholders": {} - }, - "removedBy": "Forigita de {username}", - "@removedBy": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "removeDevice": "Forigi aparaton", - "@removeDevice": { - "type": "text", - "placeholders": {} - }, - "unbanFromChat": "Malforbari", - "@unbanFromChat": { - "type": "text", - "placeholders": {} - }, - "removeYourAvatar": "Forigi vian profilbildon", - "@removeYourAvatar": { - "type": "text", - "placeholders": {} - }, - "renderRichContent": "Bildigi riĉforman enhavon de mesaĝoj", - "@renderRichContent": { - "type": "text", - "placeholders": {} - }, - "replaceRoomWithNewerVersion": "Anstataŭigi ĉambron per nova versio", - "@replaceRoomWithNewerVersion": { - "type": "text", - "placeholders": {} - }, - "reply": "Respondi", - "@reply": { - "type": "text", - "placeholders": {} - }, - "reportMessage": "Raporti mesaĝon", - "@reportMessage": { - "type": "text", - "placeholders": {} - }, - "requestPermission": "Peti permeson", - "@requestPermission": { - "type": "text", - "placeholders": {} - }, - "roomHasBeenUpgraded": "Ĉambro gradaltiĝis", - "@roomHasBeenUpgraded": { - "type": "text", - "placeholders": {} - }, - "roomVersion": "Versio de ĉambro", - "@roomVersion": { - "type": "text", - "placeholders": {} - }, - "saveFile": "Konservi dosieron", - "@saveFile": { - "type": "text", - "placeholders": {} - }, - "search": "Serĉi", - "@search": { - "type": "text", - "placeholders": {} - }, - "security": "Sekureco", - "@security": { - "type": "text", - "placeholders": {} - }, - "seenByUser": "Vidita de {username}", - "@seenByUser": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "seenByUserAndCountOthers": "{count, plural, other{Vidita de {username} kaj {count} aliaj}}", - "@seenByUserAndCountOthers": { - "type": "text", - "placeholders": { - "username": {}, - "count": {} - } - }, - "seenByUserAndUser": "Vidita de {username} kaj {username2}", - "@seenByUserAndUser": { - "type": "text", - "placeholders": { - "username": {}, - "username2": {} - } - }, - "send": "Sendi", - "@send": { - "type": "text", - "placeholders": {} - }, - "sendAMessage": "Sendi mesaĝon", - "@sendAMessage": { - "type": "text", - "placeholders": {} - }, - "sendAudio": "Sendi sondosieron", - "@sendAudio": { - "type": "text", - "placeholders": {} - }, - "sendFile": "Sendi dosieron", - "@sendFile": { - "type": "text", - "placeholders": {} - }, - "sendImage": "Sendi bildon", - "@sendImage": { - "type": "text", - "placeholders": {} - }, - "sendMessages": "Sendi mesaĝojn", - "@sendMessages": { - "type": "text", - "placeholders": {} - }, - "sendOriginal": "Sendi originalon", - "@sendOriginal": { - "type": "text", - "placeholders": {} - }, - "sendSticker": "Sendi glumarkon", - "@sendSticker": { - "type": "text", - "placeholders": {} - }, - "sendVideo": "Sendi filmon", - "@sendVideo": { - "type": "text", - "placeholders": {} - }, - "sentAFile": "{username} sendis dosieron", - "@sentAFile": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sentAnAudio": "{username} sendis sondosieron", - "@sentAnAudio": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sentAPicture": "{username} sendis bildon", - "@sentAPicture": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sentASticker": "{username} sendis glumarkon", - "@sentASticker": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sentAVideo": "{username} sendis filmon", - "@sentAVideo": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sentCallInformations": "{senderName} sendis informojn pri voko", - "@sentCallInformations": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "setAsCanonicalAlias": "Agordi kiel ĉefan kromnomon", - "@setAsCanonicalAlias": { - "type": "text", - "placeholders": {} - }, - "setCustomEmotes": "Agordi proprajn mienetojn", - "@setCustomEmotes": { - "type": "text", - "placeholders": {} - }, - "setGroupDescription": "Agordi priskribon de grupo", - "@setGroupDescription": { - "type": "text", - "placeholders": {} - }, - "setInvitationLink": "Agordi invitan ligilon", - "@setInvitationLink": { - "type": "text", - "placeholders": {} - }, - "setPermissionsLevel": "Agordi nivelon de permesoj", - "@setPermissionsLevel": { - "type": "text", - "placeholders": {} - }, - "setStatus": "Agordi staton", - "@setStatus": { - "type": "text", - "placeholders": {} - }, - "settings": "Agordoj", - "@settings": { - "type": "text", - "placeholders": {} - }, - "share": "Konigi", - "@share": { - "type": "text", - "placeholders": {} - }, - "sharedTheLocation": "{username} konigis sian lokon", - "@sharedTheLocation": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "shareLocation": "Konigi lokon", - "@shareLocation": { - "type": "text", - "placeholders": {} - }, - "showPassword": "Montri pasvorton", - "@showPassword": { - "type": "text", - "placeholders": {} - }, - "signUp": "Registriĝi", - "@signUp": { - "type": "text", - "placeholders": {} - }, - "singlesignon": "Ununura saluto", - "@singlesignon": { - "type": "text", - "placeholders": {} - }, - "skip": "Preterpasi", - "@skip": { - "type": "text", - "placeholders": {} - }, - "sourceCode": "Fontkodo", - "@sourceCode": { - "type": "text", - "placeholders": {} - }, - "spaceIsPublic": "Aro estas publika", - "@spaceIsPublic": { - "type": "text", - "placeholders": {} - }, - "spaceName": "Nomo de aro", - "@spaceName": { - "type": "text", - "placeholders": {} - }, - "startedACall": "{senderName} komencis vokon", - "@startedACall": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "status": "Stato", - "@status": { - "type": "text", - "placeholders": {} - }, - "statusExampleMessage": "Kiel vi fartas?", - "@statusExampleMessage": { - "type": "text", - "placeholders": {} - }, - "submit": "Sendi", - "@submit": { - "type": "text", - "placeholders": {} - }, - "synchronizingPleaseWait": "Spegulante… Bonvolu atendi.", - "@synchronizingPleaseWait": { - "type": "text", - "placeholders": {} - }, - "systemTheme": "Sistema", - "@systemTheme": { - "type": "text", - "placeholders": {} - }, - "theyDontMatch": "Ili ne akordas", - "@theyDontMatch": { - "type": "text", - "placeholders": {} - }, - "theyMatch": "Ili akordas", - "@theyMatch": { - "type": "text", - "placeholders": {} - }, - "title": "FluffyChat", - "@title": { - "description": "Title for the application", - "type": "text", - "placeholders": {} - }, - "toggleFavorite": "Baskuli elstarigon", - "@toggleFavorite": { - "type": "text", - "placeholders": {} - }, - "toggleMuted": "Basklui silentigon", - "@toggleMuted": { - "type": "text", - "placeholders": {} - }, - "toggleUnread": "Baskuli legitecon", - "@toggleUnread": { - "type": "text", - "placeholders": {} - }, - "tooManyRequestsWarning": "Tro multaj petoj. Bonvolu reprovi poste!", - "@tooManyRequestsWarning": { - "type": "text", - "placeholders": {} - }, - "transferFromAnotherDevice": "Transporti de alia aparato", - "@transferFromAnotherDevice": { - "type": "text", - "placeholders": {} - }, - "tryToSendAgain": "Reprovi sendi", - "@tryToSendAgain": { - "type": "text", - "placeholders": {} - }, - "unavailable": "Nedisponeble", - "@unavailable": { - "type": "text", - "placeholders": {} - }, - "unbannedUser": "{username} malforbaris uzanton {targetName}", - "@unbannedUser": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "unblockDevice": "Malbloki aparaton", - "@unblockDevice": { - "type": "text", - "placeholders": {} - }, - "unknownDevice": "Nekonata aparato", - "@unknownDevice": { - "type": "text", - "placeholders": {} - }, - "unknownEncryptionAlgorithm": "Nekonata ĉifra algoritmo", - "@unknownEncryptionAlgorithm": { - "type": "text", - "placeholders": {} - }, - "unknownEvent": "Nekonata evento «{type}»", - "@unknownEvent": { - "type": "text", - "placeholders": { - "type": {} - } - }, - "unmuteChat": "Malsilentigi babilon", - "@unmuteChat": { - "type": "text", - "placeholders": {} - }, - "unpin": "Malfiksi", - "@unpin": { - "type": "text", - "placeholders": {} - }, - "unreadChats": "{unreadCount, plural, =1{1 nelegita babilo} other{{unreadCount} nelegitaj babiloj}}", - "@unreadChats": { - "type": "text", - "placeholders": { - "unreadCount": {} - } - }, - "userAndOthersAreTyping": "{username} kaj {count} aliaj tajpas…", - "@userAndOthersAreTyping": { - "type": "text", - "placeholders": { - "username": {}, - "count": {} - } - }, - "userAndUserAreTyping": "{username} kaj {username2} tajpas…", - "@userAndUserAreTyping": { - "type": "text", - "placeholders": { - "username": {}, - "username2": {} - } - }, - "userIsTyping": "{username} tajpas…", - "@userIsTyping": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "userLeftTheChat": "{username} foriris de la babilo", - "@userLeftTheChat": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "username": "Uzantonomo", - "@username": { - "type": "text", - "placeholders": {} - }, - "userSentUnknownEvent": "{username} sendis eventon de speco {type}", - "@userSentUnknownEvent": { - "type": "text", - "placeholders": { - "username": {}, - "type": {} - } - }, - "verified": "Kontrolita", - "@verified": { - "type": "text", - "placeholders": {} - }, - "verify": "Kontroli", - "@verify": { - "type": "text", - "placeholders": {} - }, - "verifyStart": "Komenci kontrolon", - "@verifyStart": { - "type": "text", - "placeholders": {} - }, - "verifySuccess": "Vi sukcese kontrolis!", - "@verifySuccess": { - "type": "text", - "placeholders": {} - }, - "verifyTitle": "Kontrolante alian konton", - "@verifyTitle": { - "type": "text", - "placeholders": {} - }, - "videoCall": "Vidvoko", - "@videoCall": { - "type": "text", - "placeholders": {} - }, - "visibilityOfTheChatHistory": "Videbleco de historio de la babilo", - "@visibilityOfTheChatHistory": { - "type": "text", - "placeholders": {} - }, - "visibleForAllParticipants": "Videbla al ĉiuj partoprenantoj", - "@visibleForAllParticipants": { - "type": "text", - "placeholders": {} - }, - "visibleForEveryone": "Videbla al ĉiuj", - "@visibleForEveryone": { - "type": "text", - "placeholders": {} - }, - "voiceMessage": "Voĉmesaĝo", - "@voiceMessage": { - "type": "text", - "placeholders": {} - }, - "waitingPartnerAcceptRequest": "Atendante konfirmon de peto de la kunulo…", - "@waitingPartnerAcceptRequest": { - "type": "text", - "placeholders": {} - }, - "waitingPartnerEmoji": "Atendante akcepton de la bildosignoj de la kunulo…", - "@waitingPartnerEmoji": { - "type": "text", - "placeholders": {} - }, - "waitingPartnerNumbers": "Atendante akcepton de la numeroj, de la kunulo…", - "@waitingPartnerNumbers": { - "type": "text", - "placeholders": {} - }, - "wallpaper": "Fonbildo", - "@wallpaper": { - "type": "text", - "placeholders": {} - }, - "warning": "Averto!", - "@warning": { - "type": "text", - "placeholders": {} - }, - "weSentYouAnEmail": "Ni sendis retleteron al vi", - "@weSentYouAnEmail": { - "type": "text", - "placeholders": {} - }, - "whoCanPerformWhichAction": "Kiu povas kion", - "@whoCanPerformWhichAction": { - "type": "text", - "placeholders": {} - }, - "whoIsAllowedToJoinThisGroup": "Kiu rajtas aliĝi al ĉi tiu grupo", - "@whoIsAllowedToJoinThisGroup": { - "type": "text", - "placeholders": {} - }, - "whyDoYouWantToReportThis": "Kial vi volas tion ĉi raporti?", - "@whyDoYouWantToReportThis": { - "type": "text", - "placeholders": {} - }, - "wipeChatBackup": "Ĉu forviŝi la savkopion de via babilo por krei novan sekurecan ŝlosilon?", - "@wipeChatBackup": { - "type": "text", - "placeholders": {} - }, - "withTheseAddressesRecoveryDescription": "Per tiuj ĉi adresoj vi povas rehavi vian pasvorton.", - "@withTheseAddressesRecoveryDescription": { - "type": "text", - "placeholders": {} - }, - "writeAMessage": "Skribi mesaĝon…", - "@writeAMessage": { - "type": "text", - "placeholders": {} - }, - "yes": "Jes", - "@yes": { - "type": "text", - "placeholders": {} - }, - "you": "Vi", - "@you": { - "type": "text", - "placeholders": {} - }, - "youAreInvitedToThisChat": "Vi estas invitita al ĉi tiu babilo", - "@youAreInvitedToThisChat": { - "type": "text", - "placeholders": {} - }, - "youAreNoLongerParticipatingInThisChat": "Vi ne plu partoprenas ĉi tiun babilon", - "@youAreNoLongerParticipatingInThisChat": { - "type": "text", - "placeholders": {} - }, - "youCannotInviteYourself": "Vi ne povas inviti vin mem", - "@youCannotInviteYourself": { - "type": "text", - "placeholders": {} - }, - "youHaveBeenBannedFromThisChat": "Vi estas forbarita de ĉi tiu babilo", - "@youHaveBeenBannedFromThisChat": { - "type": "text", - "placeholders": {} - }, - "yourPublicKey": "Via publika ŝlosilo", - "@yourPublicKey": { - "type": "text", - "placeholders": {} - }, - "sendAsText": "Sendi kiel tekston", - "@sendAsText": { - "type": "text" - }, - "noMatrixServer": "{server1} ne estas matriksa servilo, eble provu anstataŭe servilon {server2}?", - "@noMatrixServer": { - "type": "text", - "placeholders": { - "server1": {}, - "server2": {} - } - }, - "commandHint_send": "Sendi tekston", - "@commandHint_send": { - "type": "text", - "description": "Usage hint for the command /send" - }, - "chatHasBeenAddedToThisSpace": "Babilo aldoniĝis al ĉi tiu aro", - "@chatHasBeenAddedToThisSpace": {}, - "autoplayImages": "Memage ludi movbildajn glumarkojn kaj mienetojn", - "@autoplayImages": { - "type": "text", - "placeholder": {} - }, - "addToSpace": "Aldoni al aro", - "@addToSpace": {}, - "homeserver": "Hejmservilo", - "@homeserver": {}, - "sendOnEnter": "Sendi per eniga klavo", - "@sendOnEnter": {} -} \ No newline at end of file + "@@last_modified": "2021-08-14 12:41:10.107750", + "about": "Prio", + "@about": { + "type": "text", + "placeholders": {} + }, + "accept": "Akcepti", + "@accept": { + "type": "text", + "placeholders": {} + }, + "acceptedTheInvitation": "{username} akceptis la inviton", + "@acceptedTheInvitation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "account": "Konto", + "@account": { + "type": "text", + "placeholders": {} + }, + "activatedEndToEndEncryption": "{username} aktivigis tutvojan ĉifradon", + "@activatedEndToEndEncryption": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "addEmail": "Aldoni retpoŝtadreson", + "@addEmail": { + "type": "text", + "placeholders": {} + }, + "addGroupDescription": "Aldoni priskribon de grupo", + "@addGroupDescription": { + "type": "text", + "placeholders": {} + }, + "admin": "Administranto", + "@admin": { + "type": "text", + "placeholders": {} + }, + "alias": "kromnomo", + "@alias": { + "type": "text", + "placeholders": {} + }, + "all": "Ĉio", + "@all": { + "type": "text", + "placeholders": {} + }, + "allChats": "Ĉiuj babiloj", + "@allChats": { + "type": "text", + "placeholders": {} + }, + "answeredTheCall": "{senderName} respondis la vokon", + "@answeredTheCall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "anyoneCanJoin": "Ĉiu ajn povas aliĝi", + "@anyoneCanJoin": { + "type": "text", + "placeholders": {} + }, + "appLock": "Ŝlosado", + "@appLock": { + "type": "text", + "placeholders": {} + }, + "archive": "Arĥivo", + "@archive": { + "type": "text", + "placeholders": {} + }, + "areGuestsAllowedToJoin": "Ĉu gastoj rajtas aliĝi", + "@areGuestsAllowedToJoin": { + "type": "text", + "placeholders": {} + }, + "areYouSure": "Ĉu vi certas?", + "@areYouSure": { + "type": "text", + "placeholders": {} + }, + "areYouSureYouWantToLogout": "Ĉu vi certe volas adiaŭi?", + "@areYouSureYouWantToLogout": { + "type": "text", + "placeholders": {} + }, + "askSSSSSign": "Por ke vi povu kontroli (subskribi) la alian personon, bonvolu enigi pasfrazon de via sekreta deponejo aŭ vian rehavan ŝlosilon.", + "@askSSSSSign": { + "type": "text", + "placeholders": {} + }, + "askVerificationRequest": "Ĉu akcepti ĉi tiun kontrolpeton de {username}?", + "@askVerificationRequest": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "badServerLoginTypesException": "La hejmservilo subtenas la jenajn specojn de salutoj:\n{serverVersions}\nSed ĉi tiu aplikaĵo subtenas nur:\n{supportedVersions}", + "@badServerLoginTypesException": { + "type": "text", + "placeholders": { + "serverVersions": {}, + "supportedVersions": {} + } + }, + "badServerVersionsException": "La hejmservilo subtenas la jenajn version de la specifaĵo:\n{serverVersions}\nSed ĉi tiu aplikaĵo subtenas nur {supportedVersions}", + "@badServerVersionsException": { + "type": "text", + "placeholders": { + "serverVersions": {}, + "supportedVersions": {} + } + }, + "banFromChat": "Forbari de babilo", + "@banFromChat": { + "type": "text", + "placeholders": {} + }, + "banned": "Forbarita", + "@banned": { + "type": "text", + "placeholders": {} + }, + "bannedUser": "{username} forbaris uzanton {targetName}", + "@bannedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "blockDevice": "Bloki aparaton", + "@blockDevice": { + "type": "text", + "placeholders": {} + }, + "blocked": "Blokita", + "@blocked": { + "type": "text", + "placeholders": {} + }, + "botMessages": "Mesaĝoj de robotoj", + "@botMessages": { + "type": "text", + "placeholders": {} + }, + "cancel": "Nuligi", + "@cancel": { + "type": "text", + "placeholders": {} + }, + "cantOpenUri": "Ne povis malfermi URI {uri}", + "@cantOpenUri": { + "type": "text", + "placeholders": { + "uri": {} + } + }, + "changeDeviceName": "Ŝanĝi nomon de aparato", + "@changeDeviceName": { + "type": "text", + "placeholders": {} + }, + "changedTheChatAvatar": "{username} ŝanĝis bildon de la babilo", + "@changedTheChatAvatar": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheChatDescriptionTo": "{username} ŝanĝis priskribon de la babilo al: «{description}»", + "@changedTheChatDescriptionTo": { + "type": "text", + "placeholders": { + "username": {}, + "description": {} + } + }, + "changedTheChatNameTo": "{username} ŝanĝis nomon de la babilo al: «{chatname}»", + "@changedTheChatNameTo": { + "type": "text", + "placeholders": { + "username": {}, + "chatname": {} + } + }, + "changedTheChatPermissions": "{username} ŝanĝis permesojn pri la babilo", + "@changedTheChatPermissions": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheDisplaynameTo": "{username} ŝanĝis sian prezentan nomon al: {username}", + "@changedTheDisplaynameTo": { + "type": "text", + "placeholders": { + "username": {}, + "displayname": {} + } + }, + "changedTheGuestAccessRules": "{username} ŝanĝis regulojn pri aliro de gastoj", + "@changedTheGuestAccessRules": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheGuestAccessRulesTo": "{username} ŝanĝis regulojn pri aliro de gastoj al: {rules}", + "@changedTheGuestAccessRulesTo": { + "type": "text", + "placeholders": { + "username": {}, + "rules": {} + } + }, + "changedTheHistoryVisibility": "{username} ŝanĝis videblecon de la historio", + "@changedTheHistoryVisibility": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheHistoryVisibilityTo": "{username} ŝanĝis videblecon de la historio al: {rules}", + "@changedTheHistoryVisibilityTo": { + "type": "text", + "placeholders": { + "username": {}, + "rules": {} + } + }, + "changedTheJoinRules": "{username} ŝanĝis regulojn pri aliĝado", + "@changedTheJoinRules": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheJoinRulesTo": "{username} ŝanĝis regulojn pri aliĝado al: {joinRules}", + "@changedTheJoinRulesTo": { + "type": "text", + "placeholders": { + "username": {}, + "joinRules": {} + } + }, + "changedTheProfileAvatar": "{username} ŝanĝis sian profilbildon", + "@changedTheProfileAvatar": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheRoomAliases": "{username} ŝanĝis la kromnomojn de la ĉambro", + "@changedTheRoomAliases": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheRoomInvitationLink": "{username} ŝanĝis la invitan ligilon", + "@changedTheRoomInvitationLink": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changePassword": "Ŝanĝi pasvorton", + "@changePassword": { + "type": "text", + "placeholders": {} + }, + "changeTheHomeserver": "Ŝanĝi hejmservilon", + "@changeTheHomeserver": { + "type": "text", + "placeholders": {} + }, + "changeTheme": "Ŝanĝu la haŭton", + "@changeTheme": { + "type": "text", + "placeholders": {} + }, + "changeTheNameOfTheGroup": "Ŝanĝi nomon de la grupo", + "@changeTheNameOfTheGroup": { + "type": "text", + "placeholders": {} + }, + "changeWallpaper": "Ŝanĝi fonbildon", + "@changeWallpaper": { + "type": "text", + "placeholders": {} + }, + "changeYourAvatar": "Ŝanĝi vian profilbildon", + "@changeYourAvatar": { + "type": "text", + "placeholders": {} + }, + "channelCorruptedDecryptError": "La ĉifrado estas difektita", + "@channelCorruptedDecryptError": { + "type": "text", + "placeholders": {} + }, + "chat": "Babilo", + "@chat": { + "type": "text", + "placeholders": {} + }, + "chatBackup": "Savkopiado de babilo", + "@chatBackup": { + "type": "text", + "placeholders": {} + }, + "chatBackupDescription": "Via savkopio de babilo estas sekurigita per sekureca ŝlosilo. Bonvolu certigi, ke vi ne perdos ĝin.", + "@chatBackupDescription": { + "type": "text", + "placeholders": {} + }, + "chatDetails": "Detaloj pri babilo", + "@chatDetails": { + "type": "text", + "placeholders": {} + }, + "chats": "Babiloj", + "@chats": { + "type": "text", + "placeholders": {} + }, + "chooseAStrongPassword": "Elektu fortan pasvorton", + "@chooseAStrongPassword": { + "type": "text", + "placeholders": {} + }, + "chooseAUsername": "Elektu uzantonomon", + "@chooseAUsername": { + "type": "text", + "placeholders": {} + }, + "clearArchive": "Vakigi arĥivon", + "@clearArchive": {}, + "close": "Fermi", + "@close": { + "type": "text", + "placeholders": {} + }, + "commandHint_ban": "Forbari la donitan uzanton de ĉi tiu ĉambro", + "@commandHint_ban": { + "type": "text", + "description": "Usage hint for the command /ban" + }, + "commandHint_html": "Sendi tekston formatan je HTML", + "@commandHint_html": { + "type": "text", + "description": "Usage hint for the command /html" + }, + "commandHint_invite": "Inviti la donitan uzanton al ĉi tiu ĉambro", + "@commandHint_invite": { + "type": "text", + "description": "Usage hint for the command /invite" + }, + "commandHint_join": "Aliĝi al la donita ĉambro", + "@commandHint_join": { + "type": "text", + "description": "Usage hint for the command /join" + }, + "commandHint_kick": "Forigi la donitan uzanton de ĉi tiu ĉambro", + "@commandHint_kick": { + "type": "text", + "description": "Usage hint for the command /kick" + }, + "commandHint_leave": "Foriri de ĉi tiu ĉambro", + "@commandHint_leave": { + "type": "text", + "description": "Usage hint for the command /leave" + }, + "commandHint_me": "Priskribu vian agon", + "@commandHint_me": { + "type": "text", + "description": "Usage hint for the command /me" + }, + "commandHint_myroomavatar": "Agordi vian profilbildon por ĉi tiu ĉambro (laŭ mxc-uri)", + "@commandHint_myroomavatar": { + "type": "text", + "description": "Usage hint for the command /myroomavatar" + }, + "commandHint_myroomnick": "Agordi vian prezentan nomon en ĉi tiu ĉambro", + "@commandHint_myroomnick": { + "type": "text", + "description": "Usage hint for the command /myroomnick" + }, + "commandHint_op": "Agordi povnivelon de la donita uzanto (implicite: 50)", + "@commandHint_op": { + "type": "text", + "description": "Usage hint for the command /op" + }, + "commandHint_plain": "Sendi senformatan tekston", + "@commandHint_plain": { + "type": "text", + "description": "Usage hint for the command /plain" + }, + "commandHint_react": "Sendi respondon kiel reagon", + "@commandHint_react": { + "type": "text", + "description": "Usage hint for the command /react" + }, + "commandHint_unban": "Malforbari la donitan uzanton de ĉi tiu ĉambro", + "@commandHint_unban": { + "type": "text", + "description": "Usage hint for the command /unban" + }, + "commandInvalid": "Nevalida ordono", + "@commandInvalid": { + "type": "text" + }, + "commandMissing": "{command} ne estas ordono.", + "@commandMissing": { + "type": "text", + "placeholders": { + "command": {} + }, + "description": "State that {command} is not a valid /command." + }, + "compareEmojiMatch": "Komparu kaj certigu, ke la jenaj bildosignoj samas en ambaŭ aparatoj:", + "@compareEmojiMatch": { + "type": "text", + "placeholders": {} + }, + "compareNumbersMatch": "Komparu kaj certigu, ke la jenaj numeroj samas en ambaŭ aparatoj:", + "@compareNumbersMatch": { + "type": "text", + "placeholders": {} + }, + "configureChat": "Agordi babilon", + "@configureChat": { + "type": "text", + "placeholders": {} + }, + "confirm": "Konfirmi", + "@confirm": { + "type": "text", + "placeholders": {} + }, + "connect": "Konektiĝi", + "@connect": { + "type": "text", + "placeholders": {} + }, + "contactHasBeenInvitedToTheGroup": "Kontakto invitiĝis al la grupo", + "@contactHasBeenInvitedToTheGroup": { + "type": "text", + "placeholders": {} + }, + "containsDisplayName": "Enhavas prezentan nomon", + "@containsDisplayName": { + "type": "text", + "placeholders": {} + }, + "containsUserName": "Enhavas uzantonomon", + "@containsUserName": { + "type": "text", + "placeholders": {} + }, + "contentHasBeenReported": "La enhavo raportiĝis al la administrantoj de la servilo", + "@contentHasBeenReported": { + "type": "text", + "placeholders": {} + }, + "copiedToClipboard": "Kopiite al tondujo", + "@copiedToClipboard": { + "type": "text", + "placeholders": {} + }, + "copy": "Kopii", + "@copy": { + "type": "text", + "placeholders": {} + }, + "copyToClipboard": "Kopii al tondujo", + "@copyToClipboard": { + "type": "text", + "placeholders": {} + }, + "couldNotDecryptMessage": "Ne povis malĉifri mesaĝon: {error}", + "@couldNotDecryptMessage": { + "type": "text", + "placeholders": { + "error": {} + } + }, + "countParticipants": "{count} partoprenantoj", + "@countParticipants": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "create": "Krei", + "@create": { + "type": "text", + "placeholders": {} + }, + "createdTheChat": "{username} kreis la babilon", + "@createdTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "createNewGroup": "Krei novan grupon", + "@createNewGroup": { + "type": "text", + "placeholders": {} + }, + "createNewSpace": "Nova aro", + "@createNewSpace": { + "type": "text", + "placeholders": {} + }, + "currentlyActive": "Nun aktiva", + "@currentlyActive": { + "type": "text", + "placeholders": {} + }, + "darkTheme": "Malhela", + "@darkTheme": { + "type": "text", + "placeholders": {} + }, + "dateAndTimeOfDay": "{date}, {timeOfDay}", + "@dateAndTimeOfDay": { + "type": "text", + "placeholders": { + "date": {}, + "timeOfDay": {} + } + }, + "dateWithoutYear": "{day}a de la {month}a", + "@dateWithoutYear": { + "type": "text", + "placeholders": { + "month": {}, + "day": {} + } + }, + "dateWithYear": "{day}a de la {month}a de {year}", + "@dateWithYear": { + "type": "text", + "placeholders": { + "year": {}, + "month": {}, + "day": {} + } + }, + "deactivateAccountWarning": "Ĉi tio malaktivigos vian konton de uzanto. Ne eblas tion malfari! Ĉu certe vi certas?", + "@deactivateAccountWarning": { + "type": "text", + "placeholders": {} + }, + "defaultPermissionLevel": "Norma nivelo de permesoj", + "@defaultPermissionLevel": { + "type": "text", + "placeholders": {} + }, + "delete": "Forigi", + "@delete": { + "type": "text", + "placeholders": {} + }, + "deleteAccount": "Forigi konton", + "@deleteAccount": { + "type": "text", + "placeholders": {} + }, + "deleteMessage": "Forigi mesaĝon", + "@deleteMessage": { + "type": "text", + "placeholders": {} + }, + "deny": "Malakcepti", + "@deny": { + "type": "text", + "placeholders": {} + }, + "device": "Aparato", + "@device": { + "type": "text", + "placeholders": {} + }, + "deviceId": "Identigilo de aparato", + "@deviceId": { + "type": "text", + "placeholders": {} + }, + "devices": "Aparatoj", + "@devices": { + "type": "text", + "placeholders": {} + }, + "directChats": "Rektaj babiloj", + "@directChats": { + "type": "text", + "placeholders": {} + }, + "displaynameHasBeenChanged": "Prezenta nomo ŝanĝiĝis", + "@displaynameHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "downloadFile": "Elŝuti dosieron", + "@downloadFile": { + "type": "text", + "placeholders": {} + }, + "edit": "Redakti", + "@edit": { + "type": "text", + "placeholders": {} + }, + "editBlockedServers": "Redakti blokitajn servilojn", + "@editBlockedServers": { + "type": "text", + "placeholders": {} + }, + "editChatPermissions": "Redakti permesojn de babilo", + "@editChatPermissions": { + "type": "text", + "placeholders": {} + }, + "editDisplayname": "Redakti prezentan nomon", + "@editDisplayname": { + "type": "text", + "placeholders": {} + }, + "editRoomAliases": "Ŝanĝi kromnomojn de ĉambro", + "@editRoomAliases": { + "type": "text", + "placeholders": {} + }, + "editRoomAvatar": "Redakti bildon de ĉambro", + "@editRoomAvatar": { + "type": "text", + "placeholders": {} + }, + "emoteExists": "Mieneto jam ekzistas!", + "@emoteExists": { + "type": "text", + "placeholders": {} + }, + "emoteInvalid": "Nevalida mallongigo de mieneto!", + "@emoteInvalid": { + "type": "text", + "placeholders": {} + }, + "emotePacks": "Mienetaroj por la ĉambro", + "@emotePacks": { + "type": "text", + "placeholders": {} + }, + "emoteSettings": "Agordoj pri mienetoj", + "@emoteSettings": { + "type": "text", + "placeholders": {} + }, + "emoteShortcode": "Mallongigo de mieneto", + "@emoteShortcode": { + "type": "text", + "placeholders": {} + }, + "emoteWarnNeedToPick": "Vi devas elekti mallongigon de mieneto kaj bildon!", + "@emoteWarnNeedToPick": { + "type": "text", + "placeholders": {} + }, + "emptyChat": "Malplena babilo", + "@emptyChat": { + "type": "text", + "placeholders": {} + }, + "enableEmotesGlobally": "Ŝalti mienetaron ĉie", + "@enableEmotesGlobally": { + "type": "text", + "placeholders": {} + }, + "enableEncryption": "Ŝalti ĉifradon", + "@enableEncryption": { + "type": "text", + "placeholders": {} + }, + "enableEncryptionWarning": "Vi ne povos malŝalti la ĉifradon. Ĉu vi certas?", + "@enableEncryptionWarning": { + "type": "text", + "placeholders": {} + }, + "encrypted": "Ĉifrite", + "@encrypted": { + "type": "text", + "placeholders": {} + }, + "encryption": "Ĉifrado", + "@encryption": { + "type": "text", + "placeholders": {} + }, + "encryptionNotEnabled": "Ĉifrado ne estas ŝaltita", + "@encryptionNotEnabled": { + "type": "text", + "placeholders": {} + }, + "endedTheCall": "{senderName} finis la vokon", + "@endedTheCall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "enterAGroupName": "Enigu nomon de grupo", + "@enterAGroupName": { + "type": "text", + "placeholders": {} + }, + "enterAnEmailAddress": "Enigu retpoŝtadreson", + "@enterAnEmailAddress": { + "type": "text", + "placeholders": {} + }, + "enterASpacepName": "Enigi nomon de aro", + "@enterASpacepName": {}, + "enterYourHomeserver": "Enigu vian hejmservilon", + "@enterYourHomeserver": { + "type": "text", + "placeholders": {} + }, + "errorObtainingLocation": "Eraris akirado de loko: {error}", + "@errorObtainingLocation": { + "type": "text", + "placeholders": { + "error": {} + } + }, + "everythingReady": "Ĉio pretas!", + "@everythingReady": { + "type": "text", + "placeholders": {} + }, + "extremeOffensive": "Tre ofenda", + "@extremeOffensive": { + "type": "text", + "placeholders": {} + }, + "fileName": "Dosiernomo", + "@fileName": { + "type": "text", + "placeholders": {} + }, + "fluffychat": "FluffyChat", + "@fluffychat": { + "type": "text", + "placeholders": {} + }, + "fontSize": "Grandeco de tiparo", + "@fontSize": { + "type": "text", + "placeholders": {} + }, + "forward": "Plusendi", + "@forward": { + "type": "text", + "placeholders": {} + }, + "fromJoining": "Ekde aliĝo", + "@fromJoining": { + "type": "text", + "placeholders": {} + }, + "fromTheInvitation": "Ekde la invito", + "@fromTheInvitation": { + "type": "text", + "placeholders": {} + }, + "goToTheNewRoom": "Iri al la nova ĉambro", + "@goToTheNewRoom": { + "type": "text", + "placeholders": {} + }, + "group": "Grupo", + "@group": { + "type": "text", + "placeholders": {} + }, + "groupDescription": "Priskribo de grupo", + "@groupDescription": { + "type": "text", + "placeholders": {} + }, + "groupDescriptionHasBeenChanged": "Priskribo de grupo ŝanĝiĝis", + "@groupDescriptionHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "groupIsPublic": "Grupo estas publika", + "@groupIsPublic": { + "type": "text", + "placeholders": {} + }, + "groups": "Grupoj", + "@groups": { + "type": "text", + "placeholders": {} + }, + "groupWith": "Grupo kun {displayname}", + "@groupWith": { + "type": "text", + "placeholders": { + "displayname": {} + } + }, + "guestsAreForbidden": "Gastoj estas malpermesitaj", + "@guestsAreForbidden": { + "type": "text", + "placeholders": {} + }, + "guestsCanJoin": "Gastoj povas aliĝi", + "@guestsCanJoin": { + "type": "text", + "placeholders": {} + }, + "hasWithdrawnTheInvitationFor": "{username} nuligis la inviton por {targetName}", + "@hasWithdrawnTheInvitationFor": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "help": "Helpo", + "@help": { + "type": "text", + "placeholders": {} + }, + "hideRedactedEvents": "Kaŝi obskurigitajn eventojn", + "@hideRedactedEvents": { + "type": "text", + "placeholders": {} + }, + "hideUnknownEvents": "Kaŝi nekonatajn eventojn", + "@hideUnknownEvents": { + "type": "text", + "placeholders": {} + }, + "howOffensiveIsThisContent": "Kiel ofenda estas ĉi tiu enhavo?", + "@howOffensiveIsThisContent": { + "type": "text", + "placeholders": {} + }, + "id": "Identigilo", + "@id": { + "type": "text", + "placeholders": {} + }, + "identity": "Identeco", + "@identity": { + "type": "text", + "placeholders": {} + }, + "ignore": "Malatenti", + "@ignore": { + "type": "text", + "placeholders": {} + }, + "ignoredUsers": "Malatentitaj uzantoj", + "@ignoredUsers": { + "type": "text", + "placeholders": {} + }, + "ignoreListDescription": "Vi povas malatenti uzantojn, kiuj vin ĝenas. Vi ne povos ricevi mesaĝojn nek invitojn al ĉambroj de la uzantoj sur via listo de malatentatoj.", + "@ignoreListDescription": { + "type": "text", + "placeholders": {} + }, + "ignoreUsername": "Malatenti uzantonomon", + "@ignoreUsername": { + "type": "text", + "placeholders": {} + }, + "iHaveClickedOnLink": "Mi klakis la ligilon", + "@iHaveClickedOnLink": { + "type": "text", + "placeholders": {} + }, + "incorrectPassphraseOrKey": "Neĝusta pasfrazo aŭ rehava ŝlosilo", + "@incorrectPassphraseOrKey": { + "type": "text", + "placeholders": {} + }, + "inoffensive": "Neofenda", + "@inoffensive": { + "type": "text", + "placeholders": {} + }, + "inviteContact": "Inviti kontakton", + "@inviteContact": { + "type": "text", + "placeholders": {} + }, + "inviteContactToGroup": "Inviti kontakton al {groupName}", + "@inviteContactToGroup": { + "type": "text", + "placeholders": { + "groupName": {} + } + }, + "invited": "Invitita", + "@invited": { + "type": "text", + "placeholders": {} + }, + "invitedUser": "{username} invitis uzanton {targetName}", + "@invitedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "invitedUsersOnly": "Nur invititoj", + "@invitedUsersOnly": { + "type": "text", + "placeholders": {} + }, + "inviteForMe": "Invito por mi", + "@inviteForMe": { + "type": "text", + "placeholders": {} + }, + "inviteText": "{username} invitis vin al FluffyChat. \n1. Instalu la aplikaĵon FluffyChat: https://fluffychat.im \n2. Registriĝu aŭ salutu \n3. Malfermu la invitan ligilon: {link}", + "@inviteText": { + "type": "text", + "placeholders": { + "username": {}, + "link": {} + } + }, + "isTyping": "tajpas…", + "@isTyping": { + "type": "text", + "placeholders": {} + }, + "joinedTheChat": "{username} aliĝis al la babilo", + "@joinedTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "joinRoom": "Aliĝi al ĉambro", + "@joinRoom": { + "type": "text", + "placeholders": {} + }, + "kicked": "{username} forpelis uzanton {targetName}", + "@kicked": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "kickedAndBanned": "{username} forpelis kaj forbaris uzanton {targetName}", + "@kickedAndBanned": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "kickFromChat": "Forpeli de babilo", + "@kickFromChat": { + "type": "text", + "placeholders": {} + }, + "lastActiveAgo": "Lastafoje aktiva: {localizedTimeShort}", + "@lastActiveAgo": { + "type": "text", + "placeholders": { + "localizedTimeShort": {} + } + }, + "lastSeenLongTimeAgo": "Vidita antaŭ longe", + "@lastSeenLongTimeAgo": { + "type": "text", + "placeholders": {} + }, + "leave": "Foriri", + "@leave": { + "type": "text", + "placeholders": {} + }, + "leftTheChat": "Foriris de la ĉambro", + "@leftTheChat": { + "type": "text", + "placeholders": {} + }, + "license": "Permesilo", + "@license": { + "type": "text", + "placeholders": {} + }, + "lightTheme": "Hela", + "@lightTheme": { + "type": "text", + "placeholders": {} + }, + "loadCountMoreParticipants": "Enlegi {count} pliajn partoprenantojn", + "@loadCountMoreParticipants": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "loadingPleaseWait": "Enlegante… bonvolu atendi.", + "@loadingPleaseWait": { + "type": "text", + "placeholders": {} + }, + "loadMore": "Enlegi pli…", + "@loadMore": { + "type": "text", + "placeholders": {} + }, + "login": "Saluti", + "@login": { + "type": "text", + "placeholders": {} + }, + "logInTo": "Saluti servilon {homeserver}", + "@logInTo": { + "type": "text", + "placeholders": { + "homeserver": {} + } + }, + "loginWith": "Saluti per {brand}", + "@loginWith": { + "type": "text", + "placeholders": { + "brand": {} + } + }, + "logout": "Adiaŭi", + "@logout": { + "type": "text", + "placeholders": {} + }, + "makeSureTheIdentifierIsValid": "Certigu, ke la identigilo estas valida", + "@makeSureTheIdentifierIsValid": { + "type": "text", + "placeholders": {} + }, + "memberChanges": "Ŝanĝoj de anoj", + "@memberChanges": { + "type": "text", + "placeholders": {} + }, + "mention": "Mencii", + "@mention": { + "type": "text", + "placeholders": {} + }, + "messages": "Mesaĝoj", + "@messages": { + "type": "text", + "placeholders": {} + }, + "messageWillBeRemovedWarning": "Mesaĝo foriĝos por ĉiuj partoprenantoj", + "@messageWillBeRemovedWarning": { + "type": "text", + "placeholders": {} + }, + "moderator": "Reguligisto", + "@moderator": { + "type": "text", + "placeholders": {} + }, + "muteChat": "Silentigi babilon", + "@muteChat": { + "type": "text", + "placeholders": {} + }, + "needPantalaimonWarning": "Bonvolu scii, ke vi ankoraŭ bezonas la programon Pantalaimon por uzi tutvojan ĉifradon.", + "@needPantalaimonWarning": { + "type": "text", + "placeholders": {} + }, + "newChat": "Nova babilo", + "@newChat": { + "type": "text", + "placeholders": {} + }, + "newMessageInFluffyChat": "Nova mesaĝo en FluffyChat", + "@newMessageInFluffyChat": { + "type": "text", + "placeholders": {} + }, + "newVerificationRequest": "Nova kontrolpeto!", + "@newVerificationRequest": { + "type": "text", + "placeholders": {} + }, + "next": "Sekva", + "@next": { + "type": "text", + "placeholders": {} + }, + "no": "Ne", + "@no": { + "type": "text", + "placeholders": {} + }, + "noConnectionToTheServer": "Neniu konekto al la servilo", + "@noConnectionToTheServer": { + "type": "text", + "placeholders": {} + }, + "noEmotesFound": "Neniuj mienetoj troviĝis. 😕", + "@noEmotesFound": { + "type": "text", + "placeholders": {} + }, + "noEncryptionForPublicRooms": "Vi nur povas aktivigi ĉifradon kiam la ĉambro ne plu estas publike alirebla.", + "@noEncryptionForPublicRooms": { + "type": "text", + "placeholders": {} + }, + "noGoogleServicesWarning": "Ŝajnas, ke via telefono ne havas servojn de Google. Tio estas bona decido por via privateco! Por ricevadi pasivajn sciigojn en FluffyChat, ni rekomendas, ke vi uzu la https://microg.org/ aŭ https://unifiedpush.org/.", + "@noGoogleServicesWarning": { + "type": "text", + "placeholders": {} + }, + "none": "Neniu", + "@none": { + "type": "text", + "placeholders": {} + }, + "noPasswordRecoveryDescription": "Vi ankoraŭ ne aldonis manieron rehavi vian pasvorton.", + "@noPasswordRecoveryDescription": { + "type": "text", + "placeholders": {} + }, + "noPermission": "Neniu permeso", + "@noPermission": { + "type": "text", + "placeholders": {} + }, + "noRoomsFound": "Neniuj ĉambroj troviĝis…", + "@noRoomsFound": { + "type": "text", + "placeholders": {} + }, + "notifications": "Sciigoj", + "@notifications": { + "type": "text", + "placeholders": {} + }, + "notificationsEnabledForThisAccount": "Sciigoj ŝaltiĝis por ĉi tiu konto", + "@notificationsEnabledForThisAccount": { + "type": "text", + "placeholders": {} + }, + "numUsersTyping": "{count} uzantoj tajpas…", + "@numUsersTyping": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "obtainingLocation": "Akirante lokon…", + "@obtainingLocation": { + "type": "text", + "placeholders": {} + }, + "offensive": "Ofenda", + "@offensive": { + "type": "text", + "placeholders": {} + }, + "offline": "Eksterrete", + "@offline": { + "type": "text", + "placeholders": {} + }, + "ok": "bone", + "@ok": { + "type": "text", + "placeholders": {} + }, + "online": "Enrete", + "@online": { + "type": "text", + "placeholders": {} + }, + "onlineKeyBackupEnabled": "Enreta savkopiado de ŝlosiloj estas ŝaltita", + "@onlineKeyBackupEnabled": { + "type": "text", + "placeholders": {} + }, + "oopsPushError": "Oj! Bedaŭrinde eraris la agordado de pasivaj sciigoj.", + "@oopsPushError": { + "type": "text", + "placeholders": {} + }, + "oopsSomethingWentWrong": "Oj! Io misokazis…", + "@oopsSomethingWentWrong": { + "type": "text", + "placeholders": {} + }, + "openAppToReadMessages": "Malfermu la aplikaĵon por legi mesaĝojn", + "@openAppToReadMessages": { + "type": "text", + "placeholders": {} + }, + "openCamera": "Malfermi fotilon", + "@openCamera": { + "type": "text", + "placeholders": {} + }, + "optionalGroupName": "(Malnepra) Nomo de grupo", + "@optionalGroupName": { + "type": "text", + "placeholders": {} + }, + "or": "Aŭ", + "@or": { + "type": "text", + "placeholders": {} + }, + "participant": "Partoprenanto", + "@participant": { + "type": "text", + "placeholders": {} + }, + "passphraseOrKey": "pasfrazo aŭ rehava ŝlosilo", + "@passphraseOrKey": { + "type": "text", + "placeholders": {} + }, + "password": "Pasvorto", + "@password": { + "type": "text", + "placeholders": {} + }, + "passwordForgotten": "Forgesita pasvorto", + "@passwordForgotten": { + "type": "text", + "placeholders": {} + }, + "passwordHasBeenChanged": "Pasvorto ŝanĝiĝis", + "@passwordHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "passwordRecovery": "Rehavo de pasvorto", + "@passwordRecovery": { + "type": "text", + "placeholders": {} + }, + "people": "Personoj", + "@people": { + "type": "text", + "placeholders": {} + }, + "pickImage": "Elekti bildon", + "@pickImage": { + "type": "text", + "placeholders": {} + }, + "pin": "Fiksi", + "@pin": { + "type": "text", + "placeholders": {} + }, + "play": "Ludi {fileName}", + "@play": { + "type": "text", + "placeholders": { + "fileName": {} + } + }, + "pleaseChoose": "Bonvolu elekti", + "@pleaseChoose": { + "type": "text", + "placeholders": {} + }, + "pleaseChooseAPasscode": "Bonvolu elekti paskodon", + "@pleaseChooseAPasscode": { + "type": "text", + "placeholders": {} + }, + "pleaseChooseAUsername": "Bonvolu elekti uzantonomon", + "@pleaseChooseAUsername": { + "type": "text", + "placeholders": {} + }, + "pleaseClickOnLink": "Bonvolu klaki la ligilon en la retletero kaj pluiĝi.", + "@pleaseClickOnLink": { + "type": "text", + "placeholders": {} + }, + "pleaseEnter4Digits": "Bonvolu enigi 4 ciferojn, aŭ nenion por malŝalti ŝlosadon de la aplikaĵo.", + "@pleaseEnter4Digits": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterAMatrixIdentifier": "Bonvolu enigi identigilon de Matrix.", + "@pleaseEnterAMatrixIdentifier": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourPassword": "Bonvolu enigi vian pasvorton", + "@pleaseEnterYourPassword": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourPin": "Bonvolu enigi vian personan identigan numeron", + "@pleaseEnterYourPin": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourUsername": "Bonvolu enigi vian uzantonomon", + "@pleaseEnterYourUsername": { + "type": "text", + "placeholders": {} + }, + "pleaseFollowInstructionsOnWeb": "Bonvolu sekvi la instrukciojn de la retejo kaj tuŝetu al «Sekva».", + "@pleaseFollowInstructionsOnWeb": { + "type": "text", + "placeholders": {} + }, + "privacy": "Privateco", + "@privacy": { + "type": "text", + "placeholders": {} + }, + "publicRooms": "Publikaj ĉambroj", + "@publicRooms": { + "type": "text", + "placeholders": {} + }, + "pushRules": "Reguloj de pasivaj sciigoj", + "@pushRules": { + "type": "text", + "placeholders": {} + }, + "reason": "Kialo", + "@reason": { + "type": "text", + "placeholders": {} + }, + "recording": "Registrante", + "@recording": { + "type": "text", + "placeholders": {} + }, + "redactedAnEvent": "{username} obskurigis eventon", + "@redactedAnEvent": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "redactMessage": "Obskurigi mesaĝon", + "@redactMessage": { + "type": "text", + "placeholders": {} + }, + "register": "Registriĝi", + "@register": { + "type": "text", + "placeholders": {} + }, + "reject": "Rifuzi", + "@reject": { + "type": "text", + "placeholders": {} + }, + "rejectedTheInvitation": "{username} rifuzis la inviton", + "@rejectedTheInvitation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "rejoin": "Ree aliĝi", + "@rejoin": { + "type": "text", + "placeholders": {} + }, + "remove": "Forigi", + "@remove": { + "type": "text", + "placeholders": {} + }, + "removeAllOtherDevices": "Forigi ĉiujn aliajn aparatojn", + "@removeAllOtherDevices": { + "type": "text", + "placeholders": {} + }, + "removedBy": "Forigita de {username}", + "@removedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "removeDevice": "Forigi aparaton", + "@removeDevice": { + "type": "text", + "placeholders": {} + }, + "unbanFromChat": "Malforbari", + "@unbanFromChat": { + "type": "text", + "placeholders": {} + }, + "removeYourAvatar": "Forigi vian profilbildon", + "@removeYourAvatar": { + "type": "text", + "placeholders": {} + }, + "renderRichContent": "Bildigi riĉforman enhavon de mesaĝoj", + "@renderRichContent": { + "type": "text", + "placeholders": {} + }, + "replaceRoomWithNewerVersion": "Anstataŭigi ĉambron per nova versio", + "@replaceRoomWithNewerVersion": { + "type": "text", + "placeholders": {} + }, + "reply": "Respondi", + "@reply": { + "type": "text", + "placeholders": {} + }, + "reportMessage": "Raporti mesaĝon", + "@reportMessage": { + "type": "text", + "placeholders": {} + }, + "requestPermission": "Peti permeson", + "@requestPermission": { + "type": "text", + "placeholders": {} + }, + "roomHasBeenUpgraded": "Ĉambro gradaltiĝis", + "@roomHasBeenUpgraded": { + "type": "text", + "placeholders": {} + }, + "roomVersion": "Versio de ĉambro", + "@roomVersion": { + "type": "text", + "placeholders": {} + }, + "saveFile": "Konservi dosieron", + "@saveFile": { + "type": "text", + "placeholders": {} + }, + "search": "Serĉi", + "@search": { + "type": "text", + "placeholders": {} + }, + "security": "Sekureco", + "@security": { + "type": "text", + "placeholders": {} + }, + "seenByUser": "Vidita de {username}", + "@seenByUser": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "seenByUserAndCountOthers": "{count, plural, other{Vidita de {username} kaj {count} aliaj}}", + "@seenByUserAndCountOthers": { + "type": "text", + "placeholders": { + "username": {}, + "count": {} + } + }, + "seenByUserAndUser": "Vidita de {username} kaj {username2}", + "@seenByUserAndUser": { + "type": "text", + "placeholders": { + "username": {}, + "username2": {} + } + }, + "send": "Sendi", + "@send": { + "type": "text", + "placeholders": {} + }, + "sendAMessage": "Sendi mesaĝon", + "@sendAMessage": { + "type": "text", + "placeholders": {} + }, + "sendAudio": "Sendi sondosieron", + "@sendAudio": { + "type": "text", + "placeholders": {} + }, + "sendFile": "Sendi dosieron", + "@sendFile": { + "type": "text", + "placeholders": {} + }, + "sendImage": "Sendi bildon", + "@sendImage": { + "type": "text", + "placeholders": {} + }, + "sendMessages": "Sendi mesaĝojn", + "@sendMessages": { + "type": "text", + "placeholders": {} + }, + "sendOriginal": "Sendi originalon", + "@sendOriginal": { + "type": "text", + "placeholders": {} + }, + "sendSticker": "Sendi glumarkon", + "@sendSticker": { + "type": "text", + "placeholders": {} + }, + "sendVideo": "Sendi filmon", + "@sendVideo": { + "type": "text", + "placeholders": {} + }, + "sentAFile": "{username} sendis dosieron", + "@sentAFile": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sentAnAudio": "{username} sendis sondosieron", + "@sentAnAudio": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sentAPicture": "{username} sendis bildon", + "@sentAPicture": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sentASticker": "{username} sendis glumarkon", + "@sentASticker": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sentAVideo": "{username} sendis filmon", + "@sentAVideo": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sentCallInformations": "{senderName} sendis informojn pri voko", + "@sentCallInformations": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "setAsCanonicalAlias": "Agordi kiel ĉefan kromnomon", + "@setAsCanonicalAlias": { + "type": "text", + "placeholders": {} + }, + "setCustomEmotes": "Agordi proprajn mienetojn", + "@setCustomEmotes": { + "type": "text", + "placeholders": {} + }, + "setGroupDescription": "Agordi priskribon de grupo", + "@setGroupDescription": { + "type": "text", + "placeholders": {} + }, + "setInvitationLink": "Agordi invitan ligilon", + "@setInvitationLink": { + "type": "text", + "placeholders": {} + }, + "setPermissionsLevel": "Agordi nivelon de permesoj", + "@setPermissionsLevel": { + "type": "text", + "placeholders": {} + }, + "setStatus": "Agordi staton", + "@setStatus": { + "type": "text", + "placeholders": {} + }, + "settings": "Agordoj", + "@settings": { + "type": "text", + "placeholders": {} + }, + "share": "Konigi", + "@share": { + "type": "text", + "placeholders": {} + }, + "sharedTheLocation": "{username} konigis sian lokon", + "@sharedTheLocation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "shareLocation": "Konigi lokon", + "@shareLocation": { + "type": "text", + "placeholders": {} + }, + "showPassword": "Montri pasvorton", + "@showPassword": { + "type": "text", + "placeholders": {} + }, + "signUp": "Registriĝi", + "@signUp": { + "type": "text", + "placeholders": {} + }, + "singlesignon": "Ununura saluto", + "@singlesignon": { + "type": "text", + "placeholders": {} + }, + "skip": "Preterpasi", + "@skip": { + "type": "text", + "placeholders": {} + }, + "sourceCode": "Fontkodo", + "@sourceCode": { + "type": "text", + "placeholders": {} + }, + "spaceIsPublic": "Aro estas publika", + "@spaceIsPublic": { + "type": "text", + "placeholders": {} + }, + "spaceName": "Nomo de aro", + "@spaceName": { + "type": "text", + "placeholders": {} + }, + "startedACall": "{senderName} komencis vokon", + "@startedACall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "status": "Stato", + "@status": { + "type": "text", + "placeholders": {} + }, + "statusExampleMessage": "Kiel vi fartas?", + "@statusExampleMessage": { + "type": "text", + "placeholders": {} + }, + "submit": "Sendi", + "@submit": { + "type": "text", + "placeholders": {} + }, + "synchronizingPleaseWait": "Spegulante… Bonvolu atendi.", + "@synchronizingPleaseWait": { + "type": "text", + "placeholders": {} + }, + "systemTheme": "Sistema", + "@systemTheme": { + "type": "text", + "placeholders": {} + }, + "theyDontMatch": "Ili ne akordas", + "@theyDontMatch": { + "type": "text", + "placeholders": {} + }, + "theyMatch": "Ili akordas", + "@theyMatch": { + "type": "text", + "placeholders": {} + }, + "title": "FluffyChat", + "@title": { + "description": "Title for the application", + "type": "text", + "placeholders": {} + }, + "toggleFavorite": "Baskuli elstarigon", + "@toggleFavorite": { + "type": "text", + "placeholders": {} + }, + "toggleMuted": "Basklui silentigon", + "@toggleMuted": { + "type": "text", + "placeholders": {} + }, + "toggleUnread": "Baskuli legitecon", + "@toggleUnread": { + "type": "text", + "placeholders": {} + }, + "tooManyRequestsWarning": "Tro multaj petoj. Bonvolu reprovi poste!", + "@tooManyRequestsWarning": { + "type": "text", + "placeholders": {} + }, + "transferFromAnotherDevice": "Transporti de alia aparato", + "@transferFromAnotherDevice": { + "type": "text", + "placeholders": {} + }, + "tryToSendAgain": "Reprovi sendi", + "@tryToSendAgain": { + "type": "text", + "placeholders": {} + }, + "unavailable": "Nedisponeble", + "@unavailable": { + "type": "text", + "placeholders": {} + }, + "unbannedUser": "{username} malforbaris uzanton {targetName}", + "@unbannedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "unblockDevice": "Malbloki aparaton", + "@unblockDevice": { + "type": "text", + "placeholders": {} + }, + "unknownDevice": "Nekonata aparato", + "@unknownDevice": { + "type": "text", + "placeholders": {} + }, + "unknownEncryptionAlgorithm": "Nekonata ĉifra algoritmo", + "@unknownEncryptionAlgorithm": { + "type": "text", + "placeholders": {} + }, + "unknownEvent": "Nekonata evento «{type}»", + "@unknownEvent": { + "type": "text", + "placeholders": { + "type": {} + } + }, + "unmuteChat": "Malsilentigi babilon", + "@unmuteChat": { + "type": "text", + "placeholders": {} + }, + "unpin": "Malfiksi", + "@unpin": { + "type": "text", + "placeholders": {} + }, + "unreadChats": "{unreadCount, plural, =1{1 nelegita babilo} other{{unreadCount} nelegitaj babiloj}}", + "@unreadChats": { + "type": "text", + "placeholders": { + "unreadCount": {} + } + }, + "userAndOthersAreTyping": "{username} kaj {count} aliaj tajpas…", + "@userAndOthersAreTyping": { + "type": "text", + "placeholders": { + "username": {}, + "count": {} + } + }, + "userAndUserAreTyping": "{username} kaj {username2} tajpas…", + "@userAndUserAreTyping": { + "type": "text", + "placeholders": { + "username": {}, + "username2": {} + } + }, + "userIsTyping": "{username} tajpas…", + "@userIsTyping": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "userLeftTheChat": "{username} foriris de la babilo", + "@userLeftTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "username": "Uzantonomo", + "@username": { + "type": "text", + "placeholders": {} + }, + "userSentUnknownEvent": "{username} sendis eventon de speco {type}", + "@userSentUnknownEvent": { + "type": "text", + "placeholders": { + "username": {}, + "type": {} + } + }, + "verified": "Kontrolita", + "@verified": { + "type": "text", + "placeholders": {} + }, + "verify": "Kontroli", + "@verify": { + "type": "text", + "placeholders": {} + }, + "verifyStart": "Komenci kontrolon", + "@verifyStart": { + "type": "text", + "placeholders": {} + }, + "verifySuccess": "Vi sukcese kontrolis!", + "@verifySuccess": { + "type": "text", + "placeholders": {} + }, + "verifyTitle": "Kontrolante alian konton", + "@verifyTitle": { + "type": "text", + "placeholders": {} + }, + "videoCall": "Vidvoko", + "@videoCall": { + "type": "text", + "placeholders": {} + }, + "visibilityOfTheChatHistory": "Videbleco de historio de la babilo", + "@visibilityOfTheChatHistory": { + "type": "text", + "placeholders": {} + }, + "visibleForAllParticipants": "Videbla al ĉiuj partoprenantoj", + "@visibleForAllParticipants": { + "type": "text", + "placeholders": {} + }, + "visibleForEveryone": "Videbla al ĉiuj", + "@visibleForEveryone": { + "type": "text", + "placeholders": {} + }, + "voiceMessage": "Voĉmesaĝo", + "@voiceMessage": { + "type": "text", + "placeholders": {} + }, + "waitingPartnerAcceptRequest": "Atendante konfirmon de peto de la kunulo…", + "@waitingPartnerAcceptRequest": { + "type": "text", + "placeholders": {} + }, + "waitingPartnerEmoji": "Atendante akcepton de la bildosignoj de la kunulo…", + "@waitingPartnerEmoji": { + "type": "text", + "placeholders": {} + }, + "waitingPartnerNumbers": "Atendante akcepton de la numeroj, de la kunulo…", + "@waitingPartnerNumbers": { + "type": "text", + "placeholders": {} + }, + "wallpaper": "Fonbildo", + "@wallpaper": { + "type": "text", + "placeholders": {} + }, + "warning": "Averto!", + "@warning": { + "type": "text", + "placeholders": {} + }, + "weSentYouAnEmail": "Ni sendis retleteron al vi", + "@weSentYouAnEmail": { + "type": "text", + "placeholders": {} + }, + "whoCanPerformWhichAction": "Kiu povas kion", + "@whoCanPerformWhichAction": { + "type": "text", + "placeholders": {} + }, + "whoIsAllowedToJoinThisGroup": "Kiu rajtas aliĝi al ĉi tiu grupo", + "@whoIsAllowedToJoinThisGroup": { + "type": "text", + "placeholders": {} + }, + "whyDoYouWantToReportThis": "Kial vi volas tion ĉi raporti?", + "@whyDoYouWantToReportThis": { + "type": "text", + "placeholders": {} + }, + "wipeChatBackup": "Ĉu forviŝi la savkopion de via babilo por krei novan sekurecan ŝlosilon?", + "@wipeChatBackup": { + "type": "text", + "placeholders": {} + }, + "withTheseAddressesRecoveryDescription": "Per tiuj ĉi adresoj vi povas rehavi vian pasvorton.", + "@withTheseAddressesRecoveryDescription": { + "type": "text", + "placeholders": {} + }, + "writeAMessage": "Skribi mesaĝon…", + "@writeAMessage": { + "type": "text", + "placeholders": {} + }, + "yes": "Jes", + "@yes": { + "type": "text", + "placeholders": {} + }, + "you": "Vi", + "@you": { + "type": "text", + "placeholders": {} + }, + "youAreInvitedToThisChat": "Vi estas invitita al ĉi tiu babilo", + "@youAreInvitedToThisChat": { + "type": "text", + "placeholders": {} + }, + "youAreNoLongerParticipatingInThisChat": "Vi ne plu partoprenas ĉi tiun babilon", + "@youAreNoLongerParticipatingInThisChat": { + "type": "text", + "placeholders": {} + }, + "youCannotInviteYourself": "Vi ne povas inviti vin mem", + "@youCannotInviteYourself": { + "type": "text", + "placeholders": {} + }, + "youHaveBeenBannedFromThisChat": "Vi estas forbarita de ĉi tiu babilo", + "@youHaveBeenBannedFromThisChat": { + "type": "text", + "placeholders": {} + }, + "yourPublicKey": "Via publika ŝlosilo", + "@yourPublicKey": { + "type": "text", + "placeholders": {} + }, + "sendAsText": "Sendi kiel tekston", + "@sendAsText": { + "type": "text" + }, + "noMatrixServer": "{server1} ne estas matriksa servilo, eble provu anstataŭe servilon {server2}?", + "@noMatrixServer": { + "type": "text", + "placeholders": { + "server1": {}, + "server2": {} + } + }, + "commandHint_send": "Sendi tekston", + "@commandHint_send": { + "type": "text", + "description": "Usage hint for the command /send" + }, + "chatHasBeenAddedToThisSpace": "Babilo aldoniĝis al ĉi tiu aro", + "@chatHasBeenAddedToThisSpace": {}, + "autoplayImages": "Memage ludi movbildajn glumarkojn kaj mienetojn", + "@autoplayImages": { + "type": "text", + "placeholder": {} + }, + "addToSpace": "Aldoni al aro", + "@addToSpace": {}, + "homeserver": "Hejmservilo", + "@homeserver": {}, + "sendOnEnter": "Sendi per eniga klavo", + "@sendOnEnter": {}, + "discover": "", + "@discover": { + "type": "text", + "placeholders": {} + }, + "hugContent": "", + "@hugContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "jumpToLastReadMessage": "", + "@jumpToLastReadMessage": {}, + "allRooms": "", + "@allRooms": { + "type": "text", + "placeholders": {} + }, + "whoCanSeeMyStories": "", + "@whoCanSeeMyStories": {}, + "commandHint_cuddle": "", + "@commandHint_cuddle": {}, + "widgetVideo": "", + "@widgetVideo": {}, + "dismiss": "", + "@dismiss": {}, + "reportErrorDescription": "", + "@reportErrorDescription": {}, + "addAccount": "", + "@addAccount": {}, + "unsupportedAndroidVersion": "", + "@unsupportedAndroidVersion": {}, + "widgetJitsi": "", + "@widgetJitsi": {}, + "messageType": "", + "@messageType": {}, + "noEmailWarning": "", + "@noEmailWarning": {}, + "indexedDbErrorLong": "", + "@indexedDbErrorLong": {}, + "oneClientLoggedOut": "", + "@oneClientLoggedOut": {}, + "startFirstChat": "", + "@startFirstChat": {}, + "callingAccount": "", + "@callingAccount": {}, + "setColorTheme": "", + "@setColorTheme": {}, + "nextAccount": "", + "@nextAccount": {}, + "commandHint_create": "", + "@commandHint_create": { + "type": "text", + "description": "Usage hint for the command /create" + }, + "allSpaces": "", + "@allSpaces": {}, + "supposedMxid": "", + "@supposedMxid": { + "type": "text", + "placeholders": { + "mxid": {} + } + }, + "user": "", + "@user": {}, + "youAcceptedTheInvitation": "", + "@youAcceptedTheInvitation": {}, + "youInvitedBy": "", + "@youInvitedBy": { + "placeholders": { + "user": {} + } + }, + "banUserDescription": "", + "@banUserDescription": {}, + "requests": "", + "@requests": {}, + "widgetEtherpad": "", + "@widgetEtherpad": {}, + "stories": "", + "@stories": {}, + "addToStory": "", + "@addToStory": {}, + "removeDevicesDescription": "", + "@removeDevicesDescription": {}, + "separateChatTypes": "", + "@separateChatTypes": { + "type": "text", + "placeholders": {} + }, + "tryAgain": "", + "@tryAgain": {}, + "youKickedAndBanned": "", + "@youKickedAndBanned": { + "placeholders": { + "user": {} + } + }, + "showDirectChatsInSpaces": "", + "@showDirectChatsInSpaces": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterValidEmail": "", + "@pleaseEnterValidEmail": {}, + "unbanUserDescription": "", + "@unbanUserDescription": {}, + "todoLists": "", + "@todoLists": {}, + "youRejectedTheInvitation": "", + "@youRejectedTheInvitation": {}, + "otherCallingPermissions": "", + "@otherCallingPermissions": {}, + "messagesStyle": "", + "@messagesStyle": {}, + "link": "", + "@link": {}, + "widgetUrlError": "", + "@widgetUrlError": {}, + "emailOrUsername": "", + "@emailOrUsername": {}, + "newSpaceDescription": "", + "@newSpaceDescription": {}, + "chatDescription": "", + "@chatDescription": {}, + "callingAccountDetails": "", + "@callingAccountDetails": {}, + "pleaseChooseAtLeastChars": "", + "@pleaseChooseAtLeastChars": { + "type": "text", + "placeholders": { + "min": {} + } + }, + "enterSpace": "", + "@enterSpace": {}, + "encryptThisChat": "", + "@encryptThisChat": {}, + "previousAccount": "", + "@previousAccount": {}, + "reopenChat": "", + "@reopenChat": {}, + "pleaseEnterRecoveryKey": "", + "@pleaseEnterRecoveryKey": {}, + "widgetNameError": "", + "@widgetNameError": {}, + "addToBundle": "", + "@addToBundle": {}, + "addWidget": "", + "@addWidget": {}, + "countFiles": "", + "@countFiles": { + "placeholders": { + "count": {} + } + }, + "noKeyForThisMessage": "", + "@noKeyForThisMessage": {}, + "commandHint_markasgroup": "", + "@commandHint_markasgroup": {}, + "editTodo": "", + "@editTodo": {}, + "hydrateTor": "", + "@hydrateTor": {}, + "pushNotificationsNotAvailable": "", + "@pushNotificationsNotAvailable": {}, + "storeInAppleKeyChain": "", + "@storeInAppleKeyChain": {}, + "hydrate": "", + "@hydrate": {}, + "invalidServerName": "", + "@invalidServerName": {}, + "chatPermissions": "", + "@chatPermissions": {}, + "sender": "", + "@sender": {}, + "storeInAndroidKeystore": "", + "@storeInAndroidKeystore": {}, + "signInWithPassword": "", + "@signInWithPassword": {}, + "pleaseAddATitle": "", + "@pleaseAddATitle": {}, + "updateNow": "", + "@updateNow": {}, + "makeAdminDescription": "", + "@makeAdminDescription": {}, + "commandHint_clearcache": "", + "@commandHint_clearcache": { + "type": "text", + "description": "Usage hint for the command /clearcache" + }, + "saveKeyManuallyDescription": "", + "@saveKeyManuallyDescription": {}, + "editBundlesForAccount": "", + "@editBundlesForAccount": {}, + "whyIsThisMessageEncrypted": "", + "@whyIsThisMessageEncrypted": {}, + "setChatDescription": "", + "@setChatDescription": {}, + "importFromZipFile": "", + "@importFromZipFile": {}, + "dehydrateWarning": "", + "@dehydrateWarning": {}, + "noOtherDevicesFound": "", + "@noOtherDevicesFound": {}, + "yourChatBackupHasBeenSetUp": "", + "@yourChatBackupHasBeenSetUp": {}, + "addDescription": "", + "@addDescription": {}, + "redactedBy": "", + "@redactedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "videoCallsBetaWarning": "", + "@videoCallsBetaWarning": {}, + "storyPrivacyWarning": "", + "@storyPrivacyWarning": {}, + "matrixWidgets": "", + "@matrixWidgets": {}, + "signInWith": "", + "@signInWith": { + "type": "text", + "placeholders": { + "provider": {} + } + }, + "updateAvailable": "", + "@updateAvailable": {}, + "fileIsTooBigForServer": "", + "@fileIsTooBigForServer": {}, + "noTodosYet": "", + "@noTodosYet": {}, + "repeatPassword": "", + "@repeatPassword": {}, + "callingPermissions": "", + "@callingPermissions": {}, + "readUpToHere": "", + "@readUpToHere": {}, + "start": "", + "@start": {}, + "bubbleSize": "", + "@bubbleSize": { + "type": "text", + "placeholders": {} + }, + "unlockOldMessages": "", + "@unlockOldMessages": {}, + "numChats": "", + "@numChats": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "whatIsGoingOn": "", + "@whatIsGoingOn": {}, + "optionalRedactReason": "", + "@optionalRedactReason": {}, + "dehydrate": "", + "@dehydrate": {}, + "locationPermissionDeniedNotice": "", + "@locationPermissionDeniedNotice": { + "type": "text", + "placeholders": {} + }, + "archiveRoomDescription": "", + "@archiveRoomDescription": {}, + "exportEmotePack": "", + "@exportEmotePack": {}, + "switchToAccount": "", + "@switchToAccount": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "locationDisabledNotice": "", + "@locationDisabledNotice": { + "type": "text", + "placeholders": {} + }, + "letsStart": "", + "@letsStart": {}, + "experimentalVideoCalls": "", + "@experimentalVideoCalls": {}, + "savedEmotePack": "", + "@savedEmotePack": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "pleaseEnterRecoveryKeyDescription": "", + "@pleaseEnterRecoveryKeyDescription": {}, + "openInMaps": "", + "@openInMaps": { + "type": "text", + "placeholders": {} + }, + "inviteContactToGroupQuestion": "", + "@inviteContactToGroupQuestion": {}, + "redactedByBecause": "", + "@redactedByBecause": { + "type": "text", + "placeholders": { + "username": {}, + "reason": {} + } + }, + "youHaveWithdrawnTheInvitationFor": "", + "@youHaveWithdrawnTheInvitationFor": { + "placeholders": { + "user": {} + } + }, + "appearOnTopDetails": "", + "@appearOnTopDetails": {}, + "enterRoom": "", + "@enterRoom": {}, + "reportUser": "", + "@reportUser": {}, + "confirmEventUnpin": "", + "@confirmEventUnpin": {}, + "youInvitedUser": "", + "@youInvitedUser": { + "placeholders": { + "user": {} + } + }, + "fileHasBeenSavedAt": "", + "@fileHasBeenSavedAt": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "importZipFile": "", + "@importZipFile": {}, + "anyoneCanKnock": "", + "@anyoneCanKnock": {}, + "redactMessageDescription": "", + "@redactMessageDescription": {}, + "recoveryKey": "", + "@recoveryKey": {}, + "commandHint_discardsession": "", + "@commandHint_discardsession": { + "type": "text", + "description": "Usage hint for the command /discardsession" + }, + "invalidInput": "", + "@invalidInput": {}, + "todosUnencrypted": "", + "@todosUnencrypted": {}, + "dehydrateTorLong": "", + "@dehydrateTorLong": {}, + "replyHasBeenSent": "", + "@replyHasBeenSent": {}, + "doNotShowAgain": "", + "@doNotShowAgain": {}, + "report": "", + "@report": {}, + "yourStory": "", + "@yourStory": {}, + "unverified": "", + "@unverified": {}, + "serverRequiresEmail": "", + "@serverRequiresEmail": {}, + "hideUnimportantStateEvents": "", + "@hideUnimportantStateEvents": {}, + "screenSharingTitle": "", + "@screenSharingTitle": {}, + "widgetCustom": "", + "@widgetCustom": {}, + "addToSpaceDescription": "", + "@addToSpaceDescription": {}, + "googlyEyesContent": "", + "@googlyEyesContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "whoCanSeeMyStoriesDesc": "", + "@whoCanSeeMyStoriesDesc": {}, + "youBannedUser": "", + "@youBannedUser": { + "placeholders": { + "user": {} + } + }, + "unsubscribeStories": "", + "@unsubscribeStories": {}, + "loginWithOneClick": "", + "@loginWithOneClick": {}, + "addChatDescription": "", + "@addChatDescription": {}, + "hasKnocked": "", + "@hasKnocked": { + "placeholders": { + "user": {} + } + }, + "publish": "", + "@publish": {}, + "openLinkInBrowser": "", + "@openLinkInBrowser": {}, + "messageInfo": "", + "@messageInfo": {}, + "disableEncryptionWarning": "", + "@disableEncryptionWarning": {}, + "directChat": "", + "@directChat": {}, + "noOneCanJoin": "", + "@noOneCanJoin": {}, + "wrongPinEntered": "", + "@wrongPinEntered": { + "type": "text", + "placeholders": { + "seconds": {} + } + }, + "sendTypingNotifications": "", + "@sendTypingNotifications": {}, + "inviteGroupChat": "", + "@inviteGroupChat": {}, + "appearOnTop": "", + "@appearOnTop": {}, + "invitePrivateChat": "", + "@invitePrivateChat": {}, + "foregroundServiceRunning": "", + "@foregroundServiceRunning": {}, + "voiceCall": "", + "@voiceCall": {}, + "importEmojis": "", + "@importEmojis": {}, + "wasDirectChatDisplayName": "", + "@wasDirectChatDisplayName": { + "type": "text", + "placeholders": { + "oldDisplayName": {} + } + }, + "noChatDescriptionYet": "", + "@noChatDescriptionYet": {}, + "newTodo": "", + "@newTodo": {}, + "removeFromBundle": "", + "@removeFromBundle": {}, + "confirmMatrixId": "", + "@confirmMatrixId": {}, + "learnMore": "", + "@learnMore": {}, + "notAnImage": "", + "@notAnImage": {}, + "users": "", + "@users": {}, + "openGallery": "", + "@openGallery": {}, + "chatDescriptionHasBeenChanged": "", + "@chatDescriptionHasBeenChanged": {}, + "newGroup": "", + "@newGroup": {}, + "bundleName": "", + "@bundleName": {}, + "dehydrateTor": "", + "@dehydrateTor": {}, + "todoListChangedError": "", + "@todoListChangedError": {}, + "removeFromSpace": "", + "@removeFromSpace": {}, + "enterInviteLinkOrMatrixId": "", + "@enterInviteLinkOrMatrixId": {}, + "roomUpgradeDescription": "", + "@roomUpgradeDescription": {}, + "scanQrCode": "", + "@scanQrCode": {}, + "pleaseEnterANumber": "", + "@pleaseEnterANumber": {}, + "youKicked": "", + "@youKicked": { + "placeholders": { + "user": {} + } + }, + "profileNotFound": "", + "@profileNotFound": {}, + "jump": "", + "@jump": {}, + "reactedWith": "", + "@reactedWith": { + "type": "text", + "placeholders": { + "sender": {}, + "reaction": {} + } + }, + "sorryThatsNotPossible": "", + "@sorryThatsNotPossible": {}, + "storyFrom": "", + "@storyFrom": { + "type": "text", + "placeholders": { + "date": {}, + "body": {} + } + }, + "videoWithSize": "", + "@videoWithSize": { + "type": "text", + "placeholders": { + "size": {} + } + }, + "shareInviteLink": "", + "@shareInviteLink": {}, + "commandHint_markasdm": "", + "@commandHint_markasdm": {}, + "recoveryKeyLost": "", + "@recoveryKeyLost": {}, + "cuddleContent": "", + "@cuddleContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "deviceKeys": "", + "@deviceKeys": {}, + "emoteKeyboardNoRecents": "", + "@emoteKeyboardNoRecents": { + "type": "text", + "placeholders": {} + }, + "endToEndEncryption": "", + "@endToEndEncryption": {}, + "setTheme": "", + "@setTheme": {}, + "youJoinedTheChat": "", + "@youJoinedTheChat": {}, + "openVideoCamera": "", + "@openVideoCamera": { + "type": "text", + "placeholders": {} + }, + "thisUserHasNotPostedAnythingYet": "", + "@thisUserHasNotPostedAnythingYet": {}, + "markAsRead": "", + "@markAsRead": {}, + "widgetName": "", + "@widgetName": {}, + "errorAddingWidget": "", + "@errorAddingWidget": {}, + "commandHint_dm": "", + "@commandHint_dm": { + "type": "text", + "description": "Usage hint for the command /dm" + }, + "commandHint_hug": "", + "@commandHint_hug": {}, + "replace": "", + "@replace": {}, + "youUnbannedUser": "", + "@youUnbannedUser": { + "placeholders": { + "user": {} + } + }, + "newSpace": "", + "@newSpace": {}, + "emojis": "", + "@emojis": {}, + "commandHint_googly": "", + "@commandHint_googly": {}, + "pleaseTryAgainLaterOrChooseDifferentServer": "", + "@pleaseTryAgainLaterOrChooseDifferentServer": {}, + "createGroup": "", + "@createGroup": {}, + "hydrateTorLong": "", + "@hydrateTorLong": {}, + "time": "", + "@time": {}, + "custom": "", + "@custom": {}, + "noBackupWarning": "", + "@noBackupWarning": {}, + "editWidgets": "", + "@editWidgets": {}, + "storeInSecureStorageDescription": "", + "@storeInSecureStorageDescription": {}, + "openChat": "", + "@openChat": {}, + "kickUserDescription": "", + "@kickUserDescription": {}, + "importNow": "", + "@importNow": {}, + "pinMessage": "", + "@pinMessage": {}, + "invite": "", + "@invite": {}, + "enableMultiAccounts": "", + "@enableMultiAccounts": {}, + "continueWith": "", + "@continueWith": {}, + "indexedDbErrorTitle": "", + "@indexedDbErrorTitle": {}, + "unsupportedAndroidVersionLong": "", + "@unsupportedAndroidVersionLong": {}, + "storeSecurlyOnThisDevice": "", + "@storeSecurlyOnThisDevice": {}, + "passwordsDoNotMatch": "", + "@passwordsDoNotMatch": {}, + "iUnderstand": "", + "@iUnderstand": {}, + "screenSharingDetail": "", + "@screenSharingDetail": {}, + "placeCall": "", + "@placeCall": {} +} diff --git a/assets/l10n/intl_es.arb b/assets/l10n/intl_es.arb index d19c8410d..630db9401 100644 --- a/assets/l10n/intl_es.arb +++ b/assets/l10n/intl_es.arb @@ -23,6 +23,11 @@ "type": "text", "placeholders": {} }, + "accountInformation": "Información de la cuenta", + "@accountInformation": { + "type": "text", + "placeholders": {} + }, "activatedEndToEndEncryption": "{username} activó el cifrado de extremo a extremo", "@activatedEndToEndEncryption": { "type": "text", @@ -50,6 +55,11 @@ "type": "text", "placeholders": {} }, + "alreadyHaveAnAccount": "¿Ya tiene una cuenta?", + "@alreadyHaveAnAccount": { + "type": "text", + "placeholders": {} + }, "answeredTheCall": "{senderName} respondió a la llamada", "@answeredTheCall": { "type": "text", @@ -67,33 +77,58 @@ "type": "text", "placeholders": {} }, + "archivedRoom": "", + "@archivedRoom": { + "type": "text", + "placeholders": {} + }, "areGuestsAllowedToJoin": "¿Pueden unirse los usuarios visitantes?", "@areGuestsAllowedToJoin": { "type": "text", "placeholders": {} }, - "areYouSure": "¿Estás seguro?", + "areYouSure": "¿Está seguro?", "@areYouSure": { "type": "text", "placeholders": {} }, - "areYouSureYouWantToLogout": "¿Confirma que quiere cerrar sesión?", + "areYouSureYouWantToLogout": "¿Está seguro que quiere cerrar sesión?", "@areYouSureYouWantToLogout": { "type": "text", "placeholders": {} }, + "askSSSSCache": "Ingrese su contraseña de almacenamiento segura (SSSS) o la clave de recuperación para almacenar en caché las claves.", + "@askSSSSCache": { + "type": "text", + "placeholders": {} + }, "askSSSSSign": "Para poder confirmar a la otra persona, ingrese su contraseña de almacenamiento segura o la clave de recuperación.", "@askSSSSSign": { "type": "text", "placeholders": {} }, - "askVerificationRequest": "¿Aceptar esta solicitud de verificación de {username}?", + "askSSSSVerify": "", + "@askSSSSVerify": { + "type": "text", + "placeholders": {} + }, + "askVerificationRequest": "¿Acepta esta solicitud de verificación de {username}?", "@askVerificationRequest": { "type": "text", "placeholders": { "username": {} } }, + "authentication": "Autenticación", + "@authentication": { + "type": "text", + "placeholders": {} + }, + "avatarHasBeenChanged": "Imagen de perfil modificada", + "@avatarHasBeenChanged": { + "type": "text", + "placeholders": {} + }, "badServerLoginTypesException": "El servidor soporta los siguientes mecanismos para autenticación:\n{serverVersions}\npero esta aplicación sólo soporta:\n{supportedVersions}", "@badServerLoginTypesException": { "type": "text", @@ -138,6 +173,11 @@ "type": "text", "placeholders": {} }, + "cachedKeys": "Claves almacenadas en caché", + "@cachedKeys": { + "type": "text", + "placeholders": {} + }, "cancel": "Cancelar", "@cancel": { "type": "text", @@ -238,7 +278,7 @@ "username": {} } }, - "changedTheRoomAliases": "{username} cambió el alias de la sala", + "changedTheRoomAliases": "{username} cambió el alias del chat", "@changedTheRoomAliases": { "type": "text", "placeholders": { @@ -252,11 +292,21 @@ "username": {} } }, + "changelog": "Registro de cambios", + "@changelog": { + "type": "text", + "placeholders": {} + }, "changePassword": "Cambiar la contraseña", "@changePassword": { "type": "text", "placeholders": {} }, + "changesHaveBeenSaved": "Los cambios se han guardado", + "@changesHaveBeenSaved": { + "type": "text", + "placeholders": {} + }, "changeTheHomeserver": "Cambiar el servidor", "@changeTheHomeserver": { "type": "text", @@ -272,6 +322,11 @@ "type": "text", "placeholders": {} }, + "changeTheServer": "Cambiar el servidor", + "@changeTheServer": { + "type": "text", + "placeholders": {} + }, "changeWallpaper": "Cambiar el fondo de pantalla", "@changeWallpaper": { "type": "text", @@ -302,7 +357,7 @@ "type": "text", "placeholders": {} }, - "chats": "Conversaciones", + "chats": "Chats de Groupos", "@chats": { "type": "text", "placeholders": {} @@ -324,12 +379,12 @@ "type": "text", "placeholders": {} }, - "compareEmojiMatch": "Por favor compare los emojis", + "compareEmojiMatch": "Compare y asegúrese de que los siguientes emoji coincidan con los del otro dispositivo:", "@compareEmojiMatch": { "type": "text", "placeholders": {} }, - "compareNumbersMatch": "Por favor compare los números", + "compareNumbersMatch": "Compare y asegúrese de que los siguientes números coincidan con los del otro dispositivo:", "@compareNumbersMatch": { "type": "text", "placeholders": {} @@ -339,17 +394,27 @@ "type": "text", "placeholders": {} }, - "connect": "Conectar", + "connect": "Iniciar", "@connect": { "type": "text", "placeholders": {} }, - "contactHasBeenInvitedToTheGroup": "El contacto ha sido invitado al grupo", + "connectionAttemptFailed": "Falló el intento de conexión", + "@connectionAttemptFailed": { + "type": "text", + "placeholders": {} + }, + "contactHasBeenInvitedToTheGroup": "El contacto ha sido invitado", "@contactHasBeenInvitedToTheGroup": { "type": "text", "placeholders": {} }, - "copiedToClipboard": "Copiado al portapapeles", + "contentViewer": "Visor de contenido", + "@contentViewer": { + "type": "text", + "placeholders": {} + }, + "copiedToClipboard": "Copiado al portapapeles!", "@copiedToClipboard": { "type": "text", "placeholders": {} @@ -371,6 +436,16 @@ "error": {} } }, + "couldNotSetAvatar": "No se pudo establecer la imagen de perfil", + "@couldNotSetAvatar": { + "type": "text", + "placeholders": {} + }, + "couldNotSetDisplayname": "No se pudo establecer el nombre visible", + "@couldNotSetDisplayname": { + "type": "text", + "placeholders": {} + }, "countParticipants": "{count} participantes", "@countParticipants": { "type": "text", @@ -390,11 +465,26 @@ "username": {} } }, - "createNewGroup": "Crear grupo nuevo", + "createAccountNow": "Crear cuenta ahora", + "@createAccountNow": { + "type": "text", + "placeholders": {} + }, + "createNewGroup": "Crear nuevo chat", "@createNewGroup": { "type": "text", "placeholders": {} }, + "crossSigningDisabled": "La confirmación cruzada está deshabilitada", + "@crossSigningDisabled": { + "type": "text", + "placeholders": {} + }, + "crossSigningEnabled": "La confirmación cruzada está habilitada", + "@crossSigningEnabled": { + "type": "text", + "placeholders": {} + }, "currentlyActive": "Actualmente activo", "@currentlyActive": { "type": "text", @@ -465,11 +555,26 @@ "type": "text", "placeholders": {} }, + "deviceVerifyDescription": "El cifrado solo es seguro cuando se han verificado todos los dispositivos.", + "@deviceVerifyDescription": { + "type": "text", + "placeholders": {} + }, + "discardPicture": "Descartar imagen", + "@discardPicture": { + "type": "text", + "placeholders": {} + }, "displaynameHasBeenChanged": "El nombre visible ha cambiado", "@displaynameHasBeenChanged": { "type": "text", "placeholders": {} }, + "donate": "Donar", + "@donate": { + "type": "text", + "placeholders": {} + }, "downloadFile": "Descargar archivo", "@downloadFile": { "type": "text", @@ -480,7 +585,12 @@ "type": "text", "placeholders": {} }, - "editRoomAliases": "Editar alias de la sala", + "editJitsiInstance": "Cambiar la instancia de Jitsi", + "@editJitsiInstance": { + "type": "text", + "placeholders": {} + }, + "editRoomAliases": "Editar alias del chat", "@editRoomAliases": { "type": "text", "placeholders": {} @@ -495,7 +605,7 @@ "type": "text", "placeholders": {} }, - "emotePacks": "Paquetes de emoticonos para la habitación", + "emotePacks": "Paquetes de emoticonos para el chat", "@emotePacks": { "type": "text", "placeholders": {} @@ -535,11 +645,21 @@ "type": "text", "placeholders": {} }, + "encryptionAlgorithm": "Algoritmo de cifrado", + "@encryptionAlgorithm": { + "type": "text", + "placeholders": {} + }, "encryptionNotEnabled": "El cifrado no está habilitado", "@encryptionNotEnabled": { "type": "text", "placeholders": {} }, + "end2endEncryptionSettings": "Configuración del cifrado de extremo a extremo", + "@end2endEncryptionSettings": { + "type": "text", + "placeholders": {} + }, "endedTheCall": "{senderName} terminó la llamada", "@endedTheCall": { "type": "text", @@ -547,16 +667,21 @@ "senderName": {} } }, - "enterAGroupName": "Ingrese un nombre de grupo", + "enterAGroupName": "Ingrese el nombre del chat", "@enterAGroupName": { "type": "text", "placeholders": {} }, - "enterAnEmailAddress": "Introducir una dirección de correo electrónico", + "enterAnEmailAddress": "Introduzca un correo electrónico", "@enterAnEmailAddress": { "type": "text", "placeholders": {} }, + "enterAUsername": "Ingrese un nombre de usuario", + "@enterAUsername": { + "type": "text", + "placeholders": {} + }, "enterYourHomeserver": "Ingrese su servidor", "@enterYourHomeserver": { "type": "text", @@ -572,6 +697,11 @@ "type": "text", "placeholders": {} }, + "fileSize": "Tamaño del archivo", + "@fileSize": { + "type": "text", + "placeholders": {} + }, "fluffychat": "FluffyChat", "@fluffychat": { "type": "text", @@ -582,6 +712,11 @@ "type": "text", "placeholders": {} }, + "friday": "Viernes", + "@friday": { + "type": "text", + "placeholders": {} + }, "fromJoining": "Desde que se unió", "@fromJoining": { "type": "text", @@ -619,12 +754,12 @@ "displayname": {} } }, - "guestsAreForbidden": "Los visitantes están prohibidos", + "guestsAreForbidden": "Los usuarios visitantes están prohibidos", "@guestsAreForbidden": { "type": "text", "placeholders": {} }, - "guestsCanJoin": "Los visitantes pueden unirse", + "guestsCanJoin": "Los usuarios visitantes pueden unirse", "@guestsCanJoin": { "type": "text", "placeholders": {} @@ -652,6 +787,11 @@ "type": "text", "placeholders": {} }, + "homeserverIsNotCompatible": "El servidor no es compatible", + "@homeserverIsNotCompatible": { + "type": "text", + "placeholders": {} + }, "id": "Identificación", "@id": { "type": "text", @@ -662,17 +802,17 @@ "type": "text", "placeholders": {} }, - "ignoredUsers": "Usuarios ignorados", + "ignoredUsers": "Usuarios bloqueados", "@ignoredUsers": { "type": "text", "placeholders": {} }, - "ignoreListDescription": "Puede ignorar a los usuarios que le molesten. No podrá recibir mensajes ni invitaciones a salas de los usuarios de su lista personal de ignorados.", + "ignoreListDescription": "Puede bloquear a los usuarios que le molesten. No podrá recibir mensajes ni invitaciones a chats de los usuarios de su lista personal de bloqueados.", "@ignoreListDescription": { "type": "text", "placeholders": {} }, - "ignoreUsername": "Ignorar nombre de usuario", + "ignoreUsername": "Bloquear nombre de usuario", "@ignoreUsername": { "type": "text", "placeholders": {} @@ -712,7 +852,7 @@ "type": "text", "placeholders": {} }, - "inviteText": "{username} te invitó a FluffyChat.\n1. Instale FluffyChat: https://fluffychat.im\n2. Regístrate o inicia sesión \n3. Abra el enlace de invitación: {link}", + "inviteText": "{username} le invitó a FluffyChat.\n1. Instale FluffyChat: https://fluffychat.im\n2. Regístrese o inicia sesión \n3. Abra el enlace de invitación: {link}", "@inviteText": { "type": "text", "placeholders": { @@ -720,6 +860,11 @@ "link": {} } }, + "isDeviceKeyCorrect": "¿Es correcta la siguiente clave de dispositivo?", + "@isDeviceKeyCorrect": { + "type": "text", + "placeholders": {} + }, "isTyping": "está escribiendo…", "@isTyping": { "type": "text", @@ -732,11 +877,21 @@ "username": {} } }, - "joinRoom": "Unirse a la sala", + "joinRoom": "Unirse al chat", "@joinRoom": { "type": "text", "placeholders": {} }, + "keysCached": "Las claves están en caché", + "@keysCached": { + "type": "text", + "placeholders": {} + }, + "keysMissing": "Faltan las claves", + "@keysMissing": { + "type": "text", + "placeholders": {} + }, "kicked": "👞{username} echó a {targetName}", "@kicked": { "type": "text", @@ -753,7 +908,7 @@ "targetName": {} } }, - "kickFromChat": "Echar del chat", + "kickFromChat": "Eliminar del chat", "@kickFromChat": { "type": "text", "placeholders": {} @@ -765,6 +920,11 @@ "localizedTimeShort": {} } }, + "lastSeenIp": "Última dirección IP vista", + "@lastSeenIp": { + "type": "text", + "placeholders": {} + }, "lastSeenLongTimeAgo": "Visto hace mucho tiempo", "@lastSeenLongTimeAgo": { "type": "text", @@ -807,7 +967,7 @@ "type": "text", "placeholders": {} }, - "login": "Acceso", + "login": "Iniciar sesión", "@login": { "type": "text", "placeholders": {} @@ -824,6 +984,16 @@ "type": "text", "placeholders": {} }, + "makeAModerator": "Hacer un moderador/a", + "@makeAModerator": { + "type": "text", + "placeholders": {} + }, + "makeAnAdmin": "Hacer un administrador/a", + "@makeAnAdmin": { + "type": "text", + "placeholders": {} + }, "makeSureTheIdentifierIsValid": "Asegúrese de que el identificador es válido", "@makeSureTheIdentifierIsValid": { "type": "text", @@ -844,6 +1014,18 @@ "type": "text", "placeholders": {} }, + "monday": "Lunes", + "@monday": { + "type": "text", + "placeholders": {} + }, + "moreEvents": "{count,plural, =1{1 evento más} other{{count} más eventos}}", + "@moreEvents": { + "type": "text", + "placeholders": { + "count": {} + } + }, "muteChat": "Silenciar chat", "@muteChat": { "type": "text", @@ -874,12 +1056,17 @@ "type": "text", "placeholders": {} }, + "noCrossSignBootstrap": "Fluffychat actualmente no soporta la activación de Cross-Signing. Por favor, actívelo dentro de Riot.", + "@noCrossSignBootstrap": { + "type": "text", + "placeholders": {} + }, "noEmotesFound": "Ningún emote encontrado. 😕", "@noEmotesFound": { "type": "text", "placeholders": {} }, - "noEncryptionForPublicRooms": "Sólo se puede activar el cifrado en cuanto la sala deja de ser de acceso público.", + "noEncryptionForPublicRooms": "Sólo se puede activar el cifrado en cuanto el chat deja de ser de acceso público.", "@noEncryptionForPublicRooms": { "type": "text", "placeholders": {} @@ -889,6 +1076,11 @@ "type": "text", "placeholders": {} }, + "noMegolmBootstrap": "Fluffychat actualmente no soporta la activación de Online Key Backup. Por favor, actívelo dentro de Riot.", + "@noMegolmBootstrap": { + "type": "text", + "placeholders": {} + }, "none": "Ninguno", "@none": { "type": "text", @@ -899,11 +1091,28 @@ "type": "text", "placeholders": {} }, - "noRoomsFound": "Ninguna sala encontrada…", + "noPublicRoomsFound": "Sin chats públicos…", + "@noPublicRoomsFound": { + "type": "text", + "placeholders": {} + }, + "noRoomsFound": "Ningún chat encontrado…", "@noRoomsFound": { "type": "text", "placeholders": {} }, + "notSupportedInWeb": "No es compatible con la versión web", + "@notSupportedInWeb": { + "type": "text", + "placeholders": {} + }, + "numberSelected": "{number} seleccionado(s)", + "@numberSelected": { + "type": "text", + "placeholders": { + "number": {} + } + }, "offline": "Desconectado", "@offline": { "type": "text", @@ -919,6 +1128,11 @@ "type": "text", "placeholders": {} }, + "onlineKeyBackupDisabled": "La copia de seguridad de la clave en línea está deshabilitada", + "@onlineKeyBackupDisabled": { + "type": "text", + "placeholders": {} + }, "onlineKeyBackupEnabled": "La copia de seguridad de la clave en línea está habilitada", "@onlineKeyBackupEnabled": { "type": "text", @@ -939,11 +1153,16 @@ "type": "text", "placeholders": {} }, - "optionalGroupName": "(Opcional) Nombre del grupo", + "optionalGroupName": "Nombre del chat", "@optionalGroupName": { "type": "text", "placeholders": {} }, + "participatingUserDevices": "Dispositivos de usuario participantes", + "@participatingUserDevices": { + "type": "text", + "placeholders": {} + }, "passphraseOrKey": "contraseña o clave de recuperación", "@passphraseOrKey": { "type": "text", @@ -996,6 +1215,11 @@ "type": "text", "placeholders": {} }, + "pleaseEnterSecurityKey": "Por favor, introduzca su clave de seguridad:", + "@pleaseEnterSecurityKey": { + "type": "text", + "placeholders": {} + }, "pleaseEnterYourPassword": "Por favor ingrese su contraseña", "@pleaseEnterYourPassword": { "type": "text", @@ -1016,7 +1240,12 @@ "type": "text", "placeholders": {} }, - "publicRooms": "Salas públicas", + "publicGroups": "Grupos públicos", + "@publicGroups": { + "type": "text", + "placeholders": {} + }, + "publicRooms": "Chats públicos", "@publicRooms": { "type": "text", "placeholders": {} @@ -1077,6 +1306,11 @@ "type": "text", "placeholders": {} }, + "removeMessage": "Eliminar mensaje", + "@removeMessage": { + "type": "text", + "placeholders": {} + }, "renderRichContent": "Mostrar el contenido con mensajes enriquecidos", "@renderRichContent": { "type": "text", @@ -1092,16 +1326,46 @@ "type": "text", "placeholders": {} }, - "roomHasBeenUpgraded": "La sala ha subido de categoría", + "requestToReadOlderMessages": "Solicitar poder leer mensajes antiguos", + "@requestToReadOlderMessages": { + "type": "text", + "placeholders": {} + }, + "revokeAllPermissions": "Revocar todos los permisos", + "@revokeAllPermissions": { + "type": "text", + "placeholders": {} + }, + "roomHasBeenUpgraded": "El chat ha subido de categoría", "@roomHasBeenUpgraded": { "type": "text", "placeholders": {} }, - "roomVersion": "Versión de sala", + "roomVersion": "Versión de chat", "@roomVersion": { "type": "text", "placeholders": {} }, + "saturday": "Sábado", + "@saturday": { + "type": "text", + "placeholders": {} + }, + "searchForAChat": "Buscar un chat", + "@searchForAChat": { + "type": "text", + "placeholders": {} + }, + "securityKey": "Clave de seguridad", + "@securityKey": { + "type": "text", + "placeholders": {} + }, + "securityKeyLost": "¿Peridó su llave de seguridad?", + "@securityKeyLost": { + "type": "text", + "placeholders": {} + }, "seenByUser": "Visto por {username}", "@seenByUser": { "type": "text", @@ -1140,6 +1404,11 @@ "type": "text", "placeholders": {} }, + "sendBugReports": "Permitir el envió de informes de errores con sentry.io", + "@sendBugReports": { + "type": "text", + "placeholders": {} + }, "sendFile": "Enviar un archivo", "@sendFile": { "type": "text", @@ -1202,6 +1471,21 @@ "senderName": {} } }, + "sentryInfo": "Información sobre tu privacidad: https://sentry.io/security/", + "@sentryInfo": { + "type": "text", + "placeholders": {} + }, + "sessionVerified": "La sesión está verificada", + "@sessionVerified": { + "type": "text", + "placeholders": {} + }, + "setAProfilePicture": "Establecer una foto de perfil", + "@setAProfilePicture": { + "type": "text", + "placeholders": {} + }, "setAsCanonicalAlias": "Fijar alias principal", "@setAsCanonicalAlias": { "type": "text", @@ -1239,6 +1523,49 @@ "username": {} } }, + "@showDirectChatsInSpaces": { + "type": "text", + "placeholders": {} + }, + "sender": "Remitente", + "@sender": {}, + "pinMessage": "Anclar al chat", + "@pinMessage": {}, + "confirmEventUnpin": "¿Está seguro de desanclar definitivamente el mensaje?", + "@confirmEventUnpin": {}, + "emojis": "Emojis", + "@emojis": {}, + "placeCall": "Hacer llamada", + "@placeCall": {}, + "voiceCall": "Llamada de voz", + "@voiceCall": {}, + "unsupportedAndroidVersion": "Versión de Android no compatible", + "@unsupportedAndroidVersion": {}, + "unsupportedAndroidVersionLong": "Esta función requiere una versión más reciente de Android. Verifique si hay actualizaciones o soporte de Lineage OS.", + "@unsupportedAndroidVersionLong": {}, + "videoCallsBetaWarning": "Tenga en cuenta que las videollamadas se encuentran actualmente en versión beta. Es posible que no funcionen como se esperaba o que no funcionen en todas las plataformas.", + "@videoCallsBetaWarning": {}, + "experimentalVideoCalls": "Videollamadas experimentales", + "@experimentalVideoCalls": {}, + "indexedDbErrorTitle": "Problemas del modo privado", + "@indexedDbErrorTitle": {}, + "indexedDbErrorLong": "Desafortunadamente, el almacenamiento de mensajes no está habilitado en modo privado de forma predeterminada.\nVisite\n - about:config\n - establezca dom.indexedDB.privateBrowsing.enabled en verdadero\nDe lo contrario, no es posible ejecutar FluffyChat.", + "@indexedDbErrorLong": {}, + "reactedWith": "{sender} reaccionó con {reaction}", + "@reactedWith": { + "type": "text", + "placeholders": { + "sender": {}, + "reaction": {} + } + }, + "switchToAccount": "Cambiar a la cuenta {number}", + "@switchToAccount": { + "type": "number", + "placeholders": { + "number": {} + } + }, "showPassword": "Mostrar contraseña", "@showPassword": { "type": "text", @@ -1266,7 +1593,12 @@ "senderName": {} } }, - "statusExampleMessage": "¿Cómo estás hoy?", + "startYourFirstChat": "¡Inicie su primer chat ahora mismo! 🙂\n- Toque el botón de \"Nueva conversación\"\n- Escaneé el código QR de un amigo \n- Diviértanse chateando", + "@startYourFirstChat": { + "type": "text", + "placeholders": {} + }, + "statusExampleMessage": "¿Cómo está hoy?", "@statusExampleMessage": { "type": "text", "placeholders": {} @@ -1276,11 +1608,26 @@ "type": "text", "placeholders": {} }, + "sunday": "Domingo", + "@sunday": { + "type": "text", + "placeholders": {} + }, "systemTheme": "Sistema", "@systemTheme": { "type": "text", "placeholders": {} }, + "tapOnDeviceToVerify": "Toque en otro dispositivo para verificar", + "@tapOnDeviceToVerify": { + "type": "text", + "placeholders": {} + }, + "tapToShowMenu": "Toca para mostrar el menú", + "@tapToShowMenu": { + "type": "text", + "placeholders": {} + }, "theyDontMatch": "No coinciden", "@theyDontMatch": { "type": "text", @@ -1291,6 +1638,26 @@ "type": "text", "placeholders": {} }, + "thisRoomHasBeenArchived": "Este chat ha sido archivado.", + "@thisRoomHasBeenArchived": { + "type": "text", + "placeholders": {} + }, + "thursday": "Jueves", + "@thursday": { + "type": "text", + "placeholders": {} + }, + "timeOfDay": "{hours24}:{minutes}", + "@timeOfDay": { + "type": "text", + "placeholders": { + "hours12": {}, + "hours24": {}, + "minutes": {}, + "suffix": {} + } + }, "title": "FluffyChat", "@title": { "description": "Title for the application", @@ -1307,6 +1674,11 @@ "type": "text", "placeholders": {} }, + "tuesday": "Martes", + "@tuesday": { + "type": "text", + "placeholders": {} + }, "unavailable": "Indisponible", "@unavailable": { "type": "text", @@ -1342,6 +1714,11 @@ "type": {} } }, + "unknownSessionVerify": "Sesión desconocida, por favor verifíquela", + "@unknownSessionVerify": { + "type": "text", + "placeholders": {} + }, "unmuteChat": "Dejar de silenciar el chat", "@unmuteChat": { "type": "text", @@ -1359,6 +1736,18 @@ "unreadCount": {} } }, + "unreadMessages": "{unreadEvents, plural, =1{1 mensaje no leído} other{{unreadEvents} mensajes no leídos}}", + "@unreadMessages": { + "type": "text", + "placeholders": { + "unreadEvents": {} + } + }, + "useAmoledTheme": "¿Usar colores compatibles con AMOLED?", + "@useAmoledTheme": { + "type": "text", + "placeholders": {} + }, "userAndOthersAreTyping": "{username} y {count} más están escribiendo…", "@userAndOthersAreTyping": { "type": "text", @@ -1407,11 +1796,21 @@ "type": "text", "placeholders": {} }, + "verifiedSession": "¡Sesión verificada exitosamente!", + "@verifiedSession": { + "type": "text", + "placeholders": {} + }, "verify": "Verificar", "@verify": { "type": "text", "placeholders": {} }, + "verifyManual": "Verificar manualmente", + "@verifyManual": { + "type": "text", + "placeholders": {} + }, "verifyStart": "Comenzar verificación", "@verifyStart": { "type": "text", @@ -1427,6 +1826,11 @@ "type": "text", "placeholders": {} }, + "verifyUser": "Verificar usuario", + "@verifyUser": { + "type": "text", + "placeholders": {} + }, "videoCall": "Video llamada", "@videoCall": { "type": "text", @@ -1467,7 +1871,7 @@ "type": "text", "placeholders": {} }, - "wallpaper": "Fondo de pantalla:", + "wallpaper": "Fondo de pantalla", "@wallpaper": { "type": "text", "placeholders": {} @@ -1477,7 +1881,18 @@ "type": "text", "placeholders": {} }, - "weSentYouAnEmail": "Te enviamos un correo electrónico", + "warningEncryptionInBeta": "¡El cifrado de extremo a extremo está actualmente en período de prueba! ¡Úselo bajo su propio riesgo!", + "wednesday": "Miércoles", + "@wednesday": { + "type": "text", + "placeholders": {} + }, + "welcomeText": "Bienvenidos al mensajero instantáneo más lindo de la red de Matrix.", + "@welcomeText": { + "type": "text", + "placeholders": {} + }, + "weSentYouAnEmail": "Le enviamos un correo electrónico", "@weSentYouAnEmail": { "type": "text", "placeholders": {} @@ -1497,31 +1912,53 @@ "type": "text", "placeholders": {} }, - "you": "Tú", + "you": "usted", "@you": { "type": "text", "placeholders": {} }, - "youAreInvitedToThisChat": "Estás invitado a este chat", + "youAreInvitedToThisChat": "Está invitado a este chat", "@youAreInvitedToThisChat": { "type": "text", "placeholders": {} }, - "youAreNoLongerParticipatingInThisChat": "Ya no estás participando en este chat", + "youAreNoLongerParticipatingInThisChat": "Ya no está participando en este chat", "@youAreNoLongerParticipatingInThisChat": { "type": "text", "placeholders": {} }, - "youCannotInviteYourself": "No puedes invitarte a tí mismo", + "youCannotInviteYourself": "No puede invitarse a sí mismo", "@youCannotInviteYourself": { "type": "text", "placeholders": {} }, - "youHaveBeenBannedFromThisChat": "Has sido vetado de este chat", + "youHaveBeenBannedFromThisChat": "Ha sido vetado de este chat", "@youHaveBeenBannedFromThisChat": { "type": "text", "placeholders": {} }, + "yourOwnUsername": "Su nombre de usuario", + "@yourOwnUsername": { + "type": "text", + "placeholders": {} + }, + "youWillBeConnectedTo": "Será conectado a {homeserver}", + "@youWillBeConnectedTo": { + "type": "text", + "placeholders": { + "homeserver": {} + } + }, + "zoomIn": "Acercar zoom", + "@zoomIn": { + "type": "text", + "placeholders": {} + }, + "zoomOut": "Alejar zoom", + "@zoomOut": { + "type": "text", + "placeholders": {} + }, "autoplayImages": "Reproducir emoticonos y stickers animados automáticamente", "@autoplayImages": { "type": "text", @@ -1532,7 +1969,7 @@ "type": "text", "placeholders": {} }, - "addToSpace": "Agregar al espacio", + "addToSpace": "Agregar a espacio", "@addToSpace": {}, "cantOpenUri": "No puedo abrir el URI {uri}", "@cantOpenUri": { @@ -1541,6 +1978,11 @@ "uri": {} } }, + "addNewFriend": "Agregar nuevo amigo", + "@addNewFriend": { + "type": "text", + "placeholders": {} + }, "all": "Todo", "@all": { "type": "text", @@ -1551,6 +1993,16 @@ "type": "text", "placeholders": {} }, + "audioPlayerPause": "", + "@audioPlayerPause": { + "type": "text", + "placeholders": {} + }, + "audioPlayerPlay": "Encender", + "@audioPlayerPlay": { + "type": "text", + "placeholders": {} + }, "botMessages": "Mensajes de bot", "@botMessages": { "type": "text", @@ -1591,7 +2043,7 @@ "type": "text", "placeholders": {} }, - "status": "Estado", + "status": "Status", "@status": { "type": "text", "placeholders": {} @@ -1601,12 +2053,27 @@ "type": "text", "placeholders": {} }, + "userNotVerified": "El usuario no está verificado", + "@userNotVerified": { + "type": "text", + "placeholders": {} + }, + "userVerified": "El usuario está verificado", + "@userVerified": { + "type": "text", + "placeholders": {} + }, "iHaveClickedOnLink": "He hecho clic en el enlace", "@iHaveClickedOnLink": { "type": "text", "placeholders": {} }, - "directChats": "Chat directo", + "clearText": "Borrar texto", + "@clearText": { + "type": "text", + "placeholders": {} + }, + "directChats": "Chat privado", "@directChats": { "type": "text", "placeholders": {} @@ -1645,13 +2112,10 @@ "type": "text", "placeholders": {} }, - "spaceIsPublic": "El espacio es público", "@spaceIsPublic": { "type": "text", "placeholders": {} }, - "chatHasBeenAddedToThisSpace": "El chat se ha agregado a este espacio", - "@chatHasBeenAddedToThisSpace": {}, "commandInvalid": "Comando inválido", "@commandInvalid": { "type": "text" @@ -1678,6 +2142,11 @@ "type": "text", "placeholders": {} }, + "publicKey": "Clave pública", + "@publicKey": { + "type": "text", + "placeholders": {} + }, "editBlockedServers": "Editar servidores bloqueado", "@editBlockedServers": { "type": "text", @@ -1688,6 +2157,11 @@ "type": "text", "placeholders": {} }, + "noDescription": "Sin descripción", + "@noDescription": { + "type": "text", + "placeholders": {} + }, "noConnectionToTheServer": "Sin conexión al servidor", "@noConnectionToTheServer": { "type": "text", @@ -1703,7 +2177,7 @@ "type": "text", "placeholders": {} }, - "inoffensive": "Inofensivo", + "inoffensive": "Un poco ofensivo", "@inoffensive": { "type": "text", "placeholders": {} @@ -1713,13 +2187,13 @@ "type": "text", "placeholders": {} }, - "memberChanges": "Cambios de miembros", - "@memberChanges": { + "soundVibrationLedColor": "Sonido, vibración LED de color", + "@soundVibrationLedColor": { "type": "text", "placeholders": {} }, - "createNewSpace": "Nuevo espacio", - "@createNewSpace": { + "memberChanges": "Cambios de miembros", + "@memberChanges": { "type": "text", "placeholders": {} }, @@ -1735,7 +2209,7 @@ }, "enterASpacepName": "Ingrese nombre de espacio", "@enterASpacepName": {}, - "ignore": "Ignorar", + "ignore": "Bloquear", "@ignore": { "type": "text", "placeholders": {} @@ -1750,7 +2224,7 @@ "type": "text", "placeholders": {} }, - "offensive": "Ofensiva", + "offensive": "Ofensivo", "@offensive": { "type": "text", "placeholders": {} @@ -1762,12 +2236,12 @@ "type": "text", "placeholders": {} }, - "replaceRoomWithNewerVersion": "Reemplazar habitación con una versión más nueva", + "replaceRoomWithNewerVersion": "Reemplazar chat con una versión más nueva", "@replaceRoomWithNewerVersion": { "type": "text", "placeholders": {} }, - "contentHasBeenReported": "El contenido ha sido reportado a los administradores del servidor", + "contentHasBeenReported": "El contenido ha sido reportado", "@contentHasBeenReported": { "type": "text", "placeholders": {} @@ -1777,11 +2251,18 @@ "type": "text", "placeholders": {} }, - "reportMessage": "Mensaje de informe", + "reportMessage": "Reportar mensaje", "@reportMessage": { "type": "text", "placeholders": {} }, + "savedFileAs": "Archivo guardado como {filename}", + "@savedFileAs": { + "type": "text", + "placeholders": { + "filename": {} + } + }, "search": "Buscar", "@search": { "type": "text", @@ -1836,6 +2317,11 @@ "type": "text", "placeholders": {} }, + "saveFileToFolder": "Guardar archivo en esta carpeta", + "@saveFileToFolder": { + "type": "text", + "placeholders": {} + }, "commandHint_send": "Enviar texto", "@commandHint_send": { "type": "text", @@ -1851,6 +2337,11 @@ "type": "text", "placeholders": {} }, + "dontAskAgain": "Cancelar y no volver a preguntar", + "@dontAskAgain": { + "type": "text", + "placeholders": {} + }, "oopsPushError": "¡UPS¡ Desafortunadamente, se produjo un error al configurar las notificaciones push.", "@oopsPushError": { "type": "text", @@ -1861,27 +2352,37 @@ "type": "text", "placeholders": {} }, + "discoverGroups": "Descubrir grupos", + "@discoverGroups": { + "type": "text", + "placeholders": {} + }, "enableEncryption": "Habilitar la encriptación", "@enableEncryption": { "type": "text", "placeholders": {} }, + "yourChatsAreBeingSynced": "Sus chats se están sincronizando…", + "@yourChatsAreBeingSynced": { + "type": "text", + "placeholders": {} + }, "messages": "Mensajes", "@messages": { "type": "text", "placeholders": {} }, - "fontSize": "Tamaño de fuente", + "fontSize": "Tamaño de letra", "@fontSize": { "type": "text", "placeholders": {} }, - "commandHint_ban": "Prohibir al usuario dado en esta sala", + "commandHint_ban": "Bloquear el usario de este chat", "@commandHint_ban": { "type": "text", "description": "Usage hint for the command /ban" }, - "commandHint_unban": "Des banear al usuario dado en esta sala", + "commandHint_unban": "Desbloquear al usuario dado en este chat", "@commandHint_unban": { "type": "text", "description": "Usage hint for the command /unban" @@ -1894,15 +2395,34 @@ }, "description": "State that {command} is not a valid /command." }, + "discover": "Descubrir", + "@discover": { + "type": "text", + "placeholders": {} + }, "editChatPermissions": "Editar permisos de chat", "@editChatPermissions": { "type": "text", "placeholders": {} }, + "friends": "Amigos", + "@friends": { + "type": "text", + "placeholders": {} + }, + "createNewChatExplaination": "Simplemente escanee el código QR o comparta su enlace de invitación si no están uno al lado del otro.", + "@createNewChatExplaination": {}, "shareYourInviteLink": "Compartir tu enlace de invitación", "@shareYourInviteLink": {}, + "typeInInviteLinkManually": "Escriba el enlace de invitación manualmente...", + "@typeInInviteLinkManually": {}, "scanQrCode": "Escanear código QR", "@scanQrCode": {}, + "unlockChatBackup": "Desbloquear la copia de seguridad del chat", + "@unlockChatBackup": { + "type": "text", + "placeholders": {} + }, "homeserver": "Homeserver", "@homeserver": {}, "newChat": "Nuevo chat", @@ -1910,19 +2430,19 @@ "type": "text", "placeholders": {} }, - "commandHint_join": "Únete a la sala indicada", + "commandHint_join": "Únase al chat indicado", "@commandHint_join": { "type": "text", "description": "Usage hint for the command /join" }, - "sendOnEnter": "Enviar con enter", + "sendOnEnter": "Enviar siempre con enter", "@sendOnEnter": {}, "changeYourAvatar": "Cambiar tu avatar", "@changeYourAvatar": { "type": "text", "placeholders": {} }, - "commandHint_me": "Descríbete", + "commandHint_me": "Descríbase", "@commandHint_me": { "type": "text", "description": "Usage hint for the command /me" @@ -1932,32 +2452,32 @@ "type": "text", "description": "Usage hint for the command /html" }, - "commandHint_invite": "Invitar al usuario indicado a esta sala", + "commandHint_invite": "Invitar al usuario indicado a este chat", "@commandHint_invite": { "type": "text", "description": "Usage hint for the command /invite" }, - "commandHint_kick": "Eliminar el usuario indicado de esta sala", + "commandHint_kick": "Eliminar el usuario indicado de este chat", "@commandHint_kick": { "type": "text", "description": "Usage hint for the command /kick" }, - "commandHint_leave": "Deja esta sala", + "commandHint_leave": "Salir de este chat", "@commandHint_leave": { "type": "text", "description": "Usage hint for the command /leave" }, - "commandHint_myroomavatar": "Selecciona tu foto para esta sala (by mxc-uri)", + "commandHint_myroomavatar": "Seleccione su foto para este chat (by mxc-uri)", "@commandHint_myroomavatar": { "type": "text", "description": "Usage hint for the command /myroomavatar" }, - "commandHint_myroomnick": "Establece tu nombre para mostrar para esta sala", + "commandHint_myroomnick": "Establezca su nombre para mostrar para este chat", "@commandHint_myroomnick": { "type": "text", "description": "Usage hint for the command /myroomnick" }, - "commandHint_op": "Establece el nivel de potencia del usuario dado (default: 50)", + "commandHint_op": "Establezca el nivel de potencia del usuario dado (default: 50)", "@commandHint_op": { "type": "text", "description": "Usage hint for the command /op" @@ -1977,7 +2497,12 @@ "type": "text", "placeholders": {} }, - "editRoomAvatar": "Editar avatar de sala", + "enableChatBackup": "Habilitar la copia de seguridad del chat para no perder nunca el acceso a su chats.", + "@enableChatBackup": { + "type": "text", + "placeholders": {} + }, + "editRoomAvatar": "Editar avatar de chat", "@editRoomAvatar": { "type": "text", "placeholders": {} @@ -1992,7 +2517,7 @@ "type": "text", "placeholders": {} }, - "goToTheNewRoom": "Ir a la nueva sala", + "goToTheNewRoom": "Ir al nuevo chat", "@goToTheNewRoom": { "type": "text", "placeholders": {} @@ -2005,6 +2530,20 @@ "server2": {} } }, + "invalidEmail": "Correo inválido", + "@invalidEmail": { + "type": "text", + "placeholders": {} + }, + "newPasswordDescription": "Para poder recuperar su contraseña más tarde, debe agregar una dirección de correo electrónico", + "@newPasswordDescription": {}, + "newUsernameDescription": "Su ID de usuario tendrá el formato @username:servername", + "@newUsernameDescription": {}, + "noStatusesFound": "Hasta ahora no se han encontrado estados.", + "@noStatusesFound": { + "type": "text", + "placeholders": {} + }, "openInMaps": "Abrir en maps", "@openInMaps": { "type": "text", @@ -2041,11 +2580,16 @@ "type": "text", "placeholders": {} }, - "spaceName": "Nombre del espacio", + "spaceName": "Nombre", "@spaceName": { "type": "text", "placeholders": {} }, + "tapToShowImage": "Toque para mostrar la imagen", + "@tapToShowImage": { + "type": "text", + "placeholders": {} + }, "toggleFavorite": "Alternar favorito", "@toggleFavorite": { "type": "text", @@ -2056,6 +2600,11 @@ "type": "text", "placeholders": {} }, + "userUnknownVerification": "El usuario tiene un estado de verificación desconocido", + "@userUnknownVerification": { + "type": "text", + "placeholders": {} + }, "whoCanPerformWhichAction": "Quién puede realizar qué acción", "@whoCanPerformWhichAction": { "type": "text", @@ -2071,11 +2620,19 @@ "type": "text", "placeholders": {} }, + "iWroteDownTheKey": "He escrito la clave", + "@iWroteDownTheKey": {}, "yourChatBackupHasBeenSetUp": "Se ha configurado la copia de respaldo del chat.", "@yourChatBackupHasBeenSetUp": {}, "unverified": "No verificado", "@unverified": {}, - "commandHint_clearcache": "Limpiar cache", + "setupChatBackupDescription": "Para proteger sus mensajes, hemos generado una clave de seguridad.\nConsérvela en un sitio seguro, como un gestor de contraseñas.", + "@setupChatBackupDescription": {}, + "yourUserId": "Su id. de usuario:", + "@yourUserId": {}, + "setupChatBackup": "Configurar copia de respaldo de chat", + "@setupChatBackup": {}, + "commandHint_clearcache": "limpiar cache", "@commandHint_clearcache": { "type": "text", "description": "Usage hint for the command /clearcache" @@ -2097,21 +2654,19 @@ "@pleaseEnterValidEmail": {}, "repeatPassword": "Repetir la contraseña", "@repeatPassword": {}, - "pleaseChooseAtLeastChars": "Por favor elige al menos {min} carácteres.", + "pleaseChooseAtLeastChars": "Por favor elegir al menos {min} carácteres", "@pleaseChooseAtLeastChars": { "type": "text", "placeholders": { "min": {} } }, - "removeFromSpace": "Eliminar del espacio", - "@removeFromSpace": {}, - "addToSpaceDescription": "Elige un espacio para añadir este chat a el.", - "@addToSpaceDescription": {}, "openGallery": "Abrir galería", "@openGallery": {}, "start": "Iniciar", "@start": {}, + "saveTheSecurityKeyNow": "Guardar la clave de seguridad ahora", + "@saveTheSecurityKeyNow": {}, "replyHasBeenSent": "La respuesta se ha enviado", "@replyHasBeenSent": {}, "whatIsGoingOn": "¿Qué está pasando?", @@ -2132,35 +2687,828 @@ "size": {} } }, + "pleaseEnterSecurityKeyDescription": "Para desbloquear el respaldo de tu chat, por favor ingresa tu clave de seguridad que ha sido generada en una sesión previa. Tu clave de seguridad NO es tu contraseña.", + "@pleaseEnterSecurityKeyDescription": {}, "publish": "Publicar", "@publish": {}, - "newSpace": "Nuevo espacio", - "@newSpace": {}, - "allSpaces": "Todos los espacios", - "@allSpaces": {}, - "yourStory": "Tu historia", - "@yourStory": {}, - "widgetUrlError": "Esta no es una URL válida.", - "@widgetUrlError": {}, - "commandHint_markasgroup": "Marcar como grupo", - "@commandHint_markasgroup": {}, - "nextAccount": "Siguiente cuenta", - "@nextAccount": {}, - "youRejectedTheInvitation": "Rechazaste la invitación", - "@youRejectedTheInvitation": {}, - "whoCanSeeMyStories": "¿Quién puede ver mis historias?", - "@whoCanSeeMyStories": {}, - "newGroup": "Nuevo grupo", + "updateLanguage": "Cambiar mis idiomas", + "@updateLanguage": { + "type": "text", + "placeholders": {} + }, + "languageLevelPreA1": "Principiante absoluto (Pre A1)", + "@languageLevelPreA1": { + "type": "text", + "placeholders": {} + }, + "languageLevelA1": "Principiante elemental (A1)", + "@languageLevelA1": { + "type": "text", + "placeholders": {} + }, + "languageLevelA2": "Principiante básico (A2)", + "@languageLevelA2": { + "type": "text", + "placeholders": {} + }, + "languageLevelB1": "Intermedio (B1)", + "@languageLevelB1": { + "type": "text", + "placeholders": {} + }, + "languageLevelB2": "Intermedio alto (B2)", + "@languageLevelB2": { + "type": "text", + "placeholders": {} + }, + "languageLevelC1": "Avanzado (C1)", + "@languageLevelC1": { + "type": "text", + "placeholders": {} + }, + "languageLevelC2": "Maestría (C2)", + "@languageLevelC2": { + "type": "text", + "placeholders": {} + }, + "reportAnIssue": "Ayuda", + "@reportAnIssue": { + "type": "text", + "placeholders": {} + }, + "whatLanguageYouWantToLearn": "¿Qué idioma quiere aprender?", + "@whatLanguageYouWantToLearn": { + "type": "text", + "placeholders": {} + }, + "whatIsYourBaseLanguage": "¿Cuál es su idioma base? \n\n Actualmente, la traducción interactiva solo está disponible cuando su idioma base es inglés y español. La asistencia gramatical está disponible para todos los idiomas base.", + "studentPermissions": "Permisos de estudiantes", + "@studentPermissions": { + "type": "text", + "placeholders": {} + }, + "openEnrollment": "Inscripción abierta?", + "@openEnrollment": { + "type": "text", + "placeholders": {} + }, + "openToExchanges": "¿Abierto a intercambios?", + "@openToExchanges": { + "type": "text", + "placeholders": {} + }, + "oneToOneChatsWithinExchanges": "Chats Privados dentro de Intercambios", + "@oneToOneChatsWithinExchanges": { + "type": "text", + "placeholders": {} + }, + "createGroupChats": "Crear Chats Grupales", + "@createGroupChats": { + "type": "text", + "placeholders": {} + }, + "createGroupChatsInExchanges": "Crear Chats Grupales en Intercambios", + "@createGroupChatsInExchanges": { + "type": "text", + "placeholders": {} + }, + "createGroupChatsInExchangesDesc": "Active esta opción para permitir que los estudiantes creen chats grupales dentro de los intercambios.", + "@createGroupChatsInExchangesDesc": { + "type": "text", + "placeholders": {} + }, + "shareStories": "Subir historias", + "@shareStories": { + "type": "text", + "placeholders": {} + }, + "shareStoriesDesc": "Active esta opción para permitir que los estudiantes suban historias.", + "@shareStoriesDesc": { + "type": "text", + "placeholders": {} + }, + "shareVideo": "Enviar videos", + "@shareVideo": { + "type": "text", + "placeholders": {} + }, + "shareVideoDesc": "Active esta opción para permitir que los estudiantes compartan videos en los chats.", + "@shareVideoDesc": { + "type": "text", + "placeholders": {} + }, + "sharePhotos": "Enviar fotos", + "@sharePhotos": { + "type": "text", + "placeholders": {} + }, + "sharePhotosDesc": "Active esta opción para permitir que los estudiantes compartan fotos en los chats.", + "@sharePhotosDesc": { + "type": "text", + "placeholders": {} + }, + "shareFiles": "Enviar archivos", + "@shareFiles": { + "type": "text", + "placeholders": {} + }, + "shareFilesDesc": "Active esta opción para permitir que los estudiantes compartan archivos en los chats.", + "@shareFilesDesc": { + "type": "text", + "placeholders": {} + }, + "shareLocationDesc": "Active esta opción para permitir que los estudiantes compartan su ubicación en los chats.", + "@shareLocationDesc": { + "type": "text", + "placeholders": {} + }, + "enterCityName": "Escriba ciudad, estado", + "@enterCityName": { + "type": "text", + "placeholders": {} + }, + "optionalCity": "Opcional: Ciudad, estado", + "@optionalCity": { + "type": "text", + "placeholders": {} + }, + "enterCountryName": "Escriba país", + "@enterCountryName": { + "type": "text", + "placeholders": {} + }, + "optionalCountry": "Opcional: País", + "@optionalCountry": { + "type": "text", + "placeholders": {} + }, + "enterSchoolName": "Escriba el nombre de la escuela", + "@enterSchoolName": { + "type": "text", + "placeholders": {} + }, + "optionalSchool": "Opcional: Escuela", + "@optionalSchool": { + "type": "text", + "placeholders": {} + }, + "editCityAndState": "Editar ciudad y estado", + "@editCityAndState": { + "type": "text", + "placeholders": {} + }, + "cityAndStateInformation": "Información de ciudad y estado", + "@cityAndStateInformation": { + "type": "text", + "placeholders": {} + }, + "editCountry": "Editar país", + "@editCountry": { + "type": "text", + "placeholders": {} + }, + "countryInformation": "Información de país", + "@countryInformation": { + "type": "text", + "placeholders": {} + }, + "langaugeLevel": "Nivel de lengua", + "@langaugeLevel": { + "type": "text", + "placeholders": {} + }, + "whatIsYourClassLanguageLevel": "¿Cuál es el nivel de lengua promedio de su clase? \n\nEsto se usará para organizar intercambios de clases (¡próximamente!). Junto con los datos recopilados del uso del idioma de los estudiantes y las actividades en el chat, el nivel promedio del idioma se usará para formar una línea de base para el cálculo del nivel individual del estudiante (¡próximamente!).", + "@whatIsYourClassLanguageLevel": { + "type": "text", + "placeholders": {} + }, + "l1Andl2": "L1 y L2", + "@l1Andl2": { + "type": "text", + "placeholders": {} + }, + "schoolInformation": "Información de escuela", + "@schoolInformation": { + "type": "text", + "placeholders": {} + }, + "editSchool": "Editar escuela", + "@editSchool": { + "type": "text", + "placeholders": {} + }, + "selectClassRoomDominantLanguage": "¿Cuál es el idioma base de su clase? \n\nEl idioma base de la clase se utilizará para organizar los intercambios de clases (¡Próximamente!). Los idiomas base también los establece el individuo, lo que determina la funcionalidad de las herramienta de aprendizaje. Actualmente, la asistencia de traducción solo está disponibles cuando el idioma base de la persona está configurado en español o inglés. La asistencia gramatical está disponible para todos los idiomas base.", + "@selectClassRoomDominantLanguage": { + "type": "text", + "placeholders": {} + }, + "selectTargetLanguage": "¿Cuál es el idioma que enseña en su clase? \n\nEsto se usa para determinar la funcionalidad de las herramientas de aprendizaje para su clase, incluida la asistencia gramatical, la asistencia de traducción, tarjetas emergentes de definiciones de palabras y Seguimiento de clase. Para todos los chats de su clase, esta configuración anulará cualquier configuración en conflicto a nivel individual.", + "@selectTargetLanguage": { + "type": "text", + "placeholders": {} + }, + "selectLanguageLevel": "Seleccione nivel de lengua", + "@selectLanguageLevel": { + "type": "text", + "placeholders": {} + }, + "addStudents": "Agregar estudiantes", + "@addStudents": { + "type": "text", + "placeholders": {} + }, + "findLanguageExchange": "Encuentre una clase de intercambio", + "@findLanguageExchange": { + "type": "text", + "placeholders": {} + }, + "requestToEnroll": "Solicitar inscripción", + "@requestToEnroll": { + "type": "text", + "placeholders": {} + }, + "requestAnExchange": "Solicitar un intercambio", + "@requestAnExchange": { + "type": "text", + "placeholders": {} + }, + "targetLanguage": "Idioma a aprender", + "@targetLanguage": { + "type": "text", + "placeholders": {} + }, + "sourceLanguage": "Idioma base", + "@sourceLanguage": { + "type": "text", + "placeholders": {} + }, + "numberOfStudents": "Número de estudiantes", + "@numberOfStudents": { + "type": "text", + "placeholders": {} + }, + "ratings": "Calificaciones", + "@ratings": { + "type": "text", + "placeholders": {} + }, + "myLanguages": "Mi idioma base y idioma a aprender", + "@myLanguages": { + "type": "text", + "placeholders": {} + }, + "saveChanges": "Guardar", + "@saveChanges": { + "type": "text", + "placeholders": {} + }, + "createPrivateChat": "Crear un chat privado", + "@createPrivateChat": { + "type": "text", + "placeholders": {} + }, + "findAClass": "Encuentre una clase (¡Próximamente!)", + "@findAClass": { + "type": "text", + "placeholders": {} + }, + "findALanguagePartner": "Encuentre un compañero de conversación", + "@findALanguagePartner": { + "type": "text", + "placeholders": {} + }, + "generalSettings": "Ajustes generales", + "@generalSettings": { + "type": "text", + "placeholders": {} + }, + "classSettings": "Ajustes de clase", + "@classSettings": { + "type": "text", + "placeholders": {} + }, + "suggestToClass": "Sugiera el chat a", + "@suggestToClass": { + "type": "text", + "placeholders": {} + }, + "classWelcomeChat": "Chat de bienvenida", + "@classWelcomeChat": { + "type": "text", + "placeholders": {} + }, + "iWantAConversationPartner": "Quiero un compañero de conversación quién", + "@iWantAConversationPartner": { + "type": "text", + "placeholders": {} + }, + "yourBirthdayPlease": "Pangea Chat está al servicio de escuelas y otras comunidades de aprendizaje que atienden a estudiantes de 13 años en adelante alrededor del mundo. Para proteger a nuestra población menor de edad, les pedimos a todos nuestros usuarios que verifiquen su edad antes de unirse a nuestra comunidad. Para poder encontrar clases, chats y nuevos amigos en Pangea Chat, debe verificar que tiene 18 años o más de edad.", + "@yourBirthdayPlease": { + "type": "text", + "placeholders": {} + }, + "invalidDob": "Fecha de nacimiento inválida", + "@invalidDob": { + "type": "text", + "placeholders": {} + }, + "enterYourDob": "Introduzca su fecha de nacimiento", + "@enterYourDob": { + "type": "text", + "placeholders": {} + }, + "getStarted": "Comience", + "@getStarted": { + "type": "text", + "placeholders": {} + }, + "mustBe13": "Los usuarios deben tener 13 años o más de edad.", + "@mustBe13": { + "type": "text", + "placeholders": {} + }, + "yourBirthdayPleaseShort": "Por favor, introduzca su fecha de nacimiento", + "@yourBirthdayPleaseShort": { + "type": "text", + "placeholders": {} + }, + "inviteStudentByUserName": "Invitar a estudiantes por usuario", + "@inviteStudentByUserName": { + "type": "text", + "placeholders": {} + }, + "classAnalyticsDesc": "Información detallada sobre la participación de los estudiantes y el uso del idioma", + "@classAnalyticsDesc": { + "type": "text", + "placeholders": {} + }, + "chatTopic": "Tema del chat", + "@chatTopic": { + "type": "text", + "placeholders": {} + }, + "chatTopicDesc": "Establecer un tema para el chat", + "@chatTopicDesc": { + "type": "text", + "placeholders": {} + }, + "inviteStudentByUserNameDesc": "Si su estudiante ya tiene una cuenta, puede buscarlo.", + "@inviteStudentByUserNameDesc": { + "type": "text", + "placeholders": {} + }, + "inviteWithEmail": "Invitar por correo", + "@inviteWithEmail": { + "type": "text", + "placeholders": {} + }, + "changeTheNameOfTheClass": "Cambiar el nombre", + "@changeTheNameOfTheClass": { + "type": "text", + "placeholders": {} + }, + "changeTheNameOfTheChat": "Cambiar el nombre del chat", + "@changeTheNameOfTheChat": { + "type": "text", + "placeholders": {} + }, + "accountSettings": "Ajustes de cuenta", + "@accountSettings": { + "type": "text", + "placeholders": {} + }, + "toggleIT": "Asistencia de Traducción", + "interactiveTranslatorNotAllowed": "Deshabilitado", + "@interactiveTranslatorNotAllowed": { + "type": "text", + "placeholders": {} + }, + "interactiveTranslatorAllowed": "Elección del estudiante", + "@interactiveTranslatorAllowed": { + "type": "text", + "placeholders": {} + }, + "interactiveTranslatorRequired": "Requerido", + "@interactiveTranslatorRequired": { + "type": "text", + "placeholders": {} + }, + "interactiveTranslatorRequiredDesc": "Los estudiantes no pueden desactivar la asistencia de traducción. Pueden optar por no aceptar las sugerencias de traducción. Esta restricción no se aplica a Class Admin o chats directos.", + "@interactiveTranslatorRequiredDesc": { + "type": "text", + "placeholders": {} + }, + "interactiveTranslatorSliderHeader": "Asistencia de traducción", + "interactiveTranslator": "Asistencia de traducción", + "@interactiveTranslator": { + "type": "text", + "placeholders": {} + }, + "grammarAssistance": "Asistencia gramatical", + "@grammarAssistance": { + "type": "text", + "placeholders": {} + }, + "withoutAssistance": "Sin apoyo", + "@withoutAssistance": { + "type": "text", + "placeholders": {} + }, + "oneday": "Las últimas 24 horas", + "@oneday": { + "type": "text", + "placeholders": {} + }, + "oneweek": "Los últimos 7 días", + "@oneweek": { + "type": "text", + "placeholders": {} + }, + "onemonth": "El último mes", + "@onemonth": { + "type": "text", + "placeholders": {} + }, + "sixmonth": "Los últimos 6 meses", + "@sixmonth": { + "type": "text", + "placeholders": {} + }, + "oneyear": "El último año", + "@oneyear": { + "type": "text", + "placeholders": {} + }, + "noDataForPeriod": "No se encontraron mensajes para este período", + "@noDataForPeriod": { + "type": "text", + "placeholders": {} + }, + "@allClasses": { + "type": "text", + "placeholders": {} + }, + "errorPleaseRefresh": "¡Algo salió mal! El error ha sido registrado y lo estamos investigando. Mientras tanto, actualice la página y vuelva a intentarlo. Si el error persiste, háganoslo saber en support@pangea.chat.", + "loginOrSignup": "Iniciar / Registrarse", + "noIdenticalLanguages": "Por favor, elija diferentes idiomas base e idiomas de aprender.", + "moderateOffensive": "Moderadamente ofensivo", + "searchBy": "Buscar por país e idiomas", + "languagesISpeak": "Idiomas que hablo", + "iWantALanguagePartnerFrom": "Es de:", + "iWantALanguagePartnerWhoSpeaks": "Habla:", + "iWantALanguagePartnerWhoIsLearning": "Está aprendiendo:", + "noResults": "¡No hay resultados! Intente ampliar su búsqueda.", + "worldWide": "En todo el mundo", + "ignoreInThisText": "Ignorar para este mensaje.", + "youGotSomeIssuesToResolve": "Parece que hay algunos errores de lengua en su mensaje.", + "sendVoiceNotes": "Enviar notas de voz", + "sendVoiceNotesDesc": "Active esta opción para permitir que los estudiantes envíen notas de voz en los chats.", + "translationSeemsFinished": "La traducción parece estar terminada.", + "needsItShortMessage": "¡Pruebe la traducción interactiva!", + "needsIGCShortMessage": "¡Pruebe el corrector gramatical interactivo!", + "needsItMessage": "Este mensaje tiene demasiadas palabras en su idioma base.", + "needsIgcMessage": "Este mensaje tiene un error gramatical.", + "tokenTranslationTitle": "Una palabra está en su idioma base.", + "helpMeTranslate": "¡Ayúdeme a traducir!", + "setToPublicSettingsTitle": "¿Quiere encontrar un compañero de conversación?", + "setToPublicSettingsDesc": "Antes de que pueda buscar un compañero de conversación, debe configurar la visibilidad de su perfil como pública.", + "publicProfileTitle": "Perfil público", + "publicProfileDesc": "Su perfil debe ser público para poder buscar o ser encontrado como compañero de conversación.", + "countryInformationDesc": "Si lo desea, puede dejar que la gente sepa de dónde es.", + "notYetSet": "Aún no está establecido.", + "allSuggestedRoomsJoined": "", + "suggestedRooms": "Chats sugeridos", + "emailOrUsername": "Nombre de usuario", + "@emailOrUsername": {}, + "connectedToStaging": "Estás conectado al servidor de ensayo.", + "partTitle": "Tiene un error de gramática.", + "partDesc": "Vea las correcciones sugeridas a continuación.", + "punctTitle": "Tiene un error de puntuación.", + "punctDesc": "La puntuación incluye el uso de comas, puntos, signos de interrogación, signos de exclamación, apóstrofes y acentos.", + "orthTitle": "Tiene un error de escritura.", + "orthDesc": "Errores de escritura incluyen el uso de mayúsculas, el espaciado y la partición de palabras.", + "spellTitle": "Tiene un error de ortografía.", + "spellDesc": "Vea las correcciones sugeridas a continuación.", + "woTitle": "Tiene un error con el orden de las palabras.", + "woDesc": "Esto significa que una o más de sus palabras no están en el orden correcto.", + "morphTitle": "Tiene un error con la forma de la palabra.", + "morphDesc": "Es probable que haya utilizado la forma incorrecta de una palabra, por ejemplo, el adjetivo (respetuoso) en lugar de la forma sustantiva (respeto).", + "advTitle": "Tiene un error con el adverbio.", + "advDesc": "Los adverbios son palabras que describen verbos como \"rápidamente\", \"quizás\" y \"ahora\".", + "contrTitle": "Tiene un error con la contracción.", + "contrDesc": "Una contracción es cuando dos palabras se acortan a una como \"del\" y \"al.\"", + "conjTitle": "Tiene un error con la conjunción.", + "conjDesc": "Una conjunción es una palabra como \"pero\", \"y\" o \"porque\" que unen palabras, frases y cláusulas.", + "detTitle": "Tiene un error con el determinante.", + "detDesc": "Un determinante especifica a qué se refiere o cuánto de algo se refiere e incluye palabras como \"el\", \"esto\" y \"algunos\".", + "det:artTitle": "Tiene un error con el artículo.", + "det:artDesc": "Los artículos incluyen: el, la, los, las, un, una, unos y unas.", + "prepTitle": "Tiene un error con la preposición.", + "prepDesc": "Una preposición describe el tiempo, la ubicación, la dirección o las relaciones espaciales de un objeto, por ejemplo, \"arriba\", \"al lado\" y \"en\".", + "pronTitle": "Tiene un error con el pronombre.", + "pronDesc": "Un pronombre reemplaza a un sustantivo e incluye palabras como: yo, tú, ella, mi, ellos y nuestro.", + "verbTitle": "Tiene un error con el verbo.", + "verbDesc": "Un verbo es una palabra de acción que describe lo que algo o alguien hace, como \"correr\", \"comer\" o \"hablar\".", + "verbFormTitle": "Tiene un error con la forma verbal.", + "verbFormDesc": "Esto significa que probablemente haya conjugado mal un verbo.", + "verbTenseTitle": "Tiene un error con el tiempo verbal.", + "verbTenseDesc": "Esto significa que ha utilizado el tiempo incorrecto del verbo, por ejemplo, presente, pasado, futuro, etc...", + "verbSvaTitle": "Tiene un error de concordancia sujeto-verbo.", + "verbSvaDesc": "Esto significa que el sujeto y el verbo no coinciden, por ejemplo, \"Le gusta las manzanas\".", + "verbInflTitle": "Tiene un error de gramática.", + "verbInflDesc": "Vea las correcciones sugeridas a continuación.", + "adjTitle": "Tiene un error con el adjetivo.", + "adjDesc": "Los adjetivos son palabras que describen sustantivos como \"verde\", \"pequeños\" y \"hermoso\".", + "adjFormTitle": "Tiene un error con la forma del adjetivo.", + "adjFormDesc": "Puede ser, por ejemplo, que usó \"suave\" en lugar de \"más suave\" o \"lo más suave\".", + "nounTitle": "Tiene un error con un sustantivo.", + "nounDesc": "Los sustantivos son personas, lugares y cosas.", + "nounPossTitle": "Tiene un error con el posesivo.", + "nounPossDesc": "El error puede estar relacionado con el uso de \"del\" o palabras como \"mío,\" \"su,\" o \"nuestro\" que expresan posesión.", + "nounInflTitle": "Tiene un error de gramática.", + "nounInflDesc": "Vea las correcciones sugeridas a continuación.", + "nounNumTitle": "Tiene un error con el sustantivo.", + "nounNumDesc": "Esto puede estar relacionado con el uso incorrecto de un sustantivo contable o incontable.", + "otherTitle": "Tiene un error de gramática.", + "otherDesc": "Vea las correcciones sugeridas a continuación.", + "spanTranslationTitle": "Algunas palabras están en su idioma base.", + "spanTranslationDesc": "Vea posibles traducciones abajo.", + "error601602Title": "La asistencia de traducción está deshabilitada.", + "error601Desc": "Para activar herramientas de aprendizaje, vaya a Ajustes de cuenta > Ajustes de aprendizaje y active asistencia de traducción.", + "error405Title": "Idiomas no seleccionados.", + "error405Desc": "Por favor, seleccione sus idiomas en Ajustes de cuenta > Ajustes de aprendizaje.", + "mostCommon": "¡La más común!", + "leastCommon": "¡La menos común!", + "lessCommon": "¡Menos común!", + "commonalityFeedback": "¡Su traducción parece estar terminada. ¡Escogió la elección más común {count} de {total} veces!", + "@commonalityFeedback": { + "type": "text", + "placeholders": { + "count": {}, + "total": {} + } + }, + "customInputFeedback": "¡Su traducción parece estar terminada! Creó su propia traducción.", + "seeAlternativeTranslations": "Ver traducciones alternativas.", + "itInstructionsTitle": "¡Le puedo ayudar a traduccir!", + "itInstructionsBody": "Puede oprimir con clic largo las opciones para más información.", + "chatItemTooltip": "Use clic largo para ver opciones.", + "toggleLanguages": "Cambie el idioma de los mensajes seleccionados.", + "holdForInfo": "Use clic largo para ver información de la palabra.", + "askPangeaBot": "Pídale al Pangea Bot una definición contextual.", + "deleteGroup": "Eliminar chat grupal", + "areYouSureDeleteGroup": "¿Está seguro que quiere eliminar este chat grupal?", + "cannotBeReversed": "Esta acción no se puede revertir.", + "timeOfLastMessage": "Hora del último mensaje enviado", + "totalMessages": "Mensajes totales enviados", + "changeDateRange": "Cambiar rango de fechas", + "doNotShowAgain": "No mostrar de nuevo.", + "l1SpanAndGrammarTitle": "Fuera del idioma de destino", + "l1SpanAndGrammarDesc": "Esto podría estar en su idioma base o podría ser un error gramatical.", + "allCorrect": "¡Así es como lo diría yo! ¡Muy bien!", + "newWayAllGood": "Yo no lo habría dicho así, ¡pero está bien!", + "othersAreBetter": "Hm, creo que deberías decirlo de esta manera.", + "greenFeedback": "¡Eso es lo que yo diría!", + "yellowFeedback": "Hm, ¡probablemente pueda hacer que eso funcione! Para usar esta palabra, simplemente haga clic en ella nuevamente.", + "redFeedback": "No creo que sea correcto, ¡pero puede intentarlo!", + "customInputFeedbackChoice": "Lo escribiste. ¡Bien!", + "almostPerfect": "¡Eso parece correcto! Esto es lo que yo hubiera dicho.", + "prettyGood": "¡Bastante bien! Esto es lo que yo hubiera dicho.", + "letMeThink": "Hmm, ¡vamos a ver cómo le fue!", + "clickMessageTitle": "¡Seleccione mensajes para obtener ayuda con el idioma!", + "clickMessageBody": "Los mensajes siempre se muestran en su idioma de destino, ¡pero puede seleccionarlos para acceder a definiciones y traducciones!", + "understandingMessagesTitle": "¡Definiciones y traducciones!", + "understandingMessagesBody": "Haga clic en las palabras subrayadas para ver las definiciones. Traduzca con 'opciones de mensajes' (arriba a la derecha).", + "allDone": "¡Listo!", + "vocab": "Vocabulario", + "low": "Tenemos evidencia de que el usuario no entiende estas palabras.", + "medium": "Esta palabra ha sido utilizada. No está claro si la palabra se entiende completamente o no.", + "high": "Tenemos evidencia de que el usuario entiende estas palabras.", + "unknownProficiency": "Esta palabra no se ha utilizado en Pangea Chat.", + "generateVocabulary": "Generar vocabulario basado en el título y la descripción", + "generatePrompts": "Generar preguntas basado en el título y la descripción", + "toggleImmersionMode": "Modo de inmersión", + "toggleImmersionModeDesc": "Cuando está habilitado, todos los mensajes se muestran en su idioma de destino y puede hacer clic en el mensaje para acceder a definiciones y traducciones.", + "subscribe": "Subscríbase", + "getAccess": "Activar herramientas", + "subscriptionDesc": "¡Enviar y recibir mensajes es gratis! Suscríbase para aceder a la traducción interactiva, la revisión gramatical y el análisis de aprendizaje.", + "subscriptionManagement": "Manejar subscripción", + "currentSubscription": "Subscripción actual", + "changeSubscription": "Cambiar su subscripción", + "cancelSubscription": "Cancelar su subscripción", + "selectYourPlan": "Escoja su plan", + "subsciptionPlatformTooltip": "Inicie sesión en su dispositivo original para administrar su plan de suscripción.", + "paymentMethod": "Método de pago", + "paymentHistory": "Historial de pago", + "emptyChatDownloadWarning": "No se puede descargar el chat vacío", + "appUpdateAvailable": "Actualización disponible", + "update": "Actualizar", + "updateDesc": "Ahora puede actualizar esta aplicación de {localVersion} a {storeVersion}", + "@updateDesc": { + "type": "text", + "placeholders": { + "storeVersion": {}, + "localVersion": {} + } + }, + "maybeLater": "Quizás más tarde", + "mainMenu": "Menú Principal", + "bubbleSize": "Tamaño de burbuja", + "@bubbleSize": { + "type": "text", + "placeholders": {} + }, + "gaTooltip": "Uso de L2 con asistencia gramatical", + "taTooltip": "Uso de L2 con asistencia de traducción", + "waTooltip": "Uso de L2 sin asistencia", + "unTooltip": "Otra", + "interactiveGrammarSliderHeader": "Asistencia gramatical", + "allRooms": "Todos los chats grupales", + "@allRooms": { + "type": "text", + "placeholders": {} + }, + "errorDisableIT": "La asistencia de traducción está deshabilitada.", + "errorDisableIGC": "La asistencia gramatical está deshabilitada.", + "errorDisableLanguageAssistance": "La asistencia tanto de traducción como de gramática está deshabilitada.", + "errorDisableITUserDesc": "Haga clic aquí para actualizar la configuración de asistencia de traducción.", + "errorDisableIGCUserDesc": "Haga clic aquí para actualizar la configuración de asistencia gramatical.", + "errorDisableLanguageAssistanceUserDesc": "Haga clic aquí para actualizar la asistencia de traducción y de gramática.", + "itIsDisabled": "La asistencia de traducción está deshabilitada.", + "igcIsDisabled": "La asistencia gramatical está deshabilitada.", + "goToLearningSettings": "Vaya a Ajustes de aprendizaje.", + "learningSettings": "Ajustes de aprendizaje", + "report": "Reportar", + "reportErrorDescription": "Oh, no. Algo salió mal. Por favor, inténtelo de nuevo más tarde. Si lo desea, puede reportar el error a los desarrolladores.", + "clearAll": "¿Borrar todas las palabras?", + "jump": "Saltar", + "openLinkInBrowser": "Abrir enlace en el navegador.", + "jumpToLastReadMessage": "Saltar al último mensaje leído.", + "readUpToHere": "Leído hasta aquí.", + "newSpaceDescription": "Espacios le permite consolidar sus chats y crear comunidades privadas o públicas.", + "encryptThisChat": "Encriptar este chat", + "endToEndEncryption": "Encriptado de fin a fin", + "disableEncryptionWarning": "Por razones de seguridad, no puede deshabilitar el cifrado en un chat, donde se ha habilitado antes.", + "sorryThatsNotPossible": "Discupla... eso no es posible", + "deviceKeys": "Claves del dispositivo:", + "letsStart": "¡Empecemos!", + "enterInviteLinkOrMatrixId": "Ingrese el enlace de invitación o ID de Matrix...", + "reopenChat": "Reabrir chat", + "noBackupWarning": "¡No olvida su contraseña!", + "noOtherDevicesFound": "No se encontraron otros dispositivos", + "fileIsTooBigForServer": "El servidor informa que el archivo es demasiado grande para enviarlo.", + "fileHasBeenSavedAt": "Se ha guardado el archivo en {path}", + "@fileHasBeenSavedAt": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "updateAvailable": "Actualización de FluffyChat disponible", + "@updateAvailable": {}, + "updateNow": "Comenzar actualización en segundo plano.", + "@updateNow": {}, + "toggleIGC": "Asistencia Gramatical", + "@toggleIGC": { + "type": "text", + "placeholders": {} + }, + "iAgreeToThe": "Acepto los ", + "@iAgreeToThe": { + "type": "text", + "placeholders": {} + }, + "termsAndConditions": "Términos y condiciones", + "@termsAndConditions": { + "type": "text", + "placeholders": {} + }, + "andCertifyIAmAtLeast13YearsOfAge": " y certifico que tengo al menos 13 años.", + "@andCertifyIAmAtLeast13YearsOfAge": { + "type": "text", + "placeholders": {} + }, + "error502504Title": "¡Vaya! Hay muchos estudiantes conectados.", + "@error502504Title": { + "type": "text", + "placeholders": {} + }, + "error502504Desc": "Las herramientas de assistencia gramatical y de traducción pueden ser lentas o no estar disponibles mientras los bots de Pangea se ponen al día.", + "@error502504Desc": { + "type": "text", + "placeholders": {} + }, + "error404Title": "¡Error de traducción!", + "@error404Title": { + "type": "text", + "placeholders": {} + }, + "error404Desc": "Pangea Bot no está seguro de cómo traducir eso.", + "@error404Desc": { + "type": "text", + "placeholders": {} + }, + "sorryNoResults": "¡Discupla! No hay resultados.", + "@sorryNoResults": { + "type": "text", + "placeholders": {} + }, + "user": "Usuario", + "@user": {}, + "custom": "personalizado", + "@custom": {}, + "foregroundServiceRunning": "Esta notificación aparece cuando se está ejecutando el servicio en primer plano.", + "@foregroundServiceRunning": {}, + "screenSharingTitle": "compartiendo pantalla", + "@screenSharingTitle": {}, + "screenSharingDetail": "Está compartiendo su pantalla en FluffyChat.", + "@screenSharingDetail": {}, + "callingPermissions": "Permisos de llamada", + "@callingPermissions": {}, + "callingAccount": "Llamando cuenta", + "@callingAccount": {}, + "callingAccountDetails": "Permite que FluffyChat use la aplicación de marcación nativa de Android.", + "@callingAccountDetails": {}, + "appearOnTop": "Aparecer arriba", + "@appearOnTop": {}, + "appearOnTopDetails": "Permite que la aplicación aparezca en la parte superior (no es necesario si ya tiene configurado Fluffychat como cuenta de llamadas).", + "@appearOnTopDetails": {}, + "otherCallingPermissions": "Micrófono, cámara y otros permisos de FluffyChat", + "@otherCallingPermissions": {}, + "whyIsThisMessageEncrypted": "¿Por qué este mensaje no se puede leer?", + "@whyIsThisMessageEncrypted": {}, + "noKeyForThisMessage": "Esto puede suceder si el mensaje se envió antes de que haya iniciado sesión en su cuenta en este dispositivo.\n\nTambién es posible que el remitente haya bloqueado su dispositivo o que algo haya fallado con la conexión a Internet.\n\n¿Puede leer el mensaje en otra sesión? ¡Entonces puede transferir el mensaje desde allí! Vaya a Configuración > Dispositivos y asegúrese de que sus dispositivos se hayan verificado entre sí. La próxima vez que abra la sala y ambas sesiones estén en primer plano, las claves se transmitirán automáticamente.\n\n¿No desea perder las claves al cerrar sesión o al cambiar de dispositivo? Asegúrese de haber habilitado la copia de seguridad del chat en la configuración.", + "@noKeyForThisMessage": {}, + "newGroup": "Nuevo chat", "@newGroup": {}, - "widgetJitsi": "Jitsi Meet", - "@widgetJitsi": {}, + "enterRoom": "Unirse al chat", + "@enterRoom": {}, + "numChats": "{number} chats", + "@numChats": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "numberRoomMembers": "{number} miembros", + "@numberRoomMembers": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "hideUnimportantStateEvents": "Ocultar eventos de estado sin importancia", + "wasDirectChatDisplayName": "Chat vacío (era {oldDisplayName})", + "@wasDirectChatDisplayName": { + "type": "text", + "placeholders": { + "oldDisplayName": {} + } + }, + "startFirstChat": "Empezar su primer chat", + "nextAccount": "Próxima cuenta", + "@nextAccount": {}, "previousAccount": "Cuenta anterior", "@previousAccount": {}, - "users": "Usuarios", - "@users": {}, - "stories": "Historias", - "@stories": {}, - "youInvitedBy": "📩 Has sido invitado por {user}", + "editWidgets": "Editar artilugios", + "@editWidgets": {}, + "addWidget": "Agregar artilugio", + "@addWidget": {}, + "widgetVideo": "Video", + "@widgetVideo": {}, + "widgetEtherpad": "Nota de texto", + "@widgetEtherpad": {}, + "widgetJitsi": "Jitsi Meet", + "@widgetJitsi": {}, + "widgetCustom": "Personalizado", + "@widgetCustom": {}, + "widgetName": "Nombre", + "@widgetName": {}, + "widgetUrlError": "Esto no es un enlace válido.", + "@widgetUrlError": {}, + "widgetNameError": "Proporcione un nombre para mostrar.", + "@widgetNameError": {}, + "errorAddingWidget": "Error an agregar el artilugio.", + "@errorAddingWidget": {}, + "youRejectedTheInvitation": "Rechazó la invitación.", + "@youRejectedTheInvitation": {}, + "youJoinedTheChat": "Se unió al chat.", + "@youJoinedTheChat": {}, + "youAcceptedTheInvitation": "👍 Aceptó la invitación.", + "@youAcceptedTheInvitation": {}, + "youBannedUser": "Bloqueó {user}", + "@youBannedUser": { + "placeholders": { + "user": {} + } + }, + "youHaveWithdrawnTheInvitationFor": "You have withdrawn the invitation for {user}", + "@youHaveWithdrawnTheInvitationFor": { + "placeholders": { + "user": {} + } + }, + "youInvitedBy": "📩 Ha sido invitado por {user}", "@youInvitedBy": { "placeholders": { "user": {} @@ -2173,86 +3521,1143 @@ "commandHint_cuddle": "Mandar una carantoña", "@commandHint_cuddle": {}, "supposedMxid": "Esto debería ser {mxid}", - "@supposedMxid": { - "type": "text", + "youInvitedUser": "📩 Invitó {user}", + "@youInvitedUser": { "placeholders": { - "mxid": {} + "user": {} } }, - "importFromZipFile": "Importar de un archivo .zip", - "@importFromZipFile": {}, - "updateAvailable": "Actualización para FluffyChat disponible!", - "@updateAvailable": {}, - "exportEmotePack": "Exportar paquete de emotes como .zip", - "@exportEmotePack": {}, - "savedEmotePack": "Paquete de emotes guardado en {path}!", - "@savedEmotePack": { - "type": "text", + "youKicked": "👞 Eliminó {user}", + "@youKicked": { "placeholders": { - "path": {} + "user": {} } }, - "importZipFile": "Importar archivo .zip", - "@importZipFile": {}, - "addChatDescription": "Añadir una descripción del chat", - "@addChatDescription": {}, - "sendTypingNotifications": "Enviar notificaciones \"está escribiendo\"", - "@sendTypingNotifications": {}, - "importEmojis": "Importar emojis", - "@importEmojis": {}, - "confirmMatrixId": "Por favor confirma tu Matrix ID para borrar tu cuenta.", - "@confirmMatrixId": {}, - "notAnImage": "El archivo no es una imagen.", - "@notAnImage": {}, - "commandHint_hug": "Mandar un abrazo", - "@commandHint_hug": {}, - "importNow": "Importar ahora", - "@importNow": {}, - "hugContent": "{senderName} te abraza", - "@hugContent": { - "type": "text", + "youKickedAndBanned": "🙅 Eliminó y bloqueó {user}", + "@youKickedAndBanned": { "placeholders": { - "senderName": {} + "user": {} } }, - "otherCallingPermissions": "Micrófono, cámara y otros permisos de FluffyChat", - "@otherCallingPermissions": {}, - "emailOrUsername": "Correo electrónico o nombre de usuario", - "@emailOrUsername": {}, + "youUnbannedUser": "Desbloqueó {user}", + "@youUnbannedUser": { + "placeholders": { + "user": {} + } + }, + "noEmailWarning": "Por favor, introduzca una dirección de correo electrónico válida. De lo contrario, no podrá restablecer su contraseña. Si no quiere, toque de nuevo el botón para continuar.", + "@noEmailWarning": {}, + "stories": "Historias", + "@stories": {}, + "users": "Usuarios", + "@users": {}, + "unlockOldMessages": "Desbloquear mensajes viejos.", + "@unlockOldMessages": {}, + "storeInSecureStorageDescription": "Guarde la clave de recuperación en el almacenamiento seguro de este dispositivo.", + "@storeInSecureStorageDescription": {}, + "saveKeyManuallyDescription": "Guarde esta clave manualmente activando el cuadro de diálogo compartido del sistema o el portapapeles.", + "@saveKeyManuallyDescription": {}, + "storeInAndroidKeystore": "Guardar en Android KeyStore", + "@storeInAndroidKeystore": {}, + "storeInAppleKeyChain": "Guardar en Apple Acceso de Llaveros", + "@storeInAppleKeyChain": {}, + "storeSecurlyOnThisDevice": "Almacenar de forma segura en este dispositivo", + "@storeSecurlyOnThisDevice": {}, "countFiles": "{count} archivos", "@countFiles": { "placeholders": { "count": {} } }, - "discover": "Descubrir", - "@discover": { - "type": "text", - "placeholders": {} - }, - "reportUser": "Reportar usuario", - "@reportUser": {}, - "voiceCall": "Llamada de voz", - "@voiceCall": {}, - "reactedWith": "{sender} reaccionó con {reaction}", - "@reactedWith": { + "confirmMatrixId": "Confirme su ID de Matrix para eliminar su cuenta.", + "@confirmMatrixId": {}, + "supposedMxid": "Esto debe ser {mxid}", + "@supposedMxid": { "type": "text", "placeholders": { - "sender": {}, - "reaction": {} + "mxid": {} } }, - "markAsRead": "Marcar como leído", - "@markAsRead": {}, - "widgetName": "Nombre", - "@widgetName": {}, - "updateNow": "Empezar actualización en segundo plano", - "@updateNow": {}, - "bubbleSize": "Tamaño de la burbuja", - "@bubbleSize": { + "commandHint_googly": "Enviar unos ojos saltones.", + "commandHint_cuddle": "Enviar un arrunche.", + "commandHint_hug": "Enviar un abrazo.", + "googlyEyesContent": "{senderName} le manda ojos saltones.", + "@googlyEyesContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "cuddleContent": "{senderName} se arruncha con usted.", + "@cuddleContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "hugContent": "{senderName} le abraza.", + "@hugContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "pleaseEnterRecoveryKey": "Por favor ingrese su clave de recuperación:", + "@pleaseEnterRecoveryKey": {}, + "commandHint_markasdm": "Marcar como chat de mensajes directos", + "@commandHint_markasdm": {}, + "commandHint_markasgroup": "Marcar como grupal", + "@commandHint_markasgroup": {}, + "recoveryKey": "Clave de recuperación", + "@recoveryKey": {}, + "recoveryKeyLost": "¿Clave de recuperación perdida?", + "@recoveryKeyLost": {}, + "separateChatTypes": "Separar chats privados y grupales", + "@separateChatTypes": { "type": "text", "placeholders": {} }, + "commandHint_create": "Crear un chat grupal vacío\nUse --no-encryption para deshabilitar el cifrado", "replace": "Reemplazar", - "@replace": {} + "@replace": {}, + "unsupportedAndroidVersionLong": "", + "@unsupportedAndroidVersionLong": {}, + "storeSecurlyOnThisDevice": "", + "@storeSecurlyOnThisDevice": {}, + "iUnderstand": "", + "@iUnderstand": {}, + "encryptThisChat": "", + "@encryptThisChat": {}, + "letsStart": "", + "@letsStart": {}, + "endToEndEncryption": "", + "@endToEndEncryption": {}, + "openChat": "", + "@openChat": {}, + "screenSharingDetail": "", + "@screenSharingDetail": {}, + "jumpToLastReadMessage": "", + "@jumpToLastReadMessage": {}, + "allRooms": "", + "@allRooms": { + "type": "text", + "placeholders": {} + }, + "widgetVideo": "", + "@widgetVideo": {}, + "dismiss": "", + "@dismiss": {}, + "reportErrorDescription": "", + "@reportErrorDescription": {}, + "unsupportedAndroidVersion": "", + "@unsupportedAndroidVersion": {}, + "noEmailWarning": "", + "@noEmailWarning": {}, + "indexedDbErrorLong": "", + "@indexedDbErrorLong": {}, + "startFirstChat": "", + "@startFirstChat": {}, + "callingAccount": "", + "@callingAccount": {}, + "setColorTheme": "", + "@setColorTheme": {}, + "commandHint_create": "", + "@commandHint_create": { + "type": "text", + "description": "Usage hint for the command /create" + }, + "commandHint_dm": "Empezar un chat privado\nUse --no-encryption para deshabilitar el cifrado", + "user": "", + "@user": {}, + "banUserDescription": "", + "@banUserDescription": {}, + "requests": "", + "@requests": {}, + "addToStory": "", + "@addToStory": {}, + "removeDevicesDescription": "", + "@removeDevicesDescription": {}, + "separateChatTypes": "", + "@separateChatTypes": { + "type": "text", + "placeholders": {} + }, + "tryAgain": "", + "@tryAgain": {}, + "youKickedAndBanned": "", + "@youKickedAndBanned": { + "placeholders": { + "user": {} + } + }, + "showDirectChatsInSpaces": "", + "@showDirectChatsInSpaces": { + "type": "text", + "placeholders": {} + }, + "unbanUserDescription": "", + "@unbanUserDescription": {}, + "todoLists": "", + "@todoLists": {}, + "messagesStyle": "", + "@messagesStyle": {}, + "newSpaceDescription": "", + "@newSpaceDescription": {}, + "chatDescription": "", + "@chatDescription": {}, + "callingAccountDetails": "", + "@callingAccountDetails": {}, + "enterSpace": "", + "@enterSpace": {}, + "reopenChat": "", + "@reopenChat": {}, + "pleaseEnterRecoveryKey": "", + "@pleaseEnterRecoveryKey": {}, + "widgetNameError": "", + "@widgetNameError": {}, + "addWidget": "", + "@addWidget": {}, + "noKeyForThisMessage": "", + "@noKeyForThisMessage": {}, + "editTodo": "", + "@editTodo": {}, + "hydrateTor": "", + "@hydrateTor": {}, + "pushNotificationsNotAvailable": "", + "@pushNotificationsNotAvailable": {}, + "storeInAppleKeyChain": "", + "@storeInAppleKeyChain": {}, + "hydrate": "", + "@hydrate": {}, + "invalidServerName": "", + "@invalidServerName": {}, + "chatPermissions": "", + "@chatPermissions": {}, + "sender": "", + "@sender": {}, + "storeInAndroidKeystore": "", + "@storeInAndroidKeystore": {}, + "signInWithPassword": "", + "@signInWithPassword": {}, + "pleaseAddATitle": "", + "@pleaseAddATitle": {}, + "makeAdminDescription": "", + "@makeAdminDescription": {}, + "saveKeyManuallyDescription": "", + "@saveKeyManuallyDescription": {}, + "whyIsThisMessageEncrypted": "", + "@whyIsThisMessageEncrypted": {}, + "setChatDescription": "", + "@setChatDescription": {}, + "dehydrateWarning": "", + "@dehydrateWarning": {}, + "noOtherDevicesFound": "", + "@noOtherDevicesFound": {}, + "redactedBy": "", + "@redactedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "videoCallsBetaWarning": "", + "@videoCallsBetaWarning": {}, + "storyPrivacyWarning": "", + "@storyPrivacyWarning": {}, + "matrixWidgets": "", + "@matrixWidgets": {}, + "signInWith": "", + "@signInWith": { + "type": "text", + "placeholders": { + "provider": {} + } + }, + "fileIsTooBigForServer": "", + "@fileIsTooBigForServer": {}, + "noTodosYet": "", + "@noTodosYet": {}, + "callingPermissions": "", + "@callingPermissions": {}, + "readUpToHere": "", + "@readUpToHere": {}, + "unlockOldMessages": "", + "@unlockOldMessages": {}, + "numChats": "", + "@numChats": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "optionalRedactReason": "", + "@optionalRedactReason": {}, + "dehydrate": "", + "@dehydrate": {}, + "archiveRoomDescription": "", + "@archiveRoomDescription": {}, + "switchToAccount": "", + "@switchToAccount": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "experimentalVideoCalls": "", + "@experimentalVideoCalls": {}, + "pleaseEnterRecoveryKeyDescription": "", + "@pleaseEnterRecoveryKeyDescription": {}, + "inviteContactToGroupQuestion": "", + "@inviteContactToGroupQuestion": {}, + "redactedByBecause": "", + "@redactedByBecause": { + "type": "text", + "placeholders": { + "username": {}, + "reason": {} + } + }, + "youHaveWithdrawnTheInvitationFor": "", + "@youHaveWithdrawnTheInvitationFor": { + "placeholders": { + "user": {} + } + }, + "appearOnTopDetails": "", + "@appearOnTopDetails": {}, + "enterRoom": "", + "@enterRoom": {}, + "confirmEventUnpin": "", + "@confirmEventUnpin": {}, + "youInvitedUser": "", + "@youInvitedUser": { + "placeholders": { + "user": {} + } + }, + "fileHasBeenSavedAt": "", + "@fileHasBeenSavedAt": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "anyoneCanKnock": "", + "@anyoneCanKnock": {}, + "redactMessageDescription": "", + "@redactMessageDescription": {}, + "recoveryKey": "", + "@recoveryKey": {}, + "invalidInput": "", + "@invalidInput": {}, + "todosUnencrypted": "", + "@todosUnencrypted": {}, + "dehydrateTorLong": "", + "@dehydrateTorLong": {}, + "doNotShowAgain": "", + "@doNotShowAgain": {}, + "report": "", + "@report": {}, + "hideUnimportantStateEvents": "", + "@hideUnimportantStateEvents": {}, + "screenSharingTitle": "", + "@screenSharingTitle": {}, + "widgetCustom": "", + "@widgetCustom": {}, + "whoCanSeeMyStoriesDesc": "", + "@whoCanSeeMyStoriesDesc": {}, + "youBannedUser": "", + "@youBannedUser": { + "placeholders": { + "user": {} + } + }, + "unsubscribeStories": "", + "@unsubscribeStories": {}, + "hasKnocked": "", + "@hasKnocked": { + "placeholders": { + "user": {} + } + }, + "openLinkInBrowser": "", + "@openLinkInBrowser": {}, + "disableEncryptionWarning": "", + "@disableEncryptionWarning": {}, + "directChat": "", + "@directChat": {}, + "noOneCanJoin": "", + "@noOneCanJoin": {}, + "wrongPinEntered": "", + "@wrongPinEntered": { + "type": "text", + "placeholders": { + "seconds": {} + } + }, + "inviteGroupChat": "", + "@inviteGroupChat": {}, + "appearOnTop": "", + "@appearOnTop": {}, + "invitePrivateChat": "", + "@invitePrivateChat": {}, + "foregroundServiceRunning": "", + "@foregroundServiceRunning": {}, + "wasDirectChatDisplayName": "", + "@wasDirectChatDisplayName": { + "type": "text", + "placeholders": { + "oldDisplayName": {} + } + }, + "noChatDescriptionYet": "", + "@noChatDescriptionYet": {}, + "newTodo": "", + "@newTodo": {}, + "learnMore": "", + "@learnMore": {}, + "chatDescriptionHasBeenChanged": "", + "@chatDescriptionHasBeenChanged": {}, + "dehydrateTor": "", + "@dehydrateTor": {}, + "todoListChangedError": "", + "@todoListChangedError": {}, + "enterInviteLinkOrMatrixId": "", + "@enterInviteLinkOrMatrixId": {}, + "roomUpgradeDescription": "", + "@roomUpgradeDescription": {}, + "pleaseEnterANumber": "", + "@pleaseEnterANumber": {}, + "youKicked": "", + "@youKicked": { + "placeholders": { + "user": {} + } + }, + "profileNotFound": "", + "@profileNotFound": {}, + "jump": "", + "@jump": {}, + "sorryThatsNotPossible": "", + "@sorryThatsNotPossible": {}, + "storyFrom": "", + "@storyFrom": { + "type": "text", + "placeholders": { + "date": {}, + "body": {} + } + }, + "shareInviteLink": "", + "@shareInviteLink": {}, + "commandHint_markasdm": "", + "@commandHint_markasdm": {}, + "recoveryKeyLost": "", + "@recoveryKeyLost": {}, + "deviceKeys": "", + "@deviceKeys": {}, + "emoteKeyboardNoRecents": "", + "@emoteKeyboardNoRecents": { + "type": "text", + "placeholders": {} + }, + "setTheme": "", + "@setTheme": {}, + "youJoinedTheChat": "", + "@youJoinedTheChat": {}, + "thisUserHasNotPostedAnythingYet": "", + "@thisUserHasNotPostedAnythingYet": {}, + "errorAddingWidget": "", + "@errorAddingWidget": {}, + "commandHint_dm": "", + "@commandHint_dm": { + "type": "text", + "description": "Usage hint for the command /dm" + }, + "dehydrate": "Exportar sesión y borrar dispositivo", + "@dehydrate": {}, + "dehydrateWarning": "Esta acción no se puede deshacer. Asegúrese de almacenar de forma segura el archivo de copia de seguridad.", + "@dehydrateWarning": {}, + "dehydrateTor": "TOR Usuarios: Exportar sesión", + "@dehydrateTor": {}, + "dehydrateTorLong": "Para TOR usuarios, se recomienda exportar la sesión antes de cerrar la ventana.", + "@dehydrateTorLong": {}, + "hydrateTor": "TOR Usuarios: Importar exportación de sesión", + "@hydrateTor": {}, + "hydrateTorLong": "¿Exportó su sesión la última vez en TOR? Impórtelo rápidamente y siga chateando.", + "@hydrateTorLong": {}, + "hydrate": "Restaurar desde archivo de copia de seguridad", + "@hydrate": {}, + "reportUser": "Reportar usuario", + "@reportUser": {}, + "dismiss": "Descartar", + "@dismiss": {}, + "matrixWidgets": "Artilugio de Matrix", + "@matrixWidgets": {}, + "storyPrivacyWarning": "Tenga en cuenta que las personas pueden verse y comunicarse entre sí en su historia. Sus historias estarán visibles durante 24 horas, pero no hay garantía de que se eliminen de todos los dispositivos y servidores.", + "@storyPrivacyWarning": {}, + "iUnderstand": "Entiendo", + "openChat": "Abrir Chat", + "markAsRead": "Marcar como leído", + "pleaseEnterRecoveryKeyDescription": "Para desbloquear sus mensajes antiguos, ingrese su clave de recuperación que se generó en una sesión anterior. Su clave de recuperación NO es su contraseña.", + "@pleaseEnterRecoveryKeyDescription": {}, + "addToStory": "Agregar a historia", + "@addToStory": {}, + "whoCanSeeMyStories": "¿Quién puede ver mis historias?", + "unsubscribeStories": "Darse de baja de historias", + "thisUserHasNotPostedAnythingYet": "Este usuario aún no ha publicado nada en su historia.", + "yourStory": "Su historia", + "itToggleDescription": "Esta herramienta de aprendizaje identificará palabras en su idioma base y lo ayudará a traducirlas a su idioma a aprender. Aunque es raro, la AI puede cometer errores de traducción de vez en cuando.", + "igcToggleDescription": "Esta herramienta de aprendizaje identificará errores comunes de ortografía, gramática y puntuación en su mensaje y sugerirá correcciones. Aunque es raro, la AI puede cometer errores de corrección de vez en cuando.", + "sendOnEnterDescription": "Deshabilite esta función para poder agregar espacios de línea en los mensajes. Cuando está deshabilitada en la versión web, puede presionar Shift + Intro para comenzar una nueva línea. Cuando está deshabilitada en las aplicaciones móviles, puede presionar solo Intro para comenzar una una nueva línea.", + "definitionsToolName": "Definiciones", + "messageTranslationsToolName": "Traducciones de mensajes", + "definitionsToolDescription": "Cuando está habilitado, se puede hacer clic en las palabras subrayadas en azul para obtener definiciones. Haga clic en los mensajes para acceder a las definiciones.", + "translationsToolDescrption": "Cuando esté habilitado, haga clic en un mensaje y en el icono de traducción para ver un mensaje en su idioma base.", + "originalMessage": "Mensaje original", + "sentMessage": "Mensaje enviado", + "useType": "Tipo de Uso", + "notAvailable": "No disponible", + "classExchanges": "Intercambios", + "kickAllStudents": "Patear a todos los estudiantes", + "kickAllStudentsConfirmation": "¿Estás seguro de que quieres echar a todos los estudiantes?", + "inviteAllStudents": "Invitar a todos los estudiantes", + "inviteAllStudentsConfirmation": "¿Estás seguro de que quieres invitar a todos los estudiantes?", + "whoCanSeeMyStoriesDesc": "Ten en cuenta que las personas pueden verse y ponerse en contacto en tu historia.", + "taAndGaTooltip": "Uso de la L2 con ayuda de traducción y asistencia gramatical.", + "storyFrom": "Historia de {date}: \n{body}", + "createNewSpace": "Crear una sala de intercambio", + "enterASpacepName": "Introduzca un nombre", + "oneToOneChatsWithinClass": "Chats privados dentro de la sala", + "oneToOneChatsWithinClassDesc": "Si permite chats privados, los alumnos pueden iniciar y utilizar chats privados con otros participantes de la sala. De lo contrario, sólo podrán participar en chats de grupo.", + "subscriptionManagementUnavailable": "Gestión de suscripciones no disponible", + "redeemPromoCode": "Canjear código promocional", + "enterPromoCode": "Introduzca el código promocional", + "downloadTxtFile": "Descargar archivo de texto", + "downloadCSVFile": "Descargar archivo CSV", + "promotionalSubscriptionDesc": "Su suscripción actual es promocional. Envíe un mensaje a support@pangea.chat para cambiar su suscripción.", + "originalSubscriptionPlatform": "Suscripción adquirida a través de", + "oneWeekTrial": "Una semana de prueba", + "abDisplayName": "abkhaz", + "aaDisplayName": "afar", + "afDisplayName": "africaans", + "akDisplayName": "akan", + "sqDisplayName": "albanés", + "amDisplayName": "amárico", + "arDisplayName": "arábica", + "anDisplayName": "aragonese", + "hyDisplayName": "armenio", + "asDisplayName": "assamese", + "avDisplayName": "avaric", + "aeDisplayName": "avéstico", + "ayDisplayName": "aymara", + "azDisplayName": "azerbaiyano", + "bmDisplayName": "bambara", + "baDisplayName": "bashkir", + "euDisplayName": "vasco", + "beDisplayName": "bielorruso", + "bnDisplayName": "bengalí", + "bhDisplayName": "bihari", + "biDisplayName": "bislama", + "bsDisplayName": "bosnio", + "brDisplayName": "bretón", + "bgDisplayName": "búlgaro", + "myDisplayName": "birmano", + "caDisplayName": "catalán", + "chDisplayName": "chamorro", + "ceDisplayName": "chechen", + "nyDisplayName": "chichewa", + "zhDisplayName": "chino", + "cvDisplayName": "chuvasio", + "kwDisplayName": "de Cornualles", + "coDisplayName": "corso", + "crDisplayName": "cree", + "hrDisplayName": "croata", + "csDisplayName": "checo", + "daDisplayName": "danés", + "dvDisplayName": "divehi; dhivehi; maldivian;", + "nlDisplayName": "holandés", + "enDisplayName": "inglés", + "eoDisplayName": "esperanto", + "etDisplayName": "estonio", + "eeDisplayName": "ewe", + "foDisplayName": "feroés", + "fjDisplayName": "fijian", + "fiDisplayName": "finlandés", + "frDisplayName": "francés", + "ffDisplayName": "fula; fulah; pulaar; pular", + "glDisplayName": "gallego", + "kaDisplayName": "georgiano", + "deDisplayName": "alemán", + "elDisplayName": "griego", + "gnDisplayName": "guaraní", + "guDisplayName": "guyaratí", + "htDisplayName": "haitiano", + "haDisplayName": "hausa", + "heDisplayName": "hebreo (moderno)", + "hzDisplayName": "herero", + "hiDisplayName": "hindi", + "hoDisplayName": "hiri motu", + "huDisplayName": "húngaro", + "iaDisplayName": "interlingua", + "idDisplayName": "indonesio", + "ieDisplayName": "interlingüismo", + "gaDisplayName": "irlandesa", + "igDisplayName": "igbo", + "ikDisplayName": "inupiaq", + "ioDisplayName": "ido", + "isDisplayName": "islandés", + "itDisplayName": "italiano", + "iuDisplayName": "inuktitut", + "jaDisplayName": "japonés", + "jvDisplayName": "javanés", + "klDisplayName": "kalaallisut, greenlandic", + "knDisplayName": "kannada", + "krDisplayName": "kanuri", + "ksDisplayName": "kashmiri", + "kkDisplayName": "kazajo", + "kmDisplayName": "jemer", + "kiDisplayName": "kikuyú", + "rwDisplayName": "kinyarwanda", + "kyDisplayName": "kirguís", + "kvDisplayName": "komi", + "kgDisplayName": "kongo", + "koDisplayName": "coreano", + "kuDisplayName": "kurdo", + "kjDisplayName": "kwanyama, kuanyama", + "laDisplayName": "latín", + "lbDisplayName": "luxemburgués", + "lgDisplayName": "luganda", + "liDisplayName": "limburgués", + "lnDisplayName": "lingala", + "loDisplayName": "laosiano", + "ltDisplayName": "lituano", + "luDisplayName": "luba-katanga", + "lvDisplayName": "letón", + "gvDisplayName": "manx", + "mkDisplayName": "macedónio", + "mgDisplayName": "madagascarí", + "msDisplayName": "malayo", + "mlDisplayName": "malayalam", + "mtDisplayName": "maltés", + "miDisplayName": "maorí", + "mrDisplayName": "marathi (maräthi)", + "mhDisplayName": "marshalés", + "mnDisplayName": "mongol", + "naDisplayName": "nauru", + "nvDisplayName": "navajo, navaho", + "nbDisplayName": "norwegian bokmål", + "ndDisplayName": "north ndebele", + "neDisplayName": "nepalí", + "ngDisplayName": "ndonga", + "nnDisplayName": "norwegian nynorsk", + "noDisplayName": "noruego", + "iiDisplayName": "nuosu", + "nrDisplayName": "ndebele del sur", + "ocDisplayName": "occitan", + "ojDisplayName": "ojibwe, ojibwa", + "cuDisplayName": "antiguo eslavo eclesiástico", + "omDisplayName": "oromo", + "orDisplayName": "oriya", + "osDisplayName": "ossetian, ossetic", + "paDisplayName": "panyabí", + "piDisplayName": "pāli", + "faDisplayName": "persa", + "plDisplayName": "polaco", + "psDisplayName": "pastún", + "ptDisplayName": "portugués", + "quDisplayName": "quechua", + "rmDisplayName": "romansh", + "rnDisplayName": "kirundi", + "roDisplayName": "rumano", + "ruDisplayName": "ruso", + "saDisplayName": "sanskrit (saṁskṛta)", + "scDisplayName": "sardo", + "sdDisplayName": "sindhi", + "seDisplayName": "sami del norte", + "smDisplayName": "samoano", + "sgDisplayName": "sango", + "srDisplayName": "serbio", + "gdDisplayName": "gaélico escocés", + "snDisplayName": "shona", + "siDisplayName": "cingalés", + "skDisplayName": "eslovaco", + "slDisplayName": "esloveno", + "soDisplayName": "somalí", + "stDisplayName": "sotho del sur", + "esDisplayName": "español", + "suDisplayName": "sundanés", + "swDisplayName": "swahili", + "ssDisplayName": "swati", + "svDisplayName": "sueco", + "taDisplayName": "tamil", + "teDisplayName": "telugu", + "tgDisplayName": "tayiko", + "thDisplayName": "tailandés", + "tiDisplayName": "tigrinya", + "boDisplayName": "estándar tibetano", + "tkDisplayName": "turkmeno", + "tlDisplayName": "tagalo", + "tnDisplayName": "tswana", + "toDisplayName": "tonga (Islas Tonga)", + "trDisplayName": "turco", + "tsDisplayName": "tsonga", + "ttDisplayName": "tártaro", + "twDisplayName": "twi", + "tyDisplayName": "tahitian", + "ugDisplayName": "uigur", + "ukDisplayName": "ucranio", + "urDisplayName": "urdu", + "uzDisplayName": "uzbeco", + "veDisplayName": "venda", + "viDisplayName": "vietnamita", + "voDisplayName": "volapük", + "waDisplayName": "walloon", + "cyDisplayName": "galés", + "woDisplayName": "wolof", + "fyDisplayName": "frisón occidental", + "xhDisplayName": "xhosa", + "yiDisplayName": "yídish", + "yoDisplayName": "yoruba", + "zaDisplayName": "zhuang, chuang", + "unkDisplayName": "unknown", + "zuDisplayName": "zulú", + "hawDisplayName": "hawaiano", + "hmnDisplayName": "hmong", + "multiDisplayName": "multi", + "cebDisplayName": "cebuano", + "dzDisplayName": "dzongkha", + "iwDisplayName": "hebreo", + "jwDisplayName": "javanés", + "moDisplayName": "moldavian", + "shDisplayName": "serbo-croatian", + "wwCountryDisplayName": "Mundial", + "afCountryDisplayName": "Afganistán", + "axCountryDisplayName": "Islas Åland", + "alCountryDisplayName": "Albania", + "dzCountryDisplayName": "Argelia", + "asCountryDisplayName": "Samoa Americana", + "adCountryDisplayName": "Andorra", + "aoCountryDisplayName": "Angola", + "aiCountryDisplayName": "Anguila", + "agCountryDisplayName": "Antigua y Barbuda", + "arCountryDisplayName": "Argentina", + "amCountryDisplayName": "Armenia", + "awCountryDisplayName": "Aruba", + "acCountryDisplayName": "Isla de la Ascensión", + "auCountryDisplayName": "Australia", + "atCountryDisplayName": "Austria", + "azCountryDisplayName": "Azerbaiyán", + "bsCountryDisplayName": "Bahamas", + "bhCountryDisplayName": "Baréin", + "bdCountryDisplayName": "Bangladés", + "bbCountryDisplayName": "Barbados", + "byCountryDisplayName": "Bielorrusia", + "beCountryDisplayName": "Bélgica", + "bzCountryDisplayName": "Belice", + "bjCountryDisplayName": "Benín", + "bmCountryDisplayName": "Bermudas", + "btCountryDisplayName": "Bután", + "boCountryDisplayName": "Bolivia", + "baCountryDisplayName": "Bosnia y Herzegovina", + "bwCountryDisplayName": "Botsuana", + "brCountryDisplayName": "Brasil", + "ioCountryDisplayName": "Territorio Británico del Océano Índico", + "vgCountryDisplayName": "Islas Vírgenes Británicas", + "bnCountryDisplayName": "Brunéi", + "bgCountryDisplayName": "Bulgaria", + "bfCountryDisplayName": "Burkina Faso", + "biCountryDisplayName": "Burundi", + "khCountryDisplayName": "Camboya", + "cmCountryDisplayName": "Camerún", + "caCountryDisplayName": "Canadá", + "cvCountryDisplayName": "Cabo Verde", + "bqCountryDisplayName": "Países Bajos Caribeños", + "kyCountryDisplayName": "Islas Caimán", + "cfCountryDisplayName": "República Centroafricana", + "tdCountryDisplayName": "Chad", + "clCountryDisplayName": "Chile", + "cnCountryDisplayName": "China", + "cxCountryDisplayName": "Isla de Navidad", + "ccCountryDisplayName": "Islas Cocos (Keeling)", + "coCountryDisplayName": "Colombia", + "kmCountryDisplayName": "Comoras", + "cdCountryDisplayName": "República Democrática del Congo", + "cgCountryDisplayName": "República del Congo", + "ckCountryDisplayName": "Islas Cook", + "crCountryDisplayName": "Costa Rica", + "ciCountryDisplayName": "Costa de Marfil", + "hrCountryDisplayName": "Croacia", + "cuCountryDisplayName": "Cuba", + "cwCountryDisplayName": "Curazao", + "cyCountryDisplayName": "Chipre", + "czCountryDisplayName": "República Checa", + "dkCountryDisplayName": "Dinamarca", + "djCountryDisplayName": "Yibuti", + "dmCountryDisplayName": "Dominica", + "doCountryDisplayName": "República Dominicana", + "tlCountryDisplayName": "Timor Oriental", + "ecCountryDisplayName": "Ecuador", + "egCountryDisplayName": "Egipto", + "svCountryDisplayName": "El Salvador", + "gqCountryDisplayName": "Guinea Ecuatorial", + "erCountryDisplayName": "Eritrea", + "eeCountryDisplayName": "Estonia", + "szCountryDisplayName": "Esuatini", + "etCountryDisplayName": "Etiopía", + "fkCountryDisplayName": "Islas Malvinas", + "foCountryDisplayName": "Islas Feroe", + "fjCountryDisplayName": "Fiyi", + "fiCountryDisplayName": "Finlandia", + "frCountryDisplayName": "Francia", + "gfCountryDisplayName": "Guayana Francesa", + "pfCountryDisplayName": "Polinesia Francesa", + "gaCountryDisplayName": "Gabón", + "gmCountryDisplayName": "Gambia", + "geCountryDisplayName": "Georgia", + "deCountryDisplayName": "Alemania", + "ghCountryDisplayName": "Ghana", + "giCountryDisplayName": "Gibraltar", + "grCountryDisplayName": "Grecia", + "glCountryDisplayName": "Groenlandia", + "gdCountryDisplayName": "Granada", + "gpCountryDisplayName": "Guadalupe", + "guCountryDisplayName": "Guam", + "gtCountryDisplayName": "Guatemala", + "ggCountryDisplayName": "Guernsey", + "gnCountryDisplayName": "Guinea Conakry", + "gwCountryDisplayName": "Guinea-Bissau", + "gyCountryDisplayName": "Guyana", + "htCountryDisplayName": "Haití", + "hmCountryDisplayName": "Islas Heard y McDonald", + "hnCountryDisplayName": "Honduras", + "hkCountryDisplayName": "Hong Kong", + "huCountryDisplayName": "Hungría", + "isCountryDisplayName": "Islandia", + "inCountryDisplayName": "India", + "idCountryDisplayName": "Indonesia", + "irCountryDisplayName": "Irán", + "iqCountryDisplayName": "Irak", + "ieCountryDisplayName": "Irlanda", + "imCountryDisplayName": "Isla de Man", + "ilCountryDisplayName": "Israel", + "itCountryDisplayName": "Italia", + "jmCountryDisplayName": "Jamaica", + "jpCountryDisplayName": "Japón", + "jeCountryDisplayName": "Jersey", + "joCountryDisplayName": "Jordania", + "kzCountryDisplayName": "Kazajistán", + "keCountryDisplayName": "Kenia", + "kiCountryDisplayName": "Kiribati", + "xkCountryDisplayName": "Kosovo", + "kwCountryDisplayName": "Kuwait", + "kgCountryDisplayName": "Kirguistán", + "laCountryDisplayName": "Laos", + "lvCountryDisplayName": "Letonia", + "lbCountryDisplayName": "Líbano", + "lsCountryDisplayName": "Lesoto", + "lrCountryDisplayName": "Liberia", + "lyCountryDisplayName": "Libia", + "liCountryDisplayName": "Liechtenstein", + "ltCountryDisplayName": "Lituania", + "luCountryDisplayName": "Luxemburgo", + "moCountryDisplayName": "Macao", + "mkCountryDisplayName": "Macedonia", + "mgCountryDisplayName": "Madagascar", + "mwCountryDisplayName": "Malaui", + "myCountryDisplayName": "Malasia", + "mvCountryDisplayName": "Maldivas", + "mlCountryDisplayName": "Malí", + "mtCountryDisplayName": "Malta", + "mhCountryDisplayName": "Islas Marshall", + "mqCountryDisplayName": "Martinica", + "mrCountryDisplayName": "Mauritania", + "muCountryDisplayName": "Mauricio", + "ytCountryDisplayName": "Mayotte", + "mxCountryDisplayName": "México", + "fmCountryDisplayName": "Micronesia", + "mdCountryDisplayName": "Moldavia", + "mcCountryDisplayName": "Mónaco", + "mnCountryDisplayName": "Mongolia", + "meCountryDisplayName": "Montenegro", + "msCountryDisplayName": "Montserrat", + "maCountryDisplayName": "Marruecos", + "mzCountryDisplayName": "Mozambique", + "mmCountryDisplayName": "Myanmar (Birmania)", + "naCountryDisplayName": "Namibia", + "nrCountryDisplayName": "Nauru", + "npCountryDisplayName": "Nepal", + "nlCountryDisplayName": "Países Bajos", + "ncCountryDisplayName": "Nueva Caledonia", + "nzCountryDisplayName": "Nueva Zelanda", + "niCountryDisplayName": "Nicaragua", + "neCountryDisplayName": "Níger", + "ngCountryDisplayName": "Nigeria", + "nuCountryDisplayName": "Niue", + "nfCountryDisplayName": "Isla Norfolk", + "kpCountryDisplayName": "Corea del Norte", + "mpCountryDisplayName": "Islas Marianas del Norte", + "noCountryDisplayName": "Noruega", + "omCountryDisplayName": "Omán", + "pkCountryDisplayName": "Pakistán", + "pwCountryDisplayName": "Palaos", + "psCountryDisplayName": "Territorios Palestinos", + "paCountryDisplayName": "Panamá", + "pgCountryDisplayName": "Papúa Nueva Guinea", + "pyCountryDisplayName": "Paraguay", + "peCountryDisplayName": "Perú", + "phCountryDisplayName": "Filipinas", + "plCountryDisplayName": "Polonia", + "ptCountryDisplayName": "Portugal", + "prCountryDisplayName": "Puerto Rico", + "qaCountryDisplayName": "Catar", + "reCountryDisplayName": "Reunión", + "roCountryDisplayName": "Rumanía", + "ruCountryDisplayName": "Rusia", + "rwCountryDisplayName": "Ruanda", + "blCountryDisplayName": "San Bartolomé", + "shCountryDisplayName": "Santa Elena", + "knCountryDisplayName": "San Cristóbal y Nieves", + "lcCountryDisplayName": "Santa Lucía", + "mfCountryDisplayName": "San Martín", + "pmCountryDisplayName": "San Pedro y Miquelón", + "vcCountryDisplayName": "San Vicente y las Granadinas", + "wsCountryDisplayName": "Samoa", + "smCountryDisplayName": "San Marino", + "stCountryDisplayName": "Santo Tomé y Príncipe", + "saCountryDisplayName": "Arabia Saudita", + "snCountryDisplayName": "Senegal", + "rsCountryDisplayName": "Serbia", + "scCountryDisplayName": "Seychelles", + "slCountryDisplayName": "Sierra Leona", + "sgCountryDisplayName": "Singapur", + "sxCountryDisplayName": "San Martín", + "skCountryDisplayName": "Eslovaquia", + "siCountryDisplayName": "Eslovenia", + "sbCountryDisplayName": "Islas Salomón", + "soCountryDisplayName": "Somalia", + "zaCountryDisplayName": "Sudáfrica", + "gsCountryDisplayName": "Islas Georgia del Sur y Sandwich del Sur", + "krCountryDisplayName": "Corea del Sur", + "ssCountryDisplayName": "Sudán del Sur", + "esCountryDisplayName": "España", + "lkCountryDisplayName": "Sri Lanka", + "sdCountryDisplayName": "Sudán", + "srCountryDisplayName": "Surinam", + "sjCountryDisplayName": "Svalbard y Jan Mayen", + "seCountryDisplayName": "Suecia", + "chCountryDisplayName": "Suiza", + "syCountryDisplayName": "Siria", + "twCountryDisplayName": "Taiwán", + "tjCountryDisplayName": "Tayikistán", + "tzCountryDisplayName": "Tanzania", + "thCountryDisplayName": "Tailandia", + "tgCountryDisplayName": "Togo", + "tkCountryDisplayName": "Tokelau", + "toCountryDisplayName": "Tonga", + "ttCountryDisplayName": "Trinidad y Tobago", + "tnCountryDisplayName": "Túnez", + "trCountryDisplayName": "Turquía", + "tmCountryDisplayName": "Turkmenistán", + "tcCountryDisplayName": "Islas Turcas y Caicos", + "tvCountryDisplayName": "Tuvalu", + "viCountryDisplayName": "Islas Vírgenes de los Estados Unidos", + "ugCountryDisplayName": "Uganda", + "uaCountryDisplayName": "Ucrania", + "aeCountryDisplayName": "Emiratos Árabes Unidos", + "gbCountryDisplayName": "Reino Unido", + "usCountryDisplayName": "Estados Unidos", + "uyCountryDisplayName": "Uruguay", + "uzCountryDisplayName": "Uzbekistán", + "vuCountryDisplayName": "Vanuatu", + "vaCountryDisplayName": "Ciudad del Vaticano", + "veCountryDisplayName": "Venezuela", + "vnCountryDisplayName": "Vietnam", + "wfCountryDisplayName": "Wallis y Futuna", + "ehCountryDisplayName": "Sahara Occidental", + "yeCountryDisplayName": "Yemen", + "zmCountryDisplayName": "Zambia", + "zwCountryDisplayName": "Zimbabue", + "downloadXLSXFile": "Descargar archivo Excel", + "unknownPrivateChat": "Chat Privado Desconocido", + "allPrivateChats": "Todos los chats privados (incluso con bots) en clase", + "chatHasBeenAddedToThisSpace": "Se ha añadido el chat a este espacio", + "classes": "Clases", + "showDirectChatsInSpaces": "Mostrar chats directos relacionados en Spaces", + "spaceIsPublic": "El espacio es público", + "removeFromSpace": "Retirar del espacio", + "addToSpaceDescription": "Seleccione un espacio para añadirle este chat.", + "newSpace": "Nueva clase", + "enterSpace": "Introducir espacio", + "allSpaces": "Todos los espacios", + "deleteSpace": "Borrar espacio", + "areYouSureDeleteClass": "¿Seguro que quieres borrar este espacio?", + "enterDeletedClassName": "Introduzca el nombre del espacio para confirmar:", + "incorrectClassName": "Nombre incorrecto del espacio", + "interactiveTranslatorNotAllowedDesc": "La asistencia de traducción está desactivada en los chats de grupo espaciales para todos los participantes. Esta restricción no se aplica a los chats de administrador de clase/intercambio ni a los chats directos.", + "interactiveTranslatorAllowedDesc": "Los estudiantes pueden elegir si desean utilizar la asistencia de traducción en los chats de grupo espaciales en Configuración > Configuración de aprendizaje.", + "multiLingualClass": "Clase multilingüe", + "allClasses": "Todas las clases", + "allChatsAndClasses": "Todos los chats y espacios", + "classDescription": "Descripción del espacio", + "classDescriptionDesc": "Establecer una descripción", + "copyClassLink": "Copiar enlace de invitación", + "copyClassLinkDesc": "Al hacer clic en este enlace, los usuarios accederán a la aplicación, se abrirán una cuenta y se unirán automáticamente a este espacio.", + "copyClassCode": "Copiar código de invitación", + "classSettingsDesc": "Editar idiomas de clase y nivel", + "createGroupChatsDesc": "Active esta opción para permitir a los estudiantes crear chats de grupo dentro del espacio de clase/intercambio.", + "joinWithClassCode": "Únete a una clase o a un intercambio", + "joinWithClassCodeDesc": "Conéctese a una clase o espacio de intercambio con el código de invitación de 6 dígitos proporcionado por el administrador del espacio.", + "joinWithClassCodeHint": "Introduzca el código de invitación", + "unableToFindClass": "No podemos encontrar la clase o el intercambio. Por favor, vuelva a comprobar la información con el administrador del espacio. Si sigue teniendo problemas, póngase en contacto con support@pangea.chat.", + "welcomeToYourNewClass": "Bienvenido 🙂", + "welcomeToClass": "Bienvenido! 🙂\n- ¡Prueba a unirte a un chat!\n- ¡Diviértete chateando!", + "welcomeToPangea18Plus": "Bienvenido al chat de Pangea 🙂 .\n¿Qué es lo siguiente?\n¡Crea una clase o únete a ella!\n¡O busca un compañero de conversación!", + "welcomeToPangeaMinor": "Bienvenido al chat de Pangea 🙂 .\n¿Qué es lo siguiente?\n¡Únete a una clase!\nPide a tu profesor un código de invitación.", + "unableToFindClassCode": "No se puede encontrar el código.", + "errorDisableITClassDesc": "La ayuda a la traducción está desactivada para el espacio en el que se encuentra este chat.", + "errorDisableIGCClassDesc": "La asistencia gramatical está desactivada para el espacio en el que se encuentra este chat.", + "errorDisableLanguageAssistanceClassDesc": "La ayuda a la traducción y la ayuda gramatical están desactivadas para el espacio en el que se encuentra este chat.", + "toggleToolSettingsDescription": "Aquí puedes cambiar la configuración individual de la herramienta de idioma. Para los chats dentro de un espacio, la configuración del espacio tendrá prioridad y puede anular esta configuración.", + "classNameRequired": "Introduzca un nombre de espacio", + "classRoster": "Participantes", + "alreadyInClass": "Ya estás en este espacio.", + "pleaseLoginFirst": "Inicie sesión o regístrese primero y, a continuación, se le añadirá a su clase/espacio de intercambio.", + "welcomeBack": "¡Bienvenido de nuevo! Si formó parte del piloto 2023-2024, póngase en contacto con nosotros para obtener su suscripción especial de piloto. Si es usted un profesor que ha adquirido (o cuya institución ha adquirido) licencias para su clase, póngase en contacto con nosotros para obtener su suscripción de profesor.", + "createNewClass": "Nuevo espacio para clases", + "newExchange": "Nuevo espacio de intercambio", + "inviteStudentsFromOtherClasses": "Invitar a estudiantes de otros espacios", + "allExchanges": "Todos los intercambios", + "creatingSpacePleaseWait": "Creando espacio. Por favor, espere...", + "pay": "Pagar", + "copyClassCodeDesc": "Los estudiantes que ya están en la aplicación pueden 'Unirse a una clase o a un intercambio' a través del menú principal.", + "inviteUsersFromPangea": "Añadir profesores", + "addToClass": "Añadir intercambio a la clase", + "addToClassOrExchange": "Añadir chat a la clase o al intercambio", + "classAnalytics": "Análisis de clase", + "myLearning": "Mis análisis", + "addToClassDesc": "Añadir un intercambio a una clase hará que el intercambio aparezca dentro de la clase para los estudiantes y les dará acceso a todos los chats dentro del intercambio.", + "addToClassOrExchangeDesc": "Añadir un chat a una clase o intercambio hará que el chat aparezca dentro de la clase o intercambio para los estudiantes y les dará acceso.", + "invitedToClassOrExchange": "{user} te ha invitado a unirte a ¡{classOrExchange}! ¿Deseas aceptar?", + "@invitedToClassOrExchange": { + "placeholders": { + "classOrExchange": {}, + "user": {} + } + }, + "decline": "Disminución", + "declinedInvitation": "Invitación rechazada", + "acceptedInvitation": "Invitación aceptada", + "youreInvited": "📩 ¡Estás invitado!", + "studentPermissionsDesc": "Establece los permisos para este espacio. Sólo se aplicarán al espacio de clase/intercambio. Anularán la configuración de los usuarios individuales.", + "noEligibleSpaces": "No hay espacios elegibles a los que añadir esto.", + "youAddedToSpace": "Has añadido {child} a {space}", + "@youAddedToSpace": { + "placeholders": { + "child": {}, + "space": {} + } + }, + "youRemovedFromSpace": "Has eliminado {child} de {space}", + "@youRemovedFromSpace": { + "placeholders": { + "child": {}, + "space": {} + } + }, + "changeView": "Cambia de vista.", + "invitedToChat": "{user} te ha invitado a unirte a un chat: ¡{name}! ¿Deseas aceptar?", + "total": "Total: ", + "noDataFound": "No se han encontrado datos", + "promoSubscriptionExpirationDesc": "Su suscripción actual es promocional y expira el {expiration}. Envíe un mensaje a support@pangea.chat para cambiar su suscripción.", + "@promoSubscriptionExpirationDesc": { + "placeholders": { + "expiration": {} + } + }, + "emptyChatNameWarning": "Introduzca un nombre para este chat", + "emptyClassNameWarning": "Introduzca un nombre para esta clase", + "emptyExchangeNameWarning": "Introduzca un nombre para este intercambio", + "blurMeansTranslateTitle": "¿Por qué está borroso el mensaje?", + "blurMeansTranslateBody": "Mientras el Modo Inmersión esté activado, los mensajes que se envíen en su idioma base aparecerán borrosos mientras Pangea Bot los traduce a su idioma de destino. El modo inmersión puede activarse en los ajustes individuales y de clase.", + "monthlySubscription": "Mensualmente", + "yearlySubscription": "Anualmente", + "defaultSubscription": "Suscripción al chat de Pangea", + "freeTrial": "Prueba gratuita", + "languageLevelWarning": "Seleccione un nivel de idioma de clase", + "lockedChatWarning": "🔒 Este chat ha sido bloqueado", + "lockSpace": "Espacio de bloqueo", + "lockChat": "Chat de bloqueo", + "archiveSpace": "Espacio de archivos", + "grammarAnalytics": "Análisis de errores", + "someErrorTitle": "Hm, algo no está bien", + "someErrorBody": "Podría ser un error o algo en tu lenguaje base.", + "bestCorrectionFeedback": "¡Correcto!", + "distractorFeedback": "Eso no es del todo correcto.", + "bestAnswerFeedback": "¡Correcto!", + "definitionDefaultPrompt": "¿Qué significa esta palabra?", + "practiceDefaultPrompt": "¿Cuál es la mejor respuesta?", + "correctionDefaultPrompt": "¿Cuál es la mejor corrección?", + "itStartDefaultPrompt": "¿Quiere ayuda para traducir?", + "suggestTo": "Sugerir a {spaceName}", + "suggestChatDesc": "Los chats sugeridos aparecerán en la lista de chats de {spaceName}.", + "suggestExchangeDesc": "Los intercambios sugeridos aparecerán en la lista de chat de {spaceName}.", + "acceptSelection": "Aceptar corrección", + "acceptSelectionAnyway": "Use esto de todos modos", + "replace": "Corregir", + "makingActivity": "Actividad de fabricación", + "why": "¿Por qué?", + "definition": "Definición", + "exampleSentence": "Ejemplo de frase", + "addToClassTitle": "Añadir intercambio a la clase", + "youUnbannedUser": "", + "@youUnbannedUser": { + "placeholders": { + "user": {} + } + }, + "emojis": "", + "@emojis": {}, + "pleaseTryAgainLaterOrChooseDifferentServer": "", + "@pleaseTryAgainLaterOrChooseDifferentServer": {}, + "createGroup": "", + "@createGroup": {}, + "hydrateTorLong": "", + "@hydrateTorLong": {}, + "custom": "", + "@custom": {}, + "noBackupWarning": "", + "@noBackupWarning": {}, + "editWidgets": "", + "@editWidgets": {}, + "storeInSecureStorageDescription": "", + "@storeInSecureStorageDescription": {}, + "kickUserDescription": "", + "@kickUserDescription": {}, + "pinMessage": "", + "@pinMessage": {}, + "invite": "", + "@invite": {}, + "continueWith": "", + "@continueWith": {}, + "indexedDbErrorTitle": "", + "@indexedDbErrorTitle": {}, + "googlyEyesContent": "", + "@googlyEyesContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "cuddleContent": "", + "@cuddleContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "commandHint_googly": "", + "@commandHint_googly": {}, + "placeCall": "", + "@placeCall": {} } diff --git a/assets/l10n/intl_et.arb b/assets/l10n/intl_et.arb index 4655b1373..39920bec7 100644 --- a/assets/l10n/intl_et.arb +++ b/assets/l10n/intl_et.arb @@ -1164,7 +1164,7 @@ "type": "text", "placeholders": {} }, - "noGoogleServicesWarning": "Tundub, et sinu nutiseadmes pole Google teenuseid. Sinu privaatsuse mõttes on see kindlasti hea otsus! Kui sa soovid FluffyChat'is näha tõuketeavitusi, siis soovitame, et selle jaoks kasutad https://microg.org või https://unifiedpush.org liidestust.", + "noGoogleServicesWarning": "Tundub, et sinu nutiseadmes pole Firebase Cloud Messaging teenuseid. Sinu privaatsuse mõttes on see kindlasti hea otsus! Kui sa soovid FluffyChat'is näha tõuketeavitusi, siis soovitame, et selle jaoks kasutad ntfy liidestust. Kasutades ntfy'd või mõnda muud Unified Push standardil põhinevat liidestust saad tõuketeavitusi turvalisel moel. Ntfy rakendus on saadaval nii PlayStore kui F-Droid'i rakendusepoodides.", "@noGoogleServicesWarning": { "type": "text", "placeholders": {} @@ -2617,5 +2617,45 @@ "placeholders": { "seconds": {} } - } + }, + "banUserDescription": "Sellele kasutajale on nüüd selles jututoas seatud suhtluskeeld ning ta ei saa vestluses osaleda seni, kuni suhtluskeeld pole eemaldatud.", + "@banUserDescription": {}, + "removeDevicesDescription": "Sind logitakse sellest seadmest välja ja sa enam ei saa sõnumeid.", + "@removeDevicesDescription": {}, + "unbanUserDescription": "Uuesti proovimisel saab see kasutaja nüüd vestlusega liituda.", + "@unbanUserDescription": {}, + "todoLists": "Tegemiste loendid (beetaversioon)", + "@todoLists": {}, + "editTodo": "Muuda tegevust", + "@editTodo": {}, + "pushNotificationsNotAvailable": "Tõuketeavitused pole saadaval", + "@pushNotificationsNotAvailable": {}, + "pleaseAddATitle": "Palun lisa pealkiri", + "@pleaseAddATitle": {}, + "makeAdminDescription": "Kui annad sellele kasutajale peakasutaja õigused, siis kuna tal on sinuga samad õigused, sa ei saa seda toimingut enam tagasi pöörata.", + "@makeAdminDescription": {}, + "noTodosYet": "Siia vestlusesse pole veel lisatud ühtegi tegemiste loendit. Tee esimene ja jätka selle täitmist üheskoos teistega. 📝", + "@noTodosYet": {}, + "archiveRoomDescription": "Selle vestluse tõstame nüüd arhiivi. Muud osalejad näevad, et sa oled vestlusest lahkunud.", + "@archiveRoomDescription": {}, + "hasKnocked": "{user} on jututoa uksele koputanud", + "@hasKnocked": { + "placeholders": { + "user": {} + } + }, + "newTodo": "Uus tegevus", + "@newTodo": {}, + "learnMore": "Loe lisaks", + "@learnMore": {}, + "todoListChangedError": "Hopsti... Seda tegevuste loendit on keegi muutnud just samal ajal, kui sina olid seda muutmas.", + "@todoListChangedError": {}, + "roomUpgradeDescription": "See vestlus luuakse nüüd uuesti jututoa uue versioonina. Kõik senised osalejad saavad teate, et nad peavad liituma uue vestlusega. Jututubade versioonide kohta leiad teavet https://spec.matrix.org/latest/rooms/ lehelt", + "@roomUpgradeDescription": {}, + "pleaseEnterANumber": "Palun sisesta 0'st suurem number", + "@pleaseEnterANumber": {}, + "kickUserDescription": "See kasutaja on nüüd jutuoast välja müksatud, kuid talle pole seatud suhtluskeeldu. Avaliku jututoa puhul saab ta alati uuesti liituda.", + "@kickUserDescription": {}, + "todosUnencrypted": "Palun arvesta, et tegemiste loend on nähtav kõikidele vestluses osalejatele ja pole läbivalt krüptitud.", + "@todosUnencrypted": {} } diff --git a/assets/l10n/intl_eu.arb b/assets/l10n/intl_eu.arb index e418d2b22..375fc43e4 100644 --- a/assets/l10n/intl_eu.arb +++ b/assets/l10n/intl_eu.arb @@ -84,7 +84,7 @@ "username": {} } }, - "banFromChat": "Kanporatu txatetik", + "banFromChat": "Txatera batzeko debekua ezarri", "@banFromChat": { "type": "text", "placeholders": {} @@ -226,7 +226,7 @@ "type": "text", "placeholders": {} }, - "changeTheNameOfTheGroup": "Aldatu taldearen izena", + "changeTheNameOfTheGroup": "Taldearen izena aldatu", "@changeTheNameOfTheGroup": { "type": "text", "placeholders": {} @@ -372,7 +372,7 @@ "type": "text", "placeholders": {} }, - "deleteMessage": "Ezabatu mezua", + "deleteMessage": "Mezuak ezabatu", "@deleteMessage": { "type": "text", "placeholders": {} @@ -521,12 +521,12 @@ "displayname": {} } }, - "guestsAreForbidden": "Bisitariak debekatuta daude", + "guestsAreForbidden": "Ez, bisitariak ez daude baimenduta", "@guestsAreForbidden": { "type": "text", "placeholders": {} }, - "guestsCanJoin": "Bisitariak batu daitezke", + "guestsCanJoin": "Bai, bisitariak batu daitezke", "@guestsCanJoin": { "type": "text", "placeholders": {} @@ -559,7 +559,7 @@ "type": "text", "placeholders": {} }, - "inviteContact": "Gonbidatu kontaktua", + "inviteContact": "Kontaktuak gonbidatu", "@inviteContact": { "type": "text", "placeholders": {} @@ -630,7 +630,7 @@ "targetName": {} } }, - "kickFromChat": "Kanporatu txatetik", + "kickFromChat": "Txatetik kanporatu", "@kickFromChat": { "type": "text", "placeholders": {} @@ -746,7 +746,7 @@ "type": "text", "placeholders": {} }, - "noGoogleServicesWarning": "Dirudienez ez daukazu Googleren zerbitzurik zure mugikorrean. Primerako erabakia zure pribatutasunerako! FluffyChaten jakinarazpenak jasotzeko https://microg.org/ edo https://unifiedpush.org/ erabiltzea gomendatzen dugu.", + "noGoogleServicesWarning": "Ez dirudi Firebase Cloud Messaging zure mugikorrean erabilgarri dagoenik. Jakinarazpenak jasotzeko ntfy instalatzea gomendatzen dugu. ntfy edo beste Unified Push hornitzaileren batekin, push jakinarazpenak jaso ditzazkezu datuentzako segurua den modu batean. ntfy PlayStore edo F-Droid dendetatik deskarga dezakezu.", "@noGoogleServicesWarning": { "type": "text", "placeholders": {} @@ -1021,7 +1021,7 @@ "type": "text", "placeholders": {} }, - "setInvitationLink": "Ezarri gonbidapen-esteka", + "setInvitationLink": "Gonbidapen-esteka ezarri", "@setInvitationLink": { "type": "text", "placeholders": {} @@ -1364,7 +1364,7 @@ "type": "text", "placeholders": {} }, - "editRoomAvatar": "Editatu gelaren abatarra", + "editRoomAvatar": "Gelaren abatarra editatu", "@editRoomAvatar": { "type": "text", "placeholders": {} @@ -1697,7 +1697,7 @@ }, "chatHasBeenAddedToThisSpace": "Txata gune honetara gehitu da", "@chatHasBeenAddedToThisSpace": {}, - "configureChat": "Konfiguratu txata", + "configureChat": "Txata konfiguratu", "@configureChat": { "type": "text", "placeholders": {} @@ -2101,7 +2101,7 @@ "@sendAsText": { "type": "text" }, - "sendMessages": "Bidali mezuak", + "sendMessages": "Mezuak bidali", "@sendMessages": { "type": "text", "placeholders": {} @@ -2166,7 +2166,7 @@ "type": "text", "placeholders": {} }, - "unverified": "Egiaztatu gabe", + "unverified": "Egiaztatu gabe(a)", "@unverified": {}, "verified": "Egiaztatuta", "@verified": { @@ -2504,7 +2504,7 @@ "@continueWith": {}, "pleaseTryAgainLaterOrChooseDifferentServer": "Saiatu geroago edo aukeratu beste zerbitzari bat.", "@pleaseTryAgainLaterOrChooseDifferentServer": {}, - "signInWith": "Hasi saioa {provider}(e)kin", + "signInWith": "Hasi saioa {provider}(r)ekin", "@signInWith": { "type": "text", "placeholders": { @@ -2569,7 +2569,7 @@ "reason": {} } }, - "anyoneCanKnock": "Edonork egin dezake batzeko eskaera", + "anyoneCanKnock": "Edonork eska dezake batzeko baimena", "@anyoneCanKnock": {}, "redactMessageDescription": "Mezua elkarrizketa honetako partaide guztientzat botako da atzera. Ezin da desegin.", "@redactMessageDescription": {}, @@ -2605,10 +2605,50 @@ "@createGroup": {}, "invite": "Gonbidatu", "@invite": {}, - "invalidInput": "Sarrerak ez du balio!", + "invalidInput": "Sartu duzunak ez du balio!", "@invalidInput": {}, "inviteGroupChat": "📨 Gonbidatu taldeko txatera", "@inviteGroupChat": {}, "invitePrivateChat": "📨 Gonbidatu txat pribatura", - "@invitePrivateChat": {} + "@invitePrivateChat": {}, + "banUserDescription": "Erabiltzailea txatetik kanporatu eta berriro sartzeko debekua ezarriko zaio; ezingo da berriro sartu debekua kendu arte.", + "@banUserDescription": {}, + "removeDevicesDescription": "Gailu honetako saioa amaituko da eta ezingo duzu mezurik jaso aurrerantzean.", + "@removeDevicesDescription": {}, + "unbanUserDescription": "Erabiltzailea txatera berriro sartu ahal izango da berak nahi izanez gero.", + "@unbanUserDescription": {}, + "todoLists": "(Beta) Zeregin-zerrendak", + "@todoLists": {}, + "editTodo": "Editatu zeregina", + "@editTodo": {}, + "pushNotificationsNotAvailable": "Push jakinarazpenak ez daude erabilgarri", + "@pushNotificationsNotAvailable": {}, + "pleaseAddATitle": "Gehitu izenburua", + "@pleaseAddATitle": {}, + "makeAdminDescription": "Behin erabiltzaile hau administratzaile eginda, litekeena da desegin ezin izatea zuk dituzun baimenak izango dituelako.", + "@makeAdminDescription": {}, + "noTodosYet": "Oraindik ez da zereginik gehitu txat honetara. Sortu lehen zeregina eta hasi elkarlanean besteekin. 📝", + "@noTodosYet": {}, + "archiveRoomDescription": "Txata artxibategira mugituko da. Beste erabiltzaileek txatetik alde egin duzula ikusi ahal izango dute.", + "@archiveRoomDescription": {}, + "hasKnocked": "{user}(e)k baimena eskatu du", + "@hasKnocked": { + "placeholders": { + "user": {} + } + }, + "newTodo": "Zeregin berria", + "@newTodo": {}, + "learnMore": "Gehiago irakurri", + "@learnMore": {}, + "todoListChangedError": "Hara… zeregin-zerrenda aldatu da editatzen ari zinen bitartean.", + "@todoListChangedError": {}, + "roomUpgradeDescription": "Gela bertsio berri gisa birsortuko da txata. Partaide guztiei jakinaraziko zaie txat berrira aldatu behar direla. Gehiago irakur dezakezu gela bertsioei buruz ondorengo estekan: https://spec.matrix.org/latest/rooms/", + "@roomUpgradeDescription": {}, + "pleaseEnterANumber": "Sartu 0 baino zenbaki handiago bat", + "@pleaseEnterANumber": {}, + "kickUserDescription": "Erabiltzailea txatetik kanporatu da baina ez zaio debekua ezarri. Txat publikoen kasuan, edozein momentutan batu daiteke berriro.", + "@kickUserDescription": {}, + "todosUnencrypted": "Kontuan izan zereginak txateko guztientzat daudela ikusgai, eta ez daudela ertzetik ertzera zifratuta.", + "@todosUnencrypted": {} } diff --git a/assets/l10n/intl_fa.arb b/assets/l10n/intl_fa.arb index c62752785..6a23ca398 100644 --- a/assets/l10n/intl_fa.arb +++ b/assets/l10n/intl_fa.arb @@ -2502,5 +2502,152 @@ "continueWith": "ادامه دادن با:", "@continueWith": {}, "pleaseTryAgainLaterOrChooseDifferentServer": "لطفا بعدا تلاش کنید یا سرور دیگری انتخاب کنید.", - "@pleaseTryAgainLaterOrChooseDifferentServer": {} + "@pleaseTryAgainLaterOrChooseDifferentServer": {}, + "setColorTheme": "", + "@setColorTheme": {}, + "banUserDescription": "", + "@banUserDescription": {}, + "requests": "", + "@requests": {}, + "removeDevicesDescription": "", + "@removeDevicesDescription": {}, + "tryAgain": "", + "@tryAgain": {}, + "unbanUserDescription": "", + "@unbanUserDescription": {}, + "todoLists": "", + "@todoLists": {}, + "messagesStyle": "", + "@messagesStyle": {}, + "chatDescription": "", + "@chatDescription": {}, + "editTodo": "", + "@editTodo": {}, + "pushNotificationsNotAvailable": "", + "@pushNotificationsNotAvailable": {}, + "invalidServerName": "", + "@invalidServerName": {}, + "chatPermissions": "", + "@chatPermissions": {}, + "pleaseAddATitle": "", + "@pleaseAddATitle": {}, + "makeAdminDescription": "", + "@makeAdminDescription": {}, + "setChatDescription": "", + "@setChatDescription": {}, + "importFromZipFile": "", + "@importFromZipFile": {}, + "redactedBy": "", + "@redactedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "signInWith": "", + "@signInWith": { + "type": "text", + "placeholders": { + "provider": {} + } + }, + "noTodosYet": "", + "@noTodosYet": {}, + "optionalRedactReason": "", + "@optionalRedactReason": {}, + "archiveRoomDescription": "", + "@archiveRoomDescription": {}, + "exportEmotePack": "", + "@exportEmotePack": {}, + "savedEmotePack": "", + "@savedEmotePack": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "inviteContactToGroupQuestion": "", + "@inviteContactToGroupQuestion": {}, + "redactedByBecause": "", + "@redactedByBecause": { + "type": "text", + "placeholders": { + "username": {}, + "reason": {} + } + }, + "importZipFile": "", + "@importZipFile": {}, + "anyoneCanKnock": "", + "@anyoneCanKnock": {}, + "redactMessageDescription": "", + "@redactMessageDescription": {}, + "invalidInput": "", + "@invalidInput": {}, + "todosUnencrypted": "", + "@todosUnencrypted": {}, + "addChatDescription": "", + "@addChatDescription": {}, + "hasKnocked": "", + "@hasKnocked": { + "placeholders": { + "user": {} + } + }, + "directChat": "", + "@directChat": {}, + "noOneCanJoin": "", + "@noOneCanJoin": {}, + "wrongPinEntered": "", + "@wrongPinEntered": { + "type": "text", + "placeholders": { + "seconds": {} + } + }, + "sendTypingNotifications": "", + "@sendTypingNotifications": {}, + "inviteGroupChat": "", + "@inviteGroupChat": {}, + "invitePrivateChat": "", + "@invitePrivateChat": {}, + "importEmojis": "", + "@importEmojis": {}, + "noChatDescriptionYet": "", + "@noChatDescriptionYet": {}, + "newTodo": "", + "@newTodo": {}, + "learnMore": "", + "@learnMore": {}, + "notAnImage": "", + "@notAnImage": {}, + "chatDescriptionHasBeenChanged": "", + "@chatDescriptionHasBeenChanged": {}, + "todoListChangedError": "", + "@todoListChangedError": {}, + "roomUpgradeDescription": "", + "@roomUpgradeDescription": {}, + "pleaseEnterANumber": "", + "@pleaseEnterANumber": {}, + "profileNotFound": "", + "@profileNotFound": {}, + "shareInviteLink": "", + "@shareInviteLink": {}, + "emoteKeyboardNoRecents": "", + "@emoteKeyboardNoRecents": { + "type": "text", + "placeholders": {} + }, + "setTheme": "", + "@setTheme": {}, + "replace": "", + "@replace": {}, + "createGroup": "", + "@createGroup": {}, + "kickUserDescription": "", + "@kickUserDescription": {}, + "importNow": "", + "@importNow": {}, + "invite": "", + "@invite": {} } diff --git a/assets/l10n/intl_fi.arb b/assets/l10n/intl_fi.arb index b0aceb2de..1dc681ede 100644 --- a/assets/l10n/intl_fi.arb +++ b/assets/l10n/intl_fi.arb @@ -764,7 +764,7 @@ "type": "text", "placeholders": {} }, - "inviteText": "{username} kutsui sinutFluffyChattiin. \n1. Asenna FluffyChat osoitteesta: https://fluffychat.im \n2. Rekisteröidy tai kirjaudu sisään\n3. Avaa kutsulinkki: {link}", + "inviteText": "{username} kutsui sinut FluffyChattiin.\n1. Viereaile sivulla: https://fluffychat.im ja asenna sovellus\n2. Rekisteröidy tai kirjaudu sisään\n3. Avaa kutsulinkki:\n{link}", "@inviteText": { "type": "text", "placeholders": { @@ -1249,7 +1249,7 @@ "type": "text", "placeholders": {} }, - "noGoogleServicesWarning": "Vaikuttaa siltä, ettei puhelimessasi ole Google-palveluita. Se on hyvä päätös yksityisyytesi kannalta! Vastaanottaaksesi push-notifikaatioita FluffyChätissä suosittelemme https://microg.org/ tai https://unifiedpush.org/ käyttämistä.", + "noGoogleServicesWarning": "Firebase Cloud Messaging -palvelu ei vaikuta olevan saatavilla laitteellasi. Saadaksesi push-ilmoituksia silti, suosittelemme Ntfy-sovelluksen asentamista. Käyttämällä Ntfy-sovellusta tai muuta Unified Push -tarjoajaa, saat push-ilmoitukset tietoturvallisella tavalla. Voit ladata Ntfy-sovelluksen Play Kaupasta tai F-Droidista.", "@noGoogleServicesWarning": { "type": "text", "placeholders": {} @@ -1776,7 +1776,7 @@ "type": "text", "placeholders": {} }, - "wallpaper": "Taustakuva", + "wallpaper": "Taustakuva:", "@wallpaper": { "type": "text", "placeholders": {} @@ -2366,7 +2366,7 @@ "@whyIsThisMessageEncrypted": {}, "noKeyForThisMessage": "Tämä voi tapahtua mikäli viesti lähetettiin ennen sisäänkirjautumistasi tälle laitteelle.\n\nOn myös mahdollista, että lähettäjä on estänyt tämän laitteen tai jokin meni pieleen verkkoyhteyden kanssa.\n\nPystytkö lukemaan viestin toisella istunnolla? Siinä tapauksessa voit siirtää viestin siltä! Mene Asetukset > Laitteet ja varmista, että laitteesi ovat varmistaneet toisensa. Seuraavankerran avatessasi huoneen ja molempien istuntojen ollessa etualalla, avaimet siirretään automaattisesti.\n\nHaluatko varmistaa ettet menetä avaimia uloskirjautuessa tai laitteita vaihtaessa? Varmista avainvarmuuskopion käytössäolo asetuksista.", "@noKeyForThisMessage": {}, - "commandHint_markasdm": "Merkitse yksityiskeskusteluksi", + "commandHint_markasdm": "Merkitse yksityiskeskusteluksi syötetyn Matrix IDn kanssa", "@commandHint_markasdm": {}, "foregroundServiceRunning": "Tämä ilmoitus näkyy etualapalvelun ollessa käynnissä.", "@foregroundServiceRunning": {}, @@ -2501,5 +2501,152 @@ "continueWith": "Jatka käyttäen:", "@continueWith": {}, "pleaseTryAgainLaterOrChooseDifferentServer": "Yritä myöhemmin uudelleen tai valitse toinen palvelin.", - "@pleaseTryAgainLaterOrChooseDifferentServer": {} + "@pleaseTryAgainLaterOrChooseDifferentServer": {}, + "setColorTheme": "Aseta väriteema:", + "@setColorTheme": {}, + "requests": "Pyynnöt", + "@requests": {}, + "tryAgain": "Yritä uudelleen", + "@tryAgain": {}, + "messagesStyle": "Viestit:", + "@messagesStyle": {}, + "chatDescription": "Keskustelun kuvaus", + "@chatDescription": {}, + "invalidServerName": "Virheellinen palvelimen nimi", + "@invalidServerName": {}, + "chatPermissions": "Keskustelun oikeudet", + "@chatPermissions": {}, + "setChatDescription": "Asetti keskustelun kuvauksen", + "@setChatDescription": {}, + "importFromZipFile": "Tuo .zip -tiedostosta", + "@importFromZipFile": {}, + "redactedBy": "Poistanut {username}", + "@redactedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "signInWith": "Kirjaudu sisään palvelulla {provider}", + "@signInWith": { + "type": "text", + "placeholders": { + "provider": {} + } + }, + "optionalRedactReason": "(Vapaaehtoinen) Syy tämän viestin poistamiselle...", + "@optionalRedactReason": {}, + "archiveRoomDescription": "Keskustelu siirretään arkistoon. Muut käyttäjät näkevät sinun poistuneen keskustelusta.", + "@archiveRoomDescription": {}, + "exportEmotePack": "Vie emotepaketti .zip-tiedostona", + "@exportEmotePack": {}, + "savedEmotePack": "Tallennettiin emotepaketti sijaintiin {path}!", + "@savedEmotePack": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "inviteContactToGroupQuestion": "Tahdotko kutsua yhteystiedon {contact} keskusteluun \"{groupName}\"?", + "@inviteContactToGroupQuestion": {}, + "redactedByBecause": "Poistanut {username} syystä: \"{reason}\"", + "@redactedByBecause": { + "type": "text", + "placeholders": { + "username": {}, + "reason": {} + } + }, + "importZipFile": "Tuo zip-tiedosto", + "@importZipFile": {}, + "anyoneCanKnock": "Kaikki voivat koputtaa", + "@anyoneCanKnock": {}, + "redactMessageDescription": "Viesti poistetaan kaikilta keskustelun osallistujilta. Tätä ei voida kumota.", + "@redactMessageDescription": {}, + "invalidInput": "Virheellinen syöte!", + "@invalidInput": {}, + "addChatDescription": "Lisää keskustelulle kuvaus", + "@addChatDescription": {}, + "hasKnocked": "{user} on koputtanut", + "@hasKnocked": { + "placeholders": { + "user": {} + } + }, + "directChat": "Yksityiskeskustelu", + "@directChat": {}, + "noOneCanJoin": "Kukaan ei voi liittyä", + "@noOneCanJoin": {}, + "wrongPinEntered": "Väärä pin-koodi! Yritä uudelleen {seconds} sekuntin kuluttua...", + "@wrongPinEntered": { + "type": "text", + "placeholders": { + "seconds": {} + } + }, + "sendTypingNotifications": "Lähetä kirjoitusilmoituksia", + "@sendTypingNotifications": {}, + "inviteGroupChat": "Kutsu ryhmäkeskusteluun", + "@inviteGroupChat": {}, + "invitePrivateChat": "Kutsu yksityiskeskusteluun", + "@invitePrivateChat": {}, + "importEmojis": "Tuo emojit", + "@importEmojis": {}, + "noChatDescriptionYet": "Keskustelun kuvausta ei ole vielä luotu.", + "@noChatDescriptionYet": {}, + "notAnImage": "Tämä ei ole kuvatiedosto.", + "@notAnImage": {}, + "chatDescriptionHasBeenChanged": "Keskustelun kuvaus muutettu", + "@chatDescriptionHasBeenChanged": {}, + "roomUpgradeDescription": "Keskustelu luodaan uudelleen uudella huoneversiolla. Kaikille osallistujille ilmoitetaan, että heidän tulee siirtyä uuteen keskusteluun. Voit lukea lisää huoneversioista osoitteesta https://spec.matrix.org/latest/rooms/", + "@roomUpgradeDescription": {}, + "pleaseEnterANumber": "Syötä suurempi luku kuin 0", + "@pleaseEnterANumber": {}, + "profileNotFound": "Käyttäjää ei löydy palvelimelta. Tämä voi olla yhteysongelma tai käyttäjä ei ole olemassa.", + "@profileNotFound": {}, + "shareInviteLink": "Jaa kutsulinkki", + "@shareInviteLink": {}, + "emoteKeyboardNoRecents": "Viimeaikoina käytetyt emotet tulevat näkymään täällä...", + "@emoteKeyboardNoRecents": { + "type": "text", + "placeholders": {} + }, + "setTheme": "Aseta teema:", + "@setTheme": {}, + "replace": "Korvaa", + "@replace": {}, + "createGroup": "Luo ryhmä", + "@createGroup": {}, + "importNow": "Tuo nyt", + "@importNow": {}, + "invite": "Kutsu", + "@invite": {}, + "banUserDescription": "", + "@banUserDescription": {}, + "removeDevicesDescription": "", + "@removeDevicesDescription": {}, + "unbanUserDescription": "", + "@unbanUserDescription": {}, + "todoLists": "", + "@todoLists": {}, + "editTodo": "", + "@editTodo": {}, + "pushNotificationsNotAvailable": "", + "@pushNotificationsNotAvailable": {}, + "pleaseAddATitle": "", + "@pleaseAddATitle": {}, + "makeAdminDescription": "", + "@makeAdminDescription": {}, + "noTodosYet": "", + "@noTodosYet": {}, + "todosUnencrypted": "", + "@todosUnencrypted": {}, + "newTodo": "", + "@newTodo": {}, + "learnMore": "", + "@learnMore": {}, + "todoListChangedError": "", + "@todoListChangedError": {}, + "kickUserDescription": "", + "@kickUserDescription": {} } diff --git a/assets/l10n/intl_fr.arb b/assets/l10n/intl_fr.arb index 412da0e46..6ca325c8e 100644 --- a/assets/l10n/intl_fr.arb +++ b/assets/l10n/intl_fr.arb @@ -2514,5 +2514,148 @@ "createGroup": "Créer un groupe", "@createGroup": {}, "importNow": "Importer maintenant", - "@importNow": {} + "@importNow": {}, + "reportErrorDescription": "", + "@reportErrorDescription": {}, + "setColorTheme": "", + "@setColorTheme": {}, + "banUserDescription": "", + "@banUserDescription": {}, + "requests": "", + "@requests": {}, + "removeDevicesDescription": "", + "@removeDevicesDescription": {}, + "tryAgain": "", + "@tryAgain": {}, + "unbanUserDescription": "", + "@unbanUserDescription": {}, + "todoLists": "", + "@todoLists": {}, + "messagesStyle": "", + "@messagesStyle": {}, + "chatDescription": "", + "@chatDescription": {}, + "editTodo": "", + "@editTodo": {}, + "pushNotificationsNotAvailable": "", + "@pushNotificationsNotAvailable": {}, + "invalidServerName": "", + "@invalidServerName": {}, + "signInWithPassword": "", + "@signInWithPassword": {}, + "pleaseAddATitle": "", + "@pleaseAddATitle": {}, + "makeAdminDescription": "", + "@makeAdminDescription": {}, + "setChatDescription": "", + "@setChatDescription": {}, + "redactedBy": "", + "@redactedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "signInWith": "", + "@signInWith": { + "type": "text", + "placeholders": { + "provider": {} + } + }, + "noTodosYet": "", + "@noTodosYet": {}, + "optionalRedactReason": "", + "@optionalRedactReason": {}, + "archiveRoomDescription": "", + "@archiveRoomDescription": {}, + "exportEmotePack": "", + "@exportEmotePack": {}, + "savedEmotePack": "", + "@savedEmotePack": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "redactedByBecause": "", + "@redactedByBecause": { + "type": "text", + "placeholders": { + "username": {}, + "reason": {} + } + }, + "anyoneCanKnock": "", + "@anyoneCanKnock": {}, + "redactMessageDescription": "", + "@redactMessageDescription": {}, + "invalidInput": "", + "@invalidInput": {}, + "todosUnencrypted": "", + "@todosUnencrypted": {}, + "report": "", + "@report": {}, + "addChatDescription": "", + "@addChatDescription": {}, + "hasKnocked": "", + "@hasKnocked": { + "placeholders": { + "user": {} + } + }, + "directChat": "", + "@directChat": {}, + "noOneCanJoin": "", + "@noOneCanJoin": {}, + "wrongPinEntered": "", + "@wrongPinEntered": { + "type": "text", + "placeholders": { + "seconds": {} + } + }, + "sendTypingNotifications": "", + "@sendTypingNotifications": {}, + "inviteGroupChat": "", + "@inviteGroupChat": {}, + "invitePrivateChat": "", + "@invitePrivateChat": {}, + "noChatDescriptionYet": "", + "@noChatDescriptionYet": {}, + "newTodo": "", + "@newTodo": {}, + "learnMore": "", + "@learnMore": {}, + "todoListChangedError": "", + "@todoListChangedError": {}, + "roomUpgradeDescription": "", + "@roomUpgradeDescription": {}, + "pleaseEnterANumber": "", + "@pleaseEnterANumber": {}, + "profileNotFound": "", + "@profileNotFound": {}, + "jump": "", + "@jump": {}, + "shareInviteLink": "", + "@shareInviteLink": {}, + "emoteKeyboardNoRecents": "", + "@emoteKeyboardNoRecents": { + "type": "text", + "placeholders": {} + }, + "setTheme": "", + "@setTheme": {}, + "replace": "", + "@replace": {}, + "pleaseTryAgainLaterOrChooseDifferentServer": "", + "@pleaseTryAgainLaterOrChooseDifferentServer": {}, + "kickUserDescription": "", + "@kickUserDescription": {}, + "invite": "", + "@invite": {}, + "continueWith": "", + "@continueWith": {}, + "openLinkInBrowser": "", + "@openLinkInBrowser": {} } diff --git a/assets/l10n/intl_ga.arb b/assets/l10n/intl_ga.arb index e2a68cbeb..4852f8d28 100644 --- a/assets/l10n/intl_ga.arb +++ b/assets/l10n/intl_ga.arb @@ -1,2101 +1,2659 @@ { - "you": "Tú", - "@you": { - "type": "text", - "placeholders": {} - }, - "yes": "Tá", - "@yes": { - "type": "text", - "placeholders": {} - }, - "warning": "Rabhadh!", - "@warning": { - "type": "text", - "placeholders": {} - }, - "wallpaper": "Cúlbhrat", - "@wallpaper": { - "type": "text", - "placeholders": {} - }, - "verify": "Deimhnigh", - "@verify": { - "type": "text", - "placeholders": {} - }, - "verified": "Deimhnithe", - "@verified": { - "type": "text", - "placeholders": {} - }, - "username": "Ainm úsáideora", - "@username": { - "type": "text", - "placeholders": {} - }, - "unpin": "Bain biorán", - "@unpin": { - "type": "text", - "placeholders": {} - }, - "unavailable": "Níl ar fáil", - "@unavailable": { - "type": "text", - "placeholders": {} - }, - "title": "FluffyChat", - "@title": { - "description": "Title for the application", - "type": "text", - "placeholders": {} - }, - "systemTheme": "Córas", - "@systemTheme": { - "type": "text", - "placeholders": {} - }, - "submit": "Cuir isteach", - "@submit": { - "type": "text", - "placeholders": {} - }, - "statusExampleMessage": "Conas atá tú inniu?", - "@statusExampleMessage": { - "type": "text", - "placeholders": {} - }, - "status": "Staid", - "@status": { - "type": "text", - "placeholders": {} - }, - "skip": "Léim", - "@skip": { - "type": "text", - "placeholders": {} - }, - "share": "Roinn", - "@share": { - "type": "text", - "placeholders": {} - }, - "settings": "Socruithe", - "@settings": { - "type": "text", - "placeholders": {} - }, - "send": "Seol", - "@send": { - "type": "text", - "placeholders": {} - }, - "security": "Slándáil", - "@security": { - "type": "text", - "placeholders": {} - }, - "search": "Cuardaigh", - "@search": { - "type": "text", - "placeholders": {} - }, - "reply": "Freagair", - "@reply": { - "type": "text", - "placeholders": {} - }, - "remove": "Bain", - "@remove": { - "type": "text", - "placeholders": {} - }, - "rejoin": "Téigh ar ais isteach", - "@rejoin": { - "type": "text", - "placeholders": {} - }, - "reject": "Diúltaigh", - "@reject": { - "type": "text", - "placeholders": {} - }, - "register": "Cláraigh", - "@register": { - "type": "text", - "placeholders": {} - }, - "recording": "Ag Taifeadadh", - "@recording": { - "type": "text", - "placeholders": {} - }, - "reason": "Fáth", - "@reason": { - "type": "text", - "placeholders": {} - }, - "privacy": "Príobháideacht", - "@privacy": { - "type": "text", - "placeholders": {} - }, - "pin": "Biorán", - "@pin": { - "type": "text", - "placeholders": {} - }, - "people": "Daoine", - "@people": { - "type": "text", - "placeholders": {} - }, - "password": "Pasfhocal", - "@password": { - "type": "text", - "placeholders": {} - }, - "participant": "Rannpháirtí", - "@participant": { - "type": "text", - "placeholders": {} - }, - "directChats": "Comhráite Díreacha", - "@directChats": { - "type": "text", - "placeholders": {} - }, - "deviceId": "ID gléis", - "@deviceId": { - "type": "text", - "placeholders": {} - }, - "deleteMessage": "Scrios an teachtaireacht", - "@deleteMessage": { - "type": "text", - "placeholders": {} - }, - "deleteAccount": "Scrios an cuntas", - "@deleteAccount": { - "type": "text", - "placeholders": {} - }, - "createNewSpace": "Spás nua", - "@createNewSpace": { - "type": "text", - "placeholders": {} - }, - "countParticipants": "{count} rannpháirtithe", - "@countParticipants": { - "type": "text", - "placeholders": { - "count": {} - } - }, - "or": "Nó", - "@or": { - "type": "text", - "placeholders": {} - }, - "online": "Ar líne", - "@online": { - "type": "text", - "placeholders": {} - }, - "ok": "togha", - "@ok": { - "type": "text", - "placeholders": {} - }, - "offline": "As líne", - "@offline": { - "type": "text", - "placeholders": {} - }, - "offensive": "Maslach", - "@offensive": { - "type": "text", - "placeholders": {} - }, - "notifications": "Fógraí", - "@notifications": { - "type": "text", - "placeholders": {} - }, - "none": "Aon cheann", - "@none": { - "type": "text", - "placeholders": {} - }, - "no": "Níl", - "@no": { - "type": "text", - "placeholders": {} - }, - "next": "Ar Aghaidh", - "@next": { - "type": "text", - "placeholders": {} - }, - "moderator": "Modhnóir", - "@moderator": { - "type": "text", - "placeholders": {} - }, - "messages": "Teachtaireachtaí", - "@messages": { - "type": "text", - "placeholders": {} - }, - "mention": "Luaigh", - "@mention": { - "type": "text", - "placeholders": {} - }, - "logout": "Logáil amach", - "@logout": { - "type": "text", - "placeholders": {} - }, - "login": "Logáil isteach", - "@login": { - "type": "text", - "placeholders": {} - }, - "lightTheme": "Solas", - "@lightTheme": { - "type": "text", - "placeholders": {} - }, - "license": "Ceadúnas", - "@license": { - "type": "text", - "placeholders": {} - }, - "leave": "Fág", - "@leave": { - "type": "text", - "placeholders": {} - }, - "invited": "Le cuireadh", - "@invited": { - "type": "text", - "placeholders": {} - }, - "inoffensive": "Neamhurchóideach", - "@inoffensive": { - "type": "text", - "placeholders": {} - }, - "ignore": "Tabhair neamhaird ar", - "@ignore": { - "type": "text", - "placeholders": {} - }, - "identity": "Aitheantas", - "@identity": { - "type": "text", - "placeholders": {} - }, - "id": "ID", - "@id": { - "type": "text", - "placeholders": {} - }, - "help": "Cabhair", - "@help": { - "type": "text", - "placeholders": {} - }, - "groups": "Grúpaí", - "@groups": { - "type": "text", - "placeholders": {} - }, - "group": "Grúpa", - "@group": { - "type": "text", - "placeholders": {} - }, - "forward": "Seol ar aghaidh", - "@forward": { - "type": "text", - "placeholders": {} - }, - "fluffychat": "FluffyChat", - "@fluffychat": { - "type": "text", - "placeholders": {} - }, - "homeserver": "Freastalaí baile", - "@homeserver": {}, - "encryption": "Criptiúchán", - "@encryption": { - "type": "text", - "placeholders": {} - }, - "encrypted": "Criptithe", - "@encrypted": { - "type": "text", - "placeholders": {} - }, - "edit": "Cuir in eagar", - "@edit": { - "type": "text", - "placeholders": {} - }, - "devices": "Gléasanna", - "@devices": { - "type": "text", - "placeholders": {} - }, - "device": "Gléas", - "@device": { - "type": "text", - "placeholders": {} - }, - "deny": "Diúltaigh", - "@deny": { - "type": "text", - "placeholders": {} - }, - "delete": "Scrios", - "@delete": { - "type": "text", - "placeholders": {} - }, - "dateWithYear": "{day}/{month}/{year}", - "@dateWithYear": { - "type": "text", - "placeholders": { - "year": {}, - "month": {}, - "day": {} - } - }, - "dateWithoutYear": "{day}/{month}", - "@dateWithoutYear": { - "type": "text", - "placeholders": { - "month": {}, - "day": {} - } - }, - "dateAndTimeOfDay": "{date}, {timeOfDay}", - "@dateAndTimeOfDay": { - "type": "text", - "placeholders": { - "date": {}, - "timeOfDay": {} - } - }, - "containsUserName": "Coinníonn sé ainm úsáideora", - "@containsUserName": { - "type": "text", - "placeholders": {} - }, - "configureChat": "Cumraigh comhrá", - "@configureChat": { - "type": "text", - "placeholders": {} - }, - "commandInvalid": "Ordú neamhbhailí", - "@commandInvalid": { - "type": "text" - }, - "commandHint_send": "Seol téacs", - "@commandHint_send": { - "type": "text", - "description": "Usage hint for the command /send" - }, - "commandHint_me": "Déan cur síos ort féin", - "@commandHint_me": { - "type": "text", - "description": "Usage hint for the command /me" - }, - "clearArchive": "Glan an cartlann", - "@clearArchive": {}, - "chatDetails": "Sonraí comhrá", - "@chatDetails": { - "type": "text", - "placeholders": {} - }, - "chatBackup": "Cúltaca comhrá", - "@chatBackup": { - "type": "text", - "placeholders": {} - }, - "changeWallpaper": "Athraigh cúlbhrat", - "@changeWallpaper": { - "type": "text", - "placeholders": {} - }, - "changedTheChatAvatar": "D'athraigh {username} abhatár an chomhrá", - "@changedTheChatAvatar": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changeDeviceName": "Athraigh ainm an ghléis", - "@changeDeviceName": { - "type": "text", - "placeholders": {} - }, - "cantOpenUri": "Ní féidir an URI {uri} a oscailt", - "@cantOpenUri": { - "type": "text", - "placeholders": { - "uri": {} - } - }, - "cancel": "Cealaigh", - "@cancel": { - "type": "text", - "placeholders": {} - }, - "botMessages": "Teachtaireachtaí bota", - "@botMessages": { - "type": "text", - "placeholders": {} - }, - "blocked": "Bactha", - "@blocked": { - "type": "text", - "placeholders": {} - }, - "blockDevice": "Bac Gléas", - "@blockDevice": { - "type": "text", - "placeholders": {} - }, - "bannedUser": "Chuir {username} cosc ar {targetName}", - "@bannedUser": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "banned": "Coiscthe", - "@banned": { - "type": "text", - "placeholders": {} - }, - "banFromChat": "Toirmisc ón gcomhrá", - "@banFromChat": { - "type": "text", - "placeholders": {} - }, - "sendOnEnter": "Seol ar iontráil", - "@sendOnEnter": {}, - "archive": "Cartlann", - "@archive": { - "type": "text", - "placeholders": {} - }, - "appLock": "Bac aip", - "@appLock": { - "type": "text", - "placeholders": {} - }, - "anyoneCanJoin": "Is féidir le aon duine dul isteach", - "@anyoneCanJoin": { - "type": "text", - "placeholders": {} - }, - "answeredTheCall": "D'fhreagair {senderName} an glao", - "@answeredTheCall": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "allChats": "Gach comhrá", - "@allChats": { - "type": "text", - "placeholders": {} - }, - "all": "Gach", - "@all": { - "type": "text", - "placeholders": {} - }, - "alias": "ailias", - "@alias": { - "type": "text", - "placeholders": {} - }, - "admin": "Riarthóir", - "@admin": { - "type": "text", - "placeholders": {} - }, - "addToSpace": "Cuir go spás", - "@addToSpace": {}, - "addGroupDescription": "Cuir tuairisc grúpa", - "@addGroupDescription": { - "type": "text", - "placeholders": {} - }, - "addEmail": "Cuir ríomhphoist", - "@addEmail": { - "type": "text", - "placeholders": {} - }, - "activatedEndToEndEncryption": "Thosaigh {username} an criptiú ó dheireadh go deireadh", - "@activatedEndToEndEncryption": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "account": "Cuntas", - "@account": { - "type": "text", - "placeholders": {} - }, - "acceptedTheInvitation": "Ghlac {username} leis an cuireadh", - "@acceptedTheInvitation": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "accept": "Glac", - "@accept": { - "type": "text", - "placeholders": {} - }, - "about": "Faoi", - "@about": { - "type": "text", - "placeholders": {} - }, - "askVerificationRequest": "Glac leis an iarratas fíoraithe seo ó {username}?", - "@askVerificationRequest": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "areYouSureYouWantToLogout": "An bhfuil tú cinnte gur mhaith leat logáil amach?", - "@areYouSureYouWantToLogout": { - "type": "text", - "placeholders": {} - }, - "areYouSure": "An bhfuil tú cinnte?", - "@areYouSure": { - "type": "text", - "placeholders": {} - }, - "areGuestsAllowedToJoin": "An bhfuil cead ag aoi-úsáideoirí a bheith páirteach", - "@areGuestsAllowedToJoin": { - "type": "text", - "placeholders": {} - }, - "invitedUser": "Thug {username} cuireadh do {targetName}", - "@invitedUser": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "hideRedactedEvents": "Folaigh imeachtaí athdhéanta", - "@hideRedactedEvents": { - "type": "text", - "placeholders": {} - }, - "guestsCanJoin": "Is féidir le haíonna páirt a ghlacadh", - "@guestsCanJoin": { - "type": "text", - "placeholders": {} - }, - "guestsAreForbidden": "Tá cosc ar aíonna", - "@guestsAreForbidden": { - "type": "text", - "placeholders": {} - }, - "groupWith": "Grúpa le {displayname}", - "@groupWith": { - "type": "text", - "placeholders": { - "displayname": {} - } - }, - "groupIsPublic": "Tá an grúpa poiblí", - "@groupIsPublic": { - "type": "text", - "placeholders": {} - }, - "groupDescriptionHasBeenChanged": "D'athraigh cur síos an ghrúpa", - "@groupDescriptionHasBeenChanged": { - "type": "text", - "placeholders": {} - }, - "fromTheInvitation": "Ón gcuireadh", - "@fromTheInvitation": { - "type": "text", - "placeholders": {} - }, - "enterYourHomeserver": "Cuir isteach do fhreastalaí baile", - "@enterYourHomeserver": { - "type": "text", - "placeholders": {} - }, - "emoteInvalid": "Gearrchód emote neamhbhailí!", - "@emoteInvalid": { - "type": "text", - "placeholders": {} - }, - "emoteExists": "Tá iomaite ann cheana féin!", - "@emoteExists": { - "type": "text", - "placeholders": {} - }, - "editRoomAvatar": "Cuir in eagar abhatár an tseomra", - "@editRoomAvatar": { - "type": "text", - "placeholders": {} - }, - "editRoomAliases": "Cuir ailiasanna an tseomra in eagar", - "@editRoomAliases": { - "type": "text", - "placeholders": {} - }, - "editChatPermissions": "Cuir ceadanna an chomhrá in eagar", - "@editChatPermissions": { - "type": "text", - "placeholders": {} - }, - "editBlockedServers": "Cuir freastalaí blocáilte in eagar", - "@editBlockedServers": { - "type": "text", - "placeholders": {} - }, - "defaultPermissionLevel": "Leibhéal ceada réamhshocraithe", - "@defaultPermissionLevel": { - "type": "text", - "placeholders": {} - }, - "unblockDevice": "Díbhlocáil Gléas", - "@unblockDevice": { - "type": "text", - "placeholders": {} - }, - "contactHasBeenInvitedToTheGroup": "Tugadh cuireadh don theagmháil a thar isteach sa grúpa", - "@contactHasBeenInvitedToTheGroup": { - "type": "text", - "placeholders": {} - }, - "compareNumbersMatch": "Déan comparáid idir na huimhreacha seo a leanas agus déan cinnte go bhfuil na huimhreacha seo a leanas ag teacht le huimhreacha an ghléis eile:", - "@compareNumbersMatch": { - "type": "text", - "placeholders": {} - }, - "compareEmojiMatch": "Déan comparáid agus déan cinnte go bhfuil an emoji seo a leanas comhoiriúnach le emoji an ghléis eile:", - "@compareEmojiMatch": { - "type": "text", - "placeholders": {} - }, - "commandMissing": "Ní ordú é {command}.", - "@commandMissing": { - "type": "text", - "placeholders": { - "command": {} - }, - "description": "State that {command} is not a valid /command." - }, - "commandHint_react": "Seol freagra mar fhreagairt", - "@commandHint_react": { - "type": "text", - "description": "Usage hint for the command /react" - }, - "commandHint_op": "Socraigh leibhéal cumhachta an úsáideora áirithe (réamhshocrú: 50)", - "@commandHint_op": { - "type": "text", - "description": "Usage hint for the command /op" - }, - "commandHint_myroomnick": "Socraigh d'ainm taispeána don seomra seo", - "@commandHint_myroomnick": { - "type": "text", - "description": "Usage hint for the command /myroomnick" - }, - "commandHint_myroomavatar": "Cuir do phictiúr don seomra seo (le mxc-uri)", - "@commandHint_myroomavatar": { - "type": "text", - "description": "Usage hint for the command /myroomavatar" - }, - "commandHint_kick": "Bain an t-úsáideoir áirithe den seomra seo", - "@commandHint_kick": { - "type": "text", - "description": "Usage hint for the command /kick" - }, - "commandHint_join": "Téigh isteach sa seomra áirithe", - "@commandHint_join": { - "type": "text", - "description": "Usage hint for the command /join" - }, - "commandHint_ban": "Cuir cosc ar an úsáideoir áirithe ón seomra seo", - "@commandHint_ban": { - "type": "text", - "description": "Usage hint for the command /ban" - }, - "commandHint_invite": "Cuir cosc ar an úsáideoir áirithe ón seomra seo", - "@commandHint_invite": { - "type": "text", - "description": "Usage hint for the command /invite" - }, - "chooseAStrongPassword": "Roghnaigh pasfhocal láidir", - "@chooseAStrongPassword": { - "type": "text", - "placeholders": {} - }, - "chatHasBeenAddedToThisSpace": "Cuireadh comhrá leis an spás seo", - "@chatHasBeenAddedToThisSpace": {}, - "chatBackupDescription": "Tá do chúltaca comhrá daingnithe le heochair slándála. Déan cinnte nach gcaillfidh tú é.", - "@chatBackupDescription": { - "type": "text", - "placeholders": {} - }, - "channelCorruptedDecryptError": "Truaillíodh an criptiú", - "@channelCorruptedDecryptError": { - "type": "text", - "placeholders": {} - }, - "changeTheNameOfTheGroup": "Athraigh ainm an ghrúpa", - "@changeTheNameOfTheGroup": { - "type": "text", - "placeholders": {} - }, - "changedTheRoomInvitationLink": "D'athraigh {username} nasc an chuiridh", - "@changedTheRoomInvitationLink": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheRoomAliases": "D'athraigh {username} ailiasanna an tseomra", - "@changedTheRoomAliases": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheProfileAvatar": "D'athraigh {username} a n-abhatár", - "@changedTheProfileAvatar": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheJoinRulesTo": "D'athraigh {username} na rialacha ceangail go: {joinRules}", - "@changedTheJoinRulesTo": { - "type": "text", - "placeholders": { - "username": {}, - "joinRules": {} - } - }, - "changedTheJoinRules": "D'athraigh {username} na rialacha ceangail", - "@changedTheJoinRules": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheHistoryVisibilityTo": "D'athraigh {username} infheictheacht na staire go: {rules}", - "@changedTheHistoryVisibilityTo": { - "type": "text", - "placeholders": { - "username": {}, - "rules": {} - } - }, - "changedTheHistoryVisibility": "D'athraigh {username} infheictheacht na staire", - "@changedTheHistoryVisibility": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheDisplaynameTo": "D'athraigh {username} a n-ainm taispeána go: '{displayname}'", - "@changedTheDisplaynameTo": { - "type": "text", - "placeholders": { - "username": {}, - "displayname": {} - } - }, - "changedTheChatPermissions": "D'athraigh {username} na ceadanna comhrá", - "@changedTheChatPermissions": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheChatNameTo": "D'athraigh {username} an t-ainm comhrá go: '{chatname}'", - "@changedTheChatNameTo": { - "type": "text", - "placeholders": { - "username": {}, - "chatname": {} - } - }, - "changedTheChatDescriptionTo": "D'athraigh {username} an cur síos comhrá go: '{description}'", - "@changedTheChatDescriptionTo": { - "type": "text", - "placeholders": { - "username": {}, - "description": {} - } - }, - "autoplayImages": "Seinn greamáin agus straoiseog beoite go huathoibríoch", - "@autoplayImages": { - "type": "text", - "placeholder": {} - }, - "createdTheChat": "Rinne {username} an comhrá", - "@createdTheChat": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "createNewGroup": "Déan grúpa nua", - "@createNewGroup": { - "type": "text", - "placeholders": {} - }, - "copyToClipboard": "Cóipeáil ar an ghearrthaisce", - "@copyToClipboard": { - "type": "text", - "placeholders": {} - }, - "copiedToClipboard": "Cóipeáilte ar an ghearrthaisce", - "@copiedToClipboard": { - "type": "text", - "placeholders": {} - }, - "containsDisplayName": "Coinníonn sé ainm taispeána", - "@containsDisplayName": { - "type": "text", - "placeholders": {} - }, - "commandHint_plain": "Seol téacs neamhfhoirmithe", - "@commandHint_plain": { - "type": "text", - "description": "Usage hint for the command /plain" - }, - "commandHint_leave": "Fág an seomra seo", - "@commandHint_leave": { - "type": "text", - "description": "Usage hint for the command /leave" - }, - "commandHint_html": "Seol téacs HTML-formáidithe", - "@commandHint_html": { - "type": "text", - "description": "Usage hint for the command /html" - }, - "chooseAUsername": "Roghnaigh ainm úsáideora", - "@chooseAUsername": { - "type": "text", - "placeholders": {} - }, - "changeYourAvatar": "Athraigh do abhatár", - "@changeYourAvatar": { - "type": "text", - "placeholders": {} - }, - "changeTheme": "Athraigh do stíl", - "@changeTheme": { - "type": "text", - "placeholders": {} - }, - "changeTheHomeserver": "Athraigh an freastalaí baile", - "@changeTheHomeserver": { - "type": "text", - "placeholders": {} - }, - "voiceMessage": "Glórphost", - "@voiceMessage": { - "type": "text", - "placeholders": {} - }, - "videoCall": "Físghlao", - "@videoCall": { - "type": "text", - "placeholders": {} - }, - "verifyStart": "Tosaigh Fíorú", - "@verifyStart": { - "type": "text", - "placeholders": {} - }, - "unmuteChat": "Neamhciúnaigh comhrá", - "@unmuteChat": { - "type": "text", - "placeholders": {} - }, - "hideUnknownEvents": "Folaigh imeachtaí anaithnide", - "@hideUnknownEvents": { - "type": "text", - "placeholders": {} - }, - "unknownDevice": "Gléas anaithnid", - "@unknownDevice": { - "type": "text", - "placeholders": {} - }, - "toggleUnread": "Marcáil Léite/Neamhléite", - "@toggleUnread": { - "type": "text", - "placeholders": {} - }, - "toggleMuted": "Scoránaigh mar ciúnaithe", - "@toggleMuted": { - "type": "text", - "placeholders": {} - }, - "toggleFavorite": "Scoránaigh mar ceann is fearr leat", - "@toggleFavorite": { - "type": "text", - "placeholders": {} - }, - "theyMatch": "Tá siad céanna", - "@theyMatch": { - "type": "text", - "placeholders": {} - }, - "spaceName": "Ainm an spáis", - "@spaceName": { - "type": "text", - "placeholders": {} - }, - "sourceCode": "Cód foinseach", - "@sourceCode": { - "type": "text", - "placeholders": {} - }, - "signUp": "Cláraigh Cuntas", - "@signUp": { - "type": "text", - "placeholders": {} - }, - "showPassword": "Taispeáin pasfhocal", - "@showPassword": { - "type": "text", - "placeholders": {} - }, - "shareLocation": "Roinn suíomh", - "@shareLocation": { - "type": "text", - "placeholders": {} - }, - "setStatus": "Cuir stádas", - "@setStatus": { - "type": "text", - "placeholders": {} - }, - "sendVideo": "Seol físeán", - "@sendVideo": { - "type": "text", - "placeholders": {} - }, - "sendSticker": "Seol greamán", - "@sendSticker": { - "type": "text", - "placeholders": {} - }, - "sendOriginal": "Seol an bunchóip", - "@sendOriginal": { - "type": "text", - "placeholders": {} - }, - "sendMessages": "Seol teachtaireachtaí", - "@sendMessages": { - "type": "text", - "placeholders": {} - }, - "sendImage": "Seol íomhá", - "@sendImage": { - "type": "text", - "placeholders": {} - }, - "sendFile": "Seol comhad", - "@sendFile": { - "type": "text", - "placeholders": {} - }, - "sendAudio": "Seol fuaim", - "@sendAudio": { - "type": "text", - "placeholders": {} - }, - "saveFile": "Sábháil comhad", - "@saveFile": { - "type": "text", - "placeholders": {} - }, - "roomVersion": "Leagan seomra", - "@roomVersion": { - "type": "text", - "placeholders": {} - }, - "requestPermission": "Iarr cead", - "@requestPermission": { - "type": "text", - "placeholders": {} - }, - "reportMessage": "Tuairiscigh teachtaireacht", - "@reportMessage": { - "type": "text", - "placeholders": {} - }, - "removeDevice": "Bain gléas", - "@removeDevice": { - "type": "text", - "placeholders": {} - }, - "redactMessage": "Bain teachtaireacht amach", - "@redactMessage": { - "type": "text", - "placeholders": {} - }, - "pushRules": "Rialacha na bhfógraí", - "@pushRules": { - "type": "text", - "placeholders": {} - }, - "publicRooms": "Seomraí Poiblí", - "@publicRooms": { - "type": "text", - "placeholders": {} - }, - "pleaseChoose": "Roghnaigh le do thoil", - "@pleaseChoose": { - "type": "text", - "placeholders": {} - }, - "play": "Seinn {fileName}", - "@play": { - "type": "text", - "placeholders": { - "fileName": {} - } - }, - "passwordRecovery": "Aisfháil pasfhocail", - "@passwordRecovery": { - "type": "text", - "placeholders": {} - }, - "passwordForgotten": "Pasfhocal dearmadta", - "@passwordForgotten": { - "type": "text", - "placeholders": {} - }, - "openCamera": "Oscail ceamara", - "@openCamera": { - "type": "text", - "placeholders": {} - }, - "obtainingLocation": "ag Aimsiú an suíomh…", - "@obtainingLocation": { - "type": "text", - "placeholders": {} - }, - "noPermission": "Gan cead", - "@noPermission": { - "type": "text", - "placeholders": {} - }, - "newChat": "Comhrá nua", - "@newChat": { - "type": "text", - "placeholders": {} - }, - "muteChat": "Ciúnaigh comhrá", - "@muteChat": { - "type": "text", - "placeholders": {} - }, - "memberChanges": "Athruithe ball", - "@memberChanges": { - "type": "text", - "placeholders": {} - }, - "loadMore": "Lódáil níos mó…", - "@loadMore": { - "type": "text", - "placeholders": {} - }, - "joinRoom": "Téigh isteach sa seomra", - "@joinRoom": { - "type": "text", - "placeholders": {} - }, - "isTyping": "ag clóscríobh…", - "@isTyping": { - "type": "text", - "placeholders": {} - }, - "inviteContact": "Tabhair cuireadh do theagmháil", - "@inviteContact": { - "type": "text", - "placeholders": {} - }, - "ignoreUsername": "Tabhair neamhaird ar ainm úsáideora", - "@ignoreUsername": { - "type": "text", - "placeholders": {} - }, - "ignoredUsers": "Úsáideoirí a dtugann tú neamhaird orthu", - "@ignoredUsers": { - "type": "text", - "placeholders": {} - }, - "groupDescription": "Cur síos ar an ngrúpa", - "@groupDescription": { - "type": "text", - "placeholders": {} - }, - "fromJoining": "Ó tar isteach", - "@fromJoining": { - "type": "text", - "placeholders": {} - }, - "fontSize": "Méid cló", - "@fontSize": { - "type": "text", - "placeholders": {} - }, - "enableEncryption": "Tosaigh criptiú", - "@enableEncryption": { - "type": "text", - "placeholders": {} - }, - "editDisplayname": "Cuir ainm taispeána in eagar", - "@editDisplayname": { - "type": "text", - "placeholders": {} - }, - "currentlyActive": "Gníomhach faoi láthair", - "@currentlyActive": { - "type": "text", - "placeholders": {} - }, - "fileName": "Ainm an chomhaid", - "@fileName": { - "type": "text", - "placeholders": {} - }, - "everythingReady": "Gach rud réidh!", - "@everythingReady": { - "type": "text", - "placeholders": {} - }, - "emptyChat": "Comhrá folamh", - "@emptyChat": { - "type": "text", - "placeholders": {} - }, - "emoteShortcode": "Gearrchód straoiseoige", - "@emoteShortcode": { - "type": "text", - "placeholders": {} - }, - "emoteSettings": "Socruithe straoiseoige", - "@emoteSettings": { - "type": "text", - "placeholders": {} - }, - "downloadFile": "Íoslódáil comhad", - "@downloadFile": { - "type": "text", - "placeholders": {} - }, - "changePassword": "Athraigh an pasfhocal", - "@changePassword": { - "type": "text", - "placeholders": {} - }, - "darkTheme": "Dorcha", - "@darkTheme": { - "type": "text", - "placeholders": {} - }, - "create": "Cruthaigh", - "@create": { - "type": "text", - "placeholders": {} - }, - "copy": "Cóipeáil", - "@copy": { - "type": "text", - "placeholders": {} - }, - "connect": "Ceangail", - "@connect": { - "type": "text", - "placeholders": {} - }, - "confirm": "Deimhnigh", - "@confirm": { - "type": "text", - "placeholders": {} - }, - "close": "Dún", - "@close": { - "type": "text", - "placeholders": {} - }, - "chats": "Comhráite", - "@chats": { - "type": "text", - "placeholders": {} - }, - "chat": "Comhrá", - "@chat": { - "type": "text", - "placeholders": {} - }, - "scanQrCode": "Scan cód QR", - "@scanQrCode": {}, - "inviteText": "Thug {username} cuireadh duit chuig FluffyChat.\n1. Suiteáil FluffyChat: https://fluffychat.im\n2. Cláraigh nó sínigh isteach\n3. Oscail an nasc cuiridh: {link}", - "@inviteText": { - "type": "text", - "placeholders": { - "username": {}, - "link": {} - } - }, - "shareYourInviteLink": "Roinn do nasc cuiridh", - "@shareYourInviteLink": {}, - "noMatrixServer": "Níl {server1} freastalaí Matrix. Úsáid {server2} ina áit sin?", - "@noMatrixServer": { - "type": "text", - "placeholders": { - "server1": {}, - "server2": {} - } - }, - "noGoogleServicesWarning": "Dealraíonn sé nach bhfuil aon seirbhísí google agat ar do ghuthán. Sin cinneadh maith le do phríobháideacht! Chun fógraí brú a fháil i FluffyChat molaimid https://microg.org/ nó https://unifiedpush.org/ a úsáid.", - "@noGoogleServicesWarning": { - "type": "text", - "placeholders": {} - }, - "noEncryptionForPublicRooms": "Ní féidir leat criptiú a ghníomhachtú ach a luaithe nach bhfuil an seomra inrochtana go poiblí a thuilleadh.", - "@noEncryptionForPublicRooms": { - "type": "text", - "placeholders": {} - }, - "noEmotesFound": "Níor aimsíodh aon straoiseoga. 😕", - "@noEmotesFound": { - "type": "text", - "placeholders": {} - }, - "noConnectionToTheServer": "Gan aon nasc leis an bhfreastalaí", - "@noConnectionToTheServer": { - "type": "text", - "placeholders": {} - }, - "newVerificationRequest": "Iarratas fíoraithe nua!", - "@newVerificationRequest": { - "type": "text", - "placeholders": {} - }, - "newMessageInFluffyChat": "Teachtaireacht nua i FluffyChat", - "@newMessageInFluffyChat": { - "type": "text", - "placeholders": {} - }, - "needPantalaimonWarning": "Bí ar an eolas go dteastaíonn Pantalaimon uait chun criptiú ó cheann go ceann a úsáid anois.", - "@needPantalaimonWarning": { - "type": "text", - "placeholders": {} - }, - "messageWillBeRemovedWarning": "Bainfear an teachtaireacht do na rannpháirtithe go léir", - "@messageWillBeRemovedWarning": { - "type": "text", - "placeholders": {} - }, - "makeSureTheIdentifierIsValid": "Cinntigh go bhfuil an t-aitheantóir bailí", - "@makeSureTheIdentifierIsValid": { - "type": "text", - "placeholders": {} - }, - "loginWith": "Sínigh isteach le {brand}", - "@loginWith": { - "type": "text", - "placeholders": { - "brand": {} - } - }, - "logInTo": "Logáil isteach chuig {homeserver}", - "@logInTo": { - "type": "text", - "placeholders": { - "homeserver": {} - } - }, - "locationPermissionDeniedNotice": "Diúltaíodh cead suímh. Deonaigh dóibh le do thoil go mbeidh tú in ann do shuíomh a roinnt.", - "@locationPermissionDeniedNotice": { - "type": "text", - "placeholders": {} - }, - "locationDisabledNotice": "Tá seirbhísí suímh díchumasaithe. Cuir ar a gcumas le do thoil a bheith in ann do shuíomh a roinnt.", - "@locationDisabledNotice": { - "type": "text", - "placeholders": {} - }, - "loadingPleaseWait": "Ag lódáil… Fan, le do thoil.", - "@loadingPleaseWait": { - "type": "text", - "placeholders": {} - }, - "loadCountMoreParticipants": "Lódáil {count} níos mó rannpháirtithe", - "@loadCountMoreParticipants": { - "type": "text", - "placeholders": { - "count": {} - } - }, - "leftTheChat": "Fágadh an comhrá", - "@leftTheChat": { - "type": "text", - "placeholders": {} - }, - "lastSeenLongTimeAgo": "Le feiceáil i bhfad ó shin", - "@lastSeenLongTimeAgo": { - "type": "text", - "placeholders": {} - }, - "lastActiveAgo": "Gníomhach deireanach: {localizedTimeShort}", - "@lastActiveAgo": { - "type": "text", - "placeholders": { - "localizedTimeShort": {} - } - }, - "kickFromChat": "Caith é amach as an comhrá", - "@kickFromChat": { - "type": "text", - "placeholders": {} - }, - "kicked": "Chaith {username} {targetName} amach", - "@kicked": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "kickedAndBanned": "Chaith {username} amach agus chuir cosc ar {targetName} freisin", - "@kickedAndBanned": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "joinedTheChat": "Tháinig {username} isteach sa chomhrá", - "@joinedTheChat": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "invitedUsersOnly": "Úsáideoirí le cuireadh amháin", - "@invitedUsersOnly": { - "type": "text", - "placeholders": {} - }, - "inviteContactToGroup": "Tabhair cuireadh do theagmháil chuig {groupName}", - "@inviteContactToGroup": { - "type": "text", - "placeholders": { - "groupName": {} - } - }, - "incorrectPassphraseOrKey": "Pasfhrása nó eochair téarnaimh mícheart", - "@incorrectPassphraseOrKey": { - "type": "text", - "placeholders": {} - }, - "iHaveClickedOnLink": "Chliceáil mé ar an nasc", - "@iHaveClickedOnLink": { - "type": "text", - "placeholders": {} - }, - "howOffensiveIsThisContent": "Cé chomh maslach atá an t-ábhar seo?", - "@howOffensiveIsThisContent": { - "type": "text", - "placeholders": {} - }, - "extremeOffensive": "Fíor-maslach", - "@extremeOffensive": { - "type": "text", - "placeholders": {} - }, - "hasWithdrawnTheInvitationFor": "Tharraing {username} an cuireadh do {targetName} siar", - "@hasWithdrawnTheInvitationFor": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "goToTheNewRoom": "Téigh go dtí an seomra nua", - "@goToTheNewRoom": { - "type": "text", - "placeholders": {} - }, - "errorObtainingLocation": "Earráid maidir le suíomh a fháil: {error}", - "@errorObtainingLocation": { - "type": "text", - "placeholders": { - "error": {} - } - }, - "enterASpacepName": "Cuir isteach ainm spáis", - "@enterASpacepName": {}, - "enterAnEmailAddress": "Cuir isteach seoladh ríomhphoist", - "@enterAnEmailAddress": { - "type": "text", - "placeholders": {} - }, - "enterAGroupName": "Iontráil ainm grúpa", - "@enterAGroupName": { - "type": "text", - "placeholders": {} - }, - "endedTheCall": "Chuir {senderName} deireadh leis an nglao", - "@endedTheCall": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "encryptionNotEnabled": "Ní chumasaítear criptiú", - "@encryptionNotEnabled": { - "type": "text", - "placeholders": {} - }, - "enableEncryptionWarning": "Ní bheidh in ann an criptiú a dhíchumasú níos mó. An bhfuil tú cinnte?", - "@enableEncryptionWarning": { - "type": "text", - "placeholders": {} - }, - "enableEmotesGlobally": "Cumasaigh pacáiste straoiseoige go huilíoch", - "@enableEmotesGlobally": { - "type": "text", - "placeholders": {} - }, - "emoteWarnNeedToPick": "Caithfidh tú gearrchód straoiseoige agus íomhá a roghnú!", - "@emoteWarnNeedToPick": { - "type": "text", - "placeholders": {} - }, - "emotePacks": "Pacáistí straoiseoige don seomra", - "@emotePacks": { - "type": "text", - "placeholders": {} - }, - "displaynameHasBeenChanged": "Athraíodh an t-ainm taispeána", - "@displaynameHasBeenChanged": { - "type": "text", - "placeholders": {} - }, - "deactivateAccountWarning": "Díghníomhachtaeoidh sé seo do chuntas úsáideora. Ní féidir é seo a chealú! An bhfuil tú cinnte?", - "@deactivateAccountWarning": { - "type": "text", - "placeholders": {} - }, - "couldNotDecryptMessage": "Níorbh fhéidir teachtaireacht a dhíchriptiú: {error}", - "@couldNotDecryptMessage": { - "type": "text", - "placeholders": { - "error": {} - } - }, - "contentHasBeenReported": "Tuairiscíodh an t-ábhar do lucht riaracháin an fhreastalaí", - "@contentHasBeenReported": { - "type": "text", - "placeholders": {} - }, - "commandHint_unban": "Cuir deireadh an cosc den úsáideoir áirithe ón seomra seo", - "@commandHint_unban": { - "type": "text", - "description": "Usage hint for the command /unban" - }, - "changedTheGuestAccessRulesTo": "D'athraigh {username} na rialacha maidir le rochtain aoi chuig: {rules}", - "@changedTheGuestAccessRulesTo": { - "type": "text", - "placeholders": { - "username": {}, - "rules": {} - } - }, - "changedTheGuestAccessRules": "D'athraigh {username} na rialacha rochtana aoi", - "@changedTheGuestAccessRules": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "badServerVersionsException": "Tá na leaganacha sonraíochta seo ar fáil faoin freastalaí baile:\n{serverVersions}\nAch níl ach na ceann seo ar fáil faoin aip seo {supportedVersions}", - "@badServerVersionsException": { - "type": "text", - "placeholders": { - "serverVersions": {}, - "supportedVersions": {} - } - }, - "badServerLoginTypesException": "Tá na cineálacha logála isteach seo ar fáil faoin freastalaí baile:\n{serverVersions}\nAch níl ach na ceann seo ar fáil faoin aip seo:\n{supportedVersions}", - "@badServerLoginTypesException": { - "type": "text", - "placeholders": { - "serverVersions": {}, - "supportedVersions": {} - } - }, - "askSSSSSign": "Chun a bheith in ann an duine eile a shíniú, cuir isteach do phasfhrása stóir sábháilte nó d'eochair téarnaimh.", - "@askSSSSSign": { - "type": "text", - "placeholders": {} - }, - "yourPublicKey": "D'eochair phoiblí", - "@yourPublicKey": { - "type": "text", - "placeholders": {} - }, - "youHaveBeenBannedFromThisChat": "Cuireadh cosc ort ón gcomhrá seo", - "@youHaveBeenBannedFromThisChat": { - "type": "text", - "placeholders": {} - }, - "youCannotInviteYourself": "Ní féidir leat cuireadh a thabhairt duit féin", - "@youCannotInviteYourself": { - "type": "text", - "placeholders": {} - }, - "youAreNoLongerParticipatingInThisChat": "Níl tú ag glacadh páirte sa chomhrá seo a thuilleadh", - "@youAreNoLongerParticipatingInThisChat": { - "type": "text", - "placeholders": {} - }, - "youAreInvitedToThisChat": "Tugtar cuireadh duit chuig an gcomhrá seo", - "@youAreInvitedToThisChat": { - "type": "text", - "placeholders": {} - }, - "writeAMessage": "Scríobh teachtaireacht…", - "@writeAMessage": { - "type": "text", - "placeholders": {} - }, - "withTheseAddressesRecoveryDescription": "Leis na seoltaí seo is féidir leat do phasfhocal a athshlánú.", - "@withTheseAddressesRecoveryDescription": { - "type": "text", - "placeholders": {} - }, - "wipeChatBackup": "Glan do cúltaca comhrá a chruthú eochair slándála nua?", - "@wipeChatBackup": { - "type": "text", - "placeholders": {} - }, - "whyDoYouWantToReportThis": "Cén fáth ar mhaith leat é seo a thuairisciú?", - "@whyDoYouWantToReportThis": { - "type": "text", - "placeholders": {} - }, - "whoIsAllowedToJoinThisGroup": "Cé a bhfuil cead aige/aici dul isteach sa ghrúpa seo", - "@whoIsAllowedToJoinThisGroup": { - "type": "text", - "placeholders": {} - }, - "whoCanPerformWhichAction": "Cé atá in ann an gníomh a dhéanamh", - "@whoCanPerformWhichAction": { - "type": "text", - "placeholders": {} - }, - "verifySuccess": "D'fhíoraigh tú go rathúil!", - "@verifySuccess": { - "type": "text", - "placeholders": {} - }, - "userLeftTheChat": "D'fhág {username} an comhrá", - "@userLeftTheChat": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "userAndUserAreTyping": "Tá {username} agus {username2} ag clóscríobh…", - "@userAndUserAreTyping": { - "type": "text", - "placeholders": { - "username": {}, - "username2": {} - } - }, - "userAndOthersAreTyping": "tá {username} agus {count} daoine eile ag clóscríobh…", - "@userAndOthersAreTyping": { - "type": "text", - "placeholders": { - "username": {}, - "count": {} - } - }, - "unreadChats": "{unreadCount, plural, =1{1 comhrá neamhléite} other{{unreadCount} comhráite neamhléite}}", - "@unreadChats": { - "type": "text", - "placeholders": { - "unreadCount": {} - } - }, - "unknownEncryptionAlgorithm": "Algartam criptithe anaithnid", - "@unknownEncryptionAlgorithm": { - "type": "text", - "placeholders": {} - }, - "unbannedUser": "Chuir {username} deireadh an cosc {targetName}", - "@unbannedUser": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "tryToSendAgain": "Déan iarracht a sheoladh arís", - "@tryToSendAgain": { - "type": "text", - "placeholders": {} - }, - "transferFromAnotherDevice": "Aistriú ó ghléas eile", - "@transferFromAnotherDevice": { - "type": "text", - "placeholders": {} - }, - "tooManyRequestsWarning": "An iomarca iarratas. Bain triail eile as níos déanaí!", - "@tooManyRequestsWarning": { - "type": "text", - "placeholders": {} - }, - "theyDontMatch": "Níl siad céanna", - "@theyDontMatch": { - "type": "text", - "placeholders": {} - }, - "sharedTheLocation": "Roinn {username} an suíomh", - "@sharedTheLocation": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "setPermissionsLevel": "Socraigh leibhéal ceadanna", - "@setPermissionsLevel": { - "type": "text", - "placeholders": {} - }, - "setInvitationLink": "Socraigh nasc cuiridh", - "@setInvitationLink": { - "type": "text", - "placeholders": {} - }, - "setGroupDescription": "Socraigh cur síos ar an ngrúpa", - "@setGroupDescription": { - "type": "text", - "placeholders": {} - }, - "setCustomEmotes": "Socraigh straoiseoga saincheaptha", - "@setCustomEmotes": { - "type": "text", - "placeholders": {} - }, - "setAsCanonicalAlias": "Socraigh mar phríomh-ailias", - "@setAsCanonicalAlias": { - "type": "text", - "placeholders": {} - }, - "sentCallInformations": "Sheol {senderName} faisnéis maidir le glaonna", - "@sentCallInformations": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "sentAVideo": "Sheol {username} físeán", - "@sentAVideo": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sentASticker": "Sheol {username} greamán", - "@sentASticker": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sentAPicture": "Sheol {username} pictiúr", - "@sentAPicture": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "seenByUserAndUser": "Le feiceáil ag {username} agus {username2}", - "@seenByUserAndUser": { - "type": "text", - "placeholders": { - "username": {}, - "username2": {} - } - }, - "seenByUserAndCountOthers": "{count, plural, other{Le feiceáil ag {username} agus {count} daoine eile}}", - "@seenByUserAndCountOthers": { - "type": "text", - "placeholders": { - "username": {}, - "count": {} - } - }, - "replaceRoomWithNewerVersion": "Cuir leagan seomra níos nuaí in ionad an tseomra", - "@replaceRoomWithNewerVersion": { - "type": "text", - "placeholders": {} - }, - "renderRichContent": "Taispeáin ábhar teachtaireachta saibhir", - "@renderRichContent": { - "type": "text", - "placeholders": {} - }, - "removeYourAvatar": "Bain d'abhatár", - "@removeYourAvatar": { - "type": "text", - "placeholders": {} - }, - "unbanFromChat": "Cuir deireadh an cosc ón gcomhrá", - "@unbanFromChat": { - "type": "text", - "placeholders": {} - }, - "removedBy": "Bainte de ag {username}", - "@removedBy": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "removeAllOtherDevices": "Bain gach gléas eile", - "@removeAllOtherDevices": { - "type": "text", - "placeholders": {} - }, - "rejectedTheInvitation": "Dhiúltaigh {username} don chuireadh", - "@rejectedTheInvitation": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "redactedAnEvent": "Rinne {username} cinsire imeacht", - "@redactedAnEvent": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "pleaseFollowInstructionsOnWeb": "Lean na treoracha ar an suíomh gréasáin agus tapáil \"ar aghaidh\".", - "@pleaseFollowInstructionsOnWeb": { - "type": "text", - "placeholders": {} - }, - "pleaseEnterYourUsername": "Cuir isteach d'ainm úsáideora le do thoil", - "@pleaseEnterYourUsername": { - "type": "text", - "placeholders": {} - }, - "pleaseEnterYourPin": "Cuir isteach d'uimhir PIN le do thoil", - "@pleaseEnterYourPin": { - "type": "text", - "placeholders": {} - }, - "pleaseEnterYourPassword": "Iontráil do phasfhocal le do thoil", - "@pleaseEnterYourPassword": { - "type": "text", - "placeholders": {} - }, - "pleaseEnterAMatrixIdentifier": "Iontráil ID Matrix le do thoil.", - "@pleaseEnterAMatrixIdentifier": { - "type": "text", - "placeholders": {} - }, - "pleaseEnter4Digits": "Iontráil 4 dhigit le do thoil nó fág folamh chun glas aipe a dhíchumasú.", - "@pleaseEnter4Digits": { - "type": "text", - "placeholders": {} - }, - "pleaseClickOnLink": "Cliceáil ar an nasc sa ríomhphost agus ansin lean ar aghaidh.", - "@pleaseClickOnLink": { - "type": "text", - "placeholders": {} - }, - "pleaseChooseAUsername": "Roghnaigh ainm úsáideora le do thoil", - "@pleaseChooseAUsername": { - "type": "text", - "placeholders": {} - }, - "pleaseChooseAPasscode": "Roghnaigh paschód le do thoil", - "@pleaseChooseAPasscode": { - "type": "text", - "placeholders": {} - }, - "pickImage": "Roghnaigh íomhá", - "@pickImage": { - "type": "text", - "placeholders": {} - }, - "passwordHasBeenChanged": "Athraíodh an pasfhocal", - "@passwordHasBeenChanged": { - "type": "text", - "placeholders": {} - }, - "passphraseOrKey": "pasfhrása nó eochair téarnaimh", - "@passphraseOrKey": { - "type": "text", - "placeholders": {} - }, - "optionalGroupName": "(Optional) Ainm an ghrúpa", - "@optionalGroupName": { - "type": "text", - "placeholders": {} - }, - "serverRequiresEmail": "Ní mór don fhreastalaí seo do sheoladh ríomhphoist a bhailíochtú le haghaidh clárúcháin.", - "@serverRequiresEmail": {}, - "openInMaps": "Oscail i léarscáileanna", - "@openInMaps": { - "type": "text", - "placeholders": {} - }, - "openAppToReadMessages": "Oscail an aip chun teachtaireachtaí a léamh", - "@openAppToReadMessages": { - "type": "text", - "placeholders": {} - }, - "oopsSomethingWentWrong": "Úps, chuaigh rud éigin mícheart …", - "@oopsSomethingWentWrong": { - "type": "text", - "placeholders": {} - }, - "oopsPushError": "Hoips! Ar an drochuair, tharla earráid nuair a bhí na fógraí brú á mbunú.", - "@oopsPushError": { - "type": "text", - "placeholders": {} - }, - "onlineKeyBackupEnabled": "Tá Cúltaca Eochair Ar Líne cumasaithe", - "@onlineKeyBackupEnabled": { - "type": "text", - "placeholders": {} - }, - "numUsersTyping": "Tá {count} úsáideoirí ag clóscríobh…", - "@numUsersTyping": { - "type": "text", - "placeholders": { - "count": {} - } - }, - "notificationsEnabledForThisAccount": "Fógraí cumasaithe don chuntas seo", - "@notificationsEnabledForThisAccount": { - "type": "text", - "placeholders": {} - }, - "noRoomsFound": "Níor aimsíodh aon seomraí…", - "@noRoomsFound": { - "type": "text", - "placeholders": {} - }, - "noPasswordRecoveryDescription": "Níor chuir tú bealach leis do phasfhocal a aisghabháil fós.", - "@noPasswordRecoveryDescription": { - "type": "text", - "placeholders": {} - }, - "inviteForMe": "Tabhair cuireadh dom", - "@inviteForMe": { - "type": "text", - "placeholders": {} - }, - "ignoreListDescription": "Is féidir leat neamhaird a dhéanamh d'úsáideoirí atá ag cur isteach ort. Ní bheidh tú in ann aon teachtaireachtaí nó cuireadh seomra a fháil ó na húsáideoirí ar do liosta neamhaird phearsanta.", - "@ignoreListDescription": { - "type": "text", - "placeholders": {} - }, - "weSentYouAnEmail": "Sheolamar ríomhphost chugat", - "@weSentYouAnEmail": { - "type": "text", - "placeholders": {} - }, - "waitingPartnerNumbers": "Ag fanacht le comhpháirtí glacadh leis na huimhreacha …", - "@waitingPartnerNumbers": { - "type": "text", - "placeholders": {} - }, - "waitingPartnerEmoji": "Ag fanacht le comhpháirtí glacadh leis na straoiseoga…", - "@waitingPartnerEmoji": { - "type": "text", - "placeholders": {} - }, - "waitingPartnerAcceptRequest": "Ag fanacht le comhpháirtí glacadh leis an iarratas…", - "@waitingPartnerAcceptRequest": { - "type": "text", - "placeholders": {} - }, - "visibleForEveryone": "Infheicthe do gach duine", - "@visibleForEveryone": { - "type": "text", - "placeholders": {} - }, - "visibleForAllParticipants": "Infheicthe do na rannpháirtithe go léir", - "@visibleForAllParticipants": { - "type": "text", - "placeholders": {} - }, - "visibilityOfTheChatHistory": "Infheictheacht stair na comhrá", - "@visibilityOfTheChatHistory": { - "type": "text", - "placeholders": {} - }, - "verifyTitle": "Ag fíorú cuntas eile", - "@verifyTitle": { - "type": "text", - "placeholders": {} - }, - "userSentUnknownEvent": "Sheol {username} imeacht {type}", - "@userSentUnknownEvent": { - "type": "text", - "placeholders": { - "username": {}, - "type": {} - } - }, - "userIsTyping": "Tá {username} ag clóscríobh…", - "@userIsTyping": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "unknownEvent": "Imeacht anaithnid '{type}'", - "@unknownEvent": { - "type": "text", - "placeholders": { - "type": {} - } - }, - "synchronizingPleaseWait": "Ag sioncrónú... Fan, le do thoil.", - "@synchronizingPleaseWait": { - "type": "text", - "placeholders": {} - }, - "startedACall": "Thosaigh {senderName} glao", - "@startedACall": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "spaceIsPublic": "Tá an spás poiblí", - "@spaceIsPublic": { - "type": "text", - "placeholders": {} - }, - "singlesignon": "Sínigh Aonair ar", - "@singlesignon": { - "type": "text", - "placeholders": {} - }, - "sentAnAudio": "Sheol {username} fuaim", - "@sentAnAudio": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sentAFile": "Sheol {username} comhad", - "@sentAFile": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sendAsText": "Seol mar théacs", - "@sendAsText": { - "type": "text" - }, - "sendAMessage": "Seol teachtaireacht", - "@sendAMessage": { - "type": "text", - "placeholders": {} - }, - "seenByUser": "Le feiceáil ag {username}", - "@seenByUser": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "roomHasBeenUpgraded": "Uasghrádaíodh an seomra", - "@roomHasBeenUpgraded": { - "type": "text", - "placeholders": {} - }, - "addAccount": "Breisigh cuntas", - "@addAccount": {}, - "enableMultiAccounts": "(BÉITE) Cumasaigh cuntais iomadúla ar an gléas seo", - "@enableMultiAccounts": {}, - "commandHint_create": "Cruthaigh comhrá grúpa folamh\nÚsáid --no-encryption chun criptiúchán a dhíchumasú", - "@commandHint_create": { - "type": "text", - "description": "Usage hint for the command /create" - }, - "link": "Nasc", - "@link": {}, - "commandHint_clearcache": "Glan an taisce", - "@commandHint_clearcache": { - "type": "text", - "description": "Usage hint for the command /clearcache" - }, - "videoCallsBetaWarning": "Tabhair faoi deara go bhfuil físglaonna i béite. B'fhéidir nach bhfeidhmíonn siad ar gach ardán chomh atá súil aige ná ar bith.", - "@videoCallsBetaWarning": {}, - "emailOrUsername": "Ríomhphost nó ainm úsáideora", - "@emailOrUsername": {}, - "passwordsDoNotMatch": "Níl na pasfhocail chéanna!", - "@passwordsDoNotMatch": {}, - "pleaseEnterValidEmail": "Iontráil ríomhphost bailí le do thoil.", - "@pleaseEnterValidEmail": {}, - "repeatPassword": "Scríobh an pasfhocal arís", - "@repeatPassword": {}, - "pleaseChooseAtLeastChars": "Roghnaigh {min} carachtar ar a laghad.", - "@pleaseChooseAtLeastChars": { - "type": "text", - "placeholders": { - "min": {} - } - }, - "bubbleSize": "Méid na mbolgán cainte", - "@bubbleSize": { - "type": "text", - "placeholders": {} - }, - "yourChatBackupHasBeenSetUp": "Bunaíodh do chúltaca comhrá.", - "@yourChatBackupHasBeenSetUp": {}, - "openVideoCamera": "Oscail físcheamara", - "@openVideoCamera": { - "type": "text", - "placeholders": {} + "you": "Tú", + "@you": { + "type": "text", + "placeholders": {} + }, + "yes": "Tá", + "@yes": { + "type": "text", + "placeholders": {} + }, + "warning": "Rabhadh!", + "@warning": { + "type": "text", + "placeholders": {} + }, + "wallpaper": "Cúlbhrat", + "@wallpaper": { + "type": "text", + "placeholders": {} + }, + "verify": "Deimhnigh", + "@verify": { + "type": "text", + "placeholders": {} + }, + "verified": "Deimhnithe", + "@verified": { + "type": "text", + "placeholders": {} + }, + "username": "Ainm úsáideora", + "@username": { + "type": "text", + "placeholders": {} + }, + "unpin": "Bain biorán", + "@unpin": { + "type": "text", + "placeholders": {} + }, + "unavailable": "Níl ar fáil", + "@unavailable": { + "type": "text", + "placeholders": {} + }, + "title": "FluffyChat", + "@title": { + "description": "Title for the application", + "type": "text", + "placeholders": {} + }, + "systemTheme": "Córas", + "@systemTheme": { + "type": "text", + "placeholders": {} + }, + "submit": "Cuir isteach", + "@submit": { + "type": "text", + "placeholders": {} + }, + "statusExampleMessage": "Conas atá tú inniu?", + "@statusExampleMessage": { + "type": "text", + "placeholders": {} + }, + "status": "Staid", + "@status": { + "type": "text", + "placeholders": {} + }, + "skip": "Léim", + "@skip": { + "type": "text", + "placeholders": {} + }, + "share": "Roinn", + "@share": { + "type": "text", + "placeholders": {} + }, + "settings": "Socruithe", + "@settings": { + "type": "text", + "placeholders": {} + }, + "send": "Seol", + "@send": { + "type": "text", + "placeholders": {} + }, + "security": "Slándáil", + "@security": { + "type": "text", + "placeholders": {} + }, + "search": "Cuardaigh", + "@search": { + "type": "text", + "placeholders": {} + }, + "reply": "Freagair", + "@reply": { + "type": "text", + "placeholders": {} + }, + "remove": "Bain", + "@remove": { + "type": "text", + "placeholders": {} + }, + "rejoin": "Téigh ar ais isteach", + "@rejoin": { + "type": "text", + "placeholders": {} + }, + "reject": "Diúltaigh", + "@reject": { + "type": "text", + "placeholders": {} + }, + "register": "Cláraigh", + "@register": { + "type": "text", + "placeholders": {} + }, + "recording": "Ag Taifeadadh", + "@recording": { + "type": "text", + "placeholders": {} + }, + "reason": "Fáth", + "@reason": { + "type": "text", + "placeholders": {} + }, + "privacy": "Príobháideacht", + "@privacy": { + "type": "text", + "placeholders": {} + }, + "pin": "Biorán", + "@pin": { + "type": "text", + "placeholders": {} + }, + "people": "Daoine", + "@people": { + "type": "text", + "placeholders": {} + }, + "password": "Pasfhocal", + "@password": { + "type": "text", + "placeholders": {} + }, + "participant": "Rannpháirtí", + "@participant": { + "type": "text", + "placeholders": {} + }, + "directChats": "Comhráite Díreacha", + "@directChats": { + "type": "text", + "placeholders": {} + }, + "deviceId": "ID gléis", + "@deviceId": { + "type": "text", + "placeholders": {} + }, + "deleteMessage": "Scrios an teachtaireacht", + "@deleteMessage": { + "type": "text", + "placeholders": {} + }, + "deleteAccount": "Scrios an cuntas", + "@deleteAccount": { + "type": "text", + "placeholders": {} + }, + "createNewSpace": "Spás nua", + "@createNewSpace": { + "type": "text", + "placeholders": {} + }, + "countParticipants": "{count} rannpháirtithe", + "@countParticipants": { + "type": "text", + "placeholders": { + "count": {} } -} \ No newline at end of file + }, + "or": "Nó", + "@or": { + "type": "text", + "placeholders": {} + }, + "online": "Ar líne", + "@online": { + "type": "text", + "placeholders": {} + }, + "ok": "togha", + "@ok": { + "type": "text", + "placeholders": {} + }, + "offline": "As líne", + "@offline": { + "type": "text", + "placeholders": {} + }, + "offensive": "Maslach", + "@offensive": { + "type": "text", + "placeholders": {} + }, + "notifications": "Fógraí", + "@notifications": { + "type": "text", + "placeholders": {} + }, + "none": "Aon cheann", + "@none": { + "type": "text", + "placeholders": {} + }, + "no": "Níl", + "@no": { + "type": "text", + "placeholders": {} + }, + "next": "Ar Aghaidh", + "@next": { + "type": "text", + "placeholders": {} + }, + "moderator": "Modhnóir", + "@moderator": { + "type": "text", + "placeholders": {} + }, + "messages": "Teachtaireachtaí", + "@messages": { + "type": "text", + "placeholders": {} + }, + "mention": "Luaigh", + "@mention": { + "type": "text", + "placeholders": {} + }, + "logout": "Logáil amach", + "@logout": { + "type": "text", + "placeholders": {} + }, + "login": "Logáil isteach", + "@login": { + "type": "text", + "placeholders": {} + }, + "lightTheme": "Solas", + "@lightTheme": { + "type": "text", + "placeholders": {} + }, + "license": "Ceadúnas", + "@license": { + "type": "text", + "placeholders": {} + }, + "leave": "Fág", + "@leave": { + "type": "text", + "placeholders": {} + }, + "invited": "Le cuireadh", + "@invited": { + "type": "text", + "placeholders": {} + }, + "inoffensive": "Neamhurchóideach", + "@inoffensive": { + "type": "text", + "placeholders": {} + }, + "ignore": "Tabhair neamhaird ar", + "@ignore": { + "type": "text", + "placeholders": {} + }, + "identity": "Aitheantas", + "@identity": { + "type": "text", + "placeholders": {} + }, + "id": "ID", + "@id": { + "type": "text", + "placeholders": {} + }, + "help": "Cabhair", + "@help": { + "type": "text", + "placeholders": {} + }, + "groups": "Grúpaí", + "@groups": { + "type": "text", + "placeholders": {} + }, + "group": "Grúpa", + "@group": { + "type": "text", + "placeholders": {} + }, + "forward": "Seol ar aghaidh", + "@forward": { + "type": "text", + "placeholders": {} + }, + "fluffychat": "FluffyChat", + "@fluffychat": { + "type": "text", + "placeholders": {} + }, + "homeserver": "Freastalaí baile", + "@homeserver": {}, + "encryption": "Criptiúchán", + "@encryption": { + "type": "text", + "placeholders": {} + }, + "encrypted": "Criptithe", + "@encrypted": { + "type": "text", + "placeholders": {} + }, + "edit": "Cuir in eagar", + "@edit": { + "type": "text", + "placeholders": {} + }, + "devices": "Gléasanna", + "@devices": { + "type": "text", + "placeholders": {} + }, + "device": "Gléas", + "@device": { + "type": "text", + "placeholders": {} + }, + "deny": "Diúltaigh", + "@deny": { + "type": "text", + "placeholders": {} + }, + "delete": "Scrios", + "@delete": { + "type": "text", + "placeholders": {} + }, + "dateWithYear": "{day}/{month}/{year}", + "@dateWithYear": { + "type": "text", + "placeholders": { + "year": {}, + "month": {}, + "day": {} + } + }, + "dateWithoutYear": "{day}/{month}", + "@dateWithoutYear": { + "type": "text", + "placeholders": { + "month": {}, + "day": {} + } + }, + "dateAndTimeOfDay": "{date}, {timeOfDay}", + "@dateAndTimeOfDay": { + "type": "text", + "placeholders": { + "date": {}, + "timeOfDay": {} + } + }, + "containsUserName": "Coinníonn sé ainm úsáideora", + "@containsUserName": { + "type": "text", + "placeholders": {} + }, + "configureChat": "Cumraigh comhrá", + "@configureChat": { + "type": "text", + "placeholders": {} + }, + "commandInvalid": "Ordú neamhbhailí", + "@commandInvalid": { + "type": "text" + }, + "commandHint_send": "Seol téacs", + "@commandHint_send": { + "type": "text", + "description": "Usage hint for the command /send" + }, + "commandHint_me": "Déan cur síos ort féin", + "@commandHint_me": { + "type": "text", + "description": "Usage hint for the command /me" + }, + "clearArchive": "Glan an cartlann", + "@clearArchive": {}, + "chatDetails": "Sonraí comhrá", + "@chatDetails": { + "type": "text", + "placeholders": {} + }, + "chatBackup": "Cúltaca comhrá", + "@chatBackup": { + "type": "text", + "placeholders": {} + }, + "changeWallpaper": "Athraigh cúlbhrat", + "@changeWallpaper": { + "type": "text", + "placeholders": {} + }, + "changedTheChatAvatar": "D'athraigh {username} abhatár an chomhrá", + "@changedTheChatAvatar": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changeDeviceName": "Athraigh ainm an ghléis", + "@changeDeviceName": { + "type": "text", + "placeholders": {} + }, + "cantOpenUri": "Ní féidir an URI {uri} a oscailt", + "@cantOpenUri": { + "type": "text", + "placeholders": { + "uri": {} + } + }, + "cancel": "Cealaigh", + "@cancel": { + "type": "text", + "placeholders": {} + }, + "botMessages": "Teachtaireachtaí bota", + "@botMessages": { + "type": "text", + "placeholders": {} + }, + "blocked": "Bactha", + "@blocked": { + "type": "text", + "placeholders": {} + }, + "blockDevice": "Bac Gléas", + "@blockDevice": { + "type": "text", + "placeholders": {} + }, + "bannedUser": "Chuir {username} cosc ar {targetName}", + "@bannedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "banned": "Coiscthe", + "@banned": { + "type": "text", + "placeholders": {} + }, + "banFromChat": "Toirmisc ón gcomhrá", + "@banFromChat": { + "type": "text", + "placeholders": {} + }, + "sendOnEnter": "Seol ar iontráil", + "@sendOnEnter": {}, + "archive": "Cartlann", + "@archive": { + "type": "text", + "placeholders": {} + }, + "appLock": "Bac aip", + "@appLock": { + "type": "text", + "placeholders": {} + }, + "anyoneCanJoin": "Is féidir le aon duine dul isteach", + "@anyoneCanJoin": { + "type": "text", + "placeholders": {} + }, + "answeredTheCall": "D'fhreagair {senderName} an glao", + "@answeredTheCall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "allChats": "Gach comhrá", + "@allChats": { + "type": "text", + "placeholders": {} + }, + "all": "Gach", + "@all": { + "type": "text", + "placeholders": {} + }, + "alias": "ailias", + "@alias": { + "type": "text", + "placeholders": {} + }, + "admin": "Riarthóir", + "@admin": { + "type": "text", + "placeholders": {} + }, + "addToSpace": "Cuir go spás", + "@addToSpace": {}, + "addGroupDescription": "Cuir tuairisc grúpa", + "@addGroupDescription": { + "type": "text", + "placeholders": {} + }, + "addEmail": "Cuir ríomhphoist", + "@addEmail": { + "type": "text", + "placeholders": {} + }, + "activatedEndToEndEncryption": "Thosaigh {username} an criptiú ó dheireadh go deireadh", + "@activatedEndToEndEncryption": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "account": "Cuntas", + "@account": { + "type": "text", + "placeholders": {} + }, + "acceptedTheInvitation": "Ghlac {username} leis an cuireadh", + "@acceptedTheInvitation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "accept": "Glac", + "@accept": { + "type": "text", + "placeholders": {} + }, + "about": "Faoi", + "@about": { + "type": "text", + "placeholders": {} + }, + "askVerificationRequest": "Glac leis an iarratas fíoraithe seo ó {username}?", + "@askVerificationRequest": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "areYouSureYouWantToLogout": "An bhfuil tú cinnte gur mhaith leat logáil amach?", + "@areYouSureYouWantToLogout": { + "type": "text", + "placeholders": {} + }, + "areYouSure": "An bhfuil tú cinnte?", + "@areYouSure": { + "type": "text", + "placeholders": {} + }, + "areGuestsAllowedToJoin": "An bhfuil cead ag aoi-úsáideoirí a bheith páirteach", + "@areGuestsAllowedToJoin": { + "type": "text", + "placeholders": {} + }, + "invitedUser": "Thug {username} cuireadh do {targetName}", + "@invitedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "hideRedactedEvents": "Folaigh imeachtaí athdhéanta", + "@hideRedactedEvents": { + "type": "text", + "placeholders": {} + }, + "guestsCanJoin": "Is féidir le haíonna páirt a ghlacadh", + "@guestsCanJoin": { + "type": "text", + "placeholders": {} + }, + "guestsAreForbidden": "Tá cosc ar aíonna", + "@guestsAreForbidden": { + "type": "text", + "placeholders": {} + }, + "groupWith": "Grúpa le {displayname}", + "@groupWith": { + "type": "text", + "placeholders": { + "displayname": {} + } + }, + "groupIsPublic": "Tá an grúpa poiblí", + "@groupIsPublic": { + "type": "text", + "placeholders": {} + }, + "groupDescriptionHasBeenChanged": "D'athraigh cur síos an ghrúpa", + "@groupDescriptionHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "fromTheInvitation": "Ón gcuireadh", + "@fromTheInvitation": { + "type": "text", + "placeholders": {} + }, + "enterYourHomeserver": "Cuir isteach do fhreastalaí baile", + "@enterYourHomeserver": { + "type": "text", + "placeholders": {} + }, + "emoteInvalid": "Gearrchód emote neamhbhailí!", + "@emoteInvalid": { + "type": "text", + "placeholders": {} + }, + "emoteExists": "Tá iomaite ann cheana féin!", + "@emoteExists": { + "type": "text", + "placeholders": {} + }, + "editRoomAvatar": "Cuir in eagar abhatár an tseomra", + "@editRoomAvatar": { + "type": "text", + "placeholders": {} + }, + "editRoomAliases": "Cuir ailiasanna an tseomra in eagar", + "@editRoomAliases": { + "type": "text", + "placeholders": {} + }, + "editChatPermissions": "Cuir ceadanna an chomhrá in eagar", + "@editChatPermissions": { + "type": "text", + "placeholders": {} + }, + "editBlockedServers": "Cuir freastalaí blocáilte in eagar", + "@editBlockedServers": { + "type": "text", + "placeholders": {} + }, + "defaultPermissionLevel": "Leibhéal ceada réamhshocraithe", + "@defaultPermissionLevel": { + "type": "text", + "placeholders": {} + }, + "unblockDevice": "Díbhlocáil Gléas", + "@unblockDevice": { + "type": "text", + "placeholders": {} + }, + "contactHasBeenInvitedToTheGroup": "Tugadh cuireadh don theagmháil a thar isteach sa grúpa", + "@contactHasBeenInvitedToTheGroup": { + "type": "text", + "placeholders": {} + }, + "compareNumbersMatch": "Déan comparáid idir na huimhreacha seo a leanas agus déan cinnte go bhfuil na huimhreacha seo a leanas ag teacht le huimhreacha an ghléis eile:", + "@compareNumbersMatch": { + "type": "text", + "placeholders": {} + }, + "compareEmojiMatch": "Déan comparáid agus déan cinnte go bhfuil an emoji seo a leanas comhoiriúnach le emoji an ghléis eile:", + "@compareEmojiMatch": { + "type": "text", + "placeholders": {} + }, + "commandMissing": "Ní ordú é {command}.", + "@commandMissing": { + "type": "text", + "placeholders": { + "command": {} + }, + "description": "State that {command} is not a valid /command." + }, + "commandHint_react": "Seol freagra mar fhreagairt", + "@commandHint_react": { + "type": "text", + "description": "Usage hint for the command /react" + }, + "commandHint_op": "Socraigh leibhéal cumhachta an úsáideora áirithe (réamhshocrú: 50)", + "@commandHint_op": { + "type": "text", + "description": "Usage hint for the command /op" + }, + "commandHint_myroomnick": "Socraigh d'ainm taispeána don seomra seo", + "@commandHint_myroomnick": { + "type": "text", + "description": "Usage hint for the command /myroomnick" + }, + "commandHint_myroomavatar": "Cuir do phictiúr don seomra seo (le mxc-uri)", + "@commandHint_myroomavatar": { + "type": "text", + "description": "Usage hint for the command /myroomavatar" + }, + "commandHint_kick": "Bain an t-úsáideoir áirithe den seomra seo", + "@commandHint_kick": { + "type": "text", + "description": "Usage hint for the command /kick" + }, + "commandHint_join": "Téigh isteach sa seomra áirithe", + "@commandHint_join": { + "type": "text", + "description": "Usage hint for the command /join" + }, + "commandHint_ban": "Cuir cosc ar an úsáideoir áirithe ón seomra seo", + "@commandHint_ban": { + "type": "text", + "description": "Usage hint for the command /ban" + }, + "commandHint_invite": "Cuir cosc ar an úsáideoir áirithe ón seomra seo", + "@commandHint_invite": { + "type": "text", + "description": "Usage hint for the command /invite" + }, + "chooseAStrongPassword": "Roghnaigh pasfhocal láidir", + "@chooseAStrongPassword": { + "type": "text", + "placeholders": {} + }, + "chatHasBeenAddedToThisSpace": "Cuireadh comhrá leis an spás seo", + "@chatHasBeenAddedToThisSpace": {}, + "chatBackupDescription": "Tá do chúltaca comhrá daingnithe le heochair slándála. Déan cinnte nach gcaillfidh tú é.", + "@chatBackupDescription": { + "type": "text", + "placeholders": {} + }, + "channelCorruptedDecryptError": "Truaillíodh an criptiú", + "@channelCorruptedDecryptError": { + "type": "text", + "placeholders": {} + }, + "changeTheNameOfTheGroup": "Athraigh ainm an ghrúpa", + "@changeTheNameOfTheGroup": { + "type": "text", + "placeholders": {} + }, + "changedTheRoomInvitationLink": "D'athraigh {username} nasc an chuiridh", + "@changedTheRoomInvitationLink": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheRoomAliases": "D'athraigh {username} ailiasanna an tseomra", + "@changedTheRoomAliases": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheProfileAvatar": "D'athraigh {username} a n-abhatár", + "@changedTheProfileAvatar": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheJoinRulesTo": "D'athraigh {username} na rialacha ceangail go: {joinRules}", + "@changedTheJoinRulesTo": { + "type": "text", + "placeholders": { + "username": {}, + "joinRules": {} + } + }, + "changedTheJoinRules": "D'athraigh {username} na rialacha ceangail", + "@changedTheJoinRules": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheHistoryVisibilityTo": "D'athraigh {username} infheictheacht na staire go: {rules}", + "@changedTheHistoryVisibilityTo": { + "type": "text", + "placeholders": { + "username": {}, + "rules": {} + } + }, + "changedTheHistoryVisibility": "D'athraigh {username} infheictheacht na staire", + "@changedTheHistoryVisibility": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheDisplaynameTo": "D'athraigh {username} a n-ainm taispeána go: '{displayname}'", + "@changedTheDisplaynameTo": { + "type": "text", + "placeholders": { + "username": {}, + "displayname": {} + } + }, + "changedTheChatPermissions": "D'athraigh {username} na ceadanna comhrá", + "@changedTheChatPermissions": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheChatNameTo": "D'athraigh {username} an t-ainm comhrá go: '{chatname}'", + "@changedTheChatNameTo": { + "type": "text", + "placeholders": { + "username": {}, + "chatname": {} + } + }, + "changedTheChatDescriptionTo": "D'athraigh {username} an cur síos comhrá go: '{description}'", + "@changedTheChatDescriptionTo": { + "type": "text", + "placeholders": { + "username": {}, + "description": {} + } + }, + "autoplayImages": "Seinn greamáin agus straoiseog beoite go huathoibríoch", + "@autoplayImages": { + "type": "text", + "placeholder": {} + }, + "createdTheChat": "Rinne {username} an comhrá", + "@createdTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "createNewGroup": "Déan grúpa nua", + "@createNewGroup": { + "type": "text", + "placeholders": {} + }, + "copyToClipboard": "Cóipeáil ar an ghearrthaisce", + "@copyToClipboard": { + "type": "text", + "placeholders": {} + }, + "copiedToClipboard": "Cóipeáilte ar an ghearrthaisce", + "@copiedToClipboard": { + "type": "text", + "placeholders": {} + }, + "containsDisplayName": "Coinníonn sé ainm taispeána", + "@containsDisplayName": { + "type": "text", + "placeholders": {} + }, + "commandHint_plain": "Seol téacs neamhfhoirmithe", + "@commandHint_plain": { + "type": "text", + "description": "Usage hint for the command /plain" + }, + "commandHint_leave": "Fág an seomra seo", + "@commandHint_leave": { + "type": "text", + "description": "Usage hint for the command /leave" + }, + "commandHint_html": "Seol téacs HTML-formáidithe", + "@commandHint_html": { + "type": "text", + "description": "Usage hint for the command /html" + }, + "chooseAUsername": "Roghnaigh ainm úsáideora", + "@chooseAUsername": { + "type": "text", + "placeholders": {} + }, + "changeYourAvatar": "Athraigh do abhatár", + "@changeYourAvatar": { + "type": "text", + "placeholders": {} + }, + "changeTheme": "Athraigh do stíl", + "@changeTheme": { + "type": "text", + "placeholders": {} + }, + "changeTheHomeserver": "Athraigh an freastalaí baile", + "@changeTheHomeserver": { + "type": "text", + "placeholders": {} + }, + "voiceMessage": "Glórphost", + "@voiceMessage": { + "type": "text", + "placeholders": {} + }, + "videoCall": "Físghlao", + "@videoCall": { + "type": "text", + "placeholders": {} + }, + "verifyStart": "Tosaigh Fíorú", + "@verifyStart": { + "type": "text", + "placeholders": {} + }, + "unmuteChat": "Neamhciúnaigh comhrá", + "@unmuteChat": { + "type": "text", + "placeholders": {} + }, + "hideUnknownEvents": "Folaigh imeachtaí anaithnide", + "@hideUnknownEvents": { + "type": "text", + "placeholders": {} + }, + "unknownDevice": "Gléas anaithnid", + "@unknownDevice": { + "type": "text", + "placeholders": {} + }, + "toggleUnread": "Marcáil Léite/Neamhléite", + "@toggleUnread": { + "type": "text", + "placeholders": {} + }, + "toggleMuted": "Scoránaigh mar ciúnaithe", + "@toggleMuted": { + "type": "text", + "placeholders": {} + }, + "toggleFavorite": "Scoránaigh mar ceann is fearr leat", + "@toggleFavorite": { + "type": "text", + "placeholders": {} + }, + "theyMatch": "Tá siad céanna", + "@theyMatch": { + "type": "text", + "placeholders": {} + }, + "spaceName": "Ainm an spáis", + "@spaceName": { + "type": "text", + "placeholders": {} + }, + "sourceCode": "Cód foinseach", + "@sourceCode": { + "type": "text", + "placeholders": {} + }, + "signUp": "Cláraigh Cuntas", + "@signUp": { + "type": "text", + "placeholders": {} + }, + "showPassword": "Taispeáin pasfhocal", + "@showPassword": { + "type": "text", + "placeholders": {} + }, + "shareLocation": "Roinn suíomh", + "@shareLocation": { + "type": "text", + "placeholders": {} + }, + "setStatus": "Cuir stádas", + "@setStatus": { + "type": "text", + "placeholders": {} + }, + "sendVideo": "Seol físeán", + "@sendVideo": { + "type": "text", + "placeholders": {} + }, + "sendSticker": "Seol greamán", + "@sendSticker": { + "type": "text", + "placeholders": {} + }, + "sendOriginal": "Seol an bunchóip", + "@sendOriginal": { + "type": "text", + "placeholders": {} + }, + "sendMessages": "Seol teachtaireachtaí", + "@sendMessages": { + "type": "text", + "placeholders": {} + }, + "sendImage": "Seol íomhá", + "@sendImage": { + "type": "text", + "placeholders": {} + }, + "sendFile": "Seol comhad", + "@sendFile": { + "type": "text", + "placeholders": {} + }, + "sendAudio": "Seol fuaim", + "@sendAudio": { + "type": "text", + "placeholders": {} + }, + "saveFile": "Sábháil comhad", + "@saveFile": { + "type": "text", + "placeholders": {} + }, + "roomVersion": "Leagan seomra", + "@roomVersion": { + "type": "text", + "placeholders": {} + }, + "requestPermission": "Iarr cead", + "@requestPermission": { + "type": "text", + "placeholders": {} + }, + "reportMessage": "Tuairiscigh teachtaireacht", + "@reportMessage": { + "type": "text", + "placeholders": {} + }, + "removeDevice": "Bain gléas", + "@removeDevice": { + "type": "text", + "placeholders": {} + }, + "redactMessage": "Bain teachtaireacht amach", + "@redactMessage": { + "type": "text", + "placeholders": {} + }, + "pushRules": "Rialacha na bhfógraí", + "@pushRules": { + "type": "text", + "placeholders": {} + }, + "publicRooms": "Seomraí Poiblí", + "@publicRooms": { + "type": "text", + "placeholders": {} + }, + "pleaseChoose": "Roghnaigh le do thoil", + "@pleaseChoose": { + "type": "text", + "placeholders": {} + }, + "play": "Seinn {fileName}", + "@play": { + "type": "text", + "placeholders": { + "fileName": {} + } + }, + "passwordRecovery": "Aisfháil pasfhocail", + "@passwordRecovery": { + "type": "text", + "placeholders": {} + }, + "passwordForgotten": "Pasfhocal dearmadta", + "@passwordForgotten": { + "type": "text", + "placeholders": {} + }, + "openCamera": "Oscail ceamara", + "@openCamera": { + "type": "text", + "placeholders": {} + }, + "obtainingLocation": "ag Aimsiú an suíomh…", + "@obtainingLocation": { + "type": "text", + "placeholders": {} + }, + "noPermission": "Gan cead", + "@noPermission": { + "type": "text", + "placeholders": {} + }, + "newChat": "Comhrá nua", + "@newChat": { + "type": "text", + "placeholders": {} + }, + "muteChat": "Ciúnaigh comhrá", + "@muteChat": { + "type": "text", + "placeholders": {} + }, + "memberChanges": "Athruithe ball", + "@memberChanges": { + "type": "text", + "placeholders": {} + }, + "loadMore": "Lódáil níos mó…", + "@loadMore": { + "type": "text", + "placeholders": {} + }, + "joinRoom": "Téigh isteach sa seomra", + "@joinRoom": { + "type": "text", + "placeholders": {} + }, + "isTyping": "ag clóscríobh…", + "@isTyping": { + "type": "text", + "placeholders": {} + }, + "inviteContact": "Tabhair cuireadh do theagmháil", + "@inviteContact": { + "type": "text", + "placeholders": {} + }, + "ignoreUsername": "Tabhair neamhaird ar ainm úsáideora", + "@ignoreUsername": { + "type": "text", + "placeholders": {} + }, + "ignoredUsers": "Úsáideoirí a dtugann tú neamhaird orthu", + "@ignoredUsers": { + "type": "text", + "placeholders": {} + }, + "groupDescription": "Cur síos ar an ngrúpa", + "@groupDescription": { + "type": "text", + "placeholders": {} + }, + "fromJoining": "Ó tar isteach", + "@fromJoining": { + "type": "text", + "placeholders": {} + }, + "fontSize": "Méid cló", + "@fontSize": { + "type": "text", + "placeholders": {} + }, + "enableEncryption": "Tosaigh criptiú", + "@enableEncryption": { + "type": "text", + "placeholders": {} + }, + "editDisplayname": "Cuir ainm taispeána in eagar", + "@editDisplayname": { + "type": "text", + "placeholders": {} + }, + "currentlyActive": "Gníomhach faoi láthair", + "@currentlyActive": { + "type": "text", + "placeholders": {} + }, + "fileName": "Ainm an chomhaid", + "@fileName": { + "type": "text", + "placeholders": {} + }, + "everythingReady": "Gach rud réidh!", + "@everythingReady": { + "type": "text", + "placeholders": {} + }, + "emptyChat": "Comhrá folamh", + "@emptyChat": { + "type": "text", + "placeholders": {} + }, + "emoteShortcode": "Gearrchód straoiseoige", + "@emoteShortcode": { + "type": "text", + "placeholders": {} + }, + "emoteSettings": "Socruithe straoiseoige", + "@emoteSettings": { + "type": "text", + "placeholders": {} + }, + "downloadFile": "Íoslódáil comhad", + "@downloadFile": { + "type": "text", + "placeholders": {} + }, + "changePassword": "Athraigh an pasfhocal", + "@changePassword": { + "type": "text", + "placeholders": {} + }, + "darkTheme": "Dorcha", + "@darkTheme": { + "type": "text", + "placeholders": {} + }, + "create": "Cruthaigh", + "@create": { + "type": "text", + "placeholders": {} + }, + "copy": "Cóipeáil", + "@copy": { + "type": "text", + "placeholders": {} + }, + "connect": "Ceangail", + "@connect": { + "type": "text", + "placeholders": {} + }, + "confirm": "Deimhnigh", + "@confirm": { + "type": "text", + "placeholders": {} + }, + "close": "Dún", + "@close": { + "type": "text", + "placeholders": {} + }, + "chats": "Comhráite", + "@chats": { + "type": "text", + "placeholders": {} + }, + "chat": "Comhrá", + "@chat": { + "type": "text", + "placeholders": {} + }, + "scanQrCode": "Scan cód QR", + "@scanQrCode": {}, + "inviteText": "Thug {username} cuireadh duit chuig FluffyChat.\n1. Suiteáil FluffyChat: https://fluffychat.im\n2. Cláraigh nó sínigh isteach\n3. Oscail an nasc cuiridh: {link}", + "@inviteText": { + "type": "text", + "placeholders": { + "username": {}, + "link": {} + } + }, + "shareYourInviteLink": "Roinn do nasc cuiridh", + "@shareYourInviteLink": {}, + "noMatrixServer": "Níl {server1} freastalaí Matrix. Úsáid {server2} ina áit sin?", + "@noMatrixServer": { + "type": "text", + "placeholders": { + "server1": {}, + "server2": {} + } + }, + "noGoogleServicesWarning": "Dealraíonn sé nach bhfuil aon seirbhísí google agat ar do ghuthán. Sin cinneadh maith le do phríobháideacht! Chun fógraí brú a fháil i FluffyChat molaimid https://microg.org/ nó https://unifiedpush.org/ a úsáid.", + "@noGoogleServicesWarning": { + "type": "text", + "placeholders": {} + }, + "noEncryptionForPublicRooms": "Ní féidir leat criptiú a ghníomhachtú ach a luaithe nach bhfuil an seomra inrochtana go poiblí a thuilleadh.", + "@noEncryptionForPublicRooms": { + "type": "text", + "placeholders": {} + }, + "noEmotesFound": "Níor aimsíodh aon straoiseoga. 😕", + "@noEmotesFound": { + "type": "text", + "placeholders": {} + }, + "noConnectionToTheServer": "Gan aon nasc leis an bhfreastalaí", + "@noConnectionToTheServer": { + "type": "text", + "placeholders": {} + }, + "newVerificationRequest": "Iarratas fíoraithe nua!", + "@newVerificationRequest": { + "type": "text", + "placeholders": {} + }, + "newMessageInFluffyChat": "Teachtaireacht nua i FluffyChat", + "@newMessageInFluffyChat": { + "type": "text", + "placeholders": {} + }, + "needPantalaimonWarning": "Bí ar an eolas go dteastaíonn Pantalaimon uait chun criptiú ó cheann go ceann a úsáid anois.", + "@needPantalaimonWarning": { + "type": "text", + "placeholders": {} + }, + "messageWillBeRemovedWarning": "Bainfear an teachtaireacht do na rannpháirtithe go léir", + "@messageWillBeRemovedWarning": { + "type": "text", + "placeholders": {} + }, + "makeSureTheIdentifierIsValid": "Cinntigh go bhfuil an t-aitheantóir bailí", + "@makeSureTheIdentifierIsValid": { + "type": "text", + "placeholders": {} + }, + "loginWith": "Sínigh isteach le {brand}", + "@loginWith": { + "type": "text", + "placeholders": { + "brand": {} + } + }, + "logInTo": "Logáil isteach chuig {homeserver}", + "@logInTo": { + "type": "text", + "placeholders": { + "homeserver": {} + } + }, + "locationPermissionDeniedNotice": "Diúltaíodh cead suímh. Deonaigh dóibh le do thoil go mbeidh tú in ann do shuíomh a roinnt.", + "@locationPermissionDeniedNotice": { + "type": "text", + "placeholders": {} + }, + "locationDisabledNotice": "Tá seirbhísí suímh díchumasaithe. Cuir ar a gcumas le do thoil a bheith in ann do shuíomh a roinnt.", + "@locationDisabledNotice": { + "type": "text", + "placeholders": {} + }, + "loadingPleaseWait": "Ag lódáil… Fan, le do thoil.", + "@loadingPleaseWait": { + "type": "text", + "placeholders": {} + }, + "loadCountMoreParticipants": "Lódáil {count} níos mó rannpháirtithe", + "@loadCountMoreParticipants": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "leftTheChat": "Fágadh an comhrá", + "@leftTheChat": { + "type": "text", + "placeholders": {} + }, + "lastSeenLongTimeAgo": "Le feiceáil i bhfad ó shin", + "@lastSeenLongTimeAgo": { + "type": "text", + "placeholders": {} + }, + "lastActiveAgo": "Gníomhach deireanach: {localizedTimeShort}", + "@lastActiveAgo": { + "type": "text", + "placeholders": { + "localizedTimeShort": {} + } + }, + "kickFromChat": "Caith é amach as an comhrá", + "@kickFromChat": { + "type": "text", + "placeholders": {} + }, + "kicked": "Chaith {username} {targetName} amach", + "@kicked": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "kickedAndBanned": "Chaith {username} amach agus chuir cosc ar {targetName} freisin", + "@kickedAndBanned": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "joinedTheChat": "Tháinig {username} isteach sa chomhrá", + "@joinedTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "invitedUsersOnly": "Úsáideoirí le cuireadh amháin", + "@invitedUsersOnly": { + "type": "text", + "placeholders": {} + }, + "inviteContactToGroup": "Tabhair cuireadh do theagmháil chuig {groupName}", + "@inviteContactToGroup": { + "type": "text", + "placeholders": { + "groupName": {} + } + }, + "incorrectPassphraseOrKey": "Pasfhrása nó eochair téarnaimh mícheart", + "@incorrectPassphraseOrKey": { + "type": "text", + "placeholders": {} + }, + "iHaveClickedOnLink": "Chliceáil mé ar an nasc", + "@iHaveClickedOnLink": { + "type": "text", + "placeholders": {} + }, + "howOffensiveIsThisContent": "Cé chomh maslach atá an t-ábhar seo?", + "@howOffensiveIsThisContent": { + "type": "text", + "placeholders": {} + }, + "extremeOffensive": "Fíor-maslach", + "@extremeOffensive": { + "type": "text", + "placeholders": {} + }, + "hasWithdrawnTheInvitationFor": "Tharraing {username} an cuireadh do {targetName} siar", + "@hasWithdrawnTheInvitationFor": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "goToTheNewRoom": "Téigh go dtí an seomra nua", + "@goToTheNewRoom": { + "type": "text", + "placeholders": {} + }, + "errorObtainingLocation": "Earráid maidir le suíomh a fháil: {error}", + "@errorObtainingLocation": { + "type": "text", + "placeholders": { + "error": {} + } + }, + "enterASpacepName": "Cuir isteach ainm spáis", + "@enterASpacepName": {}, + "enterAnEmailAddress": "Cuir isteach seoladh ríomhphoist", + "@enterAnEmailAddress": { + "type": "text", + "placeholders": {} + }, + "enterAGroupName": "Iontráil ainm grúpa", + "@enterAGroupName": { + "type": "text", + "placeholders": {} + }, + "endedTheCall": "Chuir {senderName} deireadh leis an nglao", + "@endedTheCall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "encryptionNotEnabled": "Ní chumasaítear criptiú", + "@encryptionNotEnabled": { + "type": "text", + "placeholders": {} + }, + "enableEncryptionWarning": "Ní bheidh in ann an criptiú a dhíchumasú níos mó. An bhfuil tú cinnte?", + "@enableEncryptionWarning": { + "type": "text", + "placeholders": {} + }, + "enableEmotesGlobally": "Cumasaigh pacáiste straoiseoige go huilíoch", + "@enableEmotesGlobally": { + "type": "text", + "placeholders": {} + }, + "emoteWarnNeedToPick": "Caithfidh tú gearrchód straoiseoige agus íomhá a roghnú!", + "@emoteWarnNeedToPick": { + "type": "text", + "placeholders": {} + }, + "emotePacks": "Pacáistí straoiseoige don seomra", + "@emotePacks": { + "type": "text", + "placeholders": {} + }, + "displaynameHasBeenChanged": "Athraíodh an t-ainm taispeána", + "@displaynameHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "deactivateAccountWarning": "Díghníomhachtaeoidh sé seo do chuntas úsáideora. Ní féidir é seo a chealú! An bhfuil tú cinnte?", + "@deactivateAccountWarning": { + "type": "text", + "placeholders": {} + }, + "couldNotDecryptMessage": "Níorbh fhéidir teachtaireacht a dhíchriptiú: {error}", + "@couldNotDecryptMessage": { + "type": "text", + "placeholders": { + "error": {} + } + }, + "contentHasBeenReported": "Tuairiscíodh an t-ábhar do lucht riaracháin an fhreastalaí", + "@contentHasBeenReported": { + "type": "text", + "placeholders": {} + }, + "commandHint_unban": "Cuir deireadh an cosc den úsáideoir áirithe ón seomra seo", + "@commandHint_unban": { + "type": "text", + "description": "Usage hint for the command /unban" + }, + "changedTheGuestAccessRulesTo": "D'athraigh {username} na rialacha maidir le rochtain aoi chuig: {rules}", + "@changedTheGuestAccessRulesTo": { + "type": "text", + "placeholders": { + "username": {}, + "rules": {} + } + }, + "changedTheGuestAccessRules": "D'athraigh {username} na rialacha rochtana aoi", + "@changedTheGuestAccessRules": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "badServerVersionsException": "Tá na leaganacha sonraíochta seo ar fáil faoin freastalaí baile:\n{serverVersions}\nAch níl ach na ceann seo ar fáil faoin aip seo {supportedVersions}", + "@badServerVersionsException": { + "type": "text", + "placeholders": { + "serverVersions": {}, + "supportedVersions": {} + } + }, + "badServerLoginTypesException": "Tá na cineálacha logála isteach seo ar fáil faoin freastalaí baile:\n{serverVersions}\nAch níl ach na ceann seo ar fáil faoin aip seo:\n{supportedVersions}", + "@badServerLoginTypesException": { + "type": "text", + "placeholders": { + "serverVersions": {}, + "supportedVersions": {} + } + }, + "askSSSSSign": "Chun a bheith in ann an duine eile a shíniú, cuir isteach do phasfhrása stóir sábháilte nó d'eochair téarnaimh.", + "@askSSSSSign": { + "type": "text", + "placeholders": {} + }, + "yourPublicKey": "D'eochair phoiblí", + "@yourPublicKey": { + "type": "text", + "placeholders": {} + }, + "youHaveBeenBannedFromThisChat": "Cuireadh cosc ort ón gcomhrá seo", + "@youHaveBeenBannedFromThisChat": { + "type": "text", + "placeholders": {} + }, + "youCannotInviteYourself": "Ní féidir leat cuireadh a thabhairt duit féin", + "@youCannotInviteYourself": { + "type": "text", + "placeholders": {} + }, + "youAreNoLongerParticipatingInThisChat": "Níl tú ag glacadh páirte sa chomhrá seo a thuilleadh", + "@youAreNoLongerParticipatingInThisChat": { + "type": "text", + "placeholders": {} + }, + "youAreInvitedToThisChat": "Tugtar cuireadh duit chuig an gcomhrá seo", + "@youAreInvitedToThisChat": { + "type": "text", + "placeholders": {} + }, + "writeAMessage": "Scríobh teachtaireacht…", + "@writeAMessage": { + "type": "text", + "placeholders": {} + }, + "withTheseAddressesRecoveryDescription": "Leis na seoltaí seo is féidir leat do phasfhocal a athshlánú.", + "@withTheseAddressesRecoveryDescription": { + "type": "text", + "placeholders": {} + }, + "wipeChatBackup": "Glan do cúltaca comhrá a chruthú eochair slándála nua?", + "@wipeChatBackup": { + "type": "text", + "placeholders": {} + }, + "whyDoYouWantToReportThis": "Cén fáth ar mhaith leat é seo a thuairisciú?", + "@whyDoYouWantToReportThis": { + "type": "text", + "placeholders": {} + }, + "whoIsAllowedToJoinThisGroup": "Cé a bhfuil cead aige/aici dul isteach sa ghrúpa seo", + "@whoIsAllowedToJoinThisGroup": { + "type": "text", + "placeholders": {} + }, + "whoCanPerformWhichAction": "Cé atá in ann an gníomh a dhéanamh", + "@whoCanPerformWhichAction": { + "type": "text", + "placeholders": {} + }, + "verifySuccess": "D'fhíoraigh tú go rathúil!", + "@verifySuccess": { + "type": "text", + "placeholders": {} + }, + "userLeftTheChat": "D'fhág {username} an comhrá", + "@userLeftTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "userAndUserAreTyping": "Tá {username} agus {username2} ag clóscríobh…", + "@userAndUserAreTyping": { + "type": "text", + "placeholders": { + "username": {}, + "username2": {} + } + }, + "userAndOthersAreTyping": "tá {username} agus {count} daoine eile ag clóscríobh…", + "@userAndOthersAreTyping": { + "type": "text", + "placeholders": { + "username": {}, + "count": {} + } + }, + "unreadChats": "{unreadCount, plural, =1{1 comhrá neamhléite} other{{unreadCount} comhráite neamhléite}}", + "@unreadChats": { + "type": "text", + "placeholders": { + "unreadCount": {} + } + }, + "unknownEncryptionAlgorithm": "Algartam criptithe anaithnid", + "@unknownEncryptionAlgorithm": { + "type": "text", + "placeholders": {} + }, + "unbannedUser": "Chuir {username} deireadh an cosc {targetName}", + "@unbannedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "tryToSendAgain": "Déan iarracht a sheoladh arís", + "@tryToSendAgain": { + "type": "text", + "placeholders": {} + }, + "transferFromAnotherDevice": "Aistriú ó ghléas eile", + "@transferFromAnotherDevice": { + "type": "text", + "placeholders": {} + }, + "tooManyRequestsWarning": "An iomarca iarratas. Bain triail eile as níos déanaí!", + "@tooManyRequestsWarning": { + "type": "text", + "placeholders": {} + }, + "theyDontMatch": "Níl siad céanna", + "@theyDontMatch": { + "type": "text", + "placeholders": {} + }, + "sharedTheLocation": "Roinn {username} an suíomh", + "@sharedTheLocation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "setPermissionsLevel": "Socraigh leibhéal ceadanna", + "@setPermissionsLevel": { + "type": "text", + "placeholders": {} + }, + "setInvitationLink": "Socraigh nasc cuiridh", + "@setInvitationLink": { + "type": "text", + "placeholders": {} + }, + "setGroupDescription": "Socraigh cur síos ar an ngrúpa", + "@setGroupDescription": { + "type": "text", + "placeholders": {} + }, + "setCustomEmotes": "Socraigh straoiseoga saincheaptha", + "@setCustomEmotes": { + "type": "text", + "placeholders": {} + }, + "setAsCanonicalAlias": "Socraigh mar phríomh-ailias", + "@setAsCanonicalAlias": { + "type": "text", + "placeholders": {} + }, + "sentCallInformations": "Sheol {senderName} faisnéis maidir le glaonna", + "@sentCallInformations": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "sentAVideo": "Sheol {username} físeán", + "@sentAVideo": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sentASticker": "Sheol {username} greamán", + "@sentASticker": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sentAPicture": "Sheol {username} pictiúr", + "@sentAPicture": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "seenByUserAndUser": "Le feiceáil ag {username} agus {username2}", + "@seenByUserAndUser": { + "type": "text", + "placeholders": { + "username": {}, + "username2": {} + } + }, + "seenByUserAndCountOthers": "{count, plural, other{Le feiceáil ag {username} agus {count} daoine eile}}", + "@seenByUserAndCountOthers": { + "type": "text", + "placeholders": { + "username": {}, + "count": {} + } + }, + "replaceRoomWithNewerVersion": "Cuir leagan seomra níos nuaí in ionad an tseomra", + "@replaceRoomWithNewerVersion": { + "type": "text", + "placeholders": {} + }, + "renderRichContent": "Taispeáin ábhar teachtaireachta saibhir", + "@renderRichContent": { + "type": "text", + "placeholders": {} + }, + "removeYourAvatar": "Bain d'abhatár", + "@removeYourAvatar": { + "type": "text", + "placeholders": {} + }, + "unbanFromChat": "Cuir deireadh an cosc ón gcomhrá", + "@unbanFromChat": { + "type": "text", + "placeholders": {} + }, + "removedBy": "Bainte de ag {username}", + "@removedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "removeAllOtherDevices": "Bain gach gléas eile", + "@removeAllOtherDevices": { + "type": "text", + "placeholders": {} + }, + "rejectedTheInvitation": "Dhiúltaigh {username} don chuireadh", + "@rejectedTheInvitation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "redactedAnEvent": "Rinne {username} cinsire imeacht", + "@redactedAnEvent": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "pleaseFollowInstructionsOnWeb": "Lean na treoracha ar an suíomh gréasáin agus tapáil \"ar aghaidh\".", + "@pleaseFollowInstructionsOnWeb": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourUsername": "Cuir isteach d'ainm úsáideora le do thoil", + "@pleaseEnterYourUsername": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourPin": "Cuir isteach d'uimhir PIN le do thoil", + "@pleaseEnterYourPin": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourPassword": "Iontráil do phasfhocal le do thoil", + "@pleaseEnterYourPassword": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterAMatrixIdentifier": "Iontráil ID Matrix le do thoil.", + "@pleaseEnterAMatrixIdentifier": { + "type": "text", + "placeholders": {} + }, + "pleaseEnter4Digits": "Iontráil 4 dhigit le do thoil nó fág folamh chun glas aipe a dhíchumasú.", + "@pleaseEnter4Digits": { + "type": "text", + "placeholders": {} + }, + "pleaseClickOnLink": "Cliceáil ar an nasc sa ríomhphost agus ansin lean ar aghaidh.", + "@pleaseClickOnLink": { + "type": "text", + "placeholders": {} + }, + "pleaseChooseAUsername": "Roghnaigh ainm úsáideora le do thoil", + "@pleaseChooseAUsername": { + "type": "text", + "placeholders": {} + }, + "pleaseChooseAPasscode": "Roghnaigh paschód le do thoil", + "@pleaseChooseAPasscode": { + "type": "text", + "placeholders": {} + }, + "pickImage": "Roghnaigh íomhá", + "@pickImage": { + "type": "text", + "placeholders": {} + }, + "passwordHasBeenChanged": "Athraíodh an pasfhocal", + "@passwordHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "passphraseOrKey": "pasfhrása nó eochair téarnaimh", + "@passphraseOrKey": { + "type": "text", + "placeholders": {} + }, + "optionalGroupName": "(Optional) Ainm an ghrúpa", + "@optionalGroupName": { + "type": "text", + "placeholders": {} + }, + "serverRequiresEmail": "Ní mór don fhreastalaí seo do sheoladh ríomhphoist a bhailíochtú le haghaidh clárúcháin.", + "@serverRequiresEmail": {}, + "openInMaps": "Oscail i léarscáileanna", + "@openInMaps": { + "type": "text", + "placeholders": {} + }, + "openAppToReadMessages": "Oscail an aip chun teachtaireachtaí a léamh", + "@openAppToReadMessages": { + "type": "text", + "placeholders": {} + }, + "oopsSomethingWentWrong": "Úps, chuaigh rud éigin mícheart …", + "@oopsSomethingWentWrong": { + "type": "text", + "placeholders": {} + }, + "oopsPushError": "Hoips! Ar an drochuair, tharla earráid nuair a bhí na fógraí brú á mbunú.", + "@oopsPushError": { + "type": "text", + "placeholders": {} + }, + "onlineKeyBackupEnabled": "Tá Cúltaca Eochair Ar Líne cumasaithe", + "@onlineKeyBackupEnabled": { + "type": "text", + "placeholders": {} + }, + "numUsersTyping": "Tá {count} úsáideoirí ag clóscríobh…", + "@numUsersTyping": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "notificationsEnabledForThisAccount": "Fógraí cumasaithe don chuntas seo", + "@notificationsEnabledForThisAccount": { + "type": "text", + "placeholders": {} + }, + "noRoomsFound": "Níor aimsíodh aon seomraí…", + "@noRoomsFound": { + "type": "text", + "placeholders": {} + }, + "noPasswordRecoveryDescription": "Níor chuir tú bealach leis do phasfhocal a aisghabháil fós.", + "@noPasswordRecoveryDescription": { + "type": "text", + "placeholders": {} + }, + "inviteForMe": "Tabhair cuireadh dom", + "@inviteForMe": { + "type": "text", + "placeholders": {} + }, + "ignoreListDescription": "Is féidir leat neamhaird a dhéanamh d'úsáideoirí atá ag cur isteach ort. Ní bheidh tú in ann aon teachtaireachtaí nó cuireadh seomra a fháil ó na húsáideoirí ar do liosta neamhaird phearsanta.", + "@ignoreListDescription": { + "type": "text", + "placeholders": {} + }, + "weSentYouAnEmail": "Sheolamar ríomhphost chugat", + "@weSentYouAnEmail": { + "type": "text", + "placeholders": {} + }, + "waitingPartnerNumbers": "Ag fanacht le comhpháirtí glacadh leis na huimhreacha …", + "@waitingPartnerNumbers": { + "type": "text", + "placeholders": {} + }, + "waitingPartnerEmoji": "Ag fanacht le comhpháirtí glacadh leis na straoiseoga…", + "@waitingPartnerEmoji": { + "type": "text", + "placeholders": {} + }, + "waitingPartnerAcceptRequest": "Ag fanacht le comhpháirtí glacadh leis an iarratas…", + "@waitingPartnerAcceptRequest": { + "type": "text", + "placeholders": {} + }, + "visibleForEveryone": "Infheicthe do gach duine", + "@visibleForEveryone": { + "type": "text", + "placeholders": {} + }, + "visibleForAllParticipants": "Infheicthe do na rannpháirtithe go léir", + "@visibleForAllParticipants": { + "type": "text", + "placeholders": {} + }, + "visibilityOfTheChatHistory": "Infheictheacht stair na comhrá", + "@visibilityOfTheChatHistory": { + "type": "text", + "placeholders": {} + }, + "verifyTitle": "Ag fíorú cuntas eile", + "@verifyTitle": { + "type": "text", + "placeholders": {} + }, + "userSentUnknownEvent": "Sheol {username} imeacht {type}", + "@userSentUnknownEvent": { + "type": "text", + "placeholders": { + "username": {}, + "type": {} + } + }, + "userIsTyping": "Tá {username} ag clóscríobh…", + "@userIsTyping": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "unknownEvent": "Imeacht anaithnid '{type}'", + "@unknownEvent": { + "type": "text", + "placeholders": { + "type": {} + } + }, + "synchronizingPleaseWait": "Ag sioncrónú... Fan, le do thoil.", + "@synchronizingPleaseWait": { + "type": "text", + "placeholders": {} + }, + "startedACall": "Thosaigh {senderName} glao", + "@startedACall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "spaceIsPublic": "Tá an spás poiblí", + "@spaceIsPublic": { + "type": "text", + "placeholders": {} + }, + "singlesignon": "Sínigh Aonair ar", + "@singlesignon": { + "type": "text", + "placeholders": {} + }, + "sentAnAudio": "Sheol {username} fuaim", + "@sentAnAudio": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sentAFile": "Sheol {username} comhad", + "@sentAFile": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sendAsText": "Seol mar théacs", + "@sendAsText": { + "type": "text" + }, + "sendAMessage": "Seol teachtaireacht", + "@sendAMessage": { + "type": "text", + "placeholders": {} + }, + "seenByUser": "Le feiceáil ag {username}", + "@seenByUser": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "roomHasBeenUpgraded": "Uasghrádaíodh an seomra", + "@roomHasBeenUpgraded": { + "type": "text", + "placeholders": {} + }, + "addAccount": "Breisigh cuntas", + "@addAccount": {}, + "enableMultiAccounts": "(BÉITE) Cumasaigh cuntais iomadúla ar an gléas seo", + "@enableMultiAccounts": {}, + "commandHint_create": "Cruthaigh comhrá grúpa folamh\nÚsáid --no-encryption chun criptiúchán a dhíchumasú", + "@commandHint_create": { + "type": "text", + "description": "Usage hint for the command /create" + }, + "link": "Nasc", + "@link": {}, + "commandHint_clearcache": "Glan an taisce", + "@commandHint_clearcache": { + "type": "text", + "description": "Usage hint for the command /clearcache" + }, + "videoCallsBetaWarning": "Tabhair faoi deara go bhfuil físglaonna i béite. B'fhéidir nach bhfeidhmíonn siad ar gach ardán chomh atá súil aige ná ar bith.", + "@videoCallsBetaWarning": {}, + "emailOrUsername": "Ríomhphost nó ainm úsáideora", + "@emailOrUsername": {}, + "passwordsDoNotMatch": "Níl na pasfhocail chéanna!", + "@passwordsDoNotMatch": {}, + "pleaseEnterValidEmail": "Iontráil ríomhphost bailí le do thoil.", + "@pleaseEnterValidEmail": {}, + "repeatPassword": "Scríobh an pasfhocal arís", + "@repeatPassword": {}, + "pleaseChooseAtLeastChars": "Roghnaigh {min} carachtar ar a laghad.", + "@pleaseChooseAtLeastChars": { + "type": "text", + "placeholders": { + "min": {} + } + }, + "bubbleSize": "Méid na mbolgán cainte", + "@bubbleSize": { + "type": "text", + "placeholders": {} + }, + "yourChatBackupHasBeenSetUp": "Bunaíodh do chúltaca comhrá.", + "@yourChatBackupHasBeenSetUp": {}, + "openVideoCamera": "Oscail físcheamara", + "@openVideoCamera": { + "type": "text", + "placeholders": {} + }, + "discover": "", + "@discover": { + "type": "text", + "placeholders": {} + }, + "hugContent": "", + "@hugContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "jumpToLastReadMessage": "", + "@jumpToLastReadMessage": {}, + "allRooms": "", + "@allRooms": { + "type": "text", + "placeholders": {} + }, + "whoCanSeeMyStories": "", + "@whoCanSeeMyStories": {}, + "commandHint_cuddle": "", + "@commandHint_cuddle": {}, + "widgetVideo": "", + "@widgetVideo": {}, + "dismiss": "", + "@dismiss": {}, + "reportErrorDescription": "", + "@reportErrorDescription": {}, + "unsupportedAndroidVersion": "", + "@unsupportedAndroidVersion": {}, + "widgetJitsi": "", + "@widgetJitsi": {}, + "messageType": "", + "@messageType": {}, + "noEmailWarning": "", + "@noEmailWarning": {}, + "indexedDbErrorLong": "", + "@indexedDbErrorLong": {}, + "oneClientLoggedOut": "", + "@oneClientLoggedOut": {}, + "startFirstChat": "", + "@startFirstChat": {}, + "callingAccount": "", + "@callingAccount": {}, + "setColorTheme": "", + "@setColorTheme": {}, + "nextAccount": "", + "@nextAccount": {}, + "allSpaces": "", + "@allSpaces": {}, + "supposedMxid": "", + "@supposedMxid": { + "type": "text", + "placeholders": { + "mxid": {} + } + }, + "user": "", + "@user": {}, + "youAcceptedTheInvitation": "", + "@youAcceptedTheInvitation": {}, + "youInvitedBy": "", + "@youInvitedBy": { + "placeholders": { + "user": {} + } + }, + "banUserDescription": "", + "@banUserDescription": {}, + "requests": "", + "@requests": {}, + "widgetEtherpad": "", + "@widgetEtherpad": {}, + "stories": "", + "@stories": {}, + "addToStory": "", + "@addToStory": {}, + "removeDevicesDescription": "", + "@removeDevicesDescription": {}, + "separateChatTypes": "", + "@separateChatTypes": { + "type": "text", + "placeholders": {} + }, + "tryAgain": "", + "@tryAgain": {}, + "youKickedAndBanned": "", + "@youKickedAndBanned": { + "placeholders": { + "user": {} + } + }, + "showDirectChatsInSpaces": "", + "@showDirectChatsInSpaces": { + "type": "text", + "placeholders": {} + }, + "unbanUserDescription": "", + "@unbanUserDescription": {}, + "todoLists": "", + "@todoLists": {}, + "youRejectedTheInvitation": "", + "@youRejectedTheInvitation": {}, + "otherCallingPermissions": "", + "@otherCallingPermissions": {}, + "messagesStyle": "", + "@messagesStyle": {}, + "widgetUrlError": "", + "@widgetUrlError": {}, + "newSpaceDescription": "", + "@newSpaceDescription": {}, + "chatDescription": "", + "@chatDescription": {}, + "callingAccountDetails": "", + "@callingAccountDetails": {}, + "enterSpace": "", + "@enterSpace": {}, + "encryptThisChat": "", + "@encryptThisChat": {}, + "previousAccount": "", + "@previousAccount": {}, + "reopenChat": "", + "@reopenChat": {}, + "pleaseEnterRecoveryKey": "", + "@pleaseEnterRecoveryKey": {}, + "widgetNameError": "", + "@widgetNameError": {}, + "addToBundle": "", + "@addToBundle": {}, + "addWidget": "", + "@addWidget": {}, + "countFiles": "", + "@countFiles": { + "placeholders": { + "count": {} + } + }, + "noKeyForThisMessage": "", + "@noKeyForThisMessage": {}, + "commandHint_markasgroup": "", + "@commandHint_markasgroup": {}, + "editTodo": "", + "@editTodo": {}, + "hydrateTor": "", + "@hydrateTor": {}, + "pushNotificationsNotAvailable": "", + "@pushNotificationsNotAvailable": {}, + "storeInAppleKeyChain": "", + "@storeInAppleKeyChain": {}, + "hydrate": "", + "@hydrate": {}, + "invalidServerName": "", + "@invalidServerName": {}, + "chatPermissions": "", + "@chatPermissions": {}, + "sender": "", + "@sender": {}, + "storeInAndroidKeystore": "", + "@storeInAndroidKeystore": {}, + "signInWithPassword": "", + "@signInWithPassword": {}, + "pleaseAddATitle": "", + "@pleaseAddATitle": {}, + "updateNow": "", + "@updateNow": {}, + "makeAdminDescription": "", + "@makeAdminDescription": {}, + "saveKeyManuallyDescription": "", + "@saveKeyManuallyDescription": {}, + "editBundlesForAccount": "", + "@editBundlesForAccount": {}, + "whyIsThisMessageEncrypted": "", + "@whyIsThisMessageEncrypted": {}, + "setChatDescription": "", + "@setChatDescription": {}, + "importFromZipFile": "", + "@importFromZipFile": {}, + "dehydrateWarning": "", + "@dehydrateWarning": {}, + "noOtherDevicesFound": "", + "@noOtherDevicesFound": {}, + "addDescription": "", + "@addDescription": {}, + "redactedBy": "", + "@redactedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "storyPrivacyWarning": "", + "@storyPrivacyWarning": {}, + "matrixWidgets": "", + "@matrixWidgets": {}, + "signInWith": "", + "@signInWith": { + "type": "text", + "placeholders": { + "provider": {} + } + }, + "updateAvailable": "", + "@updateAvailable": {}, + "fileIsTooBigForServer": "", + "@fileIsTooBigForServer": {}, + "noTodosYet": "", + "@noTodosYet": {}, + "callingPermissions": "", + "@callingPermissions": {}, + "readUpToHere": "", + "@readUpToHere": {}, + "start": "", + "@start": {}, + "unlockOldMessages": "", + "@unlockOldMessages": {}, + "numChats": "", + "@numChats": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "whatIsGoingOn": "", + "@whatIsGoingOn": {}, + "optionalRedactReason": "", + "@optionalRedactReason": {}, + "dehydrate": "", + "@dehydrate": {}, + "archiveRoomDescription": "", + "@archiveRoomDescription": {}, + "exportEmotePack": "", + "@exportEmotePack": {}, + "switchToAccount": "", + "@switchToAccount": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "letsStart": "", + "@letsStart": {}, + "experimentalVideoCalls": "", + "@experimentalVideoCalls": {}, + "savedEmotePack": "", + "@savedEmotePack": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "pleaseEnterRecoveryKeyDescription": "", + "@pleaseEnterRecoveryKeyDescription": {}, + "inviteContactToGroupQuestion": "", + "@inviteContactToGroupQuestion": {}, + "redactedByBecause": "", + "@redactedByBecause": { + "type": "text", + "placeholders": { + "username": {}, + "reason": {} + } + }, + "youHaveWithdrawnTheInvitationFor": "", + "@youHaveWithdrawnTheInvitationFor": { + "placeholders": { + "user": {} + } + }, + "appearOnTopDetails": "", + "@appearOnTopDetails": {}, + "enterRoom": "", + "@enterRoom": {}, + "reportUser": "", + "@reportUser": {}, + "confirmEventUnpin": "", + "@confirmEventUnpin": {}, + "youInvitedUser": "", + "@youInvitedUser": { + "placeholders": { + "user": {} + } + }, + "fileHasBeenSavedAt": "", + "@fileHasBeenSavedAt": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "importZipFile": "", + "@importZipFile": {}, + "anyoneCanKnock": "", + "@anyoneCanKnock": {}, + "redactMessageDescription": "", + "@redactMessageDescription": {}, + "recoveryKey": "", + "@recoveryKey": {}, + "commandHint_discardsession": "", + "@commandHint_discardsession": { + "type": "text", + "description": "Usage hint for the command /discardsession" + }, + "invalidInput": "", + "@invalidInput": {}, + "todosUnencrypted": "", + "@todosUnencrypted": {}, + "dehydrateTorLong": "", + "@dehydrateTorLong": {}, + "replyHasBeenSent": "", + "@replyHasBeenSent": {}, + "doNotShowAgain": "", + "@doNotShowAgain": {}, + "report": "", + "@report": {}, + "yourStory": "", + "@yourStory": {}, + "unverified": "", + "@unverified": {}, + "hideUnimportantStateEvents": "", + "@hideUnimportantStateEvents": {}, + "screenSharingTitle": "", + "@screenSharingTitle": {}, + "widgetCustom": "", + "@widgetCustom": {}, + "addToSpaceDescription": "", + "@addToSpaceDescription": {}, + "googlyEyesContent": "", + "@googlyEyesContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "whoCanSeeMyStoriesDesc": "", + "@whoCanSeeMyStoriesDesc": {}, + "youBannedUser": "", + "@youBannedUser": { + "placeholders": { + "user": {} + } + }, + "unsubscribeStories": "", + "@unsubscribeStories": {}, + "loginWithOneClick": "", + "@loginWithOneClick": {}, + "addChatDescription": "", + "@addChatDescription": {}, + "hasKnocked": "", + "@hasKnocked": { + "placeholders": { + "user": {} + } + }, + "publish": "", + "@publish": {}, + "openLinkInBrowser": "", + "@openLinkInBrowser": {}, + "messageInfo": "", + "@messageInfo": {}, + "disableEncryptionWarning": "", + "@disableEncryptionWarning": {}, + "directChat": "", + "@directChat": {}, + "noOneCanJoin": "", + "@noOneCanJoin": {}, + "wrongPinEntered": "", + "@wrongPinEntered": { + "type": "text", + "placeholders": { + "seconds": {} + } + }, + "sendTypingNotifications": "", + "@sendTypingNotifications": {}, + "inviteGroupChat": "", + "@inviteGroupChat": {}, + "appearOnTop": "", + "@appearOnTop": {}, + "invitePrivateChat": "", + "@invitePrivateChat": {}, + "foregroundServiceRunning": "", + "@foregroundServiceRunning": {}, + "voiceCall": "", + "@voiceCall": {}, + "importEmojis": "", + "@importEmojis": {}, + "wasDirectChatDisplayName": "", + "@wasDirectChatDisplayName": { + "type": "text", + "placeholders": { + "oldDisplayName": {} + } + }, + "noChatDescriptionYet": "", + "@noChatDescriptionYet": {}, + "newTodo": "", + "@newTodo": {}, + "removeFromBundle": "", + "@removeFromBundle": {}, + "confirmMatrixId": "", + "@confirmMatrixId": {}, + "learnMore": "", + "@learnMore": {}, + "notAnImage": "", + "@notAnImage": {}, + "users": "", + "@users": {}, + "openGallery": "", + "@openGallery": {}, + "chatDescriptionHasBeenChanged": "", + "@chatDescriptionHasBeenChanged": {}, + "newGroup": "", + "@newGroup": {}, + "bundleName": "", + "@bundleName": {}, + "dehydrateTor": "", + "@dehydrateTor": {}, + "todoListChangedError": "", + "@todoListChangedError": {}, + "removeFromSpace": "", + "@removeFromSpace": {}, + "enterInviteLinkOrMatrixId": "", + "@enterInviteLinkOrMatrixId": {}, + "roomUpgradeDescription": "", + "@roomUpgradeDescription": {}, + "pleaseEnterANumber": "", + "@pleaseEnterANumber": {}, + "youKicked": "", + "@youKicked": { + "placeholders": { + "user": {} + } + }, + "profileNotFound": "", + "@profileNotFound": {}, + "jump": "", + "@jump": {}, + "reactedWith": "", + "@reactedWith": { + "type": "text", + "placeholders": { + "sender": {}, + "reaction": {} + } + }, + "sorryThatsNotPossible": "", + "@sorryThatsNotPossible": {}, + "storyFrom": "", + "@storyFrom": { + "type": "text", + "placeholders": { + "date": {}, + "body": {} + } + }, + "videoWithSize": "", + "@videoWithSize": { + "type": "text", + "placeholders": { + "size": {} + } + }, + "shareInviteLink": "", + "@shareInviteLink": {}, + "commandHint_markasdm": "", + "@commandHint_markasdm": {}, + "recoveryKeyLost": "", + "@recoveryKeyLost": {}, + "cuddleContent": "", + "@cuddleContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "deviceKeys": "", + "@deviceKeys": {}, + "emoteKeyboardNoRecents": "", + "@emoteKeyboardNoRecents": { + "type": "text", + "placeholders": {} + }, + "endToEndEncryption": "", + "@endToEndEncryption": {}, + "setTheme": "", + "@setTheme": {}, + "youJoinedTheChat": "", + "@youJoinedTheChat": {}, + "thisUserHasNotPostedAnythingYet": "", + "@thisUserHasNotPostedAnythingYet": {}, + "markAsRead": "", + "@markAsRead": {}, + "widgetName": "", + "@widgetName": {}, + "errorAddingWidget": "", + "@errorAddingWidget": {}, + "commandHint_dm": "", + "@commandHint_dm": { + "type": "text", + "description": "Usage hint for the command /dm" + }, + "commandHint_hug": "", + "@commandHint_hug": {}, + "replace": "", + "@replace": {}, + "youUnbannedUser": "", + "@youUnbannedUser": { + "placeholders": { + "user": {} + } + }, + "newSpace": "", + "@newSpace": {}, + "emojis": "", + "@emojis": {}, + "commandHint_googly": "", + "@commandHint_googly": {}, + "pleaseTryAgainLaterOrChooseDifferentServer": "", + "@pleaseTryAgainLaterOrChooseDifferentServer": {}, + "createGroup": "", + "@createGroup": {}, + "hydrateTorLong": "", + "@hydrateTorLong": {}, + "time": "", + "@time": {}, + "custom": "", + "@custom": {}, + "noBackupWarning": "", + "@noBackupWarning": {}, + "editWidgets": "", + "@editWidgets": {}, + "storeInSecureStorageDescription": "", + "@storeInSecureStorageDescription": {}, + "openChat": "", + "@openChat": {}, + "kickUserDescription": "", + "@kickUserDescription": {}, + "importNow": "", + "@importNow": {}, + "pinMessage": "", + "@pinMessage": {}, + "invite": "", + "@invite": {}, + "continueWith": "", + "@continueWith": {}, + "indexedDbErrorTitle": "", + "@indexedDbErrorTitle": {}, + "unsupportedAndroidVersionLong": "", + "@unsupportedAndroidVersionLong": {}, + "storeSecurlyOnThisDevice": "", + "@storeSecurlyOnThisDevice": {}, + "iUnderstand": "", + "@iUnderstand": {}, + "screenSharingDetail": "", + "@screenSharingDetail": {}, + "placeCall": "", + "@placeCall": {} +} diff --git a/assets/l10n/intl_gl.arb b/assets/l10n/intl_gl.arb index 6dec950cf..a514d8fef 100644 --- a/assets/l10n/intl_gl.arb +++ b/assets/l10n/intl_gl.arb @@ -1164,7 +1164,7 @@ "type": "text", "placeholders": {} }, - "noGoogleServicesWarning": "Semella que non tes os servizos de google no teu dispositivo. Ben feito! a túa privacidade agradécecho! Para recibir notificacións push en FluffyChat recomendamos usar https://microg.org/ ou https://unifiedpush.org/.", + "noGoogleServicesWarning": "Semella que non tes Firebase Cloud Messaging dispoñible no teu dispositivo. Para recibir notificacións push recomendamos que instales MicroG ou Unified Push.", "@noGoogleServicesWarning": { "type": "text", "placeholders": {} @@ -2610,5 +2610,54 @@ "@emoteKeyboardNoRecents": { "type": "text", "placeholders": {} - } + }, + "banUserDescription": "Vaise vetar a usuaria na conversa e non poderá entrar outra vez ata que se retire o veto.", + "@banUserDescription": {}, + "removeDevicesDescription": "Vas pechar a sesión neste dispositivo e xa non poderás recibir mensaxes nel.", + "@removeDevicesDescription": {}, + "unbanUserDescription": "A usuaria vai poder entrar outra vez na conversa se quere.", + "@unbanUserDescription": {}, + "todoLists": "(Beta) Lista de tarefas", + "@todoLists": {}, + "editTodo": "Editar tarefa", + "@editTodo": {}, + "pushNotificationsNotAvailable": "Non están dispoñibles as notificacións push", + "@pushNotificationsNotAvailable": {}, + "pleaseAddATitle": "Engade un título", + "@pleaseAddATitle": {}, + "makeAdminDescription": "Cando convirtas a esta usuaria en admin non poderás desfacer a acción xa que terá os mesmos permisos ca ti.", + "@makeAdminDescription": {}, + "noTodosYet": "Non se engadiron tarefas aínda a este chat. Crea primeiro a túa lista de tarefas e comeza a colaborar con outras. 📝", + "@noTodosYet": {}, + "archiveRoomDescription": "Vaise mover o chat ao arquivo. Outras usuarias poderán ver que saíches da conversa.", + "@archiveRoomDescription": {}, + "invalidInput": "Contido non válido!", + "@invalidInput": {}, + "hasKnocked": "déronlle unha labazada a {user}", + "@hasKnocked": { + "placeholders": { + "user": {} + } + }, + "wrongPinEntered": "PIN incorrecto! Inténtao outra vez en {seconds} segundos...", + "@wrongPinEntered": { + "type": "text", + "placeholders": { + "seconds": {} + } + }, + "newTodo": "Nova tarefa", + "@newTodo": {}, + "learnMore": "Saber máis", + "@learnMore": {}, + "todoListChangedError": "Ooi... A lista cambiou mentras ti a editabas.", + "@todoListChangedError": {}, + "roomUpgradeDescription": "Vaise recrear o chat coa nova versión da sala. Todas as participantes recibirán unha notificación para que cambien ao novo chat. Podes ler máis información acerca das versións das salas en https://spec.matrix.org/latest/rooms/", + "@roomUpgradeDescription": {}, + "pleaseEnterANumber": "Escribe un número maior de cero", + "@pleaseEnterANumber": {}, + "kickUserDescription": "A usuaria foi expulsada pero non vetada. En conversas públicas a usuaria pode volver cando queira.", + "@kickUserDescription": {}, + "todosUnencrypted": "", + "@todosUnencrypted": {} } diff --git a/assets/l10n/intl_he.arb b/assets/l10n/intl_he.arb index 3ebece5d2..8982da464 100644 --- a/assets/l10n/intl_he.arb +++ b/assets/l10n/intl_he.arb @@ -1,1412 +1,2648 @@ { - "@@last_modified": "2021-08-14 12:41:10.036931", - "about": "אודות", - "@about": { - "type": "text", - "placeholders": {} - }, - "accept": "קבל", - "@accept": { - "type": "text", - "placeholders": {} - }, - "acceptedTheInvitation": "{username} קיבל את ההזמנה", - "@acceptedTheInvitation": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "account": "חשבון", - "@account": { - "type": "text", - "placeholders": {} - }, - "activatedEndToEndEncryption": "{username} הפעיל הצפנה מקצה לקצה", - "@activatedEndToEndEncryption": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "addGroupDescription": "הוספת תיאור קבוצה", - "@addGroupDescription": { - "type": "text", - "placeholders": {} - }, - "admin": "מנהל", - "@admin": { - "type": "text", - "placeholders": {} - }, - "alias": "כינוי", - "@alias": { - "type": "text", - "placeholders": {} - }, - "answeredTheCall": "{senderName} ענה לשיחה", - "@answeredTheCall": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "anyoneCanJoin": "כל אחד יכול להצטרף", - "@anyoneCanJoin": { - "type": "text", - "placeholders": {} - }, - "archive": "ארכיון", - "@archive": { - "type": "text", - "placeholders": {} - }, - "areGuestsAllowedToJoin": "האם משתמשים אורחים מורשים להצטרף", - "@areGuestsAllowedToJoin": { - "type": "text", - "placeholders": {} - }, - "areYouSure": "האם אתה בטוח?", - "@areYouSure": { - "type": "text", - "placeholders": {} - }, - "askSSSSSign": "כדי שתוכל לחתום על משתמש אחר , הזן את הסיסמה שלך או את מפתח השחזור.", - "@askSSSSSign": { - "type": "text", - "placeholders": {} - }, - "askVerificationRequest": "לקבל בקשת אימות זו מ- {username}?", - "@askVerificationRequest": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changePassword": "שנה סיסמא", - "@changePassword": { - "type": "text", - "placeholders": {} - }, - "appLock": "נעילת אפליקציה", - "@appLock": { - "type": "text", - "placeholders": {} - }, - "cancel": "ביטול", - "@cancel": { - "type": "text", - "placeholders": {} - }, - "pleaseChooseAtLeastChars": "אנא כתוב לפחות {min} תווים", - "@pleaseChooseAtLeastChars": { - "type": "text", - "placeholders": { - "min": {} - } - }, - "addEmail": "הוסף מייל", - "@addEmail": { - "type": "text", - "placeholders": {} - }, - "all": "הכל", - "@all": { - "type": "text", - "placeholders": {} - }, - "allChats": "כל הצ'אטים", - "@allChats": { - "type": "text", - "placeholders": {} - }, - "banned": "חסום", - "@banned": { - "type": "text", - "placeholders": {} - }, - "sendOnEnter": "שלח בכניסה", - "@sendOnEnter": {}, - "badServerLoginTypesException": "שרת הבית תומך בסוגי הכניסה:\n{serverVersions}\nאבל אפליקציה זו תומכת רק ב:\n{supportedVersions}", - "@badServerLoginTypesException": { - "type": "text", - "placeholders": { - "serverVersions": {}, - "supportedVersions": {} - } - }, - "changedTheGuestAccessRulesTo": "{username} שינה את כללי הגישה לאורחים ל: {rules}", - "@changedTheGuestAccessRulesTo": { - "type": "text", - "placeholders": { - "username": {}, - "rules": {} - } - }, - "changedTheJoinRules": "{username} שינה את כללי ההצטרפות", - "@changedTheJoinRules": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changeWallpaper": "שנה טפט", - "@changeWallpaper": { - "type": "text", - "placeholders": {} - }, - "changedTheChatNameTo": "{username} שינה את שם הצ'אט ל: '{chatname}'", - "@changedTheChatNameTo": { - "type": "text", - "placeholders": { - "username": {}, - "chatname": {} - } - }, - "changedTheRoomInvitationLink": "{username} שינה את קישור ההזמנה", - "@changedTheRoomInvitationLink": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "passwordsDoNotMatch": "הסיסמאות לא תואמות!", - "@passwordsDoNotMatch": {}, - "pleaseEnterValidEmail": "אנא כתוב כתובת אימייל תקינה.", - "@pleaseEnterValidEmail": {}, - "repeatPassword": "כתוב שוב את הסיסמה", - "@repeatPassword": {}, - "areYouSureYouWantToLogout": "האם אתה בטוח שברצונך לצאת?", - "@areYouSureYouWantToLogout": { - "type": "text", - "placeholders": {} - }, - "chat": "צ׳אט", - "@chat": { - "type": "text", - "placeholders": {} - }, - "autoplayImages": "הפעל אוטומטית מדבקות ואנימציות מונפשים", - "@autoplayImages": { - "type": "text", - "placeholder": {} - }, - "badServerVersionsException": "שרת הבית תומך בגרסאות:\n{serverVersions}\nאבל האפליקציה הזו תומכת רק ב-{supportedVersions}", - "@badServerVersionsException": { - "type": "text", - "placeholders": { - "serverVersions": {}, - "supportedVersions": {} - } - }, - "banFromChat": "צאט חסום", - "@banFromChat": { - "type": "text", - "placeholders": {} - }, - "bannedUser": "{username} חסם את {targetName}", - "@bannedUser": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "blockDevice": "חסום מכשיר", - "@blockDevice": { - "type": "text", - "placeholders": {} - }, - "blocked": "חסום", - "@blocked": { - "type": "text", - "placeholders": {} - }, - "botMessages": "הודעות בוט", - "@botMessages": { - "type": "text", - "placeholders": {} - }, - "cantOpenUri": "לא ניתן לפתוח את ה-URI {uri}", - "@cantOpenUri": { - "type": "text", - "placeholders": { - "uri": {} - } - }, - "changeDeviceName": "שנה את שם המכשיר", - "@changeDeviceName": { - "type": "text", - "placeholders": {} - }, - "changedTheChatAvatar": "{username} שינה את האווטאר של הצ'אט", - "@changedTheChatAvatar": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheChatDescriptionTo": "{username} שינה את תיאור הצ'אט ל: '{description}'", - "@changedTheChatDescriptionTo": { - "type": "text", - "placeholders": { - "username": {}, - "description": {} - } - }, - "changedTheChatPermissions": "{username} שינה את הרשאות הצ'אט", - "@changedTheChatPermissions": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheDisplaynameTo": "{username} שינה את שם התצוגה שלו ל: '{displayname}'", - "@changedTheDisplaynameTo": { - "type": "text", - "placeholders": { - "username": {}, - "displayname": {} - } - }, - "changedTheGuestAccessRules": "{username} שינה את כללי הגישה לאורחים", - "@changedTheGuestAccessRules": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheHistoryVisibility": "{username} שינה את נראות ההיסטוריה", - "@changedTheHistoryVisibility": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheHistoryVisibilityTo": "{username} שינה את נראות ההיסטוריה ל: {rules}", - "@changedTheHistoryVisibilityTo": { - "type": "text", - "placeholders": { - "username": {}, - "rules": {} - } - }, - "changedTheJoinRulesTo": "{username} שינה את כללי ההצטרפות ל: {joinRules}", - "@changedTheJoinRulesTo": { - "type": "text", - "placeholders": { - "username": {}, - "joinRules": {} - } - }, - "changedTheProfileAvatar": "{username} שינה את האווטאר שלו", - "@changedTheProfileAvatar": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheRoomAliases": "{username} שינה את כינוי החדר", - "@changedTheRoomAliases": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changeTheHomeserver": "שנה את שרת הבית", - "@changeTheHomeserver": { - "type": "text", - "placeholders": {} - }, - "changeTheme": "שנה את הסגנון שלך", - "@changeTheme": { - "type": "text", - "placeholders": {} - }, - "changeTheNameOfTheGroup": "שנה את שם הקבוצה", - "@changeTheNameOfTheGroup": { - "type": "text", - "placeholders": {} - }, - "changeYourAvatar": "שינוי האווטאר שלך", - "@changeYourAvatar": { - "type": "text", - "placeholders": {} - }, - "channelCorruptedDecryptError": "ההצפנה נפגמה", - "@channelCorruptedDecryptError": { - "type": "text", - "placeholders": {} - }, - "yourChatBackupHasBeenSetUp": "גיבוי הצ'אט שלך הוגדר.", - "@yourChatBackupHasBeenSetUp": {}, - "chatBackup": "גיבוי צ'אט", - "@chatBackup": { - "type": "text", - "placeholders": {} - }, - "commandHint_ban": "חסום את המשתמש הנתון מהחדר הזה", - "@commandHint_ban": { - "type": "text", - "description": "Usage hint for the command /ban" - }, - "commandHint_clearcache": "נקה מטמון", - "@commandHint_clearcache": { - "type": "text", - "description": "Usage hint for the command /clearcache" - }, - "commandHint_create": "צור צ'אט קבוצתי ריק\nהשתמש ב--no-encryption כדי להשבית את ההצפנה", - "@commandHint_create": { - "type": "text", - "description": "Usage hint for the command /create" - }, - "commandHint_discardsession": "התעלם מהסשן", - "@commandHint_discardsession": { - "type": "text", - "description": "Usage hint for the command /discardsession" - }, - "commandHint_dm": "התחל צ'אט ישיר\nהשתמש ב--no-encryption כדי להשבית את ההצפנה", - "@commandHint_dm": { - "type": "text", - "description": "Usage hint for the command /dm" - }, - "commandHint_html": "שלח טקסט בתבנית HTML", - "@commandHint_html": { - "type": "text", - "description": "Usage hint for the command /html" - }, - "commandHint_invite": "הזמן את המשתמש הנתון לחדר זה", - "@commandHint_invite": { - "type": "text", - "description": "Usage hint for the command /invite" - }, - "commandHint_join": "הצטרף לחדר הנתון", - "@commandHint_join": { - "type": "text", - "description": "Usage hint for the command /join" - }, - "commandHint_kick": "הסר את המשתמש הנתון מהחדר הזה", - "@commandHint_kick": { - "type": "text", - "description": "Usage hint for the command /kick" - }, - "commandHint_leave": "עזוב את החדר הזה", - "@commandHint_leave": { - "type": "text", - "description": "Usage hint for the command /leave" - }, - "commandHint_me": "תאר את עצמך", - "@commandHint_me": { - "type": "text", - "description": "Usage hint for the command /me" - }, - "chatDetails": "פרטי צ'אט", - "@chatDetails": { - "type": "text", - "placeholders": {} - }, - "chatBackupDescription": "גיבוי הצ'אט שלך מאובטח באמצעות מפתח אבטחה. אנא וודא שאתה לא מאבד אותו.", - "@chatBackupDescription": { - "type": "text", - "placeholders": {} - }, - "chatHasBeenAddedToThisSpace": "צ'אט נוסף למרחב הזה", - "@chatHasBeenAddedToThisSpace": {}, - "chats": "צ'אטים", - "@chats": { - "type": "text", - "placeholders": {} - }, - "chooseAStrongPassword": "בחר סיסמה חזקה", - "@chooseAStrongPassword": { - "type": "text", - "placeholders": {} - }, - "chooseAUsername": "בחר שם משתמש", - "@chooseAUsername": { - "type": "text", - "placeholders": {} - }, - "clearArchive": "נקה ארכיון", - "@clearArchive": {}, - "close": "סגור", - "@close": { - "type": "text", - "placeholders": {} - }, - "commandHint_myroomavatar": "הגדר את התמונה שלך לחדר זה (על ידי mxc-uri)", - "@commandHint_myroomavatar": { - "type": "text", - "description": "Usage hint for the command /myroomavatar" - }, - "commandHint_myroomnick": "הגדר את שם התצוגה שלך עבור חדר זה", - "@commandHint_myroomnick": { - "type": "text", - "description": "Usage hint for the command /myroomnick" - }, - "addToSpace": "הוסף לחלל", - "@addToSpace": {}, - "commandHint_unban": "בטל את החסימה של המשתמש הנתון מהחדר הזה", - "@commandHint_unban": { - "type": "text", - "description": "Usage hint for the command /unban" - }, - "countParticipants": "{count} משתתפים", - "@countParticipants": { - "type": "text", - "placeholders": { - "count": {} - } - }, - "create": "צור", - "@create": { - "type": "text", - "placeholders": {} - }, - "createdTheChat": "{username} יצר את הצ'אט", - "@createdTheChat": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "currentlyActive": "פעיל כעת", - "@currentlyActive": { - "type": "text", - "placeholders": {} - }, - "darkTheme": "כהה", - "@darkTheme": { - "type": "text", - "placeholders": {} - }, - "dateAndTimeOfDay": "{date}, {timeOfDay}", - "@dateAndTimeOfDay": { - "type": "text", - "placeholders": { - "date": {}, - "timeOfDay": {} - } - }, - "dateWithoutYear": "{month}-{day}", - "@dateWithoutYear": { - "type": "text", - "placeholders": { - "month": {}, - "day": {} - } - }, - "defaultPermissionLevel": "רמת הרשאת ברירת מחדל", - "@defaultPermissionLevel": { - "type": "text", - "placeholders": {} - }, - "deleteAccount": "מחק חשבון", - "@deleteAccount": { - "type": "text", - "placeholders": {} - }, - "deleteMessage": "מחק הודעה", - "@deleteMessage": { - "type": "text", - "placeholders": {} - }, - "deny": "דחה", - "@deny": { - "type": "text", - "placeholders": {} - }, - "deviceId": "מזהה מכשיר", - "@deviceId": { - "type": "text", - "placeholders": {} - }, - "devices": "התקנים", - "@devices": { - "type": "text", - "placeholders": {} - }, - "directChats": "צ'אטים ישירים", - "@directChats": { - "type": "text", - "placeholders": {} - }, - "downloadFile": "הורד קובץ", - "@downloadFile": { - "type": "text", - "placeholders": {} - }, - "edit": "ערוך", - "@edit": { - "type": "text", - "placeholders": {} - }, - "editChatPermissions": "ערוך הרשאות צ'אט", - "@editChatPermissions": { - "type": "text", - "placeholders": {} - }, - "editDisplayname": "ערוך את שם התצוגה", - "@editDisplayname": { - "type": "text", - "placeholders": {} - }, - "editRoomAliases": "ערוך כינויים לחדר", - "@editRoomAliases": { - "type": "text", - "placeholders": {} - }, - "emoteExists": "אימוט כבר קיים!", - "@emoteExists": { - "type": "text", - "placeholders": {} - }, - "emptyChat": "צ'אט ריק", - "@emptyChat": { - "type": "text", - "placeholders": {} - }, - "encrypted": "מוצפן", - "@encrypted": { - "type": "text", - "placeholders": {} - }, - "enterAGroupName": "הזן שם קבוצה", - "@enterAGroupName": { - "type": "text", - "placeholders": {} - }, - "enterAnEmailAddress": "הזן כתובת דואר אלקטרוני", - "@enterAnEmailAddress": { - "type": "text", - "placeholders": {} - }, - "enterASpacepName": "הזן שם חלל", - "@enterASpacepName": {}, - "enterYourHomeserver": "הזן את שרת הבית שלך", - "@enterYourHomeserver": { - "type": "text", - "placeholders": {} - }, - "everythingReady": "הכל מוכן!", - "@everythingReady": { - "type": "text", - "placeholders": {} - }, - "fileName": "שם קובץ", - "@fileName": { - "type": "text", - "placeholders": {} - }, - "fluffychat": "FluffyChat", - "@fluffychat": { - "type": "text", - "placeholders": {} - }, - "fontSize": "גודל גופן", - "@fontSize": { - "type": "text", - "placeholders": {} - }, - "forward": "העבר", - "@forward": { - "type": "text", - "placeholders": {} - }, - "fromJoining": "מהצטרפות", - "@fromJoining": { - "type": "text", - "placeholders": {} - }, - "fromTheInvitation": "מההזמנה", - "@fromTheInvitation": { - "type": "text", - "placeholders": {} - }, - "goToTheNewRoom": "עבור לחדר החדש", - "@goToTheNewRoom": { - "type": "text", - "placeholders": {} - }, - "groupDescription": "תיאור קבוצה", - "@groupDescription": { - "type": "text", - "placeholders": {} - }, - "groupDescriptionHasBeenChanged": "תיאור הקבוצה השתנה", - "@groupDescriptionHasBeenChanged": { - "type": "text", - "placeholders": {} - }, - "groupIsPublic": "הקבוצה ציבורית", - "@groupIsPublic": { - "type": "text", - "placeholders": {} - }, - "groupWith": "קבוצה עם {displayname}", - "@groupWith": { - "type": "text", - "placeholders": { - "displayname": {} - } - }, - "guestsAreForbidden": "אורחים אסורים", - "@guestsAreForbidden": { - "type": "text", - "placeholders": {} - }, - "guestsCanJoin": "אורחים יכולים להצטרף", - "@guestsCanJoin": { - "type": "text", - "placeholders": {} - }, - "id": "מזהה", - "@id": { - "type": "text", - "placeholders": {} - }, - "identity": "זהות", - "@identity": { - "type": "text", - "placeholders": {} - }, - "ignoredUsers": "משתמשים שהתעלמו מהם", - "@ignoredUsers": { - "type": "text", - "placeholders": {} - }, - "incorrectPassphraseOrKey": "ביטוי סיסמה או מפתח שחזור שגויים", - "@incorrectPassphraseOrKey": { - "type": "text", - "placeholders": {} - }, - "inviteContact": "הזמן איש קשר", - "@inviteContact": { - "type": "text", - "placeholders": {} - }, - "invited": "הזמין", - "@invited": { - "type": "text", - "placeholders": {} - }, - "invitedUser": "{username} הזמין את {targetName}", - "@invitedUser": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "invitedUsersOnly": "משתמשים מוזמנים בלבד", - "@invitedUsersOnly": { - "type": "text", - "placeholders": {} - }, - "inviteForMe": "הזמנה בשבילי", - "@inviteForMe": { - "type": "text", - "placeholders": {} - }, - "inviteText": "{username} הזמין אותך ל-FluffyChat.\n1. התקן את FluffyChat: https://fluffychat.im\n2. הירשם או היכנס\n3. פתח את קישור ההזמנה: {link}", - "@inviteText": { - "type": "text", - "placeholders": { - "username": {}, - "link": {} - } - }, - "isTyping": "מקליד/ה…", - "@isTyping": { - "type": "text", - "placeholders": {} - }, - "joinedTheChat": "{username} הצטרף לצ'אט", - "@joinedTheChat": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "joinRoom": "הצטרף לחדר", - "@joinRoom": { - "type": "text", - "placeholders": {} - }, - "kicked": "{username} בעט ב {targetName}", - "@kicked": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "kickedAndBanned": "{username} בעט וחסם {targetName}", - "@kickedAndBanned": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "kickFromChat": "בעיטה מהצ'אט", - "@kickFromChat": { - "type": "text", - "placeholders": {} - }, - "lastActiveAgo": "פעילות אחרונה: {localizedTimeShort}", - "@lastActiveAgo": { - "type": "text", - "placeholders": { - "localizedTimeShort": {} - } - }, - "lastSeenLongTimeAgo": "נראה לפני זמן רב", - "@lastSeenLongTimeAgo": { - "type": "text", - "placeholders": {} - }, - "leftTheChat": "עזב את הצ'אט", - "@leftTheChat": { - "type": "text", - "placeholders": {} - }, - "loadingPleaseWait": "טוען אנא המתן.", - "@loadingPleaseWait": { - "type": "text", - "placeholders": {} - }, - "loadMore": "טען עוד…", - "@loadMore": { - "type": "text", - "placeholders": {} - }, - "locationDisabledNotice": "שירותי המיקום מושבתים. אנא הפעל אותם כדי לשתף את המיקום שלך.", - "@locationDisabledNotice": { - "type": "text", - "placeholders": {} - }, - "copy": "העתק", - "@copy": { - "type": "text", - "placeholders": {} - }, - "commandHint_send": "שלח טקסט", - "@commandHint_send": { - "type": "text", - "description": "Usage hint for the command /send" - }, - "commandHint_op": "הגדרת רמת צריכת החשמל של המשתמש הנתון (ברירת מחדל: 50)", - "@commandHint_op": { - "type": "text", - "description": "Usage hint for the command /op" - }, - "commandHint_plain": "שלח טקסט לא מעוצב", - "@commandHint_plain": { - "type": "text", - "description": "Usage hint for the command /plain" - }, - "commandHint_react": "שלח תשובה כתגובה", - "@commandHint_react": { - "type": "text", - "description": "Usage hint for the command /react" - }, - "createNewGroup": "צור קבוצה חדשה", - "@createNewGroup": { - "type": "text", - "placeholders": {} - }, - "containsUserName": "מכיל שם משתמש", - "@containsUserName": { - "type": "text", - "placeholders": {} - }, - "createNewSpace": "חלל חדש", - "@createNewSpace": { - "type": "text", - "placeholders": {} - }, - "enableEncryption": "אפשר הצפנה", - "@enableEncryption": { - "type": "text", - "placeholders": {} - }, - "inviteContactToGroup": "הזמן איש קשר אל {groupName}", - "@inviteContactToGroup": { - "type": "text", - "placeholders": { - "groupName": {} - } - }, - "dateWithYear": "{year}-{month}-{day}", - "@dateWithYear": { - "type": "text", - "placeholders": { - "year": {}, - "month": {}, - "day": {} - } - }, - "deactivateAccountWarning": "פעולה זו תשבית את חשבון המשתמש שלך. אי אפשר לבטל את זה! האם אתה בטוח?", - "@deactivateAccountWarning": { - "type": "text", - "placeholders": {} - }, - "device": "מכשיר", - "@device": { - "type": "text", - "placeholders": {} - }, - "group": "קבוצה", - "@group": { - "type": "text", - "placeholders": {} - }, - "displaynameHasBeenChanged": "שם התצוגה השתנה", - "@displaynameHasBeenChanged": { - "type": "text", - "placeholders": {} - }, - "editBlockedServers": "ערוך שרתים חסומים", - "@editBlockedServers": { - "type": "text", - "placeholders": {} - }, - "editRoomAvatar": "עריכת אווטאר של חדר", - "@editRoomAvatar": { - "type": "text", - "placeholders": {} - }, - "endedTheCall": "{senderName} סיים את השיחה", - "@endedTheCall": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "groups": "קבוצות", - "@groups": { - "type": "text", - "placeholders": {} - }, - "enableEncryptionWarning": "לא תוכל לבטל את ההצפנה יותר. האם אתה בטוח?", - "@enableEncryptionWarning": { - "type": "text", - "placeholders": {} - }, - "encryption": "הצפנה", - "@encryption": { - "type": "text", - "placeholders": {} - }, - "errorObtainingLocation": "שגיאה בהשגת מיקום: {error}", - "@errorObtainingLocation": { - "type": "text", - "placeholders": { - "error": {} - } - }, - "hasWithdrawnTheInvitationFor": "{username} ביטל את ההזמנה עבור {targetName}", - "@hasWithdrawnTheInvitationFor": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "hideRedactedEvents": "הסתר אירועים מצונזרים", - "@hideRedactedEvents": { - "type": "text", - "placeholders": {} - }, - "encryptionNotEnabled": "ההצפנה אינה מופעלת", - "@encryptionNotEnabled": { - "type": "text", - "placeholders": {} - }, - "extremeOffensive": "פוגעני ביותר", - "@extremeOffensive": { - "type": "text", - "placeholders": {} - }, - "hideUnknownEvents": "הסתר אירועים לא ידועים", - "@hideUnknownEvents": { - "type": "text", - "placeholders": {} - }, - "loadCountMoreParticipants": "טען {count} משתתפים נוספים", - "@loadCountMoreParticipants": { - "type": "text", - "placeholders": { - "count": {} - } - }, - "homeserver": "שרת בית", - "@homeserver": {}, - "ignore": "התעלם", - "@ignore": { - "type": "text", - "placeholders": {} - }, - "ignoreListDescription": "באפשרותך להתעלם ממשתמשים שמפריעים לך. לא תוכל לקבל הודעות או הזמנות לחדר מהמשתמשים ברשימת ההתעלם האישית שלך.", - "@ignoreListDescription": { - "type": "text", - "placeholders": {} - }, - "ignoreUsername": "התעלם משם משתמש", - "@ignoreUsername": { - "type": "text", - "placeholders": {} - }, - "iHaveClickedOnLink": "לחצתי על הקישור", - "@iHaveClickedOnLink": { - "type": "text", - "placeholders": {} - }, - "leave": "לעזוב", - "@leave": { - "type": "text", - "placeholders": {} - }, - "license": "רשיון", - "@license": { - "type": "text", - "placeholders": {} - }, - "lightTheme": "בהיר", - "@lightTheme": { - "type": "text", - "placeholders": {} - }, - "delete": "מחיקה", - "@delete": { - "type": "text", - "placeholders": {} - }, - "inoffensive": "לֹא פּוֹגֵעַ", - "@inoffensive": { - "type": "text", - "placeholders": {} - }, - "configureChat": "קביעת תצורה של צ'אט", - "@configureChat": { - "type": "text", - "placeholders": {} - }, - "confirm": "לאשר", - "@confirm": { - "type": "text", - "placeholders": {} - }, - "connect": "התחבר", - "@connect": { - "type": "text", - "placeholders": {} - }, - "contactHasBeenInvitedToTheGroup": "איש הקשר הוזמן לקבוצה", - "@contactHasBeenInvitedToTheGroup": { - "type": "text", - "placeholders": {} - }, - "containsDisplayName": "מכיל שם תצוגה", - "@containsDisplayName": { - "type": "text", - "placeholders": {} - }, - "contentHasBeenReported": "התוכן דווח למנהלי השרת", - "@contentHasBeenReported": { - "type": "text", - "placeholders": {} - }, - "copiedToClipboard": "הועתק ללוח הגזירים", - "@copiedToClipboard": { - "type": "text", - "placeholders": {} - }, - "commandInvalid": "הפקודה אינה חוקית", - "@commandInvalid": { - "type": "text" - }, - "commandMissing": "{command} אינו פקודה.", - "@commandMissing": { - "type": "text", - "placeholders": { - "command": {} - }, - "description": "State that {command} is not a valid /command." - }, - "compareEmojiMatch": "השווה וודא שהאימוג'י הבאים תואמים לאלו של המכשיר השני:", - "@compareEmojiMatch": { - "type": "text", - "placeholders": {} - }, - "compareNumbersMatch": "השווה וודא שהמספרים הבאים תואמים לאלה של המכשיר השני:", - "@compareNumbersMatch": { - "type": "text", - "placeholders": {} - }, - "copyToClipboard": "העתק ללוח", - "@copyToClipboard": { - "type": "text", - "placeholders": {} - }, - "couldNotDecryptMessage": "לא ניתן לפענח הודעה: {error}", - "@couldNotDecryptMessage": { - "type": "text", - "placeholders": { - "error": {} - } - }, - "help": "עזרה", - "@help": { - "type": "text", - "placeholders": {} - }, - "howOffensiveIsThisContent": "עד כמה התוכן הזה פוגעני?", - "@howOffensiveIsThisContent": { - "type": "text", - "placeholders": {} - }, - "locationPermissionDeniedNotice": "הרשאת המיקום נדחתה. אנא אפשר את היכולת לשתף את מיקומך.", - "@locationPermissionDeniedNotice": { - "type": "text", - "placeholders": {} - }, - "login": "כניסה", - "@login": { - "type": "text", - "placeholders": {} - }, - "moderator": "מנחה", - "@moderator": { - "type": "text", - "placeholders": {} - }, - "needPantalaimonWarning": "שים לב שאתה צריך Pantalaimon כדי להשתמש בהצפנה מקצה לקצה לעת עתה.", - "@needPantalaimonWarning": { - "type": "text", - "placeholders": {} - }, - "newChat": "צ'אט חדש", - "@newChat": { - "type": "text", - "placeholders": {} - }, - "newVerificationRequest": "בקשת אימות חדשה!", - "@newVerificationRequest": { - "type": "text", - "placeholders": {} - }, - "next": "הבא", - "@next": { - "type": "text", - "placeholders": {} - }, - "no": "לא", - "@no": { - "type": "text", - "placeholders": {} - }, - "noConnectionToTheServer": "אין חיבור לשרת", - "@noConnectionToTheServer": { - "type": "text", - "placeholders": {} - }, - "noEncryptionForPublicRooms": "אתה יכול להפעיל הצפנה רק כשהחדר כבר לא נגיש לציבור.", - "@noEncryptionForPublicRooms": { - "type": "text", - "placeholders": {} - }, - "shareYourInviteLink": "שתף את קישור ההזמנה שלך", - "@shareYourInviteLink": {}, - "noRoomsFound": "לא נמצאו חדרים…", - "@noRoomsFound": { - "type": "text", - "placeholders": {} - }, - "notifications": "התראות", - "@notifications": { - "type": "text", - "placeholders": {} - }, - "numUsersTyping": "{count} משתמשים מקלידים…", - "@numUsersTyping": { - "type": "text", - "placeholders": { - "count": {} - } - }, - "obtainingLocation": "משיג מיקום…", - "@obtainingLocation": { - "type": "text", - "placeholders": {} - }, - "onlineKeyBackupEnabled": "גיבוי מפתח מקוון מופעל", - "@onlineKeyBackupEnabled": { - "type": "text", - "placeholders": {} - }, - "oopsPushError": "אופס! למרבה הצער, אירעה שגיאה בעת הגדרת התראות.", - "@oopsPushError": { - "type": "text", - "placeholders": {} - }, - "oopsSomethingWentWrong": "אופס, משהו השתבש…", - "@oopsSomethingWentWrong": { - "type": "text", - "placeholders": {} - }, - "openAppToReadMessages": "פתח את האפליקציה לקריאת הודעות", - "@openAppToReadMessages": { - "type": "text", - "placeholders": {} - }, - "oneClientLoggedOut": "אחד מהמכשירים שלך התנתק", - "@oneClientLoggedOut": {}, - "addAccount": "הוסף חשבון", - "@addAccount": {}, - "editBundlesForAccount": "ערוך חבילות עבור חשבון זה", - "@editBundlesForAccount": {}, - "participant": "משתתף", - "@participant": { - "type": "text", - "placeholders": {} - }, - "password": "סיסמה", - "@password": { - "type": "text", - "placeholders": {} - }, - "pleaseClickOnLink": "אנא לחץ על הקישור במייל ולאחר מכן המשך.", - "@pleaseClickOnLink": { - "type": "text", - "placeholders": {} - }, - "pleaseEnter4Digits": "אנא הזן 4 ספרות או השאר ריק כדי להשבית את נעילת האפליקציה.", - "@pleaseEnter4Digits": { - "type": "text", - "placeholders": {} - }, - "loginWithOneClick": "היכנס בלחיצה אחת", - "@loginWithOneClick": {}, - "online": "מחובר/ת", - "@online": { - "type": "text", - "placeholders": {} - }, - "addToBundle": "הוסף לחבילה", - "@addToBundle": {}, - "optionalGroupName": "(אופציונלי) שם קבוצה", - "@optionalGroupName": { - "type": "text", - "placeholders": {} - }, - "passphraseOrKey": "ביטוי סיסמה או מפתח שחזור", - "@passphraseOrKey": { - "type": "text", - "placeholders": {} - }, - "passwordForgotten": "שכחתי סיסמה", - "@passwordForgotten": { - "type": "text", - "placeholders": {} - }, - "passwordHasBeenChanged": "הסיסמה שונתה", - "@passwordHasBeenChanged": { - "type": "text", - "placeholders": {} - }, - "passwordRecovery": "שחזור סיסמה", - "@passwordRecovery": { - "type": "text", - "placeholders": {} - }, - "people": "אנשים", - "@people": { - "type": "text", - "placeholders": {} - }, - "pickImage": "בחר תמונה", - "@pickImage": { - "type": "text", - "placeholders": {} - }, - "play": "הפעל {fileName}", - "@play": { - "type": "text", - "placeholders": { - "fileName": {} - } - }, - "pleaseChoose": "אנא בחר", - "@pleaseChoose": { - "type": "text", - "placeholders": {} - }, - "pleaseChooseAPasscode": "אנא בחר קוד גישה", - "@pleaseChooseAPasscode": { - "type": "text", - "placeholders": {} - }, - "pleaseChooseAUsername": "אנא בחר שם משתמש", - "@pleaseChooseAUsername": { - "type": "text", - "placeholders": {} - }, - "pleaseEnterAMatrixIdentifier": "אנא הזן Matrix ID.", - "@pleaseEnterAMatrixIdentifier": { - "type": "text", - "placeholders": {} - }, - "pleaseEnterYourPassword": "נא הזן את הסיסמה שלך", - "@pleaseEnterYourPassword": { - "type": "text", - "placeholders": {} - }, - "pleaseEnterYourPin": "אנא הזן את קוד הpin שלך", - "@pleaseEnterYourPin": { - "type": "text", - "placeholders": {} - }, - "pin": "קוד pin", - "@pin": { - "type": "text", - "placeholders": {} - }, - "pleaseEnterYourUsername": "אנא הזן שם משתמש", - "@pleaseEnterYourUsername": { - "type": "text", - "placeholders": {} - }, - "newMessageInFluffyChat": "הודעה חדשה ב-FluffyChat", - "@newMessageInFluffyChat": { - "type": "text", - "placeholders": {} - }, - "noGoogleServicesWarning": "נראה שאין לך שירותי גוגל בטלפון שלך. זו החלטה טובה לפרטיות שלך! כדי לקבל התרעות ב- FluffyChat אנו ממליצים להשתמש https://microg.org/ או https://unifiedpush.org/.", - "@noGoogleServicesWarning": { - "type": "text", - "placeholders": {} - }, - "noMatrixServer": "{server1} אינו שרת מטריקס, השתמש ב-{server2} במקום זאת?", - "@noMatrixServer": { - "type": "text", - "placeholders": { - "server1": {}, - "server2": {} - } - }, - "none": "ללא", - "@none": { - "type": "text", - "placeholders": {} - }, - "noPasswordRecoveryDescription": "עדיין לא הוספת דרך לשחזר את הסיסמה שלך.", - "@noPasswordRecoveryDescription": { - "type": "text", - "placeholders": {} - }, - "offensive": "פוגעני", - "@offensive": { - "type": "text", - "placeholders": {} - }, - "notificationsEnabledForThisAccount": "התראות הופעלו עבור חשבון זה", - "@notificationsEnabledForThisAccount": { - "type": "text", - "placeholders": {} - }, - "bundleName": "שם החבילה", - "@bundleName": {}, - "offline": "לא מקוון", - "@offline": { - "type": "text", - "placeholders": {} - }, - "openVideoCamera": "פתח את המצלמה לסרטון", - "@openVideoCamera": { - "type": "text", - "placeholders": {} - }, - "removeFromBundle": "הסר מחבילה זו", - "@removeFromBundle": {}, - "enableMultiAccounts": "(בטא) אפשר ריבוי חשבונות במכשיר זה", - "@enableMultiAccounts": {}, - "openInMaps": "פתיחה במפות", - "@openInMaps": { - "type": "text", - "placeholders": {} - }, - "link": "קישור", - "@link": {}, - "serverRequiresEmail": "שרת זה צריך לאמת את כתובת הדואר האלקטרוני שלך לרישום.", - "@serverRequiresEmail": {}, - "logout": "יציאה", - "@logout": { - "type": "text", - "placeholders": {} - }, - "muteChat": "השתקת הצ'אט", - "@muteChat": { - "type": "text", - "placeholders": {} - }, - "scanQrCode": "סרוק קוד QR", - "@scanQrCode": {}, - "noPermission": "אין הרשאה", - "@noPermission": { - "type": "text", - "placeholders": {} - }, - "or": "או", - "@or": { - "type": "text", - "placeholders": {} - }, - "logInTo": "היכנס אל {homeserver}", - "@logInTo": { - "type": "text", - "placeholders": { - "homeserver": {} - } - }, - "makeSureTheIdentifierIsValid": "ודא שהמזהה חוקי", - "@makeSureTheIdentifierIsValid": { - "type": "text", - "placeholders": {} - }, - "memberChanges": "שינויים בחבר", - "@memberChanges": { - "type": "text", - "placeholders": {} - }, - "mention": "הזכיר", - "@mention": { - "type": "text", - "placeholders": {} - }, - "messageWillBeRemovedWarning": "ההודעה תוסר עבור כל המשתתפים", - "@messageWillBeRemovedWarning": { - "type": "text", - "placeholders": {} - }, - "messages": "הודעות", - "@messages": { - "type": "text", - "placeholders": {} - }, - "openCamera": "פתח מצלמה", - "@openCamera": { - "type": "text", - "placeholders": {} - }, - "updateAvailable": "עדכון FluffyChat זמין", - "@updateAvailable": {}, - "updateNow": "התחל עדכון ברקע", - "@updateNow": {}, - "bubbleSize": "גודל בועות", - "@bubbleSize": { - "type": "text", - "placeholders": {} + "@@last_modified": "2021-08-14 12:41:10.036931", + "about": "אודות", + "@about": { + "type": "text", + "placeholders": {} + }, + "accept": "קבל", + "@accept": { + "type": "text", + "placeholders": {} + }, + "acceptedTheInvitation": "{username} קיבל את ההזמנה", + "@acceptedTheInvitation": { + "type": "text", + "placeholders": { + "username": {} } -} \ No newline at end of file + }, + "account": "חשבון", + "@account": { + "type": "text", + "placeholders": {} + }, + "activatedEndToEndEncryption": "{username} הפעיל הצפנה מקצה לקצה", + "@activatedEndToEndEncryption": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "addGroupDescription": "הוספת תיאור קבוצה", + "@addGroupDescription": { + "type": "text", + "placeholders": {} + }, + "admin": "מנהל", + "@admin": { + "type": "text", + "placeholders": {} + }, + "alias": "כינוי", + "@alias": { + "type": "text", + "placeholders": {} + }, + "answeredTheCall": "{senderName} ענה לשיחה", + "@answeredTheCall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "anyoneCanJoin": "כל אחד יכול להצטרף", + "@anyoneCanJoin": { + "type": "text", + "placeholders": {} + }, + "archive": "ארכיון", + "@archive": { + "type": "text", + "placeholders": {} + }, + "areGuestsAllowedToJoin": "האם משתמשים אורחים מורשים להצטרף", + "@areGuestsAllowedToJoin": { + "type": "text", + "placeholders": {} + }, + "areYouSure": "האם אתה בטוח?", + "@areYouSure": { + "type": "text", + "placeholders": {} + }, + "askSSSSSign": "כדי שתוכל לחתום על משתמש אחר , הזן את הסיסמה שלך או את מפתח השחזור.", + "@askSSSSSign": { + "type": "text", + "placeholders": {} + }, + "askVerificationRequest": "לקבל בקשת אימות זו מ- {username}?", + "@askVerificationRequest": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changePassword": "שנה סיסמא", + "@changePassword": { + "type": "text", + "placeholders": {} + }, + "appLock": "נעילת אפליקציה", + "@appLock": { + "type": "text", + "placeholders": {} + }, + "cancel": "ביטול", + "@cancel": { + "type": "text", + "placeholders": {} + }, + "pleaseChooseAtLeastChars": "אנא כתוב לפחות {min} תווים", + "@pleaseChooseAtLeastChars": { + "type": "text", + "placeholders": { + "min": {} + } + }, + "addEmail": "הוסף מייל", + "@addEmail": { + "type": "text", + "placeholders": {} + }, + "all": "הכל", + "@all": { + "type": "text", + "placeholders": {} + }, + "allChats": "כל הצ'אטים", + "@allChats": { + "type": "text", + "placeholders": {} + }, + "banned": "חסום", + "@banned": { + "type": "text", + "placeholders": {} + }, + "sendOnEnter": "שלח בכניסה", + "@sendOnEnter": {}, + "badServerLoginTypesException": "שרת הבית תומך בסוגי הכניסה:\n{serverVersions}\nאבל אפליקציה זו תומכת רק ב:\n{supportedVersions}", + "@badServerLoginTypesException": { + "type": "text", + "placeholders": { + "serverVersions": {}, + "supportedVersions": {} + } + }, + "changedTheGuestAccessRulesTo": "{username} שינה את כללי הגישה לאורחים ל: {rules}", + "@changedTheGuestAccessRulesTo": { + "type": "text", + "placeholders": { + "username": {}, + "rules": {} + } + }, + "changedTheJoinRules": "{username} שינה את כללי ההצטרפות", + "@changedTheJoinRules": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changeWallpaper": "שנה טפט", + "@changeWallpaper": { + "type": "text", + "placeholders": {} + }, + "changedTheChatNameTo": "{username} שינה את שם הצ'אט ל: '{chatname}'", + "@changedTheChatNameTo": { + "type": "text", + "placeholders": { + "username": {}, + "chatname": {} + } + }, + "changedTheRoomInvitationLink": "{username} שינה את קישור ההזמנה", + "@changedTheRoomInvitationLink": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "passwordsDoNotMatch": "הסיסמאות לא תואמות!", + "@passwordsDoNotMatch": {}, + "pleaseEnterValidEmail": "אנא כתוב כתובת אימייל תקינה.", + "@pleaseEnterValidEmail": {}, + "repeatPassword": "כתוב שוב את הסיסמה", + "@repeatPassword": {}, + "areYouSureYouWantToLogout": "האם אתה בטוח שברצונך לצאת?", + "@areYouSureYouWantToLogout": { + "type": "text", + "placeholders": {} + }, + "chat": "צ׳אט", + "@chat": { + "type": "text", + "placeholders": {} + }, + "autoplayImages": "הפעל אוטומטית מדבקות ואנימציות מונפשים", + "@autoplayImages": { + "type": "text", + "placeholder": {} + }, + "badServerVersionsException": "שרת הבית תומך בגרסאות:\n{serverVersions}\nאבל האפליקציה הזו תומכת רק ב-{supportedVersions}", + "@badServerVersionsException": { + "type": "text", + "placeholders": { + "serverVersions": {}, + "supportedVersions": {} + } + }, + "banFromChat": "צאט חסום", + "@banFromChat": { + "type": "text", + "placeholders": {} + }, + "bannedUser": "{username} חסם את {targetName}", + "@bannedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "blockDevice": "חסום מכשיר", + "@blockDevice": { + "type": "text", + "placeholders": {} + }, + "blocked": "חסום", + "@blocked": { + "type": "text", + "placeholders": {} + }, + "botMessages": "הודעות בוט", + "@botMessages": { + "type": "text", + "placeholders": {} + }, + "cantOpenUri": "לא ניתן לפתוח את ה-URI {uri}", + "@cantOpenUri": { + "type": "text", + "placeholders": { + "uri": {} + } + }, + "changeDeviceName": "שנה את שם המכשיר", + "@changeDeviceName": { + "type": "text", + "placeholders": {} + }, + "changedTheChatAvatar": "{username} שינה את האווטאר של הצ'אט", + "@changedTheChatAvatar": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheChatDescriptionTo": "{username} שינה את תיאור הצ'אט ל: '{description}'", + "@changedTheChatDescriptionTo": { + "type": "text", + "placeholders": { + "username": {}, + "description": {} + } + }, + "changedTheChatPermissions": "{username} שינה את הרשאות הצ'אט", + "@changedTheChatPermissions": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheDisplaynameTo": "{username} שינה את שם התצוגה שלו ל: '{displayname}'", + "@changedTheDisplaynameTo": { + "type": "text", + "placeholders": { + "username": {}, + "displayname": {} + } + }, + "changedTheGuestAccessRules": "{username} שינה את כללי הגישה לאורחים", + "@changedTheGuestAccessRules": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheHistoryVisibility": "{username} שינה את נראות ההיסטוריה", + "@changedTheHistoryVisibility": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheHistoryVisibilityTo": "{username} שינה את נראות ההיסטוריה ל: {rules}", + "@changedTheHistoryVisibilityTo": { + "type": "text", + "placeholders": { + "username": {}, + "rules": {} + } + }, + "changedTheJoinRulesTo": "{username} שינה את כללי ההצטרפות ל: {joinRules}", + "@changedTheJoinRulesTo": { + "type": "text", + "placeholders": { + "username": {}, + "joinRules": {} + } + }, + "changedTheProfileAvatar": "{username} שינה את האווטאר שלו", + "@changedTheProfileAvatar": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheRoomAliases": "{username} שינה את כינוי החדר", + "@changedTheRoomAliases": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changeTheHomeserver": "שנה את שרת הבית", + "@changeTheHomeserver": { + "type": "text", + "placeholders": {} + }, + "changeTheme": "שנה את הסגנון שלך", + "@changeTheme": { + "type": "text", + "placeholders": {} + }, + "changeTheNameOfTheGroup": "שנה את שם הקבוצה", + "@changeTheNameOfTheGroup": { + "type": "text", + "placeholders": {} + }, + "changeYourAvatar": "שינוי האווטאר שלך", + "@changeYourAvatar": { + "type": "text", + "placeholders": {} + }, + "channelCorruptedDecryptError": "ההצפנה נפגמה", + "@channelCorruptedDecryptError": { + "type": "text", + "placeholders": {} + }, + "yourChatBackupHasBeenSetUp": "גיבוי הצ'אט שלך הוגדר.", + "@yourChatBackupHasBeenSetUp": {}, + "chatBackup": "גיבוי צ'אט", + "@chatBackup": { + "type": "text", + "placeholders": {} + }, + "commandHint_ban": "חסום את המשתמש הנתון מהחדר הזה", + "@commandHint_ban": { + "type": "text", + "description": "Usage hint for the command /ban" + }, + "commandHint_clearcache": "נקה מטמון", + "@commandHint_clearcache": { + "type": "text", + "description": "Usage hint for the command /clearcache" + }, + "commandHint_create": "צור צ'אט קבוצתי ריק\nהשתמש ב--no-encryption כדי להשבית את ההצפנה", + "@commandHint_create": { + "type": "text", + "description": "Usage hint for the command /create" + }, + "commandHint_discardsession": "התעלם מהסשן", + "@commandHint_discardsession": { + "type": "text", + "description": "Usage hint for the command /discardsession" + }, + "commandHint_dm": "התחל צ'אט ישיר\nהשתמש ב--no-encryption כדי להשבית את ההצפנה", + "@commandHint_dm": { + "type": "text", + "description": "Usage hint for the command /dm" + }, + "commandHint_html": "שלח טקסט בתבנית HTML", + "@commandHint_html": { + "type": "text", + "description": "Usage hint for the command /html" + }, + "commandHint_invite": "הזמן את המשתמש הנתון לחדר זה", + "@commandHint_invite": { + "type": "text", + "description": "Usage hint for the command /invite" + }, + "commandHint_join": "הצטרף לחדר הנתון", + "@commandHint_join": { + "type": "text", + "description": "Usage hint for the command /join" + }, + "commandHint_kick": "הסר את המשתמש הנתון מהחדר הזה", + "@commandHint_kick": { + "type": "text", + "description": "Usage hint for the command /kick" + }, + "commandHint_leave": "עזוב את החדר הזה", + "@commandHint_leave": { + "type": "text", + "description": "Usage hint for the command /leave" + }, + "commandHint_me": "תאר את עצמך", + "@commandHint_me": { + "type": "text", + "description": "Usage hint for the command /me" + }, + "chatDetails": "פרטי צ'אט", + "@chatDetails": { + "type": "text", + "placeholders": {} + }, + "chatBackupDescription": "גיבוי הצ'אט שלך מאובטח באמצעות מפתח אבטחה. אנא וודא שאתה לא מאבד אותו.", + "@chatBackupDescription": { + "type": "text", + "placeholders": {} + }, + "chatHasBeenAddedToThisSpace": "צ'אט נוסף למרחב הזה", + "@chatHasBeenAddedToThisSpace": {}, + "chats": "צ'אטים", + "@chats": { + "type": "text", + "placeholders": {} + }, + "chooseAStrongPassword": "בחר סיסמה חזקה", + "@chooseAStrongPassword": { + "type": "text", + "placeholders": {} + }, + "chooseAUsername": "בחר שם משתמש", + "@chooseAUsername": { + "type": "text", + "placeholders": {} + }, + "clearArchive": "נקה ארכיון", + "@clearArchive": {}, + "close": "סגור", + "@close": { + "type": "text", + "placeholders": {} + }, + "commandHint_myroomavatar": "הגדר את התמונה שלך לחדר זה (על ידי mxc-uri)", + "@commandHint_myroomavatar": { + "type": "text", + "description": "Usage hint for the command /myroomavatar" + }, + "commandHint_myroomnick": "הגדר את שם התצוגה שלך עבור חדר זה", + "@commandHint_myroomnick": { + "type": "text", + "description": "Usage hint for the command /myroomnick" + }, + "addToSpace": "הוסף לחלל", + "@addToSpace": {}, + "commandHint_unban": "בטל את החסימה של המשתמש הנתון מהחדר הזה", + "@commandHint_unban": { + "type": "text", + "description": "Usage hint for the command /unban" + }, + "countParticipants": "{count} משתתפים", + "@countParticipants": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "create": "צור", + "@create": { + "type": "text", + "placeholders": {} + }, + "createdTheChat": "{username} יצר את הצ'אט", + "@createdTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "currentlyActive": "פעיל כעת", + "@currentlyActive": { + "type": "text", + "placeholders": {} + }, + "darkTheme": "כהה", + "@darkTheme": { + "type": "text", + "placeholders": {} + }, + "dateAndTimeOfDay": "{date}, {timeOfDay}", + "@dateAndTimeOfDay": { + "type": "text", + "placeholders": { + "date": {}, + "timeOfDay": {} + } + }, + "dateWithoutYear": "{month}-{day}", + "@dateWithoutYear": { + "type": "text", + "placeholders": { + "month": {}, + "day": {} + } + }, + "defaultPermissionLevel": "רמת הרשאת ברירת מחדל", + "@defaultPermissionLevel": { + "type": "text", + "placeholders": {} + }, + "deleteAccount": "מחק חשבון", + "@deleteAccount": { + "type": "text", + "placeholders": {} + }, + "deleteMessage": "מחק הודעה", + "@deleteMessage": { + "type": "text", + "placeholders": {} + }, + "deny": "דחה", + "@deny": { + "type": "text", + "placeholders": {} + }, + "deviceId": "מזהה מכשיר", + "@deviceId": { + "type": "text", + "placeholders": {} + }, + "devices": "התקנים", + "@devices": { + "type": "text", + "placeholders": {} + }, + "directChats": "צ'אטים ישירים", + "@directChats": { + "type": "text", + "placeholders": {} + }, + "downloadFile": "הורד קובץ", + "@downloadFile": { + "type": "text", + "placeholders": {} + }, + "edit": "ערוך", + "@edit": { + "type": "text", + "placeholders": {} + }, + "editChatPermissions": "ערוך הרשאות צ'אט", + "@editChatPermissions": { + "type": "text", + "placeholders": {} + }, + "editDisplayname": "ערוך את שם התצוגה", + "@editDisplayname": { + "type": "text", + "placeholders": {} + }, + "editRoomAliases": "ערוך כינויים לחדר", + "@editRoomAliases": { + "type": "text", + "placeholders": {} + }, + "emoteExists": "אימוט כבר קיים!", + "@emoteExists": { + "type": "text", + "placeholders": {} + }, + "emptyChat": "צ'אט ריק", + "@emptyChat": { + "type": "text", + "placeholders": {} + }, + "encrypted": "מוצפן", + "@encrypted": { + "type": "text", + "placeholders": {} + }, + "enterAGroupName": "הזן שם קבוצה", + "@enterAGroupName": { + "type": "text", + "placeholders": {} + }, + "enterAnEmailAddress": "הזן כתובת דואר אלקטרוני", + "@enterAnEmailAddress": { + "type": "text", + "placeholders": {} + }, + "enterASpacepName": "הזן שם חלל", + "@enterASpacepName": {}, + "enterYourHomeserver": "הזן את שרת הבית שלך", + "@enterYourHomeserver": { + "type": "text", + "placeholders": {} + }, + "everythingReady": "הכל מוכן!", + "@everythingReady": { + "type": "text", + "placeholders": {} + }, + "fileName": "שם קובץ", + "@fileName": { + "type": "text", + "placeholders": {} + }, + "fluffychat": "FluffyChat", + "@fluffychat": { + "type": "text", + "placeholders": {} + }, + "fontSize": "גודל גופן", + "@fontSize": { + "type": "text", + "placeholders": {} + }, + "forward": "העבר", + "@forward": { + "type": "text", + "placeholders": {} + }, + "fromJoining": "מהצטרפות", + "@fromJoining": { + "type": "text", + "placeholders": {} + }, + "fromTheInvitation": "מההזמנה", + "@fromTheInvitation": { + "type": "text", + "placeholders": {} + }, + "goToTheNewRoom": "עבור לחדר החדש", + "@goToTheNewRoom": { + "type": "text", + "placeholders": {} + }, + "groupDescription": "תיאור קבוצה", + "@groupDescription": { + "type": "text", + "placeholders": {} + }, + "groupDescriptionHasBeenChanged": "תיאור הקבוצה השתנה", + "@groupDescriptionHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "groupIsPublic": "הקבוצה ציבורית", + "@groupIsPublic": { + "type": "text", + "placeholders": {} + }, + "groupWith": "קבוצה עם {displayname}", + "@groupWith": { + "type": "text", + "placeholders": { + "displayname": {} + } + }, + "guestsAreForbidden": "אורחים אסורים", + "@guestsAreForbidden": { + "type": "text", + "placeholders": {} + }, + "guestsCanJoin": "אורחים יכולים להצטרף", + "@guestsCanJoin": { + "type": "text", + "placeholders": {} + }, + "id": "מזהה", + "@id": { + "type": "text", + "placeholders": {} + }, + "identity": "זהות", + "@identity": { + "type": "text", + "placeholders": {} + }, + "ignoredUsers": "משתמשים שהתעלמו מהם", + "@ignoredUsers": { + "type": "text", + "placeholders": {} + }, + "incorrectPassphraseOrKey": "ביטוי סיסמה או מפתח שחזור שגויים", + "@incorrectPassphraseOrKey": { + "type": "text", + "placeholders": {} + }, + "inviteContact": "הזמן איש קשר", + "@inviteContact": { + "type": "text", + "placeholders": {} + }, + "invited": "הזמין", + "@invited": { + "type": "text", + "placeholders": {} + }, + "invitedUser": "{username} הזמין את {targetName}", + "@invitedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "invitedUsersOnly": "משתמשים מוזמנים בלבד", + "@invitedUsersOnly": { + "type": "text", + "placeholders": {} + }, + "inviteForMe": "הזמנה בשבילי", + "@inviteForMe": { + "type": "text", + "placeholders": {} + }, + "inviteText": "{username} הזמין אותך ל-FluffyChat.\n1. התקן את FluffyChat: https://fluffychat.im\n2. הירשם או היכנס\n3. פתח את קישור ההזמנה: {link}", + "@inviteText": { + "type": "text", + "placeholders": { + "username": {}, + "link": {} + } + }, + "isTyping": "מקליד/ה…", + "@isTyping": { + "type": "text", + "placeholders": {} + }, + "joinedTheChat": "{username} הצטרף לצ'אט", + "@joinedTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "joinRoom": "הצטרף לחדר", + "@joinRoom": { + "type": "text", + "placeholders": {} + }, + "kicked": "{username} בעט ב {targetName}", + "@kicked": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "kickedAndBanned": "{username} בעט וחסם {targetName}", + "@kickedAndBanned": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "kickFromChat": "בעיטה מהצ'אט", + "@kickFromChat": { + "type": "text", + "placeholders": {} + }, + "lastActiveAgo": "פעילות אחרונה: {localizedTimeShort}", + "@lastActiveAgo": { + "type": "text", + "placeholders": { + "localizedTimeShort": {} + } + }, + "lastSeenLongTimeAgo": "נראה לפני זמן רב", + "@lastSeenLongTimeAgo": { + "type": "text", + "placeholders": {} + }, + "leftTheChat": "עזב את הצ'אט", + "@leftTheChat": { + "type": "text", + "placeholders": {} + }, + "loadingPleaseWait": "טוען אנא המתן.", + "@loadingPleaseWait": { + "type": "text", + "placeholders": {} + }, + "loadMore": "טען עוד…", + "@loadMore": { + "type": "text", + "placeholders": {} + }, + "locationDisabledNotice": "שירותי המיקום מושבתים. אנא הפעל אותם כדי לשתף את המיקום שלך.", + "@locationDisabledNotice": { + "type": "text", + "placeholders": {} + }, + "copy": "העתק", + "@copy": { + "type": "text", + "placeholders": {} + }, + "commandHint_send": "שלח טקסט", + "@commandHint_send": { + "type": "text", + "description": "Usage hint for the command /send" + }, + "commandHint_op": "הגדרת רמת צריכת החשמל של המשתמש הנתון (ברירת מחדל: 50)", + "@commandHint_op": { + "type": "text", + "description": "Usage hint for the command /op" + }, + "commandHint_plain": "שלח טקסט לא מעוצב", + "@commandHint_plain": { + "type": "text", + "description": "Usage hint for the command /plain" + }, + "commandHint_react": "שלח תשובה כתגובה", + "@commandHint_react": { + "type": "text", + "description": "Usage hint for the command /react" + }, + "createNewGroup": "צור קבוצה חדשה", + "@createNewGroup": { + "type": "text", + "placeholders": {} + }, + "containsUserName": "מכיל שם משתמש", + "@containsUserName": { + "type": "text", + "placeholders": {} + }, + "createNewSpace": "חלל חדש", + "@createNewSpace": { + "type": "text", + "placeholders": {} + }, + "enableEncryption": "אפשר הצפנה", + "@enableEncryption": { + "type": "text", + "placeholders": {} + }, + "inviteContactToGroup": "הזמן איש קשר אל {groupName}", + "@inviteContactToGroup": { + "type": "text", + "placeholders": { + "groupName": {} + } + }, + "dateWithYear": "{year}-{month}-{day}", + "@dateWithYear": { + "type": "text", + "placeholders": { + "year": {}, + "month": {}, + "day": {} + } + }, + "deactivateAccountWarning": "פעולה זו תשבית את חשבון המשתמש שלך. אי אפשר לבטל את זה! האם אתה בטוח?", + "@deactivateAccountWarning": { + "type": "text", + "placeholders": {} + }, + "device": "מכשיר", + "@device": { + "type": "text", + "placeholders": {} + }, + "group": "קבוצה", + "@group": { + "type": "text", + "placeholders": {} + }, + "displaynameHasBeenChanged": "שם התצוגה השתנה", + "@displaynameHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "editBlockedServers": "ערוך שרתים חסומים", + "@editBlockedServers": { + "type": "text", + "placeholders": {} + }, + "editRoomAvatar": "עריכת אווטאר של חדר", + "@editRoomAvatar": { + "type": "text", + "placeholders": {} + }, + "endedTheCall": "{senderName} סיים את השיחה", + "@endedTheCall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "groups": "קבוצות", + "@groups": { + "type": "text", + "placeholders": {} + }, + "enableEncryptionWarning": "לא תוכל לבטל את ההצפנה יותר. האם אתה בטוח?", + "@enableEncryptionWarning": { + "type": "text", + "placeholders": {} + }, + "encryption": "הצפנה", + "@encryption": { + "type": "text", + "placeholders": {} + }, + "errorObtainingLocation": "שגיאה בהשגת מיקום: {error}", + "@errorObtainingLocation": { + "type": "text", + "placeholders": { + "error": {} + } + }, + "hasWithdrawnTheInvitationFor": "{username} ביטל את ההזמנה עבור {targetName}", + "@hasWithdrawnTheInvitationFor": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "hideRedactedEvents": "הסתר אירועים מצונזרים", + "@hideRedactedEvents": { + "type": "text", + "placeholders": {} + }, + "encryptionNotEnabled": "ההצפנה אינה מופעלת", + "@encryptionNotEnabled": { + "type": "text", + "placeholders": {} + }, + "extremeOffensive": "פוגעני ביותר", + "@extremeOffensive": { + "type": "text", + "placeholders": {} + }, + "hideUnknownEvents": "הסתר אירועים לא ידועים", + "@hideUnknownEvents": { + "type": "text", + "placeholders": {} + }, + "loadCountMoreParticipants": "טען {count} משתתפים נוספים", + "@loadCountMoreParticipants": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "homeserver": "שרת בית", + "@homeserver": {}, + "ignore": "התעלם", + "@ignore": { + "type": "text", + "placeholders": {} + }, + "ignoreListDescription": "באפשרותך להתעלם ממשתמשים שמפריעים לך. לא תוכל לקבל הודעות או הזמנות לחדר מהמשתמשים ברשימת ההתעלם האישית שלך.", + "@ignoreListDescription": { + "type": "text", + "placeholders": {} + }, + "ignoreUsername": "התעלם משם משתמש", + "@ignoreUsername": { + "type": "text", + "placeholders": {} + }, + "iHaveClickedOnLink": "לחצתי על הקישור", + "@iHaveClickedOnLink": { + "type": "text", + "placeholders": {} + }, + "leave": "לעזוב", + "@leave": { + "type": "text", + "placeholders": {} + }, + "license": "רשיון", + "@license": { + "type": "text", + "placeholders": {} + }, + "lightTheme": "בהיר", + "@lightTheme": { + "type": "text", + "placeholders": {} + }, + "delete": "מחיקה", + "@delete": { + "type": "text", + "placeholders": {} + }, + "inoffensive": "לֹא פּוֹגֵעַ", + "@inoffensive": { + "type": "text", + "placeholders": {} + }, + "configureChat": "קביעת תצורה של צ'אט", + "@configureChat": { + "type": "text", + "placeholders": {} + }, + "confirm": "לאשר", + "@confirm": { + "type": "text", + "placeholders": {} + }, + "connect": "התחבר", + "@connect": { + "type": "text", + "placeholders": {} + }, + "contactHasBeenInvitedToTheGroup": "איש הקשר הוזמן לקבוצה", + "@contactHasBeenInvitedToTheGroup": { + "type": "text", + "placeholders": {} + }, + "containsDisplayName": "מכיל שם תצוגה", + "@containsDisplayName": { + "type": "text", + "placeholders": {} + }, + "contentHasBeenReported": "התוכן דווח למנהלי השרת", + "@contentHasBeenReported": { + "type": "text", + "placeholders": {} + }, + "copiedToClipboard": "הועתק ללוח הגזירים", + "@copiedToClipboard": { + "type": "text", + "placeholders": {} + }, + "commandInvalid": "הפקודה אינה חוקית", + "@commandInvalid": { + "type": "text" + }, + "commandMissing": "{command} אינו פקודה.", + "@commandMissing": { + "type": "text", + "placeholders": { + "command": {} + }, + "description": "State that {command} is not a valid /command." + }, + "compareEmojiMatch": "השווה וודא שהאימוג'י הבאים תואמים לאלו של המכשיר השני:", + "@compareEmojiMatch": { + "type": "text", + "placeholders": {} + }, + "compareNumbersMatch": "השווה וודא שהמספרים הבאים תואמים לאלה של המכשיר השני:", + "@compareNumbersMatch": { + "type": "text", + "placeholders": {} + }, + "copyToClipboard": "העתק ללוח", + "@copyToClipboard": { + "type": "text", + "placeholders": {} + }, + "couldNotDecryptMessage": "לא ניתן לפענח הודעה: {error}", + "@couldNotDecryptMessage": { + "type": "text", + "placeholders": { + "error": {} + } + }, + "help": "עזרה", + "@help": { + "type": "text", + "placeholders": {} + }, + "howOffensiveIsThisContent": "עד כמה התוכן הזה פוגעני?", + "@howOffensiveIsThisContent": { + "type": "text", + "placeholders": {} + }, + "locationPermissionDeniedNotice": "הרשאת המיקום נדחתה. אנא אפשר את היכולת לשתף את מיקומך.", + "@locationPermissionDeniedNotice": { + "type": "text", + "placeholders": {} + }, + "login": "כניסה", + "@login": { + "type": "text", + "placeholders": {} + }, + "moderator": "מנחה", + "@moderator": { + "type": "text", + "placeholders": {} + }, + "needPantalaimonWarning": "שים לב שאתה צריך Pantalaimon כדי להשתמש בהצפנה מקצה לקצה לעת עתה.", + "@needPantalaimonWarning": { + "type": "text", + "placeholders": {} + }, + "newChat": "צ'אט חדש", + "@newChat": { + "type": "text", + "placeholders": {} + }, + "newVerificationRequest": "בקשת אימות חדשה!", + "@newVerificationRequest": { + "type": "text", + "placeholders": {} + }, + "next": "הבא", + "@next": { + "type": "text", + "placeholders": {} + }, + "no": "לא", + "@no": { + "type": "text", + "placeholders": {} + }, + "noConnectionToTheServer": "אין חיבור לשרת", + "@noConnectionToTheServer": { + "type": "text", + "placeholders": {} + }, + "noEncryptionForPublicRooms": "אתה יכול להפעיל הצפנה רק כשהחדר כבר לא נגיש לציבור.", + "@noEncryptionForPublicRooms": { + "type": "text", + "placeholders": {} + }, + "shareYourInviteLink": "שתף את קישור ההזמנה שלך", + "@shareYourInviteLink": {}, + "noRoomsFound": "לא נמצאו חדרים…", + "@noRoomsFound": { + "type": "text", + "placeholders": {} + }, + "notifications": "התראות", + "@notifications": { + "type": "text", + "placeholders": {} + }, + "numUsersTyping": "{count} משתמשים מקלידים…", + "@numUsersTyping": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "obtainingLocation": "משיג מיקום…", + "@obtainingLocation": { + "type": "text", + "placeholders": {} + }, + "onlineKeyBackupEnabled": "גיבוי מפתח מקוון מופעל", + "@onlineKeyBackupEnabled": { + "type": "text", + "placeholders": {} + }, + "oopsPushError": "אופס! למרבה הצער, אירעה שגיאה בעת הגדרת התראות.", + "@oopsPushError": { + "type": "text", + "placeholders": {} + }, + "oopsSomethingWentWrong": "אופס, משהו השתבש…", + "@oopsSomethingWentWrong": { + "type": "text", + "placeholders": {} + }, + "openAppToReadMessages": "פתח את האפליקציה לקריאת הודעות", + "@openAppToReadMessages": { + "type": "text", + "placeholders": {} + }, + "oneClientLoggedOut": "אחד מהמכשירים שלך התנתק", + "@oneClientLoggedOut": {}, + "addAccount": "הוסף חשבון", + "@addAccount": {}, + "editBundlesForAccount": "ערוך חבילות עבור חשבון זה", + "@editBundlesForAccount": {}, + "participant": "משתתף", + "@participant": { + "type": "text", + "placeholders": {} + }, + "password": "סיסמה", + "@password": { + "type": "text", + "placeholders": {} + }, + "pleaseClickOnLink": "אנא לחץ על הקישור במייל ולאחר מכן המשך.", + "@pleaseClickOnLink": { + "type": "text", + "placeholders": {} + }, + "pleaseEnter4Digits": "אנא הזן 4 ספרות או השאר ריק כדי להשבית את נעילת האפליקציה.", + "@pleaseEnter4Digits": { + "type": "text", + "placeholders": {} + }, + "loginWithOneClick": "היכנס בלחיצה אחת", + "@loginWithOneClick": {}, + "online": "מחובר/ת", + "@online": { + "type": "text", + "placeholders": {} + }, + "addToBundle": "הוסף לחבילה", + "@addToBundle": {}, + "optionalGroupName": "(אופציונלי) שם קבוצה", + "@optionalGroupName": { + "type": "text", + "placeholders": {} + }, + "passphraseOrKey": "ביטוי סיסמה או מפתח שחזור", + "@passphraseOrKey": { + "type": "text", + "placeholders": {} + }, + "passwordForgotten": "שכחתי סיסמה", + "@passwordForgotten": { + "type": "text", + "placeholders": {} + }, + "passwordHasBeenChanged": "הסיסמה שונתה", + "@passwordHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "passwordRecovery": "שחזור סיסמה", + "@passwordRecovery": { + "type": "text", + "placeholders": {} + }, + "people": "אנשים", + "@people": { + "type": "text", + "placeholders": {} + }, + "pickImage": "בחר תמונה", + "@pickImage": { + "type": "text", + "placeholders": {} + }, + "play": "הפעל {fileName}", + "@play": { + "type": "text", + "placeholders": { + "fileName": {} + } + }, + "pleaseChoose": "אנא בחר", + "@pleaseChoose": { + "type": "text", + "placeholders": {} + }, + "pleaseChooseAPasscode": "אנא בחר קוד גישה", + "@pleaseChooseAPasscode": { + "type": "text", + "placeholders": {} + }, + "pleaseChooseAUsername": "אנא בחר שם משתמש", + "@pleaseChooseAUsername": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterAMatrixIdentifier": "אנא הזן Matrix ID.", + "@pleaseEnterAMatrixIdentifier": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourPassword": "נא הזן את הסיסמה שלך", + "@pleaseEnterYourPassword": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourPin": "אנא הזן את קוד הpin שלך", + "@pleaseEnterYourPin": { + "type": "text", + "placeholders": {} + }, + "pin": "קוד pin", + "@pin": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourUsername": "אנא הזן שם משתמש", + "@pleaseEnterYourUsername": { + "type": "text", + "placeholders": {} + }, + "newMessageInFluffyChat": "הודעה חדשה ב-FluffyChat", + "@newMessageInFluffyChat": { + "type": "text", + "placeholders": {} + }, + "noGoogleServicesWarning": "נראה שאין לך שירותי גוגל בטלפון שלך. זו החלטה טובה לפרטיות שלך! כדי לקבל התרעות ב- FluffyChat אנו ממליצים להשתמש https://microg.org/ או https://unifiedpush.org/.", + "@noGoogleServicesWarning": { + "type": "text", + "placeholders": {} + }, + "noMatrixServer": "{server1} אינו שרת מטריקס, השתמש ב-{server2} במקום זאת?", + "@noMatrixServer": { + "type": "text", + "placeholders": { + "server1": {}, + "server2": {} + } + }, + "none": "ללא", + "@none": { + "type": "text", + "placeholders": {} + }, + "noPasswordRecoveryDescription": "עדיין לא הוספת דרך לשחזר את הסיסמה שלך.", + "@noPasswordRecoveryDescription": { + "type": "text", + "placeholders": {} + }, + "offensive": "פוגעני", + "@offensive": { + "type": "text", + "placeholders": {} + }, + "notificationsEnabledForThisAccount": "התראות הופעלו עבור חשבון זה", + "@notificationsEnabledForThisAccount": { + "type": "text", + "placeholders": {} + }, + "bundleName": "שם החבילה", + "@bundleName": {}, + "offline": "לא מקוון", + "@offline": { + "type": "text", + "placeholders": {} + }, + "openVideoCamera": "פתח את המצלמה לסרטון", + "@openVideoCamera": { + "type": "text", + "placeholders": {} + }, + "removeFromBundle": "הסר מחבילה זו", + "@removeFromBundle": {}, + "enableMultiAccounts": "(בטא) אפשר ריבוי חשבונות במכשיר זה", + "@enableMultiAccounts": {}, + "openInMaps": "פתיחה במפות", + "@openInMaps": { + "type": "text", + "placeholders": {} + }, + "link": "קישור", + "@link": {}, + "serverRequiresEmail": "שרת זה צריך לאמת את כתובת הדואר האלקטרוני שלך לרישום.", + "@serverRequiresEmail": {}, + "logout": "יציאה", + "@logout": { + "type": "text", + "placeholders": {} + }, + "muteChat": "השתקת הצ'אט", + "@muteChat": { + "type": "text", + "placeholders": {} + }, + "scanQrCode": "סרוק קוד QR", + "@scanQrCode": {}, + "noPermission": "אין הרשאה", + "@noPermission": { + "type": "text", + "placeholders": {} + }, + "or": "או", + "@or": { + "type": "text", + "placeholders": {} + }, + "logInTo": "היכנס אל {homeserver}", + "@logInTo": { + "type": "text", + "placeholders": { + "homeserver": {} + } + }, + "makeSureTheIdentifierIsValid": "ודא שהמזהה חוקי", + "@makeSureTheIdentifierIsValid": { + "type": "text", + "placeholders": {} + }, + "memberChanges": "שינויים בחבר", + "@memberChanges": { + "type": "text", + "placeholders": {} + }, + "mention": "הזכיר", + "@mention": { + "type": "text", + "placeholders": {} + }, + "messageWillBeRemovedWarning": "ההודעה תוסר עבור כל המשתתפים", + "@messageWillBeRemovedWarning": { + "type": "text", + "placeholders": {} + }, + "messages": "הודעות", + "@messages": { + "type": "text", + "placeholders": {} + }, + "openCamera": "פתח מצלמה", + "@openCamera": { + "type": "text", + "placeholders": {} + }, + "updateAvailable": "עדכון FluffyChat זמין", + "@updateAvailable": {}, + "updateNow": "התחל עדכון ברקע", + "@updateNow": {}, + "bubbleSize": "גודל בועות", + "@bubbleSize": { + "type": "text", + "placeholders": {} + }, + "showPassword": "", + "@showPassword": { + "type": "text", + "placeholders": {} + }, + "hugContent": "", + "@hugContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "theyMatch": "", + "@theyMatch": { + "type": "text", + "placeholders": {} + }, + "jumpToLastReadMessage": "", + "@jumpToLastReadMessage": {}, + "allRooms": "", + "@allRooms": { + "type": "text", + "placeholders": {} + }, + "whoCanSeeMyStories": "", + "@whoCanSeeMyStories": {}, + "commandHint_cuddle": "", + "@commandHint_cuddle": {}, + "widgetVideo": "", + "@widgetVideo": {}, + "dismiss": "", + "@dismiss": {}, + "unknownDevice": "", + "@unknownDevice": { + "type": "text", + "placeholders": {} + }, + "emoteShortcode": "", + "@emoteShortcode": { + "type": "text", + "placeholders": {} + }, + "reportErrorDescription": "", + "@reportErrorDescription": {}, + "setPermissionsLevel": "", + "@setPermissionsLevel": { + "type": "text", + "placeholders": {} + }, + "seenByUserAndUser": "", + "@seenByUserAndUser": { + "type": "text", + "placeholders": { + "username": {}, + "username2": {} + } + }, + "reply": "", + "@reply": { + "type": "text", + "placeholders": {} + }, + "removeYourAvatar": "", + "@removeYourAvatar": { + "type": "text", + "placeholders": {} + }, + "unsupportedAndroidVersion": "", + "@unsupportedAndroidVersion": {}, + "widgetJitsi": "", + "@widgetJitsi": {}, + "youAreNoLongerParticipatingInThisChat": "", + "@youAreNoLongerParticipatingInThisChat": { + "type": "text", + "placeholders": {} + }, + "messageType": "", + "@messageType": {}, + "noEmailWarning": "", + "@noEmailWarning": {}, + "indexedDbErrorLong": "", + "@indexedDbErrorLong": {}, + "toggleMuted": "", + "@toggleMuted": { + "type": "text", + "placeholders": {} + }, + "title": "", + "@title": { + "description": "Title for the application", + "type": "text", + "placeholders": {} + }, + "verifySuccess": "", + "@verifySuccess": { + "type": "text", + "placeholders": {} + }, + "sendFile": "", + "@sendFile": { + "type": "text", + "placeholders": {} + }, + "startFirstChat": "", + "@startFirstChat": {}, + "callingAccount": "", + "@callingAccount": {}, + "requestPermission": "", + "@requestPermission": { + "type": "text", + "placeholders": {} + }, + "sentAPicture": "", + "@sentAPicture": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "setColorTheme": "", + "@setColorTheme": {}, + "nextAccount": "", + "@nextAccount": {}, + "youAreInvitedToThisChat": "", + "@youAreInvitedToThisChat": { + "type": "text", + "placeholders": {} + }, + "singlesignon": "", + "@singlesignon": { + "type": "text", + "placeholders": {} + }, + "warning": "", + "@warning": { + "type": "text", + "placeholders": {} + }, + "allSpaces": "", + "@allSpaces": {}, + "supposedMxid": "", + "@supposedMxid": { + "type": "text", + "placeholders": { + "mxid": {} + } + }, + "user": "", + "@user": {}, + "roomVersion": "", + "@roomVersion": { + "type": "text", + "placeholders": {} + }, + "sentAFile": "", + "@sentAFile": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "videoCall": "", + "@videoCall": { + "type": "text", + "placeholders": {} + }, + "youAcceptedTheInvitation": "", + "@youAcceptedTheInvitation": {}, + "userAndOthersAreTyping": "", + "@userAndOthersAreTyping": { + "type": "text", + "placeholders": { + "username": {}, + "count": {} + } + }, + "youInvitedBy": "", + "@youInvitedBy": { + "placeholders": { + "user": {} + } + }, + "userIsTyping": "", + "@userIsTyping": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sentAVideo": "", + "@sentAVideo": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "banUserDescription": "", + "@banUserDescription": {}, + "requests": "", + "@requests": {}, + "widgetEtherpad": "", + "@widgetEtherpad": {}, + "waitingPartnerAcceptRequest": "", + "@waitingPartnerAcceptRequest": { + "type": "text", + "placeholders": {} + }, + "remove": "", + "@remove": { + "type": "text", + "placeholders": {} + }, + "writeAMessage": "", + "@writeAMessage": { + "type": "text", + "placeholders": {} + }, + "stories": "", + "@stories": {}, + "addToStory": "", + "@addToStory": {}, + "removeDevicesDescription": "", + "@removeDevicesDescription": {}, + "separateChatTypes": "", + "@separateChatTypes": { + "type": "text", + "placeholders": {} + }, + "tryAgain": "", + "@tryAgain": {}, + "youKickedAndBanned": "", + "@youKickedAndBanned": { + "placeholders": { + "user": {} + } + }, + "showDirectChatsInSpaces": "", + "@showDirectChatsInSpaces": { + "type": "text", + "placeholders": {} + }, + "removeDevice": "", + "@removeDevice": { + "type": "text", + "placeholders": {} + }, + "youCannotInviteYourself": "", + "@youCannotInviteYourself": { + "type": "text", + "placeholders": {} + }, + "unbanUserDescription": "", + "@unbanUserDescription": {}, + "todoLists": "", + "@todoLists": {}, + "userAndUserAreTyping": "", + "@userAndUserAreTyping": { + "type": "text", + "placeholders": { + "username": {}, + "username2": {} + } + }, + "saveFile": "", + "@saveFile": { + "type": "text", + "placeholders": {} + }, + "seenByUserAndCountOthers": "", + "@seenByUserAndCountOthers": { + "type": "text", + "placeholders": { + "username": {}, + "count": {} + } + }, + "youRejectedTheInvitation": "", + "@youRejectedTheInvitation": {}, + "otherCallingPermissions": "", + "@otherCallingPermissions": {}, + "messagesStyle": "", + "@messagesStyle": {}, + "widgetUrlError": "", + "@widgetUrlError": {}, + "emailOrUsername": "", + "@emailOrUsername": {}, + "newSpaceDescription": "", + "@newSpaceDescription": {}, + "chatDescription": "", + "@chatDescription": {}, + "callingAccountDetails": "", + "@callingAccountDetails": {}, + "pleaseFollowInstructionsOnWeb": "", + "@pleaseFollowInstructionsOnWeb": { + "type": "text", + "placeholders": {} + }, + "enterSpace": "", + "@enterSpace": {}, + "encryptThisChat": "", + "@encryptThisChat": {}, + "unavailable": "", + "@unavailable": { + "type": "text", + "placeholders": {} + }, + "previousAccount": "", + "@previousAccount": {}, + "publicRooms": "", + "@publicRooms": { + "type": "text", + "placeholders": {} + }, + "sendMessages": "", + "@sendMessages": { + "type": "text", + "placeholders": {} + }, + "emoteWarnNeedToPick": "", + "@emoteWarnNeedToPick": { + "type": "text", + "placeholders": {} + }, + "reopenChat": "", + "@reopenChat": {}, + "pleaseEnterRecoveryKey": "", + "@pleaseEnterRecoveryKey": {}, + "toggleFavorite": "", + "@toggleFavorite": { + "type": "text", + "placeholders": {} + }, + "widgetNameError": "", + "@widgetNameError": {}, + "unpin": "", + "@unpin": { + "type": "text", + "placeholders": {} + }, + "reportMessage": "", + "@reportMessage": { + "type": "text", + "placeholders": {} + }, + "spaceIsPublic": "", + "@spaceIsPublic": { + "type": "text", + "placeholders": {} + }, + "addWidget": "", + "@addWidget": {}, + "removeAllOtherDevices": "", + "@removeAllOtherDevices": { + "type": "text", + "placeholders": {} + }, + "unblockDevice": "", + "@unblockDevice": { + "type": "text", + "placeholders": {} + }, + "countFiles": "", + "@countFiles": { + "placeholders": { + "count": {} + } + }, + "noKeyForThisMessage": "", + "@noKeyForThisMessage": {}, + "shareLocation": "", + "@shareLocation": { + "type": "text", + "placeholders": {} + }, + "reason": "", + "@reason": { + "type": "text", + "placeholders": {} + }, + "commandHint_markasgroup": "", + "@commandHint_markasgroup": {}, + "editTodo": "", + "@editTodo": {}, + "hydrateTor": "", + "@hydrateTor": {}, + "pushNotificationsNotAvailable": "", + "@pushNotificationsNotAvailable": {}, + "storeInAppleKeyChain": "", + "@storeInAppleKeyChain": {}, + "replaceRoomWithNewerVersion": "", + "@replaceRoomWithNewerVersion": { + "type": "text", + "placeholders": {} + }, + "hydrate": "", + "@hydrate": {}, + "invalidServerName": "", + "@invalidServerName": {}, + "chatPermissions": "", + "@chatPermissions": {}, + "voiceMessage": "", + "@voiceMessage": { + "type": "text", + "placeholders": {} + }, + "wipeChatBackup": "", + "@wipeChatBackup": { + "type": "text", + "placeholders": {} + }, + "sender": "", + "@sender": {}, + "storeInAndroidKeystore": "", + "@storeInAndroidKeystore": {}, + "signInWithPassword": "", + "@signInWithPassword": {}, + "pleaseAddATitle": "", + "@pleaseAddATitle": {}, + "weSentYouAnEmail": "", + "@weSentYouAnEmail": { + "type": "text", + "placeholders": {} + }, + "makeAdminDescription": "", + "@makeAdminDescription": {}, + "noEmotesFound": "", + "@noEmotesFound": { + "type": "text", + "placeholders": {} + }, + "synchronizingPleaseWait": "", + "@synchronizingPleaseWait": { + "type": "text", + "placeholders": {} + }, + "transferFromAnotherDevice": "", + "@transferFromAnotherDevice": { + "type": "text", + "placeholders": {} + }, + "pushRules": "", + "@pushRules": { + "type": "text", + "placeholders": {} + }, + "saveKeyManuallyDescription": "", + "@saveKeyManuallyDescription": {}, + "renderRichContent": "", + "@renderRichContent": { + "type": "text", + "placeholders": {} + }, + "whyIsThisMessageEncrypted": "", + "@whyIsThisMessageEncrypted": {}, + "rejectedTheInvitation": "", + "@rejectedTheInvitation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "setChatDescription": "", + "@setChatDescription": {}, + "userLeftTheChat": "", + "@userLeftTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "spaceName": "", + "@spaceName": { + "type": "text", + "placeholders": {} + }, + "importFromZipFile": "", + "@importFromZipFile": {}, + "toggleUnread": "", + "@toggleUnread": { + "type": "text", + "placeholders": {} + }, + "dehydrateWarning": "", + "@dehydrateWarning": {}, + "sendOriginal": "", + "@sendOriginal": { + "type": "text", + "placeholders": {} + }, + "noOtherDevicesFound": "", + "@noOtherDevicesFound": {}, + "whoIsAllowedToJoinThisGroup": "", + "@whoIsAllowedToJoinThisGroup": { + "type": "text", + "placeholders": {} + }, + "seenByUser": "", + "@seenByUser": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "addDescription": "", + "@addDescription": {}, + "redactedBy": "", + "@redactedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "submit": "", + "@submit": { + "type": "text", + "placeholders": {} + }, + "videoCallsBetaWarning": "", + "@videoCallsBetaWarning": {}, + "unmuteChat": "", + "@unmuteChat": { + "type": "text", + "placeholders": {} + }, + "redactedAnEvent": "", + "@redactedAnEvent": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "storyPrivacyWarning": "", + "@storyPrivacyWarning": {}, + "matrixWidgets": "", + "@matrixWidgets": {}, + "yes": "", + "@yes": { + "type": "text", + "placeholders": {} + }, + "signInWith": "", + "@signInWith": { + "type": "text", + "placeholders": { + "provider": {} + } + }, + "username": "", + "@username": { + "type": "text", + "placeholders": {} + }, + "fileIsTooBigForServer": "", + "@fileIsTooBigForServer": {}, + "noTodosYet": "", + "@noTodosYet": {}, + "verified": "", + "@verified": { + "type": "text", + "placeholders": {} + }, + "setStatus": "", + "@setStatus": { + "type": "text", + "placeholders": {} + }, + "callingPermissions": "", + "@callingPermissions": {}, + "readUpToHere": "", + "@readUpToHere": {}, + "start": "", + "@start": {}, + "register": "", + "@register": { + "type": "text", + "placeholders": {} + }, + "unlockOldMessages": "", + "@unlockOldMessages": {}, + "numChats": "", + "@numChats": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "whatIsGoingOn": "", + "@whatIsGoingOn": {}, + "recording": "", + "@recording": { + "type": "text", + "placeholders": {} + }, + "optionalRedactReason": "", + "@optionalRedactReason": {}, + "waitingPartnerEmoji": "", + "@waitingPartnerEmoji": { + "type": "text", + "placeholders": {} + }, + "tryToSendAgain": "", + "@tryToSendAgain": { + "type": "text", + "placeholders": {} + }, + "dehydrate": "", + "@dehydrate": {}, + "send": "", + "@send": { + "type": "text", + "placeholders": {} + }, + "visibleForAllParticipants": "", + "@visibleForAllParticipants": { + "type": "text", + "placeholders": {} + }, + "sendAsText": "", + "@sendAsText": { + "type": "text" + }, + "archiveRoomDescription": "", + "@archiveRoomDescription": {}, + "exportEmotePack": "", + "@exportEmotePack": {}, + "sendSticker": "", + "@sendSticker": { + "type": "text", + "placeholders": {} + }, + "switchToAccount": "", + "@switchToAccount": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "setAsCanonicalAlias": "", + "@setAsCanonicalAlias": { + "type": "text", + "placeholders": {} + }, + "whyDoYouWantToReportThis": "", + "@whyDoYouWantToReportThis": { + "type": "text", + "placeholders": {} + }, + "letsStart": "", + "@letsStart": {}, + "removedBy": "", + "@removedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "emoteSettings": "", + "@emoteSettings": { + "type": "text", + "placeholders": {} + }, + "experimentalVideoCalls": "", + "@experimentalVideoCalls": {}, + "savedEmotePack": "", + "@savedEmotePack": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "pleaseEnterRecoveryKeyDescription": "", + "@pleaseEnterRecoveryKeyDescription": {}, + "withTheseAddressesRecoveryDescription": "", + "@withTheseAddressesRecoveryDescription": { + "type": "text", + "placeholders": {} + }, + "inviteContactToGroupQuestion": "", + "@inviteContactToGroupQuestion": {}, + "redactedByBecause": "", + "@redactedByBecause": { + "type": "text", + "placeholders": { + "username": {}, + "reason": {} + } + }, + "youHaveWithdrawnTheInvitationFor": "", + "@youHaveWithdrawnTheInvitationFor": { + "placeholders": { + "user": {} + } + }, + "skip": "", + "@skip": { + "type": "text", + "placeholders": {} + }, + "appearOnTopDetails": "", + "@appearOnTopDetails": {}, + "roomHasBeenUpgraded": "", + "@roomHasBeenUpgraded": { + "type": "text", + "placeholders": {} + }, + "enterRoom": "", + "@enterRoom": {}, + "enableEmotesGlobally": "", + "@enableEmotesGlobally": { + "type": "text", + "placeholders": {} + }, + "reportUser": "", + "@reportUser": {}, + "unbannedUser": "", + "@unbannedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "confirmEventUnpin": "", + "@confirmEventUnpin": {}, + "youInvitedUser": "", + "@youInvitedUser": { + "placeholders": { + "user": {} + } + }, + "fileHasBeenSavedAt": "", + "@fileHasBeenSavedAt": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "importZipFile": "", + "@importZipFile": {}, + "anyoneCanKnock": "", + "@anyoneCanKnock": {}, + "redactMessageDescription": "", + "@redactMessageDescription": {}, + "rejoin": "", + "@rejoin": { + "type": "text", + "placeholders": {} + }, + "recoveryKey": "", + "@recoveryKey": {}, + "redactMessage": "", + "@redactMessage": { + "type": "text", + "placeholders": {} + }, + "invalidInput": "", + "@invalidInput": {}, + "todosUnencrypted": "", + "@todosUnencrypted": {}, + "dehydrateTorLong": "", + "@dehydrateTorLong": {}, + "yourPublicKey": "", + "@yourPublicKey": { + "type": "text", + "placeholders": {} + }, + "tooManyRequestsWarning": "", + "@tooManyRequestsWarning": { + "type": "text", + "placeholders": {} + }, + "replyHasBeenSent": "", + "@replyHasBeenSent": {}, + "doNotShowAgain": "", + "@doNotShowAgain": {}, + "report": "", + "@report": {}, + "status": "", + "@status": { + "type": "text", + "placeholders": {} + }, + "verifyStart": "", + "@verifyStart": { + "type": "text", + "placeholders": {} + }, + "yourStory": "", + "@yourStory": {}, + "unverified": "", + "@unverified": {}, + "hideUnimportantStateEvents": "", + "@hideUnimportantStateEvents": {}, + "screenSharingTitle": "", + "@screenSharingTitle": {}, + "widgetCustom": "", + "@widgetCustom": {}, + "sentCallInformations": "", + "@sentCallInformations": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "addToSpaceDescription": "", + "@addToSpaceDescription": {}, + "googlyEyesContent": "", + "@googlyEyesContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "whoCanSeeMyStoriesDesc": "", + "@whoCanSeeMyStoriesDesc": {}, + "youBannedUser": "", + "@youBannedUser": { + "placeholders": { + "user": {} + } + }, + "theyDontMatch": "", + "@theyDontMatch": { + "type": "text", + "placeholders": {} + }, + "unsubscribeStories": "", + "@unsubscribeStories": {}, + "youHaveBeenBannedFromThisChat": "", + "@youHaveBeenBannedFromThisChat": { + "type": "text", + "placeholders": {} + }, + "addChatDescription": "", + "@addChatDescription": {}, + "sentAnAudio": "", + "@sentAnAudio": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "hasKnocked": "", + "@hasKnocked": { + "placeholders": { + "user": {} + } + }, + "publish": "", + "@publish": {}, + "openLinkInBrowser": "", + "@openLinkInBrowser": {}, + "messageInfo": "", + "@messageInfo": {}, + "disableEncryptionWarning": "", + "@disableEncryptionWarning": {}, + "directChat": "", + "@directChat": {}, + "noOneCanJoin": "", + "@noOneCanJoin": {}, + "wrongPinEntered": "", + "@wrongPinEntered": { + "type": "text", + "placeholders": { + "seconds": {} + } + }, + "sendTypingNotifications": "", + "@sendTypingNotifications": {}, + "inviteGroupChat": "", + "@inviteGroupChat": {}, + "appearOnTop": "", + "@appearOnTop": {}, + "invitePrivateChat": "", + "@invitePrivateChat": {}, + "verifyTitle": "", + "@verifyTitle": { + "type": "text", + "placeholders": {} + }, + "foregroundServiceRunning": "", + "@foregroundServiceRunning": {}, + "voiceCall": "", + "@voiceCall": {}, + "unknownEncryptionAlgorithm": "", + "@unknownEncryptionAlgorithm": { + "type": "text", + "placeholders": {} + }, + "importEmojis": "", + "@importEmojis": {}, + "wasDirectChatDisplayName": "", + "@wasDirectChatDisplayName": { + "type": "text", + "placeholders": { + "oldDisplayName": {} + } + }, + "noChatDescriptionYet": "", + "@noChatDescriptionYet": {}, + "newTodo": "", + "@newTodo": {}, + "whoCanPerformWhichAction": "", + "@whoCanPerformWhichAction": { + "type": "text", + "placeholders": {} + }, + "confirmMatrixId": "", + "@confirmMatrixId": {}, + "learnMore": "", + "@learnMore": {}, + "you": "", + "@you": { + "type": "text", + "placeholders": {} + }, + "notAnImage": "", + "@notAnImage": {}, + "users": "", + "@users": {}, + "openGallery": "", + "@openGallery": {}, + "chatDescriptionHasBeenChanged": "", + "@chatDescriptionHasBeenChanged": {}, + "search": "", + "@search": { + "type": "text", + "placeholders": {} + }, + "newGroup": "", + "@newGroup": {}, + "dehydrateTor": "", + "@dehydrateTor": {}, + "todoListChangedError": "", + "@todoListChangedError": {}, + "removeFromSpace": "", + "@removeFromSpace": {}, + "enterInviteLinkOrMatrixId": "", + "@enterInviteLinkOrMatrixId": {}, + "sourceCode": "", + "@sourceCode": { + "type": "text", + "placeholders": {} + }, + "roomUpgradeDescription": "", + "@roomUpgradeDescription": {}, + "userSentUnknownEvent": "", + "@userSentUnknownEvent": { + "type": "text", + "placeholders": { + "username": {}, + "type": {} + } + }, + "pleaseEnterANumber": "", + "@pleaseEnterANumber": {}, + "youKicked": "", + "@youKicked": { + "placeholders": { + "user": {} + } + }, + "profileNotFound": "", + "@profileNotFound": {}, + "jump": "", + "@jump": {}, + "reactedWith": "", + "@reactedWith": { + "type": "text", + "placeholders": { + "sender": {}, + "reaction": {} + } + }, + "sorryThatsNotPossible": "", + "@sorryThatsNotPossible": {}, + "storyFrom": "", + "@storyFrom": { + "type": "text", + "placeholders": { + "date": {}, + "body": {} + } + }, + "videoWithSize": "", + "@videoWithSize": { + "type": "text", + "placeholders": { + "size": {} + } + }, + "shareInviteLink": "", + "@shareInviteLink": {}, + "commandHint_markasdm": "", + "@commandHint_markasdm": {}, + "recoveryKeyLost": "", + "@recoveryKeyLost": {}, + "cuddleContent": "", + "@cuddleContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "deviceKeys": "", + "@deviceKeys": {}, + "waitingPartnerNumbers": "", + "@waitingPartnerNumbers": { + "type": "text", + "placeholders": {} + }, + "emoteKeyboardNoRecents": "", + "@emoteKeyboardNoRecents": { + "type": "text", + "placeholders": {} + }, + "setCustomEmotes": "", + "@setCustomEmotes": { + "type": "text", + "placeholders": {} + }, + "startedACall": "", + "@startedACall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "emoteInvalid": "", + "@emoteInvalid": { + "type": "text", + "placeholders": {} + }, + "systemTheme": "", + "@systemTheme": { + "type": "text", + "placeholders": {} + }, + "endToEndEncryption": "", + "@endToEndEncryption": {}, + "visibilityOfTheChatHistory": "", + "@visibilityOfTheChatHistory": { + "type": "text", + "placeholders": {} + }, + "settings": "", + "@settings": { + "type": "text", + "placeholders": {} + }, + "setTheme": "", + "@setTheme": {}, + "youJoinedTheChat": "", + "@youJoinedTheChat": {}, + "wallpaper": "", + "@wallpaper": { + "type": "text", + "placeholders": {} + }, + "statusExampleMessage": "", + "@statusExampleMessage": { + "type": "text", + "placeholders": {} + }, + "thisUserHasNotPostedAnythingYet": "", + "@thisUserHasNotPostedAnythingYet": {}, + "security": "", + "@security": { + "type": "text", + "placeholders": {} + }, + "markAsRead": "", + "@markAsRead": {}, + "sendAudio": "", + "@sendAudio": { + "type": "text", + "placeholders": {} + }, + "widgetName": "", + "@widgetName": {}, + "sentASticker": "", + "@sentASticker": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "errorAddingWidget": "", + "@errorAddingWidget": {}, + "commandHint_hug": "", + "@commandHint_hug": {}, + "replace": "", + "@replace": {}, + "reject": "", + "@reject": { + "type": "text", + "placeholders": {} + }, + "youUnbannedUser": "", + "@youUnbannedUser": { + "placeholders": { + "user": {} + } + }, + "visibleForEveryone": "", + "@visibleForEveryone": { + "type": "text", + "placeholders": {} + }, + "newSpace": "", + "@newSpace": {}, + "unknownEvent": "", + "@unknownEvent": { + "type": "text", + "placeholders": { + "type": {} + } + }, + "emojis": "", + "@emojis": {}, + "signUp": "", + "@signUp": { + "type": "text", + "placeholders": {} + }, + "share": "", + "@share": { + "type": "text", + "placeholders": {} + }, + "commandHint_googly": "", + "@commandHint_googly": {}, + "pleaseTryAgainLaterOrChooseDifferentServer": "", + "@pleaseTryAgainLaterOrChooseDifferentServer": {}, + "createGroup": "", + "@createGroup": {}, + "privacy": "", + "@privacy": { + "type": "text", + "placeholders": {} + }, + "sendImage": "", + "@sendImage": { + "type": "text", + "placeholders": {} + }, + "hydrateTorLong": "", + "@hydrateTorLong": {}, + "time": "", + "@time": {}, + "custom": "", + "@custom": {}, + "noBackupWarning": "", + "@noBackupWarning": {}, + "verify": "", + "@verify": { + "type": "text", + "placeholders": {} + }, + "sendVideo": "", + "@sendVideo": { + "type": "text", + "placeholders": {} + }, + "editWidgets": "", + "@editWidgets": {}, + "storeInSecureStorageDescription": "", + "@storeInSecureStorageDescription": {}, + "openChat": "", + "@openChat": {}, + "kickUserDescription": "", + "@kickUserDescription": {}, + "sendAMessage": "", + "@sendAMessage": { + "type": "text", + "placeholders": {} + }, + "importNow": "", + "@importNow": {}, + "setInvitationLink": "", + "@setInvitationLink": { + "type": "text", + "placeholders": {} + }, + "pinMessage": "", + "@pinMessage": {}, + "invite": "", + "@invite": {}, + "emotePacks": "", + "@emotePacks": { + "type": "text", + "placeholders": {} + }, + "continueWith": "", + "@continueWith": {}, + "indexedDbErrorTitle": "", + "@indexedDbErrorTitle": {}, + "discover": "", + "@discover": { + "type": "text", + "placeholders": {} + }, + "unsupportedAndroidVersionLong": "", + "@unsupportedAndroidVersionLong": {}, + "storeSecurlyOnThisDevice": "", + "@storeSecurlyOnThisDevice": {}, + "ok": "", + "@ok": { + "type": "text", + "placeholders": {} + }, + "sharedTheLocation": "", + "@sharedTheLocation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "unbanFromChat": "", + "@unbanFromChat": { + "type": "text", + "placeholders": {} + }, + "iUnderstand": "", + "@iUnderstand": {}, + "screenSharingDetail": "", + "@screenSharingDetail": {}, + "unreadChats": "", + "@unreadChats": { + "type": "text", + "placeholders": { + "unreadCount": {} + } + }, + "placeCall": "", + "@placeCall": {} +} diff --git a/assets/l10n/intl_hi.arb b/assets/l10n/intl_hi.arb index 9e26dfeeb..d138084cf 100644 --- a/assets/l10n/intl_hi.arb +++ b/assets/l10n/intl_hi.arb @@ -1 +1,2620 @@ -{} \ No newline at end of file +{ + "showPassword": "", + "@showPassword": { + "type": "text", + "placeholders": {} + }, + "hugContent": "", + "@hugContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "darkTheme": "", + "@darkTheme": { + "type": "text", + "placeholders": {} + }, + "passphraseOrKey": "", + "@passphraseOrKey": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourPassword": "", + "@pleaseEnterYourPassword": { + "type": "text", + "placeholders": {} + }, + "theyMatch": "", + "@theyMatch": { + "type": "text", + "placeholders": {} + }, + "connect": "", + "@connect": { + "type": "text", + "placeholders": {} + }, + "jumpToLastReadMessage": "", + "@jumpToLastReadMessage": {}, + "allRooms": "", + "@allRooms": { + "type": "text", + "placeholders": {} + }, + "obtainingLocation": "", + "@obtainingLocation": { + "type": "text", + "placeholders": {} + }, + "whoCanSeeMyStories": "", + "@whoCanSeeMyStories": {}, + "commandHint_cuddle": "", + "@commandHint_cuddle": {}, + "chats": "", + "@chats": { + "type": "text", + "placeholders": {} + }, + "widgetVideo": "", + "@widgetVideo": {}, + "dismiss": "", + "@dismiss": {}, + "unknownDevice": "", + "@unknownDevice": { + "type": "text", + "placeholders": {} + }, + "emoteShortcode": "", + "@emoteShortcode": { + "type": "text", + "placeholders": {} + }, + "noEncryptionForPublicRooms": "", + "@noEncryptionForPublicRooms": { + "type": "text", + "placeholders": {} + }, + "admin": "", + "@admin": { + "type": "text", + "placeholders": {} + }, + "reportErrorDescription": "", + "@reportErrorDescription": {}, + "directChats": "", + "@directChats": { + "type": "text", + "placeholders": {} + }, + "setPermissionsLevel": "", + "@setPermissionsLevel": { + "type": "text", + "placeholders": {} + }, + "inviteContactToGroup": "", + "@inviteContactToGroup": { + "type": "text", + "placeholders": { + "groupName": {} + } + }, + "addAccount": "", + "@addAccount": {}, + "close": "", + "@close": { + "type": "text", + "placeholders": {} + }, + "configureChat": "", + "@configureChat": { + "type": "text", + "placeholders": {} + }, + "seenByUserAndUser": "", + "@seenByUserAndUser": { + "type": "text", + "placeholders": { + "username": {}, + "username2": {} + } + }, + "chatHasBeenAddedToThisSpace": "", + "@chatHasBeenAddedToThisSpace": {}, + "reply": "", + "@reply": { + "type": "text", + "placeholders": {} + }, + "currentlyActive": "", + "@currentlyActive": { + "type": "text", + "placeholders": {} + }, + "removeYourAvatar": "", + "@removeYourAvatar": { + "type": "text", + "placeholders": {} + }, + "unsupportedAndroidVersion": "", + "@unsupportedAndroidVersion": {}, + "enterASpacepName": "", + "@enterASpacepName": {}, + "device": "", + "@device": { + "type": "text", + "placeholders": {} + }, + "blockDevice": "", + "@blockDevice": { + "type": "text", + "placeholders": {} + }, + "commandHint_html": "", + "@commandHint_html": { + "type": "text", + "description": "Usage hint for the command /html" + }, + "widgetJitsi": "", + "@widgetJitsi": {}, + "youAreNoLongerParticipatingInThisChat": "", + "@youAreNoLongerParticipatingInThisChat": { + "type": "text", + "placeholders": {} + }, + "encryption": "", + "@encryption": { + "type": "text", + "placeholders": {} + }, + "messageType": "", + "@messageType": {}, + "noEmailWarning": "", + "@noEmailWarning": {}, + "indexedDbErrorLong": "", + "@indexedDbErrorLong": {}, + "oneClientLoggedOut": "", + "@oneClientLoggedOut": {}, + "toggleMuted": "", + "@toggleMuted": { + "type": "text", + "placeholders": {} + }, + "unsupportedAndroidVersionLong": "", + "@unsupportedAndroidVersionLong": {}, + "kicked": "", + "@kicked": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "title": "", + "@title": { + "description": "Title for the application", + "type": "text", + "placeholders": {} + }, + "changeTheNameOfTheGroup": "", + "@changeTheNameOfTheGroup": { + "type": "text", + "placeholders": {} + }, + "changedTheChatAvatar": "", + "@changedTheChatAvatar": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "verifySuccess": "", + "@verifySuccess": { + "type": "text", + "placeholders": {} + }, + "sendFile": "", + "@sendFile": { + "type": "text", + "placeholders": {} + }, + "newVerificationRequest": "", + "@newVerificationRequest": { + "type": "text", + "placeholders": {} + }, + "startFirstChat": "", + "@startFirstChat": {}, + "callingAccount": "", + "@callingAccount": {}, + "requestPermission": "", + "@requestPermission": { + "type": "text", + "placeholders": {} + }, + "sentAPicture": "", + "@sentAPicture": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "invited": "", + "@invited": { + "type": "text", + "placeholders": {} + }, + "changedTheDisplaynameTo": "", + "@changedTheDisplaynameTo": { + "type": "text", + "placeholders": { + "username": {}, + "displayname": {} + } + }, + "setColorTheme": "", + "@setColorTheme": {}, + "nextAccount": "", + "@nextAccount": {}, + "commandHint_create": "", + "@commandHint_create": { + "type": "text", + "description": "Usage hint for the command /create" + }, + "youAreInvitedToThisChat": "", + "@youAreInvitedToThisChat": { + "type": "text", + "placeholders": {} + }, + "singlesignon": "", + "@singlesignon": { + "type": "text", + "placeholders": {} + }, + "warning": "", + "@warning": { + "type": "text", + "placeholders": {} + }, + "password": "", + "@password": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterAMatrixIdentifier": "", + "@pleaseEnterAMatrixIdentifier": { + "type": "text", + "placeholders": {} + }, + "allSpaces": "", + "@allSpaces": {}, + "supposedMxid": "", + "@supposedMxid": { + "type": "text", + "placeholders": { + "mxid": {} + } + }, + "editDisplayname": "", + "@editDisplayname": { + "type": "text", + "placeholders": {} + }, + "user": "", + "@user": {}, + "roomVersion": "", + "@roomVersion": { + "type": "text", + "placeholders": {} + }, + "sentAFile": "", + "@sentAFile": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "videoCall": "", + "@videoCall": { + "type": "text", + "placeholders": {} + }, + "youAcceptedTheInvitation": "", + "@youAcceptedTheInvitation": {}, + "banFromChat": "", + "@banFromChat": { + "type": "text", + "placeholders": {} + }, + "noMatrixServer": "", + "@noMatrixServer": { + "type": "text", + "placeholders": { + "server1": {}, + "server2": {} + } + }, + "userAndOthersAreTyping": "", + "@userAndOthersAreTyping": { + "type": "text", + "placeholders": { + "username": {}, + "count": {} + } + }, + "youInvitedBy": "", + "@youInvitedBy": { + "placeholders": { + "user": {} + } + }, + "userIsTyping": "", + "@userIsTyping": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "openAppToReadMessages": "", + "@openAppToReadMessages": { + "type": "text", + "placeholders": {} + }, + "sentAVideo": "", + "@sentAVideo": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "banUserDescription": "", + "@banUserDescription": {}, + "inviteContact": "", + "@inviteContact": { + "type": "text", + "placeholders": {} + }, + "requests": "", + "@requests": {}, + "askSSSSSign": "", + "@askSSSSSign": { + "type": "text", + "placeholders": {} + }, + "widgetEtherpad": "", + "@widgetEtherpad": {}, + "waitingPartnerAcceptRequest": "", + "@waitingPartnerAcceptRequest": { + "type": "text", + "placeholders": {} + }, + "remove": "", + "@remove": { + "type": "text", + "placeholders": {} + }, + "writeAMessage": "", + "@writeAMessage": { + "type": "text", + "placeholders": {} + }, + "changeTheme": "", + "@changeTheme": { + "type": "text", + "placeholders": {} + }, + "stories": "", + "@stories": {}, + "id": "", + "@id": { + "type": "text", + "placeholders": {} + }, + "addToStory": "", + "@addToStory": {}, + "removeDevicesDescription": "", + "@removeDevicesDescription": {}, + "changedTheChatDescriptionTo": "", + "@changedTheChatDescriptionTo": { + "type": "text", + "placeholders": { + "username": {}, + "description": {} + } + }, + "countParticipants": "", + "@countParticipants": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "separateChatTypes": "", + "@separateChatTypes": { + "type": "text", + "placeholders": {} + }, + "tryAgain": "", + "@tryAgain": {}, + "areGuestsAllowedToJoin": "", + "@areGuestsAllowedToJoin": { + "type": "text", + "placeholders": {} + }, + "blocked": "", + "@blocked": { + "type": "text", + "placeholders": {} + }, + "youKickedAndBanned": "", + "@youKickedAndBanned": { + "placeholders": { + "user": {} + } + }, + "dateWithoutYear": "", + "@dateWithoutYear": { + "type": "text", + "placeholders": { + "month": {}, + "day": {} + } + }, + "showDirectChatsInSpaces": "", + "@showDirectChatsInSpaces": { + "type": "text", + "placeholders": {} + }, + "removeDevice": "", + "@removeDevice": { + "type": "text", + "placeholders": {} + }, + "youCannotInviteYourself": "", + "@youCannotInviteYourself": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterValidEmail": "", + "@pleaseEnterValidEmail": {}, + "unbanUserDescription": "", + "@unbanUserDescription": {}, + "todoLists": "", + "@todoLists": {}, + "userAndUserAreTyping": "", + "@userAndUserAreTyping": { + "type": "text", + "placeholders": { + "username": {}, + "username2": {} + } + }, + "pleaseClickOnLink": "", + "@pleaseClickOnLink": { + "type": "text", + "placeholders": {} + }, + "saveFile": "", + "@saveFile": { + "type": "text", + "placeholders": {} + }, + "sendOnEnter": "", + "@sendOnEnter": {}, + "seenByUserAndCountOthers": "", + "@seenByUserAndCountOthers": { + "type": "text", + "placeholders": { + "username": {}, + "count": {} + } + }, + "pickImage": "", + "@pickImage": { + "type": "text", + "placeholders": {} + }, + "answeredTheCall": "", + "@answeredTheCall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "youRejectedTheInvitation": "", + "@youRejectedTheInvitation": {}, + "otherCallingPermissions": "", + "@otherCallingPermissions": {}, + "messagesStyle": "", + "@messagesStyle": {}, + "couldNotDecryptMessage": "", + "@couldNotDecryptMessage": { + "type": "text", + "placeholders": { + "error": {} + } + }, + "invitedUsersOnly": "", + "@invitedUsersOnly": { + "type": "text", + "placeholders": {} + }, + "link": "", + "@link": {}, + "widgetUrlError": "", + "@widgetUrlError": {}, + "emailOrUsername": "", + "@emailOrUsername": {}, + "newSpaceDescription": "", + "@newSpaceDescription": {}, + "chatDescription": "", + "@chatDescription": {}, + "callingAccountDetails": "", + "@callingAccountDetails": {}, + "next": "", + "@next": { + "type": "text", + "placeholders": {} + }, + "pleaseFollowInstructionsOnWeb": "", + "@pleaseFollowInstructionsOnWeb": { + "type": "text", + "placeholders": {} + }, + "changedTheGuestAccessRules": "", + "@changedTheGuestAccessRules": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "pleaseChooseAtLeastChars": "", + "@pleaseChooseAtLeastChars": { + "type": "text", + "placeholders": { + "min": {} + } + }, + "dateWithYear": "", + "@dateWithYear": { + "type": "text", + "placeholders": { + "year": {}, + "month": {}, + "day": {} + } + }, + "editRoomAliases": "", + "@editRoomAliases": { + "type": "text", + "placeholders": {} + }, + "enterSpace": "", + "@enterSpace": {}, + "encryptThisChat": "", + "@encryptThisChat": {}, + "fileName": "", + "@fileName": { + "type": "text", + "placeholders": {} + }, + "unavailable": "", + "@unavailable": { + "type": "text", + "placeholders": {} + }, + "previousAccount": "", + "@previousAccount": {}, + "publicRooms": "", + "@publicRooms": { + "type": "text", + "placeholders": {} + }, + "fromTheInvitation": "", + "@fromTheInvitation": { + "type": "text", + "placeholders": {} + }, + "sendMessages": "", + "@sendMessages": { + "type": "text", + "placeholders": {} + }, + "incorrectPassphraseOrKey": "", + "@incorrectPassphraseOrKey": { + "type": "text", + "placeholders": {} + }, + "emoteWarnNeedToPick": "", + "@emoteWarnNeedToPick": { + "type": "text", + "placeholders": {} + }, + "reopenChat": "", + "@reopenChat": {}, + "pleaseEnterRecoveryKey": "", + "@pleaseEnterRecoveryKey": {}, + "create": "", + "@create": { + "type": "text", + "placeholders": {} + }, + "toggleFavorite": "", + "@toggleFavorite": { + "type": "text", + "placeholders": {} + }, + "no": "", + "@no": { + "type": "text", + "placeholders": {} + }, + "alias": "", + "@alias": { + "type": "text", + "placeholders": {} + }, + "widgetNameError": "", + "@widgetNameError": {}, + "inoffensive": "", + "@inoffensive": { + "type": "text", + "placeholders": {} + }, + "unpin": "", + "@unpin": { + "type": "text", + "placeholders": {} + }, + "addToBundle": "", + "@addToBundle": {}, + "reportMessage": "", + "@reportMessage": { + "type": "text", + "placeholders": {} + }, + "spaceIsPublic": "", + "@spaceIsPublic": { + "type": "text", + "placeholders": {} + }, + "addWidget": "", + "@addWidget": {}, + "all": "", + "@all": { + "type": "text", + "placeholders": {} + }, + "removeAllOtherDevices": "", + "@removeAllOtherDevices": { + "type": "text", + "placeholders": {} + }, + "unblockDevice": "", + "@unblockDevice": { + "type": "text", + "placeholders": {} + }, + "countFiles": "", + "@countFiles": { + "placeholders": { + "count": {} + } + }, + "noKeyForThisMessage": "", + "@noKeyForThisMessage": {}, + "enableEncryptionWarning": "", + "@enableEncryptionWarning": { + "type": "text", + "placeholders": {} + }, + "inviteText": "", + "@inviteText": { + "type": "text", + "placeholders": { + "username": {}, + "link": {} + } + }, + "shareLocation": "", + "@shareLocation": { + "type": "text", + "placeholders": {} + }, + "reason": "", + "@reason": { + "type": "text", + "placeholders": {} + }, + "commandHint_markasgroup": "", + "@commandHint_markasgroup": {}, + "editTodo": "", + "@editTodo": {}, + "errorObtainingLocation": "", + "@errorObtainingLocation": { + "type": "text", + "placeholders": { + "error": {} + } + }, + "hydrateTor": "", + "@hydrateTor": {}, + "pushNotificationsNotAvailable": "", + "@pushNotificationsNotAvailable": {}, + "passwordRecovery": "", + "@passwordRecovery": { + "type": "text", + "placeholders": {} + }, + "storeInAppleKeyChain": "", + "@storeInAppleKeyChain": {}, + "replaceRoomWithNewerVersion": "", + "@replaceRoomWithNewerVersion": { + "type": "text", + "placeholders": {} + }, + "hydrate": "", + "@hydrate": {}, + "invalidServerName": "", + "@invalidServerName": {}, + "chatPermissions": "", + "@chatPermissions": {}, + "voiceMessage": "", + "@voiceMessage": { + "type": "text", + "placeholders": {} + }, + "badServerLoginTypesException": "", + "@badServerLoginTypesException": { + "type": "text", + "placeholders": { + "serverVersions": {}, + "supportedVersions": {} + } + }, + "wipeChatBackup": "", + "@wipeChatBackup": { + "type": "text", + "placeholders": {} + }, + "cantOpenUri": "", + "@cantOpenUri": { + "type": "text", + "placeholders": { + "uri": {} + } + }, + "sender": "", + "@sender": {}, + "storeInAndroidKeystore": "", + "@storeInAndroidKeystore": {}, + "optionalGroupName": "", + "@optionalGroupName": { + "type": "text", + "placeholders": {} + }, + "hideRedactedEvents": "", + "@hideRedactedEvents": { + "type": "text", + "placeholders": {} + }, + "online": "", + "@online": { + "type": "text", + "placeholders": {} + }, + "signInWithPassword": "", + "@signInWithPassword": {}, + "pleaseAddATitle": "", + "@pleaseAddATitle": {}, + "updateNow": "", + "@updateNow": {}, + "ignoredUsers": "", + "@ignoredUsers": { + "type": "text", + "placeholders": {} + }, + "lastActiveAgo": "", + "@lastActiveAgo": { + "type": "text", + "placeholders": { + "localizedTimeShort": {} + } + }, + "changedTheGuestAccessRulesTo": "", + "@changedTheGuestAccessRulesTo": { + "type": "text", + "placeholders": { + "username": {}, + "rules": {} + } + }, + "weSentYouAnEmail": "", + "@weSentYouAnEmail": { + "type": "text", + "placeholders": {} + }, + "offensive": "", + "@offensive": { + "type": "text", + "placeholders": {} + }, + "needPantalaimonWarning": "", + "@needPantalaimonWarning": { + "type": "text", + "placeholders": {} + }, + "makeAdminDescription": "", + "@makeAdminDescription": {}, + "edit": "", + "@edit": { + "type": "text", + "placeholders": {} + }, + "loadMore": "", + "@loadMore": { + "type": "text", + "placeholders": {} + }, + "noEmotesFound": "", + "@noEmotesFound": { + "type": "text", + "placeholders": {} + }, + "synchronizingPleaseWait": "", + "@synchronizingPleaseWait": { + "type": "text", + "placeholders": {} + }, + "transferFromAnotherDevice": "", + "@transferFromAnotherDevice": { + "type": "text", + "placeholders": {} + }, + "passwordHasBeenChanged": "", + "@passwordHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "pushRules": "", + "@pushRules": { + "type": "text", + "placeholders": {} + }, + "goToTheNewRoom": "", + "@goToTheNewRoom": { + "type": "text", + "placeholders": {} + }, + "commandHint_clearcache": "", + "@commandHint_clearcache": { + "type": "text", + "description": "Usage hint for the command /clearcache" + }, + "loadingPleaseWait": "", + "@loadingPleaseWait": { + "type": "text", + "placeholders": {} + }, + "copy": "", + "@copy": { + "type": "text", + "placeholders": {} + }, + "saveKeyManuallyDescription": "", + "@saveKeyManuallyDescription": {}, + "none": "", + "@none": { + "type": "text", + "placeholders": {} + }, + "editBundlesForAccount": "", + "@editBundlesForAccount": {}, + "renderRichContent": "", + "@renderRichContent": { + "type": "text", + "placeholders": {} + }, + "enableEncryption": "", + "@enableEncryption": { + "type": "text", + "placeholders": {} + }, + "whyIsThisMessageEncrypted": "", + "@whyIsThisMessageEncrypted": {}, + "unreadChats": "", + "@unreadChats": { + "type": "text", + "placeholders": { + "unreadCount": {} + } + }, + "rejectedTheInvitation": "", + "@rejectedTheInvitation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "setChatDescription": "", + "@setChatDescription": {}, + "userLeftTheChat": "", + "@userLeftTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "spaceName": "", + "@spaceName": { + "type": "text", + "placeholders": {} + }, + "importFromZipFile": "", + "@importFromZipFile": {}, + "discover": "", + "@discover": { + "type": "text", + "placeholders": {} + }, + "toggleUnread": "", + "@toggleUnread": { + "type": "text", + "placeholders": {} + }, + "or": "", + "@or": { + "type": "text", + "placeholders": {} + }, + "dehydrateWarning": "", + "@dehydrateWarning": {}, + "sendOriginal": "", + "@sendOriginal": { + "type": "text", + "placeholders": {} + }, + "noOtherDevicesFound": "", + "@noOtherDevicesFound": {}, + "whoIsAllowedToJoinThisGroup": "", + "@whoIsAllowedToJoinThisGroup": { + "type": "text", + "placeholders": {} + }, + "emptyChat": "", + "@emptyChat": { + "type": "text", + "placeholders": {} + }, + "seenByUser": "", + "@seenByUser": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "storeSecurlyOnThisDevice": "", + "@storeSecurlyOnThisDevice": {}, + "yourChatBackupHasBeenSetUp": "", + "@yourChatBackupHasBeenSetUp": {}, + "addDescription": "", + "@addDescription": {}, + "chatBackup": "", + "@chatBackup": { + "type": "text", + "placeholders": {} + }, + "redactedBy": "", + "@redactedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "submit": "", + "@submit": { + "type": "text", + "placeholders": {} + }, + "videoCallsBetaWarning": "", + "@videoCallsBetaWarning": {}, + "unmuteChat": "", + "@unmuteChat": { + "type": "text", + "placeholders": {} + }, + "createdTheChat": "", + "@createdTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "redactedAnEvent": "", + "@redactedAnEvent": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "autoplayImages": "", + "@autoplayImages": { + "type": "text", + "placeholder": {} + }, + "storyPrivacyWarning": "", + "@storyPrivacyWarning": {}, + "compareEmojiMatch": "", + "@compareEmojiMatch": { + "type": "text", + "placeholders": {} + }, + "matrixWidgets": "", + "@matrixWidgets": {}, + "participant": "", + "@participant": { + "type": "text", + "placeholders": {} + }, + "logInTo": "", + "@logInTo": { + "type": "text", + "placeholders": { + "homeserver": {} + } + }, + "yes": "", + "@yes": { + "type": "text", + "placeholders": {} + }, + "containsDisplayName": "", + "@containsDisplayName": { + "type": "text", + "placeholders": {} + }, + "signInWith": "", + "@signInWith": { + "type": "text", + "placeholders": { + "provider": {} + } + }, + "username": "", + "@username": { + "type": "text", + "placeholders": {} + }, + "changedTheRoomAliases": "", + "@changedTheRoomAliases": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "updateAvailable": "", + "@updateAvailable": {}, + "fileIsTooBigForServer": "", + "@fileIsTooBigForServer": {}, + "homeserver": "", + "@homeserver": {}, + "help": "", + "@help": { + "type": "text", + "placeholders": {} + }, + "noTodosYet": "", + "@noTodosYet": {}, + "chatDetails": "", + "@chatDetails": { + "type": "text", + "placeholders": {} + }, + "people": "", + "@people": { + "type": "text", + "placeholders": {} + }, + "changedTheHistoryVisibilityTo": "", + "@changedTheHistoryVisibilityTo": { + "type": "text", + "placeholders": { + "username": {}, + "rules": {} + } + }, + "leftTheChat": "", + "@leftTheChat": { + "type": "text", + "placeholders": {} + }, + "verified": "", + "@verified": { + "type": "text", + "placeholders": {} + }, + "repeatPassword": "", + "@repeatPassword": {}, + "setStatus": "", + "@setStatus": { + "type": "text", + "placeholders": {} + }, + "groupWith": "", + "@groupWith": { + "type": "text", + "placeholders": { + "displayname": {} + } + }, + "callingPermissions": "", + "@callingPermissions": {}, + "delete": "", + "@delete": { + "type": "text", + "placeholders": {} + }, + "newMessageInFluffyChat": "", + "@newMessageInFluffyChat": { + "type": "text", + "placeholders": {} + }, + "readUpToHere": "", + "@readUpToHere": {}, + "start": "", + "@start": {}, + "bubbleSize": "", + "@bubbleSize": { + "type": "text", + "placeholders": {} + }, + "downloadFile": "", + "@downloadFile": { + "type": "text", + "placeholders": {} + }, + "deviceId": "", + "@deviceId": { + "type": "text", + "placeholders": {} + }, + "register": "", + "@register": { + "type": "text", + "placeholders": {} + }, + "unlockOldMessages": "", + "@unlockOldMessages": {}, + "identity": "", + "@identity": { + "type": "text", + "placeholders": {} + }, + "numChats": "", + "@numChats": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "changedTheJoinRulesTo": "", + "@changedTheJoinRulesTo": { + "type": "text", + "placeholders": { + "username": {}, + "joinRules": {} + } + }, + "ignore": "", + "@ignore": { + "type": "text", + "placeholders": {} + }, + "whatIsGoingOn": "", + "@whatIsGoingOn": {}, + "recording": "", + "@recording": { + "type": "text", + "placeholders": {} + }, + "changedTheChatPermissions": "", + "@changedTheChatPermissions": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changeWallpaper": "", + "@changeWallpaper": { + "type": "text", + "placeholders": {} + }, + "moderator": "", + "@moderator": { + "type": "text", + "placeholders": {} + }, + "optionalRedactReason": "", + "@optionalRedactReason": {}, + "acceptedTheInvitation": "", + "@acceptedTheInvitation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "waitingPartnerEmoji": "", + "@waitingPartnerEmoji": { + "type": "text", + "placeholders": {} + }, + "channelCorruptedDecryptError": "", + "@channelCorruptedDecryptError": { + "type": "text", + "placeholders": {} + }, + "tryToSendAgain": "", + "@tryToSendAgain": { + "type": "text", + "placeholders": {} + }, + "guestsCanJoin": "", + "@guestsCanJoin": { + "type": "text", + "placeholders": {} + }, + "ok": "", + "@ok": { + "type": "text", + "placeholders": {} + }, + "copyToClipboard": "", + "@copyToClipboard": { + "type": "text", + "placeholders": {} + }, + "dehydrate": "", + "@dehydrate": {}, + "locationPermissionDeniedNotice": "", + "@locationPermissionDeniedNotice": { + "type": "text", + "placeholders": {} + }, + "send": "", + "@send": { + "type": "text", + "placeholders": {} + }, + "hasWithdrawnTheInvitationFor": "", + "@hasWithdrawnTheInvitationFor": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "visibleForAllParticipants": "", + "@visibleForAllParticipants": { + "type": "text", + "placeholders": {} + }, + "noRoomsFound": "", + "@noRoomsFound": { + "type": "text", + "placeholders": {} + }, + "banned": "", + "@banned": { + "type": "text", + "placeholders": {} + }, + "sendAsText": "", + "@sendAsText": { + "type": "text" + }, + "inviteForMe": "", + "@inviteForMe": { + "type": "text", + "placeholders": {} + }, + "archiveRoomDescription": "", + "@archiveRoomDescription": {}, + "exportEmotePack": "", + "@exportEmotePack": {}, + "changedTheChatNameTo": "", + "@changedTheChatNameTo": { + "type": "text", + "placeholders": { + "username": {}, + "chatname": {} + } + }, + "sendSticker": "", + "@sendSticker": { + "type": "text", + "placeholders": {} + }, + "account": "", + "@account": { + "type": "text", + "placeholders": {} + }, + "switchToAccount": "", + "@switchToAccount": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "commandInvalid": "", + "@commandInvalid": { + "type": "text" + }, + "setAsCanonicalAlias": "", + "@setAsCanonicalAlias": { + "type": "text", + "placeholders": {} + }, + "whyDoYouWantToReportThis": "", + "@whyDoYouWantToReportThis": { + "type": "text", + "placeholders": {} + }, + "locationDisabledNotice": "", + "@locationDisabledNotice": { + "type": "text", + "placeholders": {} + }, + "letsStart": "", + "@letsStart": {}, + "placeCall": "", + "@placeCall": {}, + "removedBy": "", + "@removedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheRoomInvitationLink": "", + "@changedTheRoomInvitationLink": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "newChat": "", + "@newChat": { + "type": "text", + "placeholders": {} + }, + "notifications": "", + "@notifications": { + "type": "text", + "placeholders": {} + }, + "commandHint_plain": "", + "@commandHint_plain": { + "type": "text", + "description": "Usage hint for the command /plain" + }, + "emoteSettings": "", + "@emoteSettings": { + "type": "text", + "placeholders": {} + }, + "experimentalVideoCalls": "", + "@experimentalVideoCalls": {}, + "savedEmotePack": "", + "@savedEmotePack": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "openCamera": "", + "@openCamera": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterRecoveryKeyDescription": "", + "@pleaseEnterRecoveryKeyDescription": {}, + "guestsAreForbidden": "", + "@guestsAreForbidden": { + "type": "text", + "placeholders": {} + }, + "mention": "", + "@mention": { + "type": "text", + "placeholders": {} + }, + "openInMaps": "", + "@openInMaps": { + "type": "text", + "placeholders": {} + }, + "withTheseAddressesRecoveryDescription": "", + "@withTheseAddressesRecoveryDescription": { + "type": "text", + "placeholders": {} + }, + "inviteContactToGroupQuestion": "", + "@inviteContactToGroupQuestion": {}, + "emoteExists": "", + "@emoteExists": { + "type": "text", + "placeholders": {} + }, + "redactedByBecause": "", + "@redactedByBecause": { + "type": "text", + "placeholders": { + "username": {}, + "reason": {} + } + }, + "isTyping": "", + "@isTyping": { + "type": "text", + "placeholders": {} + }, + "youHaveWithdrawnTheInvitationFor": "", + "@youHaveWithdrawnTheInvitationFor": { + "placeholders": { + "user": {} + } + }, + "chat": "", + "@chat": { + "type": "text", + "placeholders": {} + }, + "group": "", + "@group": { + "type": "text", + "placeholders": {} + }, + "leave": "", + "@leave": { + "type": "text", + "placeholders": {} + }, + "skip": "", + "@skip": { + "type": "text", + "placeholders": {} + }, + "appearOnTopDetails": "", + "@appearOnTopDetails": {}, + "roomHasBeenUpgraded": "", + "@roomHasBeenUpgraded": { + "type": "text", + "placeholders": {} + }, + "enterRoom": "", + "@enterRoom": {}, + "enableEmotesGlobally": "", + "@enableEmotesGlobally": { + "type": "text", + "placeholders": {} + }, + "areYouSure": "", + "@areYouSure": { + "type": "text", + "placeholders": {} + }, + "ignoreListDescription": "", + "@ignoreListDescription": { + "type": "text", + "placeholders": {} + }, + "pleaseChooseAPasscode": "", + "@pleaseChooseAPasscode": { + "type": "text", + "placeholders": {} + }, + "noPasswordRecoveryDescription": "", + "@noPasswordRecoveryDescription": { + "type": "text", + "placeholders": {} + }, + "changedTheProfileAvatar": "", + "@changedTheProfileAvatar": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "allChats": "", + "@allChats": { + "type": "text", + "placeholders": {} + }, + "reportUser": "", + "@reportUser": {}, + "passwordsDoNotMatch": "", + "@passwordsDoNotMatch": {}, + "sharedTheLocation": "", + "@sharedTheLocation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "commandHint_send": "", + "@commandHint_send": { + "type": "text", + "description": "Usage hint for the command /send" + }, + "onlineKeyBackupEnabled": "", + "@onlineKeyBackupEnabled": { + "type": "text", + "placeholders": {} + }, + "unbannedUser": "", + "@unbannedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "confirmEventUnpin": "", + "@confirmEventUnpin": {}, + "badServerVersionsException": "", + "@badServerVersionsException": { + "type": "text", + "placeholders": { + "serverVersions": {}, + "supportedVersions": {} + } + }, + "youInvitedUser": "", + "@youInvitedUser": { + "placeholders": { + "user": {} + } + }, + "kickedAndBanned": "", + "@kickedAndBanned": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "noConnectionToTheServer": "", + "@noConnectionToTheServer": { + "type": "text", + "placeholders": {} + }, + "fileHasBeenSavedAt": "", + "@fileHasBeenSavedAt": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "license": "", + "@license": { + "type": "text", + "placeholders": {} + }, + "addToSpace": "", + "@addToSpace": {}, + "unbanFromChat": "", + "@unbanFromChat": { + "type": "text", + "placeholders": {} + }, + "importZipFile": "", + "@importZipFile": {}, + "anyoneCanKnock": "", + "@anyoneCanKnock": {}, + "commandMissing": "", + "@commandMissing": { + "type": "text", + "placeholders": { + "command": {} + }, + "description": "State that {command} is not a valid /command." + }, + "redactMessageDescription": "", + "@redactMessageDescription": {}, + "rejoin": "", + "@rejoin": { + "type": "text", + "placeholders": {} + }, + "recoveryKey": "", + "@recoveryKey": {}, + "redactMessage": "", + "@redactMessage": { + "type": "text", + "placeholders": {} + }, + "forward": "", + "@forward": { + "type": "text", + "placeholders": {} + }, + "commandHint_discardsession": "", + "@commandHint_discardsession": { + "type": "text", + "description": "Usage hint for the command /discardsession" + }, + "invalidInput": "", + "@invalidInput": {}, + "about": "", + "@about": { + "type": "text", + "placeholders": {} + }, + "chooseAStrongPassword": "", + "@chooseAStrongPassword": { + "type": "text", + "placeholders": {} + }, + "hideUnknownEvents": "", + "@hideUnknownEvents": { + "type": "text", + "placeholders": {} + }, + "todosUnencrypted": "", + "@todosUnencrypted": {}, + "dehydrateTorLong": "", + "@dehydrateTorLong": {}, + "yourPublicKey": "", + "@yourPublicKey": { + "type": "text", + "placeholders": {} + }, + "tooManyRequestsWarning": "", + "@tooManyRequestsWarning": { + "type": "text", + "placeholders": {} + }, + "invitedUser": "", + "@invitedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "kickFromChat": "", + "@kickFromChat": { + "type": "text", + "placeholders": {} + }, + "commandHint_myroomnick": "", + "@commandHint_myroomnick": { + "type": "text", + "description": "Usage hint for the command /myroomnick" + }, + "offline": "", + "@offline": { + "type": "text", + "placeholders": {} + }, + "replyHasBeenSent": "", + "@replyHasBeenSent": {}, + "noPermission": "", + "@noPermission": { + "type": "text", + "placeholders": {} + }, + "doNotShowAgain": "", + "@doNotShowAgain": {}, + "activatedEndToEndEncryption": "", + "@activatedEndToEndEncryption": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "report": "", + "@report": {}, + "status": "", + "@status": { + "type": "text", + "placeholders": {} + }, + "deny": "", + "@deny": { + "type": "text", + "placeholders": {} + }, + "compareNumbersMatch": "", + "@compareNumbersMatch": { + "type": "text", + "placeholders": {} + }, + "groupIsPublic": "", + "@groupIsPublic": { + "type": "text", + "placeholders": {} + }, + "verifyStart": "", + "@verifyStart": { + "type": "text", + "placeholders": {} + }, + "yourStory": "", + "@yourStory": {}, + "memberChanges": "", + "@memberChanges": { + "type": "text", + "placeholders": {} + }, + "joinRoom": "", + "@joinRoom": { + "type": "text", + "placeholders": {} + }, + "ignoreUsername": "", + "@ignoreUsername": { + "type": "text", + "placeholders": {} + }, + "unverified": "", + "@unverified": {}, + "fluffychat": "", + "@fluffychat": { + "type": "text", + "placeholders": {} + }, + "howOffensiveIsThisContent": "", + "@howOffensiveIsThisContent": { + "type": "text", + "placeholders": {} + }, + "serverRequiresEmail": "", + "@serverRequiresEmail": {}, + "hideUnimportantStateEvents": "", + "@hideUnimportantStateEvents": {}, + "screenSharingTitle": "", + "@screenSharingTitle": {}, + "widgetCustom": "", + "@widgetCustom": {}, + "sentCallInformations": "", + "@sentCallInformations": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "addToSpaceDescription": "", + "@addToSpaceDescription": {}, + "googlyEyesContent": "", + "@googlyEyesContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "whoCanSeeMyStoriesDesc": "", + "@whoCanSeeMyStoriesDesc": {}, + "youBannedUser": "", + "@youBannedUser": { + "placeholders": { + "user": {} + } + }, + "theyDontMatch": "", + "@theyDontMatch": { + "type": "text", + "placeholders": {} + }, + "unsubscribeStories": "", + "@unsubscribeStories": {}, + "youHaveBeenBannedFromThisChat": "", + "@youHaveBeenBannedFromThisChat": { + "type": "text", + "placeholders": {} + }, + "displaynameHasBeenChanged": "", + "@displaynameHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "loginWithOneClick": "", + "@loginWithOneClick": {}, + "addChatDescription": "", + "@addChatDescription": {}, + "sentAnAudio": "", + "@sentAnAudio": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "editRoomAvatar": "", + "@editRoomAvatar": { + "type": "text", + "placeholders": {} + }, + "encrypted": "", + "@encrypted": { + "type": "text", + "placeholders": {} + }, + "commandHint_leave": "", + "@commandHint_leave": { + "type": "text", + "description": "Usage hint for the command /leave" + }, + "commandHint_myroomavatar": "", + "@commandHint_myroomavatar": { + "type": "text", + "description": "Usage hint for the command /myroomavatar" + }, + "cancel": "", + "@cancel": { + "type": "text", + "placeholders": {} + }, + "hasKnocked": "", + "@hasKnocked": { + "placeholders": { + "user": {} + } + }, + "publish": "", + "@publish": {}, + "openLinkInBrowser": "", + "@openLinkInBrowser": {}, + "clearArchive": "", + "@clearArchive": {}, + "appLock": "", + "@appLock": { + "type": "text", + "placeholders": {} + }, + "commandHint_react": "", + "@commandHint_react": { + "type": "text", + "description": "Usage hint for the command /react" + }, + "changedTheHistoryVisibility": "", + "@changedTheHistoryVisibility": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "commandHint_me": "", + "@commandHint_me": { + "type": "text", + "description": "Usage hint for the command /me" + }, + "pleaseEnterYourUsername": "", + "@pleaseEnterYourUsername": { + "type": "text", + "placeholders": {} + }, + "messageInfo": "", + "@messageInfo": {}, + "disableEncryptionWarning": "", + "@disableEncryptionWarning": {}, + "directChat": "", + "@directChat": {}, + "noOneCanJoin": "", + "@noOneCanJoin": {}, + "encryptionNotEnabled": "", + "@encryptionNotEnabled": { + "type": "text", + "placeholders": {} + }, + "wrongPinEntered": "", + "@wrongPinEntered": { + "type": "text", + "placeholders": { + "seconds": {} + } + }, + "sendTypingNotifications": "", + "@sendTypingNotifications": {}, + "lightTheme": "", + "@lightTheme": { + "type": "text", + "placeholders": {} + }, + "inviteGroupChat": "", + "@inviteGroupChat": {}, + "appearOnTop": "", + "@appearOnTop": {}, + "invitePrivateChat": "", + "@invitePrivateChat": {}, + "verifyTitle": "", + "@verifyTitle": { + "type": "text", + "placeholders": {} + }, + "foregroundServiceRunning": "", + "@foregroundServiceRunning": {}, + "enterAnEmailAddress": "", + "@enterAnEmailAddress": { + "type": "text", + "placeholders": {} + }, + "voiceCall": "", + "@voiceCall": {}, + "commandHint_kick": "", + "@commandHint_kick": { + "type": "text", + "description": "Usage hint for the command /kick" + }, + "copiedToClipboard": "", + "@copiedToClipboard": { + "type": "text", + "placeholders": {} + }, + "createNewSpace": "", + "@createNewSpace": { + "type": "text", + "placeholders": {} + }, + "commandHint_unban": "", + "@commandHint_unban": { + "type": "text", + "description": "Usage hint for the command /unban" + }, + "unknownEncryptionAlgorithm": "", + "@unknownEncryptionAlgorithm": { + "type": "text", + "placeholders": {} + }, + "commandHint_ban": "", + "@commandHint_ban": { + "type": "text", + "description": "Usage hint for the command /ban" + }, + "importEmojis": "", + "@importEmojis": {}, + "confirm": "", + "@confirm": { + "type": "text", + "placeholders": {} + }, + "wasDirectChatDisplayName": "", + "@wasDirectChatDisplayName": { + "type": "text", + "placeholders": { + "oldDisplayName": {} + } + }, + "noChatDescriptionYet": "", + "@noChatDescriptionYet": {}, + "defaultPermissionLevel": "", + "@defaultPermissionLevel": { + "type": "text", + "placeholders": {} + }, + "newTodo": "", + "@newTodo": {}, + "removeFromBundle": "", + "@removeFromBundle": {}, + "numUsersTyping": "", + "@numUsersTyping": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "fontSize": "", + "@fontSize": { + "type": "text", + "placeholders": {} + }, + "whoCanPerformWhichAction": "", + "@whoCanPerformWhichAction": { + "type": "text", + "placeholders": {} + }, + "confirmMatrixId": "", + "@confirmMatrixId": {}, + "learnMore": "", + "@learnMore": {}, + "iHaveClickedOnLink": "", + "@iHaveClickedOnLink": { + "type": "text", + "placeholders": {} + }, + "you": "", + "@you": { + "type": "text", + "placeholders": {} + }, + "notAnImage": "", + "@notAnImage": {}, + "users": "", + "@users": {}, + "openGallery": "", + "@openGallery": {}, + "chatDescriptionHasBeenChanged": "", + "@chatDescriptionHasBeenChanged": {}, + "search": "", + "@search": { + "type": "text", + "placeholders": {} + }, + "newGroup": "", + "@newGroup": {}, + "bundleName": "", + "@bundleName": {}, + "dehydrateTor": "", + "@dehydrateTor": {}, + "todoListChangedError": "", + "@todoListChangedError": {}, + "removeFromSpace": "", + "@removeFromSpace": {}, + "enterInviteLinkOrMatrixId": "", + "@enterInviteLinkOrMatrixId": {}, + "dateAndTimeOfDay": "", + "@dateAndTimeOfDay": { + "type": "text", + "placeholders": { + "date": {}, + "timeOfDay": {} + } + }, + "commandHint_op": "", + "@commandHint_op": { + "type": "text", + "description": "Usage hint for the command /op" + }, + "commandHint_join": "", + "@commandHint_join": { + "type": "text", + "description": "Usage hint for the command /join" + }, + "sourceCode": "", + "@sourceCode": { + "type": "text", + "placeholders": {} + }, + "enterAGroupName": "", + "@enterAGroupName": { + "type": "text", + "placeholders": {} + }, + "roomUpgradeDescription": "", + "@roomUpgradeDescription": {}, + "commandHint_invite": "", + "@commandHint_invite": { + "type": "text", + "description": "Usage hint for the command /invite" + }, + "userSentUnknownEvent": "", + "@userSentUnknownEvent": { + "type": "text", + "placeholders": { + "username": {}, + "type": {} + } + }, + "scanQrCode": "", + "@scanQrCode": {}, + "logout": "", + "@logout": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterANumber": "", + "@pleaseEnterANumber": {}, + "contactHasBeenInvitedToTheGroup": "", + "@contactHasBeenInvitedToTheGroup": { + "type": "text", + "placeholders": {} + }, + "youKicked": "", + "@youKicked": { + "placeholders": { + "user": {} + } + }, + "areYouSureYouWantToLogout": "", + "@areYouSureYouWantToLogout": { + "type": "text", + "placeholders": {} + }, + "changedTheJoinRules": "", + "@changedTheJoinRules": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "profileNotFound": "", + "@profileNotFound": {}, + "jump": "", + "@jump": {}, + "groups": "", + "@groups": { + "type": "text", + "placeholders": {} + }, + "reactedWith": "", + "@reactedWith": { + "type": "text", + "placeholders": { + "sender": {}, + "reaction": {} + } + }, + "bannedUser": "", + "@bannedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "iUnderstand": "", + "@iUnderstand": {}, + "sorryThatsNotPossible": "", + "@sorryThatsNotPossible": {}, + "storyFrom": "", + "@storyFrom": { + "type": "text", + "placeholders": { + "date": {}, + "body": {} + } + }, + "videoWithSize": "", + "@videoWithSize": { + "type": "text", + "placeholders": { + "size": {} + } + }, + "oopsSomethingWentWrong": "", + "@oopsSomethingWentWrong": { + "type": "text", + "placeholders": {} + }, + "loadCountMoreParticipants": "", + "@loadCountMoreParticipants": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "shareInviteLink": "", + "@shareInviteLink": {}, + "commandHint_markasdm": "", + "@commandHint_markasdm": {}, + "recoveryKeyLost": "", + "@recoveryKeyLost": {}, + "cuddleContent": "", + "@cuddleContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "askVerificationRequest": "", + "@askVerificationRequest": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "containsUserName": "", + "@containsUserName": { + "type": "text", + "placeholders": {} + }, + "messages": "", + "@messages": { + "type": "text", + "placeholders": {} + }, + "login": "", + "@login": { + "type": "text", + "placeholders": {} + }, + "deviceKeys": "", + "@deviceKeys": {}, + "waitingPartnerNumbers": "", + "@waitingPartnerNumbers": { + "type": "text", + "placeholders": {} + }, + "noGoogleServicesWarning": "", + "@noGoogleServicesWarning": { + "type": "text", + "placeholders": {} + }, + "everythingReady": "", + "@everythingReady": { + "type": "text", + "placeholders": {} + }, + "addEmail": "", + "@addEmail": { + "type": "text", + "placeholders": {} + }, + "emoteKeyboardNoRecents": "", + "@emoteKeyboardNoRecents": { + "type": "text", + "placeholders": {} + }, + "setCustomEmotes": "", + "@setCustomEmotes": { + "type": "text", + "placeholders": {} + }, + "startedACall": "", + "@startedACall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "emoteInvalid": "", + "@emoteInvalid": { + "type": "text", + "placeholders": {} + }, + "systemTheme": "", + "@systemTheme": { + "type": "text", + "placeholders": {} + }, + "messageWillBeRemovedWarning": "", + "@messageWillBeRemovedWarning": { + "type": "text", + "placeholders": {} + }, + "endToEndEncryption": "", + "@endToEndEncryption": {}, + "notificationsEnabledForThisAccount": "", + "@notificationsEnabledForThisAccount": { + "type": "text", + "placeholders": {} + }, + "deleteMessage": "", + "@deleteMessage": { + "type": "text", + "placeholders": {} + }, + "visibilityOfTheChatHistory": "", + "@visibilityOfTheChatHistory": { + "type": "text", + "placeholders": {} + }, + "settings": "", + "@settings": { + "type": "text", + "placeholders": {} + }, + "setTheme": "", + "@setTheme": {}, + "changeTheHomeserver": "", + "@changeTheHomeserver": { + "type": "text", + "placeholders": {} + }, + "youJoinedTheChat": "", + "@youJoinedTheChat": {}, + "wallpaper": "", + "@wallpaper": { + "type": "text", + "placeholders": {} + }, + "openVideoCamera": "", + "@openVideoCamera": { + "type": "text", + "placeholders": {} + }, + "play": "", + "@play": { + "type": "text", + "placeholders": { + "fileName": {} + } + }, + "chatBackupDescription": "", + "@chatBackupDescription": { + "type": "text", + "placeholders": {} + }, + "changeDeviceName": "", + "@changeDeviceName": { + "type": "text", + "placeholders": {} + }, + "lastSeenLongTimeAgo": "", + "@lastSeenLongTimeAgo": { + "type": "text", + "placeholders": {} + }, + "passwordForgotten": "", + "@passwordForgotten": { + "type": "text", + "placeholders": {} + }, + "statusExampleMessage": "", + "@statusExampleMessage": { + "type": "text", + "placeholders": {} + }, + "thisUserHasNotPostedAnythingYet": "", + "@thisUserHasNotPostedAnythingYet": {}, + "security": "", + "@security": { + "type": "text", + "placeholders": {} + }, + "markAsRead": "", + "@markAsRead": {}, + "sendAudio": "", + "@sendAudio": { + "type": "text", + "placeholders": {} + }, + "widgetName": "", + "@widgetName": {}, + "sentASticker": "", + "@sentASticker": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "errorAddingWidget": "", + "@errorAddingWidget": {}, + "commandHint_dm": "", + "@commandHint_dm": { + "type": "text", + "description": "Usage hint for the command /dm" + }, + "commandHint_hug": "", + "@commandHint_hug": {}, + "replace": "", + "@replace": {}, + "reject": "", + "@reject": { + "type": "text", + "placeholders": {} + }, + "extremeOffensive": "", + "@extremeOffensive": { + "type": "text", + "placeholders": {} + }, + "editBlockedServers": "", + "@editBlockedServers": { + "type": "text", + "placeholders": {} + }, + "oopsPushError": "", + "@oopsPushError": { + "type": "text", + "placeholders": {} + }, + "youUnbannedUser": "", + "@youUnbannedUser": { + "placeholders": { + "user": {} + } + }, + "deactivateAccountWarning": "", + "@deactivateAccountWarning": { + "type": "text", + "placeholders": {} + }, + "archive": "", + "@archive": { + "type": "text", + "placeholders": {} + }, + "joinedTheChat": "", + "@joinedTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "visibleForEveryone": "", + "@visibleForEveryone": { + "type": "text", + "placeholders": {} + }, + "pleaseEnter4Digits": "", + "@pleaseEnter4Digits": { + "type": "text", + "placeholders": {} + }, + "newSpace": "", + "@newSpace": {}, + "changePassword": "", + "@changePassword": { + "type": "text", + "placeholders": {} + }, + "devices": "", + "@devices": { + "type": "text", + "placeholders": {} + }, + "accept": "", + "@accept": { + "type": "text", + "placeholders": {} + }, + "unknownEvent": "", + "@unknownEvent": { + "type": "text", + "placeholders": { + "type": {} + } + }, + "emojis": "", + "@emojis": {}, + "signUp": "", + "@signUp": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourPin": "", + "@pleaseEnterYourPin": { + "type": "text", + "placeholders": {} + }, + "pleaseChoose": "", + "@pleaseChoose": { + "type": "text", + "placeholders": {} + }, + "share": "", + "@share": { + "type": "text", + "placeholders": {} + }, + "commandHint_googly": "", + "@commandHint_googly": {}, + "pleaseTryAgainLaterOrChooseDifferentServer": "", + "@pleaseTryAgainLaterOrChooseDifferentServer": {}, + "createGroup": "", + "@createGroup": {}, + "privacy": "", + "@privacy": { + "type": "text", + "placeholders": {} + }, + "changeYourAvatar": "", + "@changeYourAvatar": { + "type": "text", + "placeholders": {} + }, + "sendImage": "", + "@sendImage": { + "type": "text", + "placeholders": {} + }, + "hydrateTorLong": "", + "@hydrateTorLong": {}, + "time": "", + "@time": {}, + "enterYourHomeserver": "", + "@enterYourHomeserver": { + "type": "text", + "placeholders": {} + }, + "botMessages": "", + "@botMessages": { + "type": "text", + "placeholders": {} + }, + "contentHasBeenReported": "", + "@contentHasBeenReported": { + "type": "text", + "placeholders": {} + }, + "custom": "", + "@custom": {}, + "noBackupWarning": "", + "@noBackupWarning": {}, + "fromJoining": "", + "@fromJoining": { + "type": "text", + "placeholders": {} + }, + "verify": "", + "@verify": { + "type": "text", + "placeholders": {} + }, + "sendVideo": "", + "@sendVideo": { + "type": "text", + "placeholders": {} + }, + "editWidgets": "", + "@editWidgets": {}, + "storeInSecureStorageDescription": "", + "@storeInSecureStorageDescription": {}, + "openChat": "", + "@openChat": {}, + "kickUserDescription": "", + "@kickUserDescription": {}, + "sendAMessage": "", + "@sendAMessage": { + "type": "text", + "placeholders": {} + }, + "pin": "", + "@pin": { + "type": "text", + "placeholders": {} + }, + "importNow": "", + "@importNow": {}, + "deleteAccount": "", + "@deleteAccount": { + "type": "text", + "placeholders": {} + }, + "setInvitationLink": "", + "@setInvitationLink": { + "type": "text", + "placeholders": {} + }, + "pinMessage": "", + "@pinMessage": {}, + "screenSharingDetail": "", + "@screenSharingDetail": {}, + "muteChat": "", + "@muteChat": { + "type": "text", + "placeholders": {} + }, + "invite": "", + "@invite": {}, + "enableMultiAccounts": "", + "@enableMultiAccounts": {}, + "chooseAUsername": "", + "@chooseAUsername": { + "type": "text", + "placeholders": {} + }, + "anyoneCanJoin": "", + "@anyoneCanJoin": { + "type": "text", + "placeholders": {} + }, + "emotePacks": "", + "@emotePacks": { + "type": "text", + "placeholders": {} + }, + "makeSureTheIdentifierIsValid": "", + "@makeSureTheIdentifierIsValid": { + "type": "text", + "placeholders": {} + }, + "continueWith": "", + "@continueWith": {}, + "indexedDbErrorTitle": "", + "@indexedDbErrorTitle": {}, + "pleaseChooseAUsername": "", + "@pleaseChooseAUsername": { + "type": "text", + "placeholders": {} + }, + "endedTheCall": "", + "@endedTheCall": { + "type": "text", + "placeholders": { + "senderName": {} + } + } +} diff --git a/assets/l10n/intl_hr.arb b/assets/l10n/intl_hr.arb index cb93cd2d7..1ac5468c5 100644 --- a/assets/l10n/intl_hr.arb +++ b/assets/l10n/intl_hr.arb @@ -2309,7 +2309,7 @@ "user": {} } }, - "youUnbannedUser": "Ponovo si uključio/la si korisnika {user}", + "youUnbannedUser": "Ponovo si uključio/la korisnika {user}", "@youUnbannedUser": { "placeholders": { "user": {} @@ -2617,5 +2617,45 @@ "placeholders": { "seconds": {} } - } + }, + "hasKnocked": "{user} je pokucao/la", + "@hasKnocked": { + "placeholders": { + "user": {} + } + }, + "pleaseEnterANumber": "Upiši broj veći od 0", + "@pleaseEnterANumber": {}, + "banUserDescription": "", + "@banUserDescription": {}, + "removeDevicesDescription": "", + "@removeDevicesDescription": {}, + "unbanUserDescription": "", + "@unbanUserDescription": {}, + "todoLists": "", + "@todoLists": {}, + "editTodo": "", + "@editTodo": {}, + "pushNotificationsNotAvailable": "", + "@pushNotificationsNotAvailable": {}, + "pleaseAddATitle": "", + "@pleaseAddATitle": {}, + "makeAdminDescription": "", + "@makeAdminDescription": {}, + "noTodosYet": "", + "@noTodosYet": {}, + "archiveRoomDescription": "", + "@archiveRoomDescription": {}, + "todosUnencrypted": "", + "@todosUnencrypted": {}, + "newTodo": "", + "@newTodo": {}, + "learnMore": "", + "@learnMore": {}, + "todoListChangedError": "", + "@todoListChangedError": {}, + "roomUpgradeDescription": "", + "@roomUpgradeDescription": {}, + "kickUserDescription": "", + "@kickUserDescription": {} } diff --git a/assets/l10n/intl_hu.arb b/assets/l10n/intl_hu.arb index 609dc81b0..6a770da8e 100644 --- a/assets/l10n/intl_hu.arb +++ b/assets/l10n/intl_hu.arb @@ -2004,5 +2004,651 @@ "placeholders": {} }, "notAnImage": "Nem kép fájl.", - "@notAnImage": {} + "@notAnImage": {}, + "showPassword": "", + "@showPassword": { + "type": "text", + "placeholders": {} + }, + "hugContent": "", + "@hugContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "jumpToLastReadMessage": "", + "@jumpToLastReadMessage": {}, + "allRooms": "", + "@allRooms": { + "type": "text", + "placeholders": {} + }, + "whoCanSeeMyStories": "", + "@whoCanSeeMyStories": {}, + "widgetVideo": "", + "@widgetVideo": {}, + "dismiss": "", + "@dismiss": {}, + "reportErrorDescription": "", + "@reportErrorDescription": {}, + "setPermissionsLevel": "", + "@setPermissionsLevel": { + "type": "text", + "placeholders": {} + }, + "removeYourAvatar": "", + "@removeYourAvatar": { + "type": "text", + "placeholders": {} + }, + "unsupportedAndroidVersion": "", + "@unsupportedAndroidVersion": {}, + "widgetJitsi": "", + "@widgetJitsi": {}, + "messageType": "", + "@messageType": {}, + "noEmailWarning": "", + "@noEmailWarning": {}, + "indexedDbErrorLong": "", + "@indexedDbErrorLong": {}, + "oneClientLoggedOut": "", + "@oneClientLoggedOut": {}, + "toggleMuted": "", + "@toggleMuted": { + "type": "text", + "placeholders": {} + }, + "startFirstChat": "", + "@startFirstChat": {}, + "callingAccount": "", + "@callingAccount": {}, + "setColorTheme": "", + "@setColorTheme": {}, + "nextAccount": "", + "@nextAccount": {}, + "singlesignon": "", + "@singlesignon": { + "type": "text", + "placeholders": {} + }, + "allSpaces": "", + "@allSpaces": {}, + "supposedMxid": "", + "@supposedMxid": { + "type": "text", + "placeholders": { + "mxid": {} + } + }, + "user": "", + "@user": {}, + "youAcceptedTheInvitation": "", + "@youAcceptedTheInvitation": {}, + "youInvitedBy": "", + "@youInvitedBy": { + "placeholders": { + "user": {} + } + }, + "banUserDescription": "", + "@banUserDescription": {}, + "requests": "", + "@requests": {}, + "widgetEtherpad": "", + "@widgetEtherpad": {}, + "stories": "", + "@stories": {}, + "addToStory": "", + "@addToStory": {}, + "removeDevicesDescription": "", + "@removeDevicesDescription": {}, + "separateChatTypes": "", + "@separateChatTypes": { + "type": "text", + "placeholders": {} + }, + "tryAgain": "", + "@tryAgain": {}, + "youKickedAndBanned": "", + "@youKickedAndBanned": { + "placeholders": { + "user": {} + } + }, + "showDirectChatsInSpaces": "", + "@showDirectChatsInSpaces": { + "type": "text", + "placeholders": {} + }, + "unbanUserDescription": "", + "@unbanUserDescription": {}, + "todoLists": "", + "@todoLists": {}, + "pleaseClickOnLink": "", + "@pleaseClickOnLink": { + "type": "text", + "placeholders": {} + }, + "youRejectedTheInvitation": "", + "@youRejectedTheInvitation": {}, + "otherCallingPermissions": "", + "@otherCallingPermissions": {}, + "messagesStyle": "", + "@messagesStyle": {}, + "widgetUrlError": "", + "@widgetUrlError": {}, + "emailOrUsername": "", + "@emailOrUsername": {}, + "newSpaceDescription": "", + "@newSpaceDescription": {}, + "chatDescription": "", + "@chatDescription": {}, + "callingAccountDetails": "", + "@callingAccountDetails": {}, + "pleaseFollowInstructionsOnWeb": "", + "@pleaseFollowInstructionsOnWeb": { + "type": "text", + "placeholders": {} + }, + "enterSpace": "", + "@enterSpace": {}, + "encryptThisChat": "", + "@encryptThisChat": {}, + "previousAccount": "", + "@previousAccount": {}, + "reopenChat": "", + "@reopenChat": {}, + "pleaseEnterRecoveryKey": "", + "@pleaseEnterRecoveryKey": {}, + "toggleFavorite": "", + "@toggleFavorite": { + "type": "text", + "placeholders": {} + }, + "widgetNameError": "", + "@widgetNameError": {}, + "addToBundle": "", + "@addToBundle": {}, + "spaceIsPublic": "", + "@spaceIsPublic": { + "type": "text", + "placeholders": {} + }, + "addWidget": "", + "@addWidget": {}, + "countFiles": "", + "@countFiles": { + "placeholders": { + "count": {} + } + }, + "noKeyForThisMessage": "", + "@noKeyForThisMessage": {}, + "shareLocation": "", + "@shareLocation": { + "type": "text", + "placeholders": {} + }, + "editTodo": "", + "@editTodo": {}, + "pushNotificationsNotAvailable": "", + "@pushNotificationsNotAvailable": {}, + "storeInAppleKeyChain": "", + "@storeInAppleKeyChain": {}, + "replaceRoomWithNewerVersion": "", + "@replaceRoomWithNewerVersion": { + "type": "text", + "placeholders": {} + }, + "invalidServerName": "", + "@invalidServerName": {}, + "chatPermissions": "", + "@chatPermissions": {}, + "wipeChatBackup": "", + "@wipeChatBackup": { + "type": "text", + "placeholders": {} + }, + "sender": "", + "@sender": {}, + "storeInAndroidKeystore": "", + "@storeInAndroidKeystore": {}, + "signInWithPassword": "", + "@signInWithPassword": {}, + "pleaseAddATitle": "", + "@pleaseAddATitle": {}, + "makeAdminDescription": "", + "@makeAdminDescription": {}, + "synchronizingPleaseWait": "", + "@synchronizingPleaseWait": { + "type": "text", + "placeholders": {} + }, + "transferFromAnotherDevice": "", + "@transferFromAnotherDevice": { + "type": "text", + "placeholders": {} + }, + "pushRules": "", + "@pushRules": { + "type": "text", + "placeholders": {} + }, + "saveKeyManuallyDescription": "", + "@saveKeyManuallyDescription": {}, + "editBundlesForAccount": "", + "@editBundlesForAccount": {}, + "whyIsThisMessageEncrypted": "", + "@whyIsThisMessageEncrypted": {}, + "setChatDescription": "", + "@setChatDescription": {}, + "spaceName": "", + "@spaceName": { + "type": "text", + "placeholders": {} + }, + "importFromZipFile": "", + "@importFromZipFile": {}, + "toggleUnread": "", + "@toggleUnread": { + "type": "text", + "placeholders": {} + }, + "noOtherDevicesFound": "", + "@noOtherDevicesFound": {}, + "addDescription": "", + "@addDescription": {}, + "redactedBy": "", + "@redactedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "videoCallsBetaWarning": "", + "@videoCallsBetaWarning": {}, + "storyPrivacyWarning": "", + "@storyPrivacyWarning": {}, + "matrixWidgets": "", + "@matrixWidgets": {}, + "signInWith": "", + "@signInWith": { + "type": "text", + "placeholders": { + "provider": {} + } + }, + "fileIsTooBigForServer": "", + "@fileIsTooBigForServer": {}, + "noTodosYet": "", + "@noTodosYet": {}, + "verified": "", + "@verified": { + "type": "text", + "placeholders": {} + }, + "callingPermissions": "", + "@callingPermissions": {}, + "readUpToHere": "", + "@readUpToHere": {}, + "start": "", + "@start": {}, + "unlockOldMessages": "", + "@unlockOldMessages": {}, + "numChats": "", + "@numChats": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "whatIsGoingOn": "", + "@whatIsGoingOn": {}, + "optionalRedactReason": "", + "@optionalRedactReason": {}, + "sendAsText": "", + "@sendAsText": { + "type": "text" + }, + "archiveRoomDescription": "", + "@archiveRoomDescription": {}, + "exportEmotePack": "", + "@exportEmotePack": {}, + "switchToAccount": "", + "@switchToAccount": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "setAsCanonicalAlias": "", + "@setAsCanonicalAlias": { + "type": "text", + "placeholders": {} + }, + "whyDoYouWantToReportThis": "", + "@whyDoYouWantToReportThis": { + "type": "text", + "placeholders": {} + }, + "letsStart": "", + "@letsStart": {}, + "experimentalVideoCalls": "", + "@experimentalVideoCalls": {}, + "savedEmotePack": "", + "@savedEmotePack": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "pleaseEnterRecoveryKeyDescription": "", + "@pleaseEnterRecoveryKeyDescription": {}, + "inviteContactToGroupQuestion": "", + "@inviteContactToGroupQuestion": {}, + "redactedByBecause": "", + "@redactedByBecause": { + "type": "text", + "placeholders": { + "username": {}, + "reason": {} + } + }, + "youHaveWithdrawnTheInvitationFor": "", + "@youHaveWithdrawnTheInvitationFor": { + "placeholders": { + "user": {} + } + }, + "appearOnTopDetails": "", + "@appearOnTopDetails": {}, + "enterRoom": "", + "@enterRoom": {}, + "pleaseChooseAPasscode": "", + "@pleaseChooseAPasscode": { + "type": "text", + "placeholders": {} + }, + "reportUser": "", + "@reportUser": {}, + "confirmEventUnpin": "", + "@confirmEventUnpin": {}, + "youInvitedUser": "", + "@youInvitedUser": { + "placeholders": { + "user": {} + } + }, + "fileHasBeenSavedAt": "", + "@fileHasBeenSavedAt": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "importZipFile": "", + "@importZipFile": {}, + "anyoneCanKnock": "", + "@anyoneCanKnock": {}, + "redactMessageDescription": "", + "@redactMessageDescription": {}, + "recoveryKey": "", + "@recoveryKey": {}, + "invalidInput": "", + "@invalidInput": {}, + "todosUnencrypted": "", + "@todosUnencrypted": {}, + "yourPublicKey": "", + "@yourPublicKey": { + "type": "text", + "placeholders": {} + }, + "tooManyRequestsWarning": "", + "@tooManyRequestsWarning": { + "type": "text", + "placeholders": {} + }, + "replyHasBeenSent": "", + "@replyHasBeenSent": {}, + "doNotShowAgain": "", + "@doNotShowAgain": {}, + "report": "", + "@report": {}, + "status": "", + "@status": { + "type": "text", + "placeholders": {} + }, + "yourStory": "", + "@yourStory": {}, + "unverified": "", + "@unverified": {}, + "serverRequiresEmail": "", + "@serverRequiresEmail": {}, + "hideUnimportantStateEvents": "", + "@hideUnimportantStateEvents": {}, + "screenSharingTitle": "", + "@screenSharingTitle": {}, + "widgetCustom": "", + "@widgetCustom": {}, + "addToSpaceDescription": "", + "@addToSpaceDescription": {}, + "whoCanSeeMyStoriesDesc": "", + "@whoCanSeeMyStoriesDesc": {}, + "youBannedUser": "", + "@youBannedUser": { + "placeholders": { + "user": {} + } + }, + "unsubscribeStories": "", + "@unsubscribeStories": {}, + "addChatDescription": "", + "@addChatDescription": {}, + "hasKnocked": "", + "@hasKnocked": { + "placeholders": { + "user": {} + } + }, + "publish": "", + "@publish": {}, + "openLinkInBrowser": "", + "@openLinkInBrowser": {}, + "messageInfo": "", + "@messageInfo": {}, + "disableEncryptionWarning": "", + "@disableEncryptionWarning": {}, + "directChat": "", + "@directChat": {}, + "noOneCanJoin": "", + "@noOneCanJoin": {}, + "wrongPinEntered": "", + "@wrongPinEntered": { + "type": "text", + "placeholders": { + "seconds": {} + } + }, + "sendTypingNotifications": "", + "@sendTypingNotifications": {}, + "inviteGroupChat": "", + "@inviteGroupChat": {}, + "appearOnTop": "", + "@appearOnTop": {}, + "invitePrivateChat": "", + "@invitePrivateChat": {}, + "foregroundServiceRunning": "", + "@foregroundServiceRunning": {}, + "voiceCall": "", + "@voiceCall": {}, + "importEmojis": "", + "@importEmojis": {}, + "wasDirectChatDisplayName": "", + "@wasDirectChatDisplayName": { + "type": "text", + "placeholders": { + "oldDisplayName": {} + } + }, + "noChatDescriptionYet": "", + "@noChatDescriptionYet": {}, + "newTodo": "", + "@newTodo": {}, + "removeFromBundle": "", + "@removeFromBundle": {}, + "whoCanPerformWhichAction": "", + "@whoCanPerformWhichAction": { + "type": "text", + "placeholders": {} + }, + "learnMore": "", + "@learnMore": {}, + "users": "", + "@users": {}, + "openGallery": "", + "@openGallery": {}, + "chatDescriptionHasBeenChanged": "", + "@chatDescriptionHasBeenChanged": {}, + "newGroup": "", + "@newGroup": {}, + "bundleName": "", + "@bundleName": {}, + "todoListChangedError": "", + "@todoListChangedError": {}, + "removeFromSpace": "", + "@removeFromSpace": {}, + "enterInviteLinkOrMatrixId": "", + "@enterInviteLinkOrMatrixId": {}, + "roomUpgradeDescription": "", + "@roomUpgradeDescription": {}, + "pleaseEnterANumber": "", + "@pleaseEnterANumber": {}, + "youKicked": "", + "@youKicked": { + "placeholders": { + "user": {} + } + }, + "profileNotFound": "", + "@profileNotFound": {}, + "jump": "", + "@jump": {}, + "reactedWith": "", + "@reactedWith": { + "type": "text", + "placeholders": { + "sender": {}, + "reaction": {} + } + }, + "sorryThatsNotPossible": "", + "@sorryThatsNotPossible": {}, + "storyFrom": "", + "@storyFrom": { + "type": "text", + "placeholders": { + "date": {}, + "body": {} + } + }, + "videoWithSize": "", + "@videoWithSize": { + "type": "text", + "placeholders": { + "size": {} + } + }, + "shareInviteLink": "", + "@shareInviteLink": {}, + "commandHint_markasdm": "", + "@commandHint_markasdm": {}, + "recoveryKeyLost": "", + "@recoveryKeyLost": {}, + "deviceKeys": "", + "@deviceKeys": {}, + "emoteKeyboardNoRecents": "", + "@emoteKeyboardNoRecents": { + "type": "text", + "placeholders": {} + }, + "setCustomEmotes": "", + "@setCustomEmotes": { + "type": "text", + "placeholders": {} + }, + "endToEndEncryption": "", + "@endToEndEncryption": {}, + "setTheme": "", + "@setTheme": {}, + "youJoinedTheChat": "", + "@youJoinedTheChat": {}, + "thisUserHasNotPostedAnythingYet": "", + "@thisUserHasNotPostedAnythingYet": {}, + "markAsRead": "", + "@markAsRead": {}, + "widgetName": "", + "@widgetName": {}, + "errorAddingWidget": "", + "@errorAddingWidget": {}, + "replace": "", + "@replace": {}, + "youUnbannedUser": "", + "@youUnbannedUser": { + "placeholders": { + "user": {} + } + }, + "newSpace": "", + "@newSpace": {}, + "emojis": "", + "@emojis": {}, + "pleaseTryAgainLaterOrChooseDifferentServer": "", + "@pleaseTryAgainLaterOrChooseDifferentServer": {}, + "createGroup": "", + "@createGroup": {}, + "hydrateTorLong": "", + "@hydrateTorLong": {}, + "time": "", + "@time": {}, + "custom": "", + "@custom": {}, + "noBackupWarning": "", + "@noBackupWarning": {}, + "editWidgets": "", + "@editWidgets": {}, + "storeInSecureStorageDescription": "", + "@storeInSecureStorageDescription": {}, + "openChat": "", + "@openChat": {}, + "kickUserDescription": "", + "@kickUserDescription": {}, + "importNow": "", + "@importNow": {}, + "pinMessage": "", + "@pinMessage": {}, + "invite": "", + "@invite": {}, + "enableMultiAccounts": "", + "@enableMultiAccounts": {}, + "continueWith": "", + "@continueWith": {}, + "indexedDbErrorTitle": "", + "@indexedDbErrorTitle": {}, + "discover": "", + "@discover": { + "type": "text", + "placeholders": {} + }, + "unsupportedAndroidVersionLong": "", + "@unsupportedAndroidVersionLong": {}, + "storeSecurlyOnThisDevice": "", + "@storeSecurlyOnThisDevice": {}, + "iUnderstand": "", + "@iUnderstand": {}, + "screenSharingDetail": "", + "@screenSharingDetail": {}, + "placeCall": "", + "@placeCall": {} } diff --git a/assets/l10n/intl_id.arb b/assets/l10n/intl_id.arb index 5c028404e..a1b1b1641 100644 --- a/assets/l10n/intl_id.arb +++ b/assets/l10n/intl_id.arb @@ -2616,5 +2616,45 @@ "placeholders": { "seconds": {} } - } + }, + "banUserDescription": "", + "@banUserDescription": {}, + "removeDevicesDescription": "", + "@removeDevicesDescription": {}, + "unbanUserDescription": "", + "@unbanUserDescription": {}, + "todoLists": "", + "@todoLists": {}, + "editTodo": "", + "@editTodo": {}, + "pushNotificationsNotAvailable": "", + "@pushNotificationsNotAvailable": {}, + "pleaseAddATitle": "", + "@pleaseAddATitle": {}, + "makeAdminDescription": "", + "@makeAdminDescription": {}, + "noTodosYet": "", + "@noTodosYet": {}, + "archiveRoomDescription": "", + "@archiveRoomDescription": {}, + "todosUnencrypted": "", + "@todosUnencrypted": {}, + "hasKnocked": "", + "@hasKnocked": { + "placeholders": { + "user": {} + } + }, + "newTodo": "", + "@newTodo": {}, + "learnMore": "", + "@learnMore": {}, + "todoListChangedError": "", + "@todoListChangedError": {}, + "roomUpgradeDescription": "", + "@roomUpgradeDescription": {}, + "pleaseEnterANumber": "", + "@pleaseEnterANumber": {}, + "kickUserDescription": "", + "@kickUserDescription": {} } diff --git a/assets/l10n/intl_ie.arb b/assets/l10n/intl_ie.arb index 470f5cd25..a9ec96a1d 100644 --- a/assets/l10n/intl_ie.arb +++ b/assets/l10n/intl_ie.arb @@ -1,1213 +1,2635 @@ { - "group": "Gruppe", - "@group": { - "type": "text", - "placeholders": {} - }, - "identity": "Identitá", - "@identity": { - "type": "text", - "placeholders": {} - }, - "close": "Cluder", - "@close": { - "type": "text", - "placeholders": {} - }, - "confirm": "Confirmar", - "@confirm": { - "type": "text", - "placeholders": {} - }, - "admin": "Administrator", - "@admin": { - "type": "text", - "placeholders": {} - }, - "chats": "Conversationes", - "@chats": { - "type": "text", - "placeholders": {} - }, - "deny": "Refusar", - "@deny": { - "type": "text", - "placeholders": {} - }, - "containsUserName": "Contene li nómine", - "@containsUserName": { - "type": "text", - "placeholders": {} - }, - "containsDisplayName": "Contene li visibil nómine", - "@containsDisplayName": { - "type": "text", - "placeholders": {} - }, - "copiedToClipboard": "Copiat al Paperiere", - "@copiedToClipboard": { - "type": "text", - "placeholders": {} - }, - "copyToClipboard": "Copiar al Paperiere", - "@copyToClipboard": { - "type": "text", - "placeholders": {} - }, - "countParticipants": "{count} participantes", - "@countParticipants": { - "type": "text", - "placeholders": { - "count": {} - } - }, - "createNewSpace": "Crear un spacie", - "@createNewSpace": { - "type": "text", - "placeholders": {} - }, - "currentlyActive": "Activ actualmen", - "@currentlyActive": { - "type": "text", - "placeholders": {} - }, - "dateAndTimeOfDay": "{date}, {timeOfDay}", - "@dateAndTimeOfDay": { - "type": "text", - "placeholders": { - "date": {}, - "timeOfDay": {} - } - }, - "deleteAccount": "Destructer li conto", - "@deleteAccount": { - "type": "text", - "placeholders": {} - }, - "deleteMessage": "Remover li missage", - "@deleteMessage": { - "type": "text", - "placeholders": {} - }, - "editBlockedServers": "Modificar blocat servitores", - "@editBlockedServers": { - "type": "text", - "placeholders": {} - }, - "everythingReady": "Omni es pret!", - "@everythingReady": { - "type": "text", - "placeholders": {} - }, - "extremeOffensive": "Extremmen offensiv", - "@extremeOffensive": { - "type": "text", - "placeholders": {} - }, - "fileName": "Nómine de file", - "@fileName": { - "type": "text", - "placeholders": {} - }, - "fontSize": "Dimension de fonde", - "@fontSize": { - "type": "text", - "placeholders": {} - }, - "fromJoining": "Pro adhesion", - "@fromJoining": { - "type": "text", - "placeholders": {} - }, - "enterYourHomeserver": "Provide vor hem-servitor", - "@enterYourHomeserver": { - "type": "text", - "placeholders": {} - }, - "fromTheInvitation": "Pro invitation", - "@fromTheInvitation": { - "type": "text", - "placeholders": {} - }, - "groupIsPublic": "Gruppe es public", - "@groupIsPublic": { - "type": "text", - "placeholders": {} - }, - "help": "Auxilie", - "@help": { - "type": "text", - "placeholders": {} - }, - "hideUnknownEvents": "Celar ínconosset evenimentes", - "@hideUnknownEvents": { - "type": "text", - "placeholders": {} - }, - "id": "ID", - "@id": { - "type": "text", - "placeholders": {} - }, - "ignoredUsers": "Ignorat usatores", - "@ignoredUsers": { - "type": "text", - "placeholders": {} - }, - "invitedUsersOnly": "Solmen invitat usatores", - "@invitedUsersOnly": { - "type": "text", - "placeholders": {} - }, - "login": "Aperter li session", - "@login": { - "type": "text", - "placeholders": {} - }, - "isTyping": "tippa…", - "@isTyping": { - "type": "text", - "placeholders": {} - }, - "joinRoom": "Adherer al chambre", - "@joinRoom": { - "type": "text", - "placeholders": {} - }, - "loadMore": "Cargar plu…", - "@loadMore": { - "type": "text", - "placeholders": {} - }, - "inviteForMe": "Invitationes por me", - "@inviteForMe": { - "type": "text", - "placeholders": {} - }, - "lastActiveAgo": "Ultim activité: {localizedTimeShort}", - "@lastActiveAgo": { - "type": "text", - "placeholders": { - "localizedTimeShort": {} - } - }, - "mention": "Mentionar", - "@mention": { - "type": "text", - "placeholders": {} - }, - "next": "Sequent", - "@next": { - "type": "text", - "placeholders": {} - }, - "no": "No", - "@no": { - "type": "text", - "placeholders": {} - }, - "offensive": "Offensiv", - "@offensive": { - "type": "text", - "placeholders": {} - }, - "offline": "For del rete", - "@offline": { - "type": "text", - "placeholders": {} - }, - "ok": "OK", - "@ok": { - "type": "text", - "placeholders": {} - }, - "online": "In li rete", - "@online": { - "type": "text", - "placeholders": {} - }, - "memberChanges": "Cambios inter membres", - "@memberChanges": { - "type": "text", - "placeholders": {} - }, - "muteChat": "Assurdar li conversation", - "@muteChat": { - "type": "text", - "placeholders": {} - }, - "newChat": "Crear un conversation", - "@newChat": { - "type": "text", - "placeholders": {} - }, - "newVerificationRequest": "Nov demanda de verification!", - "@newVerificationRequest": { - "type": "text", - "placeholders": {} - }, - "scanQrCode": "Scannar un code QR", - "@scanQrCode": {}, - "noRoomsFound": "Null chambres trovat…", - "@noRoomsFound": { - "type": "text", - "placeholders": {} - }, - "openInMaps": "Aperter in mappas", - "@openInMaps": { - "type": "text", - "placeholders": {} - }, - "optionalGroupName": "(Facultativ) Nómine de gruppe", - "@optionalGroupName": { - "type": "text", - "placeholders": {} - }, - "password": "Contrasigne", - "@password": { - "type": "text", - "placeholders": {} - }, - "passwordForgotten": "Li contrasigne esset obliviat", - "@passwordForgotten": { - "type": "text", - "placeholders": {} - }, - "passwordRecovery": "Reganiar li contrasigne", - "@passwordRecovery": { - "type": "text", - "placeholders": {} - }, - "pleaseChoose": "Ples selecter", - "@pleaseChoose": { - "type": "text", - "placeholders": {} - }, - "pushRules": "Regules de push-notificationes", - "@pushRules": { - "type": "text", - "placeholders": {} - }, - "redactMessage": "Redacter li missage", - "@redactMessage": { - "type": "text", - "placeholders": {} - }, - "removeDevice": "Remover li aparate", - "@removeDevice": { - "type": "text", - "placeholders": {} - }, - "saveFile": "Gardar li file", - "@saveFile": { - "type": "text", - "placeholders": {} - }, - "recoveryKey": "Clave de regania", - "@recoveryKey": {}, - "sendMessages": "Inviar missages", - "@sendMessages": { - "type": "text", - "placeholders": {} - }, - "sendVideo": "Inviar video", - "@sendVideo": { - "type": "text", - "placeholders": {} - }, - "shareLocation": "Partir un localisation", - "@shareLocation": { - "type": "text", - "placeholders": {} - }, - "signUp": "Inregistrar se", - "@signUp": { - "type": "text", - "placeholders": {} - }, - "spaceName": "Nómine de spacie", - "@spaceName": { - "type": "text", - "placeholders": {} - }, - "unavailable": "Índisponibil", - "@unavailable": { - "type": "text", - "placeholders": {} - }, - "toggleUnread": "Marcar quam (ín)leet", - "@toggleUnread": { - "type": "text", - "placeholders": {} - }, - "unblockDevice": "Deblocar li aparate", - "@unblockDevice": { - "type": "text", - "placeholders": {} - }, - "unknownDevice": "Ínconosset aparate", - "@unknownDevice": { - "type": "text", - "placeholders": {} - }, - "voiceMessage": "Voce-missage", - "@voiceMessage": { - "type": "text", - "placeholders": {} - }, - "wallpaper": "Tapete", - "@wallpaper": { - "type": "text", - "placeholders": {} - }, - "messageType": "Tip de missage", - "@messageType": {}, - "start": "Iniciar", - "@start": {}, - "messageInfo": "Information pri li missage", - "@messageInfo": {}, - "openGallery": "Aperter li galerie", - "@openGallery": {}, - "unsubscribeStories": "Desabonnar racontas", - "@unsubscribeStories": {}, - "yourStory": "Vor raconte", - "@yourStory": {}, - "videoWithSize": "Video ({size})", - "@videoWithSize": { - "type": "text", - "placeholders": { - "size": {} - } - }, - "reportUser": "Raportar li usator", - "@reportUser": {}, - "matrixWidgets": "Widgets de Matrix", - "@matrixWidgets": {}, - "voiceCall": "Telefonada", - "@voiceCall": {}, - "nextAccount": "Sequent conto", - "@nextAccount": {}, - "previousAccount": "Precedent conto", - "@previousAccount": {}, - "countFiles": "{count} files", - "@countFiles": { - "placeholders": { - "count": {} - } - }, - "all": "Omni", - "@all": { - "type": "text", - "placeholders": {} - }, - "create": "Crear", - "@create": { - "type": "text", - "placeholders": {} - }, - "connect": "Conexer", - "@connect": { - "type": "text", - "placeholders": {} - }, - "copy": "Copiar", - "@copy": { - "type": "text", - "placeholders": {} - }, - "darkTheme": "Obscur", - "@darkTheme": { - "type": "text", - "placeholders": {} - }, - "messages": "Missages", - "@messages": { - "type": "text", - "placeholders": {} - }, - "none": "Null", - "@none": { - "type": "text", - "placeholders": {} - }, - "rejoin": "Re-adherer", - "@rejoin": { - "type": "text", - "placeholders": {} - }, - "remove": "Remover", - "@remove": { - "type": "text", - "placeholders": {} - }, - "notifications": "Notificationes", - "@notifications": { - "type": "text", - "placeholders": {} - }, - "reply": "Responder", - "@reply": { - "type": "text", - "placeholders": {} - }, - "dateWithYear": "{day}.{month}.{year}", - "@dateWithYear": { - "type": "text", - "placeholders": { - "year": {}, - "month": {}, - "day": {} - } - }, - "delete": "Remover", - "@delete": { - "type": "text", - "placeholders": {} - }, - "search": "Sercha", - "@search": { - "type": "text", - "placeholders": {} - }, - "devices": "Aparates", - "@devices": { - "type": "text", - "placeholders": {} - }, - "lightTheme": "Lucid", - "@lightTheme": { - "type": "text", - "placeholders": {} - }, - "edit": "Redacter", - "@edit": { - "type": "text", - "placeholders": {} - }, - "security": "Securitá", - "@security": { - "type": "text", - "placeholders": {} - }, - "settings": "Parametres", - "@settings": { - "type": "text", - "placeholders": {} - }, - "share": "Partir", - "@share": { - "type": "text", - "placeholders": {} - }, - "systemTheme": "Del sistema", - "@systemTheme": { - "type": "text", - "placeholders": {} - }, - "username": "Nómine de usator", - "@username": { - "type": "text", - "placeholders": {} - }, - "verify": "Verificar", - "@verify": { - "type": "text", - "placeholders": {} - }, - "submit": "Inviar", - "@submit": { - "type": "text", - "placeholders": {} - }, - "unpin": "Defixar", - "@unpin": { - "type": "text", - "placeholders": {} - }, - "verified": "Verificat", - "@verified": { - "type": "text", - "placeholders": {} - }, - "warning": "Avise!", - "@warning": { - "type": "text", - "placeholders": {} - }, - "yes": "Yes", - "@yes": { - "type": "text", - "placeholders": {} - }, - "time": "Hora", - "@time": {}, - "publish": "Publicar", - "@publish": {}, - "sender": "Autor", - "@sender": {}, - "dismiss": "Demisser", - "@dismiss": {}, - "custom": "Personalisat", - "@custom": {}, - "emojis": "Emoji", - "@emojis": {}, - "widgetCustom": "Personalisat", - "@widgetCustom": {}, - "users": "Usatores", - "@users": {}, - "user": "Usator", - "@user": {}, - "stories": "Racontas", - "@stories": {}, - "forward": "Avan", - "@forward": { - "type": "text", - "placeholders": {} - }, - "groups": "Gruppes", - "@groups": { - "type": "text", - "placeholders": {} - }, - "ignore": "Ignorar", - "@ignore": { - "type": "text", - "placeholders": {} - }, - "inoffensive": "Ínoffensiv", - "@inoffensive": { - "type": "text", - "placeholders": {} - }, - "invited": "Invitat", - "@invited": { - "type": "text", - "placeholders": {} - }, - "leave": "Forlassar", - "@leave": { - "type": "text", - "placeholders": {} - }, - "license": "Licentie", - "@license": { - "type": "text", - "placeholders": {} - }, - "or": "O", - "@or": { - "type": "text", - "placeholders": {} - }, - "link": "Ligament", - "@link": {}, - "participant": "Participante", - "@participant": { - "type": "text", - "placeholders": {} - }, - "reason": "Cause", - "@reason": { - "type": "text", - "placeholders": {} - }, - "people": "Homes", - "@people": { - "type": "text", - "placeholders": {} - }, - "pin": "Fixar", - "@pin": { - "type": "text", - "placeholders": {} - }, - "privacy": "Privatie", - "@privacy": { - "type": "text", - "placeholders": {} - }, - "recording": "Registrante", - "@recording": { - "type": "text", - "placeholders": {} - }, - "register": "Inregistrar se", - "@register": { - "type": "text", - "placeholders": {} - }, - "reject": "Refuser", - "@reject": { - "type": "text", - "placeholders": {} - }, - "repeatPassword": "Repetir li contrasigne", - "@repeatPassword": {}, - "addEmail": "Adjunter e-post", - "@addEmail": { - "type": "text", - "placeholders": {} - }, - "changePassword": "Cambiar li contrasigne", - "@changePassword": { - "type": "text", - "placeholders": {} - }, - "changeWallpaper": "Cambiar li tapete", - "@changeWallpaper": { - "type": "text", - "placeholders": {} - }, - "clearArchive": "Vacuar li archive", - "@clearArchive": {}, - "commandHint_clearcache": "Vacuar li cache", - "@commandHint_clearcache": { - "type": "text", - "description": "Usage hint for the command /clearcache" - }, - "commandHint_send": "Inviar li textu", - "@commandHint_send": { - "type": "text", - "description": "Usage hint for the command /send" - }, - "configureChat": "Configurar li conversation", - "@configureChat": { - "type": "text", - "placeholders": {} - }, - "directChats": "Direct conversationes", - "@directChats": { - "type": "text", - "placeholders": {} - }, - "enableEncryption": "Activar li ciffration", - "@enableEncryption": { - "type": "text", - "placeholders": {} - }, - "downloadFile": "Descargar li file", - "@downloadFile": { - "type": "text", - "placeholders": {} - }, - "emoteSettings": "Parametres de emotiones", - "@emoteSettings": { - "type": "text", - "placeholders": {} - }, - "emoteShortcode": "Curt-code de emotion", - "@emoteShortcode": { - "type": "text", - "placeholders": {} - }, - "emptyChat": "Vacui conversation", - "@emptyChat": { - "type": "text", - "placeholders": {} - }, - "groupDescription": "Descrition del gruppe", - "@groupDescription": { - "type": "text", - "placeholders": {} - }, - "videoCall": "Videotelefonada", - "@videoCall": { - "type": "text", - "placeholders": {} - }, - "openChat": "Aperter li conversation", - "@openChat": {}, - "reportMessage": "Raportar li missage", - "@reportMessage": { - "type": "text", - "placeholders": {} - }, - "noPermission": "Sin permission", - "@noPermission": { - "type": "text", - "placeholders": {} - }, - "openCamera": "Aperter li cámera", - "@openCamera": { - "type": "text", - "placeholders": {} - }, - "showPassword": "Monstrar li contrasigne", - "@showPassword": { - "type": "text", - "placeholders": {} - }, - "sendFile": "Inviar un file", - "@sendFile": { - "type": "text", - "placeholders": {} - }, - "sendImage": "Inviar un image", - "@sendImage": { - "type": "text", - "placeholders": {} - }, - "sendOriginal": "Inviar li originale", - "@sendOriginal": { - "type": "text", - "placeholders": {} - }, - "theyMatch": "Corresponde", - "@theyMatch": { - "type": "text", - "placeholders": {} - }, - "anyoneCanJoin": "Alquí posse adherer se", - "@anyoneCanJoin": { - "type": "text", - "placeholders": {} - }, - "obtainingLocation": "Obtenente li localisation…", - "@obtainingLocation": { - "type": "text", - "placeholders": {} - }, - "iUnderstand": "Yo comprende", - "@iUnderstand": {}, - "addWidget": "Adjunter un widget", - "@addWidget": {}, - "addAccount": "Adjunter un conto", - "@addAccount": {}, - "publicRooms": "Public chambres", - "@publicRooms": { - "type": "text", - "placeholders": {} - }, - "verifyStart": "Iniciar li verification", - "@verifyStart": { - "type": "text", - "placeholders": {} - }, - "addDescription": "Adjunter un descrition", - "@addDescription": {}, - "roomVersion": "Version del chambre", - "@roomVersion": { - "type": "text", - "placeholders": {} - }, - "sendAudio": "Inviar audio", - "@sendAudio": { - "type": "text", - "placeholders": {} - }, - "sendSticker": "Inviar un nota adhesiv", - "@sendSticker": { - "type": "text", - "placeholders": {} - }, - "setStatus": "Assignar li statu", - "@setStatus": { - "type": "text", - "placeholders": {} - }, - "sourceCode": "Code de fonte", - "@sourceCode": { - "type": "text", - "placeholders": {} - }, - "play": "Reproducter {fileName}", - "@play": { - "type": "text", - "placeholders": { - "fileName": {} - } - }, - "pleaseEnterValidEmail": "Ples provider un valid adresse de e-post.", - "@pleaseEnterValidEmail": {}, - "about": "Pri", - "@about": { - "type": "text", - "placeholders": {} - }, - "accept": "Acceptar", - "@accept": { - "type": "text", - "placeholders": {} - }, - "updateNow": "Actualisar in li funde", - "@updateNow": {}, - "confirmMatrixId": "Ples confirmar vor Matrix ID por destructer vor conto.", - "@confirmMatrixId": {}, - "allChats": "Omni conversationes", - "@allChats": { - "type": "text", - "placeholders": {} - }, - "addToSpace": "Adjunter al spacie", - "@addToSpace": {}, - "addGroupDescription": "Adjunter un descrition de gruppe", - "@addGroupDescription": { - "type": "text", - "placeholders": {} - }, - "askVerificationRequest": "Esque acceptar ti demanda de verification de {username}?", - "@askVerificationRequest": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "autoplayImages": "Automaticmen reproducter animat images", - "@autoplayImages": { - "type": "text", - "placeholder": {} - }, - "sendOnEnter": "Inviar per Enter", - "@sendOnEnter": {}, - "blocked": "Blocat", - "@blocked": { - "type": "text", - "placeholders": {} - }, - "blockDevice": "Blocar li aparate", - "@blockDevice": { - "type": "text", - "placeholders": {} - }, - "botMessages": "Missages de robots", - "@botMessages": { - "type": "text", - "placeholders": {} - }, - "bubbleSize": "Dimension de parlada-bul", - "@bubbleSize": { - "type": "text", - "placeholders": {} - }, - "changeDeviceName": "Cambiar li nómine de aparate", - "@changeDeviceName": { - "type": "text", - "placeholders": {} - }, - "changeTheHomeserver": "Cambiar li hem-servitor", - "@changeTheHomeserver": { - "type": "text", - "placeholders": {} - }, - "chat": "Conversation", - "@chat": { - "type": "text", - "placeholders": {} - }, - "changeYourAvatar": "Cambiar vor avatar", - "@changeYourAvatar": { - "type": "text", - "placeholders": {} - }, - "chatBackup": "Archive de conversation", - "@chatBackup": { - "type": "text", - "placeholders": {} - }, - "chatDetails": "Detallies del conversation", - "@chatDetails": { - "type": "text", - "placeholders": {} - }, - "chooseAUsername": "Selecte un nómine de usator", - "@chooseAUsername": { - "type": "text", - "placeholders": {} - }, - "commandHint_me": "Ples descrir vos", - "@commandHint_me": { - "type": "text", - "description": "Usage hint for the command /me" - }, - "commandHint_leave": "Forlassar ti chambre", - "@commandHint_leave": { - "type": "text", - "description": "Usage hint for the command /leave" - }, - "commandInvalid": "Comande es ínvalid", - "@commandInvalid": { - "type": "text" - }, - "updateAvailable": "Un actualisament de FluffyChat es disponibil", - "@updateAvailable": {}, - "editWidgets": "Modificar li widgets", - "@editWidgets": {}, - "widgetEtherpad": "Textual nota", - "@widgetEtherpad": {}, - "banFromChat": "Bannir del conversation", - "@banFromChat": { - "type": "text", - "placeholders": {} - }, - "changeTheme": "Cambiar li stil", - "@changeTheme": { - "type": "text", - "placeholders": {} - }, - "commandHint_markasgroup": "Marcar quam gruppe", - "@commandHint_markasgroup": {}, - "widgetJitsi": "Jitsi Meet", - "@widgetJitsi": {}, - "screenSharingTitle": "partir li ecran", - "@screenSharingTitle": {}, - "callingPermissions": "Permissiones de telefonada", - "@callingPermissions": {}, - "callingAccount": "Conto telefonante", - "@callingAccount": {}, - "bannedUser": "{username} ha bannit {targetName}", - "@bannedUser": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "commandHint_html": "Inviar contenete HTML", - "@commandHint_html": { - "type": "text", - "description": "Usage hint for the command /html" - }, - "commandHint_plain": "Inviar textu sin formate", - "@commandHint_plain": { - "type": "text", - "description": "Usage hint for the command /plain" - }, - "editRoomAliases": "Modificar pseudonimos del chambre", - "@editRoomAliases": { - "type": "text", - "placeholders": {} - }, - "emoteExists": "Emotion ja existe!", - "@emoteExists": { - "type": "text", - "placeholders": {} - }, - "createNewGroup": "Crear un nov gruppe", - "@createNewGroup": { - "type": "text", - "placeholders": {} - }, - "editRoomAvatar": "Modificar li avatar del chambre", - "@editRoomAvatar": { - "type": "text", - "placeholders": {} - }, - "groupWith": "Gruppe con {displayname}", - "@groupWith": { - "type": "text", - "placeholders": { - "displayname": {} - } - }, - "invitedUser": "{username} invitat {targetName}", - "@invitedUser": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "leftTheChat": "Surtit ex li conversation", - "@leftTheChat": { - "type": "text", - "placeholders": {} - }, - "loadingPleaseWait": "Cargante... ples atender.", - "@loadingPleaseWait": { - "type": "text", - "placeholders": {} - }, - "acceptedTheInvitation": "{username} ha acceptat li invitation", - "@acceptedTheInvitation": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "supposedMxid": "To deve esser {mxid}", - "@supposedMxid": { - "type": "text", - "placeholders": { - "mxid": {} - } - }, - "areYouSureYouWantToLogout": "Esque vu vole cluder li session?", - "@areYouSureYouWantToLogout": { - "type": "text", - "placeholders": {} - }, - "badServerLoginTypesException": "Li hem-servitor supporta ti tipes de autentication:\n{serverVersions}\nMa ti-ci application supporta solmen:\n{supportedVersions}", - "@badServerLoginTypesException": { - "type": "text", - "placeholders": { - "serverVersions": {}, - "supportedVersions": {} - } - }, - "cantOpenUri": "Ne successat aperter li adresse {uri}", - "@cantOpenUri": { - "type": "text", - "placeholders": { - "uri": {} - } - }, - "badServerVersionsException": "Li hem-servitor supporta ti versiones de specification:\n{serverVersions}\nMa ti-ci application supporta solmen {supportedVersions}", - "@badServerVersionsException": { - "type": "text", - "placeholders": { - "serverVersions": {}, - "supportedVersions": {} - } - }, - "dateWithoutYear": "{day}.{month}", - "@dateWithoutYear": { - "type": "text", - "placeholders": { - "month": {}, - "day": {} - } - }, - "device": "Aparate", - "@device": { - "type": "text", - "placeholders": {} - }, - "widgetVideo": "Video", - "@widgetVideo": {}, - "widgetName": "Nómine", - "@widgetName": {}, - "account": "Conto", - "@account": { - "type": "text", - "placeholders": {} - }, - "alias": "pseudonim", - "@alias": { - "type": "text", - "placeholders": {} - }, - "archive": "Archive", - "@archive": { - "type": "text", - "placeholders": {} - }, - "banned": "Bannit", - "@banned": { - "type": "text", - "placeholders": {} - }, - "cancel": "Anullar", - "@cancel": { - "type": "text", - "placeholders": {} - }, - "encrypted": "Ciffrat", - "@encrypted": { - "type": "text", - "placeholders": {} - }, - "encryption": "Ciffration", - "@encryption": { - "type": "text", - "placeholders": {} - }, - "homeserver": "Hem-servitor", - "@homeserver": {}, - "fluffychat": "FluffyChat", - "@fluffychat": { - "type": "text", - "placeholders": {} - }, - "moderator": "Moderator", - "@moderator": { - "type": "text", - "placeholders": {} - }, - "newGroup": "Crear un gruppe", - "@newGroup": {}, - "newSpace": "Crear un spacie", - "@newSpace": {}, - "enterSpace": "Intrar li spacie", - "@enterSpace": {}, - "enterRoom": "Intrar li chambre", - "@enterRoom": {}, - "allSpaces": "Omni spacies", - "@allSpaces": {}, - "numChats": "{number} conversationes", - "@numChats": { - "type": "number", - "placeholders": { - "number": {} - } - }, - "logout": "Cluder li session", - "@logout": { - "type": "text", - "placeholders": {} - }, - "send": "Inviar", - "@send": { - "type": "text", - "placeholders": {} - }, - "you": "Vu", - "@you": { - "type": "text", - "placeholders": {} - }, - "title": "FluffyChat", - "@title": { - "description": "Title for the application", - "type": "text", - "placeholders": {} - }, - "skip": "Omisser", - "@skip": { - "type": "text", - "placeholders": {} - }, - "status": "Statu", - "@status": { - "type": "text", - "placeholders": {} - }, - "unverified": "Ínverificat", - "@unverified": {}, - "deviceId": "ID de aparate", - "@deviceId": { - "type": "text", - "placeholders": {} - }, - "editDisplayname": "Redacter li visibil nómine", - "@editDisplayname": { - "type": "text", - "placeholders": {} - }, - "ignoreUsername": "Ignorar un nómine", - "@ignoreUsername": { - "type": "text", - "placeholders": {} - }, - "inviteContact": "Invitar un contacte", - "@inviteContact": { - "type": "text", - "placeholders": {} - }, - "requestPermission": "Demandar li permission", - "@requestPermission": { - "type": "text", - "placeholders": {} - }, - "areYouSure": "Esque vu es cert?", - "@areYouSure": { - "type": "text", - "placeholders": {} - }, - "pleaseChooseAtLeastChars": "Ples usar adminim {min} caracteres.", - "@pleaseChooseAtLeastChars": { - "type": "text", - "placeholders": { - "min": {} - } + "group": "Gruppe", + "@group": { + "type": "text", + "placeholders": {} + }, + "identity": "Identitá", + "@identity": { + "type": "text", + "placeholders": {} + }, + "close": "Cluder", + "@close": { + "type": "text", + "placeholders": {} + }, + "confirm": "Confirmar", + "@confirm": { + "type": "text", + "placeholders": {} + }, + "admin": "Administrator", + "@admin": { + "type": "text", + "placeholders": {} + }, + "chats": "Conversationes", + "@chats": { + "type": "text", + "placeholders": {} + }, + "deny": "Refusar", + "@deny": { + "type": "text", + "placeholders": {} + }, + "containsUserName": "Contene li nómine", + "@containsUserName": { + "type": "text", + "placeholders": {} + }, + "containsDisplayName": "Contene li visibil nómine", + "@containsDisplayName": { + "type": "text", + "placeholders": {} + }, + "copiedToClipboard": "Copiat al Paperiere", + "@copiedToClipboard": { + "type": "text", + "placeholders": {} + }, + "copyToClipboard": "Copiar al Paperiere", + "@copyToClipboard": { + "type": "text", + "placeholders": {} + }, + "countParticipants": "{count} participantes", + "@countParticipants": { + "type": "text", + "placeholders": { + "count": {} } -} \ No newline at end of file + }, + "createNewSpace": "Crear un spacie", + "@createNewSpace": { + "type": "text", + "placeholders": {} + }, + "currentlyActive": "Activ actualmen", + "@currentlyActive": { + "type": "text", + "placeholders": {} + }, + "dateAndTimeOfDay": "{date}, {timeOfDay}", + "@dateAndTimeOfDay": { + "type": "text", + "placeholders": { + "date": {}, + "timeOfDay": {} + } + }, + "deleteAccount": "Destructer li conto", + "@deleteAccount": { + "type": "text", + "placeholders": {} + }, + "deleteMessage": "Remover li missage", + "@deleteMessage": { + "type": "text", + "placeholders": {} + }, + "editBlockedServers": "Modificar blocat servitores", + "@editBlockedServers": { + "type": "text", + "placeholders": {} + }, + "everythingReady": "Omni es pret!", + "@everythingReady": { + "type": "text", + "placeholders": {} + }, + "extremeOffensive": "Extremmen offensiv", + "@extremeOffensive": { + "type": "text", + "placeholders": {} + }, + "fileName": "Nómine de file", + "@fileName": { + "type": "text", + "placeholders": {} + }, + "fontSize": "Dimension de fonde", + "@fontSize": { + "type": "text", + "placeholders": {} + }, + "fromJoining": "Pro adhesion", + "@fromJoining": { + "type": "text", + "placeholders": {} + }, + "enterYourHomeserver": "Provide vor hem-servitor", + "@enterYourHomeserver": { + "type": "text", + "placeholders": {} + }, + "fromTheInvitation": "Pro invitation", + "@fromTheInvitation": { + "type": "text", + "placeholders": {} + }, + "groupIsPublic": "Gruppe es public", + "@groupIsPublic": { + "type": "text", + "placeholders": {} + }, + "help": "Auxilie", + "@help": { + "type": "text", + "placeholders": {} + }, + "hideUnknownEvents": "Celar ínconosset evenimentes", + "@hideUnknownEvents": { + "type": "text", + "placeholders": {} + }, + "id": "ID", + "@id": { + "type": "text", + "placeholders": {} + }, + "ignoredUsers": "Ignorat usatores", + "@ignoredUsers": { + "type": "text", + "placeholders": {} + }, + "invitedUsersOnly": "Solmen invitat usatores", + "@invitedUsersOnly": { + "type": "text", + "placeholders": {} + }, + "login": "Aperter li session", + "@login": { + "type": "text", + "placeholders": {} + }, + "isTyping": "tippa…", + "@isTyping": { + "type": "text", + "placeholders": {} + }, + "joinRoom": "Adherer al chambre", + "@joinRoom": { + "type": "text", + "placeholders": {} + }, + "loadMore": "Cargar plu…", + "@loadMore": { + "type": "text", + "placeholders": {} + }, + "inviteForMe": "Invitationes por me", + "@inviteForMe": { + "type": "text", + "placeholders": {} + }, + "lastActiveAgo": "Ultim activité: {localizedTimeShort}", + "@lastActiveAgo": { + "type": "text", + "placeholders": { + "localizedTimeShort": {} + } + }, + "mention": "Mentionar", + "@mention": { + "type": "text", + "placeholders": {} + }, + "next": "Sequent", + "@next": { + "type": "text", + "placeholders": {} + }, + "no": "No", + "@no": { + "type": "text", + "placeholders": {} + }, + "offensive": "Offensiv", + "@offensive": { + "type": "text", + "placeholders": {} + }, + "offline": "For del rete", + "@offline": { + "type": "text", + "placeholders": {} + }, + "ok": "OK", + "@ok": { + "type": "text", + "placeholders": {} + }, + "online": "In li rete", + "@online": { + "type": "text", + "placeholders": {} + }, + "memberChanges": "Cambios inter membres", + "@memberChanges": { + "type": "text", + "placeholders": {} + }, + "muteChat": "Assurdar li conversation", + "@muteChat": { + "type": "text", + "placeholders": {} + }, + "newChat": "Crear un conversation", + "@newChat": { + "type": "text", + "placeholders": {} + }, + "newVerificationRequest": "Nov demanda de verification!", + "@newVerificationRequest": { + "type": "text", + "placeholders": {} + }, + "scanQrCode": "Scannar un code QR", + "@scanQrCode": {}, + "noRoomsFound": "Null chambres trovat…", + "@noRoomsFound": { + "type": "text", + "placeholders": {} + }, + "openInMaps": "Aperter in mappas", + "@openInMaps": { + "type": "text", + "placeholders": {} + }, + "optionalGroupName": "(Facultativ) Nómine de gruppe", + "@optionalGroupName": { + "type": "text", + "placeholders": {} + }, + "password": "Contrasigne", + "@password": { + "type": "text", + "placeholders": {} + }, + "passwordForgotten": "Li contrasigne esset obliviat", + "@passwordForgotten": { + "type": "text", + "placeholders": {} + }, + "passwordRecovery": "Reganiar li contrasigne", + "@passwordRecovery": { + "type": "text", + "placeholders": {} + }, + "pleaseChoose": "Ples selecter", + "@pleaseChoose": { + "type": "text", + "placeholders": {} + }, + "pushRules": "Regules de push-notificationes", + "@pushRules": { + "type": "text", + "placeholders": {} + }, + "redactMessage": "Redacter li missage", + "@redactMessage": { + "type": "text", + "placeholders": {} + }, + "removeDevice": "Remover li aparate", + "@removeDevice": { + "type": "text", + "placeholders": {} + }, + "saveFile": "Gardar li file", + "@saveFile": { + "type": "text", + "placeholders": {} + }, + "recoveryKey": "Clave de regania", + "@recoveryKey": {}, + "sendMessages": "Inviar missages", + "@sendMessages": { + "type": "text", + "placeholders": {} + }, + "sendVideo": "Inviar video", + "@sendVideo": { + "type": "text", + "placeholders": {} + }, + "shareLocation": "Partir un localisation", + "@shareLocation": { + "type": "text", + "placeholders": {} + }, + "signUp": "Inregistrar se", + "@signUp": { + "type": "text", + "placeholders": {} + }, + "spaceName": "Nómine de spacie", + "@spaceName": { + "type": "text", + "placeholders": {} + }, + "unavailable": "Índisponibil", + "@unavailable": { + "type": "text", + "placeholders": {} + }, + "toggleUnread": "Marcar quam (ín)leet", + "@toggleUnread": { + "type": "text", + "placeholders": {} + }, + "unblockDevice": "Deblocar li aparate", + "@unblockDevice": { + "type": "text", + "placeholders": {} + }, + "unknownDevice": "Ínconosset aparate", + "@unknownDevice": { + "type": "text", + "placeholders": {} + }, + "voiceMessage": "Voce-missage", + "@voiceMessage": { + "type": "text", + "placeholders": {} + }, + "wallpaper": "Tapete", + "@wallpaper": { + "type": "text", + "placeholders": {} + }, + "messageType": "Tip de missage", + "@messageType": {}, + "start": "Iniciar", + "@start": {}, + "messageInfo": "Information pri li missage", + "@messageInfo": {}, + "openGallery": "Aperter li galerie", + "@openGallery": {}, + "unsubscribeStories": "Desabonnar racontas", + "@unsubscribeStories": {}, + "yourStory": "Vor raconte", + "@yourStory": {}, + "videoWithSize": "Video ({size})", + "@videoWithSize": { + "type": "text", + "placeholders": { + "size": {} + } + }, + "reportUser": "Raportar li usator", + "@reportUser": {}, + "matrixWidgets": "Widgets de Matrix", + "@matrixWidgets": {}, + "voiceCall": "Telefonada", + "@voiceCall": {}, + "nextAccount": "Sequent conto", + "@nextAccount": {}, + "previousAccount": "Precedent conto", + "@previousAccount": {}, + "countFiles": "{count} files", + "@countFiles": { + "placeholders": { + "count": {} + } + }, + "all": "Omni", + "@all": { + "type": "text", + "placeholders": {} + }, + "create": "Crear", + "@create": { + "type": "text", + "placeholders": {} + }, + "connect": "Conexer", + "@connect": { + "type": "text", + "placeholders": {} + }, + "copy": "Copiar", + "@copy": { + "type": "text", + "placeholders": {} + }, + "darkTheme": "Obscur", + "@darkTheme": { + "type": "text", + "placeholders": {} + }, + "messages": "Missages", + "@messages": { + "type": "text", + "placeholders": {} + }, + "none": "Null", + "@none": { + "type": "text", + "placeholders": {} + }, + "rejoin": "Re-adherer", + "@rejoin": { + "type": "text", + "placeholders": {} + }, + "remove": "Remover", + "@remove": { + "type": "text", + "placeholders": {} + }, + "notifications": "Notificationes", + "@notifications": { + "type": "text", + "placeholders": {} + }, + "reply": "Responder", + "@reply": { + "type": "text", + "placeholders": {} + }, + "dateWithYear": "{day}.{month}.{year}", + "@dateWithYear": { + "type": "text", + "placeholders": { + "year": {}, + "month": {}, + "day": {} + } + }, + "delete": "Remover", + "@delete": { + "type": "text", + "placeholders": {} + }, + "search": "Sercha", + "@search": { + "type": "text", + "placeholders": {} + }, + "devices": "Aparates", + "@devices": { + "type": "text", + "placeholders": {} + }, + "lightTheme": "Lucid", + "@lightTheme": { + "type": "text", + "placeholders": {} + }, + "edit": "Redacter", + "@edit": { + "type": "text", + "placeholders": {} + }, + "security": "Securitá", + "@security": { + "type": "text", + "placeholders": {} + }, + "settings": "Parametres", + "@settings": { + "type": "text", + "placeholders": {} + }, + "share": "Partir", + "@share": { + "type": "text", + "placeholders": {} + }, + "systemTheme": "Del sistema", + "@systemTheme": { + "type": "text", + "placeholders": {} + }, + "username": "Nómine de usator", + "@username": { + "type": "text", + "placeholders": {} + }, + "verify": "Verificar", + "@verify": { + "type": "text", + "placeholders": {} + }, + "submit": "Inviar", + "@submit": { + "type": "text", + "placeholders": {} + }, + "unpin": "Defixar", + "@unpin": { + "type": "text", + "placeholders": {} + }, + "verified": "Verificat", + "@verified": { + "type": "text", + "placeholders": {} + }, + "warning": "Avise!", + "@warning": { + "type": "text", + "placeholders": {} + }, + "yes": "Yes", + "@yes": { + "type": "text", + "placeholders": {} + }, + "time": "Hora", + "@time": {}, + "publish": "Publicar", + "@publish": {}, + "sender": "Autor", + "@sender": {}, + "dismiss": "Demisser", + "@dismiss": {}, + "custom": "Personalisat", + "@custom": {}, + "emojis": "Emoji", + "@emojis": {}, + "widgetCustom": "Personalisat", + "@widgetCustom": {}, + "users": "Usatores", + "@users": {}, + "user": "Usator", + "@user": {}, + "stories": "Racontas", + "@stories": {}, + "forward": "Avan", + "@forward": { + "type": "text", + "placeholders": {} + }, + "groups": "Gruppes", + "@groups": { + "type": "text", + "placeholders": {} + }, + "ignore": "Ignorar", + "@ignore": { + "type": "text", + "placeholders": {} + }, + "inoffensive": "Ínoffensiv", + "@inoffensive": { + "type": "text", + "placeholders": {} + }, + "invited": "Invitat", + "@invited": { + "type": "text", + "placeholders": {} + }, + "leave": "Forlassar", + "@leave": { + "type": "text", + "placeholders": {} + }, + "license": "Licentie", + "@license": { + "type": "text", + "placeholders": {} + }, + "or": "O", + "@or": { + "type": "text", + "placeholders": {} + }, + "link": "Ligament", + "@link": {}, + "participant": "Participante", + "@participant": { + "type": "text", + "placeholders": {} + }, + "reason": "Cause", + "@reason": { + "type": "text", + "placeholders": {} + }, + "people": "Homes", + "@people": { + "type": "text", + "placeholders": {} + }, + "pin": "Fixar", + "@pin": { + "type": "text", + "placeholders": {} + }, + "privacy": "Privatie", + "@privacy": { + "type": "text", + "placeholders": {} + }, + "recording": "Registrante", + "@recording": { + "type": "text", + "placeholders": {} + }, + "register": "Inregistrar se", + "@register": { + "type": "text", + "placeholders": {} + }, + "reject": "Refuser", + "@reject": { + "type": "text", + "placeholders": {} + }, + "repeatPassword": "Repetir li contrasigne", + "@repeatPassword": {}, + "addEmail": "Adjunter e-post", + "@addEmail": { + "type": "text", + "placeholders": {} + }, + "changePassword": "Cambiar li contrasigne", + "@changePassword": { + "type": "text", + "placeholders": {} + }, + "changeWallpaper": "Cambiar li tapete", + "@changeWallpaper": { + "type": "text", + "placeholders": {} + }, + "clearArchive": "Vacuar li archive", + "@clearArchive": {}, + "commandHint_clearcache": "Vacuar li cache", + "@commandHint_clearcache": { + "type": "text", + "description": "Usage hint for the command /clearcache" + }, + "commandHint_send": "Inviar li textu", + "@commandHint_send": { + "type": "text", + "description": "Usage hint for the command /send" + }, + "configureChat": "Configurar li conversation", + "@configureChat": { + "type": "text", + "placeholders": {} + }, + "directChats": "Direct conversationes", + "@directChats": { + "type": "text", + "placeholders": {} + }, + "enableEncryption": "Activar li ciffration", + "@enableEncryption": { + "type": "text", + "placeholders": {} + }, + "downloadFile": "Descargar li file", + "@downloadFile": { + "type": "text", + "placeholders": {} + }, + "emoteSettings": "Parametres de emotiones", + "@emoteSettings": { + "type": "text", + "placeholders": {} + }, + "emoteShortcode": "Curt-code de emotion", + "@emoteShortcode": { + "type": "text", + "placeholders": {} + }, + "emptyChat": "Vacui conversation", + "@emptyChat": { + "type": "text", + "placeholders": {} + }, + "groupDescription": "Descrition del gruppe", + "@groupDescription": { + "type": "text", + "placeholders": {} + }, + "videoCall": "Videotelefonada", + "@videoCall": { + "type": "text", + "placeholders": {} + }, + "openChat": "Aperter li conversation", + "@openChat": {}, + "reportMessage": "Raportar li missage", + "@reportMessage": { + "type": "text", + "placeholders": {} + }, + "noPermission": "Sin permission", + "@noPermission": { + "type": "text", + "placeholders": {} + }, + "openCamera": "Aperter li cámera", + "@openCamera": { + "type": "text", + "placeholders": {} + }, + "showPassword": "Monstrar li contrasigne", + "@showPassword": { + "type": "text", + "placeholders": {} + }, + "sendFile": "Inviar un file", + "@sendFile": { + "type": "text", + "placeholders": {} + }, + "sendImage": "Inviar un image", + "@sendImage": { + "type": "text", + "placeholders": {} + }, + "sendOriginal": "Inviar li originale", + "@sendOriginal": { + "type": "text", + "placeholders": {} + }, + "theyMatch": "Corresponde", + "@theyMatch": { + "type": "text", + "placeholders": {} + }, + "anyoneCanJoin": "Alquí posse adherer se", + "@anyoneCanJoin": { + "type": "text", + "placeholders": {} + }, + "obtainingLocation": "Obtenente li localisation…", + "@obtainingLocation": { + "type": "text", + "placeholders": {} + }, + "iUnderstand": "Yo comprende", + "@iUnderstand": {}, + "addWidget": "Adjunter un widget", + "@addWidget": {}, + "addAccount": "Adjunter un conto", + "@addAccount": {}, + "publicRooms": "Public chambres", + "@publicRooms": { + "type": "text", + "placeholders": {} + }, + "verifyStart": "Iniciar li verification", + "@verifyStart": { + "type": "text", + "placeholders": {} + }, + "addDescription": "Adjunter un descrition", + "@addDescription": {}, + "roomVersion": "Version del chambre", + "@roomVersion": { + "type": "text", + "placeholders": {} + }, + "sendAudio": "Inviar audio", + "@sendAudio": { + "type": "text", + "placeholders": {} + }, + "sendSticker": "Inviar un nota adhesiv", + "@sendSticker": { + "type": "text", + "placeholders": {} + }, + "setStatus": "Assignar li statu", + "@setStatus": { + "type": "text", + "placeholders": {} + }, + "sourceCode": "Code de fonte", + "@sourceCode": { + "type": "text", + "placeholders": {} + }, + "play": "Reproducter {fileName}", + "@play": { + "type": "text", + "placeholders": { + "fileName": {} + } + }, + "pleaseEnterValidEmail": "Ples provider un valid adresse de e-post.", + "@pleaseEnterValidEmail": {}, + "about": "Pri", + "@about": { + "type": "text", + "placeholders": {} + }, + "accept": "Acceptar", + "@accept": { + "type": "text", + "placeholders": {} + }, + "updateNow": "Actualisar in li funde", + "@updateNow": {}, + "confirmMatrixId": "Ples confirmar vor Matrix ID por destructer vor conto.", + "@confirmMatrixId": {}, + "allChats": "Omni conversationes", + "@allChats": { + "type": "text", + "placeholders": {} + }, + "addToSpace": "Adjunter al spacie", + "@addToSpace": {}, + "addGroupDescription": "Adjunter un descrition de gruppe", + "@addGroupDescription": { + "type": "text", + "placeholders": {} + }, + "askVerificationRequest": "Esque acceptar ti demanda de verification de {username}?", + "@askVerificationRequest": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "autoplayImages": "Automaticmen reproducter animat images", + "@autoplayImages": { + "type": "text", + "placeholder": {} + }, + "sendOnEnter": "Inviar per Enter", + "@sendOnEnter": {}, + "blocked": "Blocat", + "@blocked": { + "type": "text", + "placeholders": {} + }, + "blockDevice": "Blocar li aparate", + "@blockDevice": { + "type": "text", + "placeholders": {} + }, + "botMessages": "Missages de robots", + "@botMessages": { + "type": "text", + "placeholders": {} + }, + "bubbleSize": "Dimension de parlada-bul", + "@bubbleSize": { + "type": "text", + "placeholders": {} + }, + "changeDeviceName": "Cambiar li nómine de aparate", + "@changeDeviceName": { + "type": "text", + "placeholders": {} + }, + "changeTheHomeserver": "Cambiar li hem-servitor", + "@changeTheHomeserver": { + "type": "text", + "placeholders": {} + }, + "chat": "Conversation", + "@chat": { + "type": "text", + "placeholders": {} + }, + "changeYourAvatar": "Cambiar vor avatar", + "@changeYourAvatar": { + "type": "text", + "placeholders": {} + }, + "chatBackup": "Archive de conversation", + "@chatBackup": { + "type": "text", + "placeholders": {} + }, + "chatDetails": "Detallies del conversation", + "@chatDetails": { + "type": "text", + "placeholders": {} + }, + "chooseAUsername": "Selecte un nómine de usator", + "@chooseAUsername": { + "type": "text", + "placeholders": {} + }, + "commandHint_me": "Ples descrir vos", + "@commandHint_me": { + "type": "text", + "description": "Usage hint for the command /me" + }, + "commandHint_leave": "Forlassar ti chambre", + "@commandHint_leave": { + "type": "text", + "description": "Usage hint for the command /leave" + }, + "commandInvalid": "Comande es ínvalid", + "@commandInvalid": { + "type": "text" + }, + "updateAvailable": "Un actualisament de FluffyChat es disponibil", + "@updateAvailable": {}, + "editWidgets": "Modificar li widgets", + "@editWidgets": {}, + "widgetEtherpad": "Textual nota", + "@widgetEtherpad": {}, + "banFromChat": "Bannir del conversation", + "@banFromChat": { + "type": "text", + "placeholders": {} + }, + "changeTheme": "Cambiar li stil", + "@changeTheme": { + "type": "text", + "placeholders": {} + }, + "commandHint_markasgroup": "Marcar quam gruppe", + "@commandHint_markasgroup": {}, + "widgetJitsi": "Jitsi Meet", + "@widgetJitsi": {}, + "screenSharingTitle": "partir li ecran", + "@screenSharingTitle": {}, + "callingPermissions": "Permissiones de telefonada", + "@callingPermissions": {}, + "callingAccount": "Conto telefonante", + "@callingAccount": {}, + "bannedUser": "{username} ha bannit {targetName}", + "@bannedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "commandHint_html": "Inviar contenete HTML", + "@commandHint_html": { + "type": "text", + "description": "Usage hint for the command /html" + }, + "commandHint_plain": "Inviar textu sin formate", + "@commandHint_plain": { + "type": "text", + "description": "Usage hint for the command /plain" + }, + "editRoomAliases": "Modificar pseudonimos del chambre", + "@editRoomAliases": { + "type": "text", + "placeholders": {} + }, + "emoteExists": "Emotion ja existe!", + "@emoteExists": { + "type": "text", + "placeholders": {} + }, + "createNewGroup": "Crear un nov gruppe", + "@createNewGroup": { + "type": "text", + "placeholders": {} + }, + "editRoomAvatar": "Modificar li avatar del chambre", + "@editRoomAvatar": { + "type": "text", + "placeholders": {} + }, + "groupWith": "Gruppe con {displayname}", + "@groupWith": { + "type": "text", + "placeholders": { + "displayname": {} + } + }, + "invitedUser": "{username} invitat {targetName}", + "@invitedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "leftTheChat": "Surtit ex li conversation", + "@leftTheChat": { + "type": "text", + "placeholders": {} + }, + "loadingPleaseWait": "Cargante... ples atender.", + "@loadingPleaseWait": { + "type": "text", + "placeholders": {} + }, + "acceptedTheInvitation": "{username} ha acceptat li invitation", + "@acceptedTheInvitation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "supposedMxid": "To deve esser {mxid}", + "@supposedMxid": { + "type": "text", + "placeholders": { + "mxid": {} + } + }, + "areYouSureYouWantToLogout": "Esque vu vole cluder li session?", + "@areYouSureYouWantToLogout": { + "type": "text", + "placeholders": {} + }, + "badServerLoginTypesException": "Li hem-servitor supporta ti tipes de autentication:\n{serverVersions}\nMa ti-ci application supporta solmen:\n{supportedVersions}", + "@badServerLoginTypesException": { + "type": "text", + "placeholders": { + "serverVersions": {}, + "supportedVersions": {} + } + }, + "cantOpenUri": "Ne successat aperter li adresse {uri}", + "@cantOpenUri": { + "type": "text", + "placeholders": { + "uri": {} + } + }, + "badServerVersionsException": "Li hem-servitor supporta ti versiones de specification:\n{serverVersions}\nMa ti-ci application supporta solmen {supportedVersions}", + "@badServerVersionsException": { + "type": "text", + "placeholders": { + "serverVersions": {}, + "supportedVersions": {} + } + }, + "dateWithoutYear": "{day}.{month}", + "@dateWithoutYear": { + "type": "text", + "placeholders": { + "month": {}, + "day": {} + } + }, + "device": "Aparate", + "@device": { + "type": "text", + "placeholders": {} + }, + "widgetVideo": "Video", + "@widgetVideo": {}, + "widgetName": "Nómine", + "@widgetName": {}, + "account": "Conto", + "@account": { + "type": "text", + "placeholders": {} + }, + "alias": "pseudonim", + "@alias": { + "type": "text", + "placeholders": {} + }, + "archive": "Archive", + "@archive": { + "type": "text", + "placeholders": {} + }, + "banned": "Bannit", + "@banned": { + "type": "text", + "placeholders": {} + }, + "cancel": "Anullar", + "@cancel": { + "type": "text", + "placeholders": {} + }, + "encrypted": "Ciffrat", + "@encrypted": { + "type": "text", + "placeholders": {} + }, + "encryption": "Ciffration", + "@encryption": { + "type": "text", + "placeholders": {} + }, + "homeserver": "Hem-servitor", + "@homeserver": {}, + "fluffychat": "FluffyChat", + "@fluffychat": { + "type": "text", + "placeholders": {} + }, + "moderator": "Moderator", + "@moderator": { + "type": "text", + "placeholders": {} + }, + "newGroup": "Crear un gruppe", + "@newGroup": {}, + "newSpace": "Crear un spacie", + "@newSpace": {}, + "enterSpace": "Intrar li spacie", + "@enterSpace": {}, + "enterRoom": "Intrar li chambre", + "@enterRoom": {}, + "allSpaces": "Omni spacies", + "@allSpaces": {}, + "numChats": "{number} conversationes", + "@numChats": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "logout": "Cluder li session", + "@logout": { + "type": "text", + "placeholders": {} + }, + "send": "Inviar", + "@send": { + "type": "text", + "placeholders": {} + }, + "you": "Vu", + "@you": { + "type": "text", + "placeholders": {} + }, + "title": "FluffyChat", + "@title": { + "description": "Title for the application", + "type": "text", + "placeholders": {} + }, + "skip": "Omisser", + "@skip": { + "type": "text", + "placeholders": {} + }, + "status": "Statu", + "@status": { + "type": "text", + "placeholders": {} + }, + "unverified": "Ínverificat", + "@unverified": {}, + "deviceId": "ID de aparate", + "@deviceId": { + "type": "text", + "placeholders": {} + }, + "editDisplayname": "Redacter li visibil nómine", + "@editDisplayname": { + "type": "text", + "placeholders": {} + }, + "ignoreUsername": "Ignorar un nómine", + "@ignoreUsername": { + "type": "text", + "placeholders": {} + }, + "inviteContact": "Invitar un contacte", + "@inviteContact": { + "type": "text", + "placeholders": {} + }, + "requestPermission": "Demandar li permission", + "@requestPermission": { + "type": "text", + "placeholders": {} + }, + "areYouSure": "Esque vu es cert?", + "@areYouSure": { + "type": "text", + "placeholders": {} + }, + "pleaseChooseAtLeastChars": "Ples usar adminim {min} caracteres.", + "@pleaseChooseAtLeastChars": { + "type": "text", + "placeholders": { + "min": {} + } + }, + "discover": "", + "@discover": { + "type": "text", + "placeholders": {} + }, + "hugContent": "", + "@hugContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "passphraseOrKey": "", + "@passphraseOrKey": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourPassword": "", + "@pleaseEnterYourPassword": { + "type": "text", + "placeholders": {} + }, + "jumpToLastReadMessage": "", + "@jumpToLastReadMessage": {}, + "allRooms": "", + "@allRooms": { + "type": "text", + "placeholders": {} + }, + "whoCanSeeMyStories": "", + "@whoCanSeeMyStories": {}, + "commandHint_cuddle": "", + "@commandHint_cuddle": {}, + "noEncryptionForPublicRooms": "", + "@noEncryptionForPublicRooms": { + "type": "text", + "placeholders": {} + }, + "reportErrorDescription": "", + "@reportErrorDescription": {}, + "setPermissionsLevel": "", + "@setPermissionsLevel": { + "type": "text", + "placeholders": {} + }, + "inviteContactToGroup": "", + "@inviteContactToGroup": { + "type": "text", + "placeholders": { + "groupName": {} + } + }, + "seenByUserAndUser": "", + "@seenByUserAndUser": { + "type": "text", + "placeholders": { + "username": {}, + "username2": {} + } + }, + "chatHasBeenAddedToThisSpace": "", + "@chatHasBeenAddedToThisSpace": {}, + "removeYourAvatar": "", + "@removeYourAvatar": { + "type": "text", + "placeholders": {} + }, + "unsupportedAndroidVersion": "", + "@unsupportedAndroidVersion": {}, + "enterASpacepName": "", + "@enterASpacepName": {}, + "youAreNoLongerParticipatingInThisChat": "", + "@youAreNoLongerParticipatingInThisChat": { + "type": "text", + "placeholders": {} + }, + "noEmailWarning": "", + "@noEmailWarning": {}, + "indexedDbErrorLong": "", + "@indexedDbErrorLong": {}, + "oneClientLoggedOut": "", + "@oneClientLoggedOut": {}, + "toggleMuted": "", + "@toggleMuted": { + "type": "text", + "placeholders": {} + }, + "unsupportedAndroidVersionLong": "", + "@unsupportedAndroidVersionLong": {}, + "kicked": "", + "@kicked": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "changeTheNameOfTheGroup": "", + "@changeTheNameOfTheGroup": { + "type": "text", + "placeholders": {} + }, + "changedTheChatAvatar": "", + "@changedTheChatAvatar": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "verifySuccess": "", + "@verifySuccess": { + "type": "text", + "placeholders": {} + }, + "startFirstChat": "", + "@startFirstChat": {}, + "sentAPicture": "", + "@sentAPicture": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheDisplaynameTo": "", + "@changedTheDisplaynameTo": { + "type": "text", + "placeholders": { + "username": {}, + "displayname": {} + } + }, + "setColorTheme": "", + "@setColorTheme": {}, + "commandHint_create": "", + "@commandHint_create": { + "type": "text", + "description": "Usage hint for the command /create" + }, + "youAreInvitedToThisChat": "", + "@youAreInvitedToThisChat": { + "type": "text", + "placeholders": {} + }, + "singlesignon": "", + "@singlesignon": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterAMatrixIdentifier": "", + "@pleaseEnterAMatrixIdentifier": { + "type": "text", + "placeholders": {} + }, + "sentAFile": "", + "@sentAFile": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "youAcceptedTheInvitation": "", + "@youAcceptedTheInvitation": {}, + "noMatrixServer": "", + "@noMatrixServer": { + "type": "text", + "placeholders": { + "server1": {}, + "server2": {} + } + }, + "userAndOthersAreTyping": "", + "@userAndOthersAreTyping": { + "type": "text", + "placeholders": { + "username": {}, + "count": {} + } + }, + "youInvitedBy": "", + "@youInvitedBy": { + "placeholders": { + "user": {} + } + }, + "userIsTyping": "", + "@userIsTyping": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "openAppToReadMessages": "", + "@openAppToReadMessages": { + "type": "text", + "placeholders": {} + }, + "sentAVideo": "", + "@sentAVideo": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "banUserDescription": "", + "@banUserDescription": {}, + "requests": "", + "@requests": {}, + "askSSSSSign": "", + "@askSSSSSign": { + "type": "text", + "placeholders": {} + }, + "waitingPartnerAcceptRequest": "", + "@waitingPartnerAcceptRequest": { + "type": "text", + "placeholders": {} + }, + "writeAMessage": "", + "@writeAMessage": { + "type": "text", + "placeholders": {} + }, + "addToStory": "", + "@addToStory": {}, + "removeDevicesDescription": "", + "@removeDevicesDescription": {}, + "changedTheChatDescriptionTo": "", + "@changedTheChatDescriptionTo": { + "type": "text", + "placeholders": { + "username": {}, + "description": {} + } + }, + "separateChatTypes": "", + "@separateChatTypes": { + "type": "text", + "placeholders": {} + }, + "tryAgain": "", + "@tryAgain": {}, + "areGuestsAllowedToJoin": "", + "@areGuestsAllowedToJoin": { + "type": "text", + "placeholders": {} + }, + "youKickedAndBanned": "", + "@youKickedAndBanned": { + "placeholders": { + "user": {} + } + }, + "showDirectChatsInSpaces": "", + "@showDirectChatsInSpaces": { + "type": "text", + "placeholders": {} + }, + "youCannotInviteYourself": "", + "@youCannotInviteYourself": { + "type": "text", + "placeholders": {} + }, + "unbanUserDescription": "", + "@unbanUserDescription": {}, + "todoLists": "", + "@todoLists": {}, + "userAndUserAreTyping": "", + "@userAndUserAreTyping": { + "type": "text", + "placeholders": { + "username": {}, + "username2": {} + } + }, + "pleaseClickOnLink": "", + "@pleaseClickOnLink": { + "type": "text", + "placeholders": {} + }, + "seenByUserAndCountOthers": "", + "@seenByUserAndCountOthers": { + "type": "text", + "placeholders": { + "username": {}, + "count": {} + } + }, + "pickImage": "", + "@pickImage": { + "type": "text", + "placeholders": {} + }, + "answeredTheCall": "", + "@answeredTheCall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "youRejectedTheInvitation": "", + "@youRejectedTheInvitation": {}, + "otherCallingPermissions": "", + "@otherCallingPermissions": {}, + "messagesStyle": "", + "@messagesStyle": {}, + "couldNotDecryptMessage": "", + "@couldNotDecryptMessage": { + "type": "text", + "placeholders": { + "error": {} + } + }, + "widgetUrlError": "", + "@widgetUrlError": {}, + "emailOrUsername": "", + "@emailOrUsername": {}, + "newSpaceDescription": "", + "@newSpaceDescription": {}, + "chatDescription": "", + "@chatDescription": {}, + "callingAccountDetails": "", + "@callingAccountDetails": {}, + "pleaseFollowInstructionsOnWeb": "", + "@pleaseFollowInstructionsOnWeb": { + "type": "text", + "placeholders": {} + }, + "changedTheGuestAccessRules": "", + "@changedTheGuestAccessRules": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "encryptThisChat": "", + "@encryptThisChat": {}, + "incorrectPassphraseOrKey": "", + "@incorrectPassphraseOrKey": { + "type": "text", + "placeholders": {} + }, + "emoteWarnNeedToPick": "", + "@emoteWarnNeedToPick": { + "type": "text", + "placeholders": {} + }, + "reopenChat": "", + "@reopenChat": {}, + "pleaseEnterRecoveryKey": "", + "@pleaseEnterRecoveryKey": {}, + "toggleFavorite": "", + "@toggleFavorite": { + "type": "text", + "placeholders": {} + }, + "widgetNameError": "", + "@widgetNameError": {}, + "addToBundle": "", + "@addToBundle": {}, + "spaceIsPublic": "", + "@spaceIsPublic": { + "type": "text", + "placeholders": {} + }, + "removeAllOtherDevices": "", + "@removeAllOtherDevices": { + "type": "text", + "placeholders": {} + }, + "noKeyForThisMessage": "", + "@noKeyForThisMessage": {}, + "enableEncryptionWarning": "", + "@enableEncryptionWarning": { + "type": "text", + "placeholders": {} + }, + "inviteText": "", + "@inviteText": { + "type": "text", + "placeholders": { + "username": {}, + "link": {} + } + }, + "editTodo": "", + "@editTodo": {}, + "errorObtainingLocation": "", + "@errorObtainingLocation": { + "type": "text", + "placeholders": { + "error": {} + } + }, + "hydrateTor": "", + "@hydrateTor": {}, + "pushNotificationsNotAvailable": "", + "@pushNotificationsNotAvailable": {}, + "storeInAppleKeyChain": "", + "@storeInAppleKeyChain": {}, + "replaceRoomWithNewerVersion": "", + "@replaceRoomWithNewerVersion": { + "type": "text", + "placeholders": {} + }, + "hydrate": "", + "@hydrate": {}, + "invalidServerName": "", + "@invalidServerName": {}, + "chatPermissions": "", + "@chatPermissions": {}, + "wipeChatBackup": "", + "@wipeChatBackup": { + "type": "text", + "placeholders": {} + }, + "storeInAndroidKeystore": "", + "@storeInAndroidKeystore": {}, + "hideRedactedEvents": "", + "@hideRedactedEvents": { + "type": "text", + "placeholders": {} + }, + "signInWithPassword": "", + "@signInWithPassword": {}, + "pleaseAddATitle": "", + "@pleaseAddATitle": {}, + "changedTheGuestAccessRulesTo": "", + "@changedTheGuestAccessRulesTo": { + "type": "text", + "placeholders": { + "username": {}, + "rules": {} + } + }, + "weSentYouAnEmail": "", + "@weSentYouAnEmail": { + "type": "text", + "placeholders": {} + }, + "needPantalaimonWarning": "", + "@needPantalaimonWarning": { + "type": "text", + "placeholders": {} + }, + "makeAdminDescription": "", + "@makeAdminDescription": {}, + "noEmotesFound": "", + "@noEmotesFound": { + "type": "text", + "placeholders": {} + }, + "synchronizingPleaseWait": "", + "@synchronizingPleaseWait": { + "type": "text", + "placeholders": {} + }, + "transferFromAnotherDevice": "", + "@transferFromAnotherDevice": { + "type": "text", + "placeholders": {} + }, + "passwordHasBeenChanged": "", + "@passwordHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "goToTheNewRoom": "", + "@goToTheNewRoom": { + "type": "text", + "placeholders": {} + }, + "saveKeyManuallyDescription": "", + "@saveKeyManuallyDescription": {}, + "editBundlesForAccount": "", + "@editBundlesForAccount": {}, + "renderRichContent": "", + "@renderRichContent": { + "type": "text", + "placeholders": {} + }, + "whyIsThisMessageEncrypted": "", + "@whyIsThisMessageEncrypted": {}, + "unreadChats": "", + "@unreadChats": { + "type": "text", + "placeholders": { + "unreadCount": {} + } + }, + "rejectedTheInvitation": "", + "@rejectedTheInvitation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "setChatDescription": "", + "@setChatDescription": {}, + "userLeftTheChat": "", + "@userLeftTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "importFromZipFile": "", + "@importFromZipFile": {}, + "dehydrateWarning": "", + "@dehydrateWarning": {}, + "noOtherDevicesFound": "", + "@noOtherDevicesFound": {}, + "whoIsAllowedToJoinThisGroup": "", + "@whoIsAllowedToJoinThisGroup": { + "type": "text", + "placeholders": {} + }, + "seenByUser": "", + "@seenByUser": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "storeSecurlyOnThisDevice": "", + "@storeSecurlyOnThisDevice": {}, + "yourChatBackupHasBeenSetUp": "", + "@yourChatBackupHasBeenSetUp": {}, + "redactedBy": "", + "@redactedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "videoCallsBetaWarning": "", + "@videoCallsBetaWarning": {}, + "unmuteChat": "", + "@unmuteChat": { + "type": "text", + "placeholders": {} + }, + "createdTheChat": "", + "@createdTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "redactedAnEvent": "", + "@redactedAnEvent": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "storyPrivacyWarning": "", + "@storyPrivacyWarning": {}, + "compareEmojiMatch": "", + "@compareEmojiMatch": { + "type": "text", + "placeholders": {} + }, + "logInTo": "", + "@logInTo": { + "type": "text", + "placeholders": { + "homeserver": {} + } + }, + "signInWith": "", + "@signInWith": { + "type": "text", + "placeholders": { + "provider": {} + } + }, + "changedTheRoomAliases": "", + "@changedTheRoomAliases": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "fileIsTooBigForServer": "", + "@fileIsTooBigForServer": {}, + "noTodosYet": "", + "@noTodosYet": {}, + "changedTheHistoryVisibilityTo": "", + "@changedTheHistoryVisibilityTo": { + "type": "text", + "placeholders": { + "username": {}, + "rules": {} + } + }, + "newMessageInFluffyChat": "", + "@newMessageInFluffyChat": { + "type": "text", + "placeholders": {} + }, + "readUpToHere": "", + "@readUpToHere": {}, + "unlockOldMessages": "", + "@unlockOldMessages": {}, + "changedTheJoinRulesTo": "", + "@changedTheJoinRulesTo": { + "type": "text", + "placeholders": { + "username": {}, + "joinRules": {} + } + }, + "whatIsGoingOn": "", + "@whatIsGoingOn": {}, + "changedTheChatPermissions": "", + "@changedTheChatPermissions": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "optionalRedactReason": "", + "@optionalRedactReason": {}, + "waitingPartnerEmoji": "", + "@waitingPartnerEmoji": { + "type": "text", + "placeholders": {} + }, + "channelCorruptedDecryptError": "", + "@channelCorruptedDecryptError": { + "type": "text", + "placeholders": {} + }, + "tryToSendAgain": "", + "@tryToSendAgain": { + "type": "text", + "placeholders": {} + }, + "guestsCanJoin": "", + "@guestsCanJoin": { + "type": "text", + "placeholders": {} + }, + "dehydrate": "", + "@dehydrate": {}, + "locationPermissionDeniedNotice": "", + "@locationPermissionDeniedNotice": { + "type": "text", + "placeholders": {} + }, + "hasWithdrawnTheInvitationFor": "", + "@hasWithdrawnTheInvitationFor": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "visibleForAllParticipants": "", + "@visibleForAllParticipants": { + "type": "text", + "placeholders": {} + }, + "sendAsText": "", + "@sendAsText": { + "type": "text" + }, + "archiveRoomDescription": "", + "@archiveRoomDescription": {}, + "exportEmotePack": "", + "@exportEmotePack": {}, + "changedTheChatNameTo": "", + "@changedTheChatNameTo": { + "type": "text", + "placeholders": { + "username": {}, + "chatname": {} + } + }, + "switchToAccount": "", + "@switchToAccount": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "setAsCanonicalAlias": "", + "@setAsCanonicalAlias": { + "type": "text", + "placeholders": {} + }, + "whyDoYouWantToReportThis": "", + "@whyDoYouWantToReportThis": { + "type": "text", + "placeholders": {} + }, + "locationDisabledNotice": "", + "@locationDisabledNotice": { + "type": "text", + "placeholders": {} + }, + "letsStart": "", + "@letsStart": {}, + "placeCall": "", + "@placeCall": {}, + "removedBy": "", + "@removedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheRoomInvitationLink": "", + "@changedTheRoomInvitationLink": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "experimentalVideoCalls": "", + "@experimentalVideoCalls": {}, + "savedEmotePack": "", + "@savedEmotePack": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "pleaseEnterRecoveryKeyDescription": "", + "@pleaseEnterRecoveryKeyDescription": {}, + "guestsAreForbidden": "", + "@guestsAreForbidden": { + "type": "text", + "placeholders": {} + }, + "withTheseAddressesRecoveryDescription": "", + "@withTheseAddressesRecoveryDescription": { + "type": "text", + "placeholders": {} + }, + "inviteContactToGroupQuestion": "", + "@inviteContactToGroupQuestion": {}, + "redactedByBecause": "", + "@redactedByBecause": { + "type": "text", + "placeholders": { + "username": {}, + "reason": {} + } + }, + "youHaveWithdrawnTheInvitationFor": "", + "@youHaveWithdrawnTheInvitationFor": { + "placeholders": { + "user": {} + } + }, + "appearOnTopDetails": "", + "@appearOnTopDetails": {}, + "roomHasBeenUpgraded": "", + "@roomHasBeenUpgraded": { + "type": "text", + "placeholders": {} + }, + "enableEmotesGlobally": "", + "@enableEmotesGlobally": { + "type": "text", + "placeholders": {} + }, + "ignoreListDescription": "", + "@ignoreListDescription": { + "type": "text", + "placeholders": {} + }, + "pleaseChooseAPasscode": "", + "@pleaseChooseAPasscode": { + "type": "text", + "placeholders": {} + }, + "noPasswordRecoveryDescription": "", + "@noPasswordRecoveryDescription": { + "type": "text", + "placeholders": {} + }, + "changedTheProfileAvatar": "", + "@changedTheProfileAvatar": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "passwordsDoNotMatch": "", + "@passwordsDoNotMatch": {}, + "sharedTheLocation": "", + "@sharedTheLocation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "onlineKeyBackupEnabled": "", + "@onlineKeyBackupEnabled": { + "type": "text", + "placeholders": {} + }, + "unbannedUser": "", + "@unbannedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "confirmEventUnpin": "", + "@confirmEventUnpin": {}, + "youInvitedUser": "", + "@youInvitedUser": { + "placeholders": { + "user": {} + } + }, + "kickedAndBanned": "", + "@kickedAndBanned": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "noConnectionToTheServer": "", + "@noConnectionToTheServer": { + "type": "text", + "placeholders": {} + }, + "fileHasBeenSavedAt": "", + "@fileHasBeenSavedAt": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "unbanFromChat": "", + "@unbanFromChat": { + "type": "text", + "placeholders": {} + }, + "importZipFile": "", + "@importZipFile": {}, + "anyoneCanKnock": "", + "@anyoneCanKnock": {}, + "commandMissing": "", + "@commandMissing": { + "type": "text", + "placeholders": { + "command": {} + }, + "description": "State that {command} is not a valid /command." + }, + "redactMessageDescription": "", + "@redactMessageDescription": {}, + "commandHint_discardsession": "", + "@commandHint_discardsession": { + "type": "text", + "description": "Usage hint for the command /discardsession" + }, + "invalidInput": "", + "@invalidInput": {}, + "chooseAStrongPassword": "", + "@chooseAStrongPassword": { + "type": "text", + "placeholders": {} + }, + "todosUnencrypted": "", + "@todosUnencrypted": {}, + "dehydrateTorLong": "", + "@dehydrateTorLong": {}, + "yourPublicKey": "", + "@yourPublicKey": { + "type": "text", + "placeholders": {} + }, + "tooManyRequestsWarning": "", + "@tooManyRequestsWarning": { + "type": "text", + "placeholders": {} + }, + "kickFromChat": "", + "@kickFromChat": { + "type": "text", + "placeholders": {} + }, + "commandHint_myroomnick": "", + "@commandHint_myroomnick": { + "type": "text", + "description": "Usage hint for the command /myroomnick" + }, + "replyHasBeenSent": "", + "@replyHasBeenSent": {}, + "doNotShowAgain": "", + "@doNotShowAgain": {}, + "activatedEndToEndEncryption": "", + "@activatedEndToEndEncryption": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "report": "", + "@report": {}, + "compareNumbersMatch": "", + "@compareNumbersMatch": { + "type": "text", + "placeholders": {} + }, + "howOffensiveIsThisContent": "", + "@howOffensiveIsThisContent": { + "type": "text", + "placeholders": {} + }, + "serverRequiresEmail": "", + "@serverRequiresEmail": {}, + "hideUnimportantStateEvents": "", + "@hideUnimportantStateEvents": {}, + "sentCallInformations": "", + "@sentCallInformations": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "addToSpaceDescription": "", + "@addToSpaceDescription": {}, + "googlyEyesContent": "", + "@googlyEyesContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "whoCanSeeMyStoriesDesc": "", + "@whoCanSeeMyStoriesDesc": {}, + "youBannedUser": "", + "@youBannedUser": { + "placeholders": { + "user": {} + } + }, + "theyDontMatch": "", + "@theyDontMatch": { + "type": "text", + "placeholders": {} + }, + "youHaveBeenBannedFromThisChat": "", + "@youHaveBeenBannedFromThisChat": { + "type": "text", + "placeholders": {} + }, + "displaynameHasBeenChanged": "", + "@displaynameHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "loginWithOneClick": "", + "@loginWithOneClick": {}, + "addChatDescription": "", + "@addChatDescription": {}, + "sentAnAudio": "", + "@sentAnAudio": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "commandHint_myroomavatar": "", + "@commandHint_myroomavatar": { + "type": "text", + "description": "Usage hint for the command /myroomavatar" + }, + "hasKnocked": "", + "@hasKnocked": { + "placeholders": { + "user": {} + } + }, + "openLinkInBrowser": "", + "@openLinkInBrowser": {}, + "appLock": "", + "@appLock": { + "type": "text", + "placeholders": {} + }, + "commandHint_react": "", + "@commandHint_react": { + "type": "text", + "description": "Usage hint for the command /react" + }, + "changedTheHistoryVisibility": "", + "@changedTheHistoryVisibility": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "pleaseEnterYourUsername": "", + "@pleaseEnterYourUsername": { + "type": "text", + "placeholders": {} + }, + "disableEncryptionWarning": "", + "@disableEncryptionWarning": {}, + "directChat": "", + "@directChat": {}, + "noOneCanJoin": "", + "@noOneCanJoin": {}, + "encryptionNotEnabled": "", + "@encryptionNotEnabled": { + "type": "text", + "placeholders": {} + }, + "wrongPinEntered": "", + "@wrongPinEntered": { + "type": "text", + "placeholders": { + "seconds": {} + } + }, + "sendTypingNotifications": "", + "@sendTypingNotifications": {}, + "inviteGroupChat": "", + "@inviteGroupChat": {}, + "appearOnTop": "", + "@appearOnTop": {}, + "invitePrivateChat": "", + "@invitePrivateChat": {}, + "verifyTitle": "", + "@verifyTitle": { + "type": "text", + "placeholders": {} + }, + "foregroundServiceRunning": "", + "@foregroundServiceRunning": {}, + "enterAnEmailAddress": "", + "@enterAnEmailAddress": { + "type": "text", + "placeholders": {} + }, + "commandHint_kick": "", + "@commandHint_kick": { + "type": "text", + "description": "Usage hint for the command /kick" + }, + "commandHint_unban": "", + "@commandHint_unban": { + "type": "text", + "description": "Usage hint for the command /unban" + }, + "unknownEncryptionAlgorithm": "", + "@unknownEncryptionAlgorithm": { + "type": "text", + "placeholders": {} + }, + "commandHint_ban": "", + "@commandHint_ban": { + "type": "text", + "description": "Usage hint for the command /ban" + }, + "importEmojis": "", + "@importEmojis": {}, + "wasDirectChatDisplayName": "", + "@wasDirectChatDisplayName": { + "type": "text", + "placeholders": { + "oldDisplayName": {} + } + }, + "noChatDescriptionYet": "", + "@noChatDescriptionYet": {}, + "defaultPermissionLevel": "", + "@defaultPermissionLevel": { + "type": "text", + "placeholders": {} + }, + "newTodo": "", + "@newTodo": {}, + "removeFromBundle": "", + "@removeFromBundle": {}, + "numUsersTyping": "", + "@numUsersTyping": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "whoCanPerformWhichAction": "", + "@whoCanPerformWhichAction": { + "type": "text", + "placeholders": {} + }, + "learnMore": "", + "@learnMore": {}, + "iHaveClickedOnLink": "", + "@iHaveClickedOnLink": { + "type": "text", + "placeholders": {} + }, + "notAnImage": "", + "@notAnImage": {}, + "chatDescriptionHasBeenChanged": "", + "@chatDescriptionHasBeenChanged": {}, + "bundleName": "", + "@bundleName": {}, + "dehydrateTor": "", + "@dehydrateTor": {}, + "todoListChangedError": "", + "@todoListChangedError": {}, + "removeFromSpace": "", + "@removeFromSpace": {}, + "enterInviteLinkOrMatrixId": "", + "@enterInviteLinkOrMatrixId": {}, + "commandHint_op": "", + "@commandHint_op": { + "type": "text", + "description": "Usage hint for the command /op" + }, + "commandHint_join": "", + "@commandHint_join": { + "type": "text", + "description": "Usage hint for the command /join" + }, + "enterAGroupName": "", + "@enterAGroupName": { + "type": "text", + "placeholders": {} + }, + "roomUpgradeDescription": "", + "@roomUpgradeDescription": {}, + "commandHint_invite": "", + "@commandHint_invite": { + "type": "text", + "description": "Usage hint for the command /invite" + }, + "userSentUnknownEvent": "", + "@userSentUnknownEvent": { + "type": "text", + "placeholders": { + "username": {}, + "type": {} + } + }, + "pleaseEnterANumber": "", + "@pleaseEnterANumber": {}, + "contactHasBeenInvitedToTheGroup": "", + "@contactHasBeenInvitedToTheGroup": { + "type": "text", + "placeholders": {} + }, + "youKicked": "", + "@youKicked": { + "placeholders": { + "user": {} + } + }, + "changedTheJoinRules": "", + "@changedTheJoinRules": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "profileNotFound": "", + "@profileNotFound": {}, + "jump": "", + "@jump": {}, + "reactedWith": "", + "@reactedWith": { + "type": "text", + "placeholders": { + "sender": {}, + "reaction": {} + } + }, + "sorryThatsNotPossible": "", + "@sorryThatsNotPossible": {}, + "storyFrom": "", + "@storyFrom": { + "type": "text", + "placeholders": { + "date": {}, + "body": {} + } + }, + "oopsSomethingWentWrong": "", + "@oopsSomethingWentWrong": { + "type": "text", + "placeholders": {} + }, + "loadCountMoreParticipants": "", + "@loadCountMoreParticipants": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "shareInviteLink": "", + "@shareInviteLink": {}, + "commandHint_markasdm": "", + "@commandHint_markasdm": {}, + "recoveryKeyLost": "", + "@recoveryKeyLost": {}, + "cuddleContent": "", + "@cuddleContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "deviceKeys": "", + "@deviceKeys": {}, + "waitingPartnerNumbers": "", + "@waitingPartnerNumbers": { + "type": "text", + "placeholders": {} + }, + "noGoogleServicesWarning": "", + "@noGoogleServicesWarning": { + "type": "text", + "placeholders": {} + }, + "emoteKeyboardNoRecents": "", + "@emoteKeyboardNoRecents": { + "type": "text", + "placeholders": {} + }, + "setCustomEmotes": "", + "@setCustomEmotes": { + "type": "text", + "placeholders": {} + }, + "startedACall": "", + "@startedACall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "emoteInvalid": "", + "@emoteInvalid": { + "type": "text", + "placeholders": {} + }, + "messageWillBeRemovedWarning": "", + "@messageWillBeRemovedWarning": { + "type": "text", + "placeholders": {} + }, + "endToEndEncryption": "", + "@endToEndEncryption": {}, + "notificationsEnabledForThisAccount": "", + "@notificationsEnabledForThisAccount": { + "type": "text", + "placeholders": {} + }, + "visibilityOfTheChatHistory": "", + "@visibilityOfTheChatHistory": { + "type": "text", + "placeholders": {} + }, + "setTheme": "", + "@setTheme": {}, + "youJoinedTheChat": "", + "@youJoinedTheChat": {}, + "openVideoCamera": "", + "@openVideoCamera": { + "type": "text", + "placeholders": {} + }, + "chatBackupDescription": "", + "@chatBackupDescription": { + "type": "text", + "placeholders": {} + }, + "lastSeenLongTimeAgo": "", + "@lastSeenLongTimeAgo": { + "type": "text", + "placeholders": {} + }, + "statusExampleMessage": "", + "@statusExampleMessage": { + "type": "text", + "placeholders": {} + }, + "thisUserHasNotPostedAnythingYet": "", + "@thisUserHasNotPostedAnythingYet": {}, + "markAsRead": "", + "@markAsRead": {}, + "sentASticker": "", + "@sentASticker": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "errorAddingWidget": "", + "@errorAddingWidget": {}, + "commandHint_dm": "", + "@commandHint_dm": { + "type": "text", + "description": "Usage hint for the command /dm" + }, + "commandHint_hug": "", + "@commandHint_hug": {}, + "replace": "", + "@replace": {}, + "oopsPushError": "", + "@oopsPushError": { + "type": "text", + "placeholders": {} + }, + "youUnbannedUser": "", + "@youUnbannedUser": { + "placeholders": { + "user": {} + } + }, + "deactivateAccountWarning": "", + "@deactivateAccountWarning": { + "type": "text", + "placeholders": {} + }, + "joinedTheChat": "", + "@joinedTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "visibleForEveryone": "", + "@visibleForEveryone": { + "type": "text", + "placeholders": {} + }, + "pleaseEnter4Digits": "", + "@pleaseEnter4Digits": { + "type": "text", + "placeholders": {} + }, + "unknownEvent": "", + "@unknownEvent": { + "type": "text", + "placeholders": { + "type": {} + } + }, + "pleaseEnterYourPin": "", + "@pleaseEnterYourPin": { + "type": "text", + "placeholders": {} + }, + "commandHint_googly": "", + "@commandHint_googly": {}, + "pleaseTryAgainLaterOrChooseDifferentServer": "", + "@pleaseTryAgainLaterOrChooseDifferentServer": {}, + "createGroup": "", + "@createGroup": {}, + "hydrateTorLong": "", + "@hydrateTorLong": {}, + "contentHasBeenReported": "", + "@contentHasBeenReported": { + "type": "text", + "placeholders": {} + }, + "noBackupWarning": "", + "@noBackupWarning": {}, + "storeInSecureStorageDescription": "", + "@storeInSecureStorageDescription": {}, + "kickUserDescription": "", + "@kickUserDescription": {}, + "sendAMessage": "", + "@sendAMessage": { + "type": "text", + "placeholders": {} + }, + "importNow": "", + "@importNow": {}, + "setInvitationLink": "", + "@setInvitationLink": { + "type": "text", + "placeholders": {} + }, + "pinMessage": "", + "@pinMessage": {}, + "screenSharingDetail": "", + "@screenSharingDetail": {}, + "invite": "", + "@invite": {}, + "enableMultiAccounts": "", + "@enableMultiAccounts": {}, + "emotePacks": "", + "@emotePacks": { + "type": "text", + "placeholders": {} + }, + "makeSureTheIdentifierIsValid": "", + "@makeSureTheIdentifierIsValid": { + "type": "text", + "placeholders": {} + }, + "continueWith": "", + "@continueWith": {}, + "indexedDbErrorTitle": "", + "@indexedDbErrorTitle": {}, + "pleaseChooseAUsername": "", + "@pleaseChooseAUsername": { + "type": "text", + "placeholders": {} + }, + "endedTheCall": "", + "@endedTheCall": { + "type": "text", + "placeholders": { + "senderName": {} + } + } +} diff --git a/assets/l10n/intl_it.arb b/assets/l10n/intl_it.arb index a058dd068..b71cbdd8c 100644 --- a/assets/l10n/intl_it.arb +++ b/assets/l10n/intl_it.arb @@ -1,1970 +1,2658 @@ { - "@@last_modified": "2021-08-14 12:41:09.992206", - "about": "Informazioni", - "@about": { - "type": "text", - "placeholders": {} - }, - "accept": "Accetta", - "@accept": { - "type": "text", - "placeholders": {} - }, - "acceptedTheInvitation": "{username} ha accettato l'invito", - "@acceptedTheInvitation": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "account": "Account", - "@account": { - "type": "text", - "placeholders": {} - }, - "activatedEndToEndEncryption": "{username} ha abilitato la crittografia end to end", - "@activatedEndToEndEncryption": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "addEmail": "Aggiungi e-mail", - "@addEmail": { - "type": "text", - "placeholders": {} - }, - "addGroupDescription": "Aggiungi una descrizione al gruppo", - "@addGroupDescription": { - "type": "text", - "placeholders": {} - }, - "admin": "Amministratore", - "@admin": { - "type": "text", - "placeholders": {} - }, - "alias": "alias", - "@alias": { - "type": "text", - "placeholders": {} - }, - "all": "Tutto", - "@all": { - "type": "text", - "placeholders": {} - }, - "answeredTheCall": "{senderName} ha risposto alla chiamata", - "@answeredTheCall": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "anyoneCanJoin": "Tutti possono partecipare", - "@anyoneCanJoin": { - "type": "text", - "placeholders": {} - }, - "appLock": "Blocco dell'app", - "@appLock": { - "type": "text", - "placeholders": {} - }, - "archive": "Archivia", - "@archive": { - "type": "text", - "placeholders": {} - }, - "areGuestsAllowedToJoin": "Gli utenti ospiti possono partecipare", - "@areGuestsAllowedToJoin": { - "type": "text", - "placeholders": {} - }, - "areYouSure": "Sei sicuro/a?", - "@areYouSure": { - "type": "text", - "placeholders": {} - }, - "areYouSureYouWantToLogout": "Sei sicuro/a di voler uscire?", - "@areYouSureYouWantToLogout": { - "type": "text", - "placeholders": {} - }, - "askSSSSSign": "Per far accedere l'altra persona, per favore inserisci la tua frase segreta o chiave di recupero.", - "@askSSSSSign": { - "type": "text", - "placeholders": {} - }, - "askVerificationRequest": "Accettare questa richiesta di verifica da {username}?", - "@askVerificationRequest": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "badServerLoginTypesException": "L'homeserver supporta i tipi di accesso:\n{serverVersions}\nMa questa applicazione supporta solo:\n{supportedVersions}", - "@badServerLoginTypesException": { - "type": "text", - "placeholders": { - "serverVersions": {}, - "supportedVersions": {} - } - }, - "badServerVersionsException": "L'homeserver supporta le versioni Spec:\n{serverVersions}\nMa questa applicazione supporta solo {supportedVersions}", - "@badServerVersionsException": { - "type": "text", - "placeholders": { - "serverVersions": {}, - "supportedVersions": {} - } - }, - "banFromChat": "Bandisci dalla chat", - "@banFromChat": { - "type": "text", - "placeholders": {} - }, - "banned": "Bandito", - "@banned": { - "type": "text", - "placeholders": {} - }, - "bannedUser": "{username} ha bandito {targetName}", - "@bannedUser": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "blockDevice": "Blocca dispositivo", - "@blockDevice": { - "type": "text", - "placeholders": {} - }, - "blocked": "Bloccato", - "@blocked": { - "type": "text", - "placeholders": {} - }, - "botMessages": "Messaggi bot", - "@botMessages": { - "type": "text", - "placeholders": {} - }, - "cancel": "Cancella", - "@cancel": { - "type": "text", - "placeholders": {} - }, - "changeDeviceName": "Cambia nome dispositivo", - "@changeDeviceName": { - "type": "text", - "placeholders": {} - }, - "changedTheChatAvatar": "{username} ha cambiato l'avatar della discussione", - "@changedTheChatAvatar": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheChatDescriptionTo": "{username} ha cambiato la descrizione della chat in: «{description}»", - "@changedTheChatDescriptionTo": { - "type": "text", - "placeholders": { - "username": {}, - "description": {} - } - }, - "changedTheChatNameTo": "{username} ha cambiato il nome della discussione in: «{chatname}»", - "@changedTheChatNameTo": { - "type": "text", - "placeholders": { - "username": {}, - "chatname": {} - } - }, - "changedTheChatPermissions": "{username} ha cambiato i permessi della chat", - "@changedTheChatPermissions": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheDisplaynameTo": "{username} ha cambiato nome in: {displayname}", - "@changedTheDisplaynameTo": { - "type": "text", - "placeholders": { - "username": {}, - "displayname": {} - } - }, - "changedTheGuestAccessRules": "{username} ha cambiato le regole di accesso per ospiti", - "@changedTheGuestAccessRules": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheGuestAccessRulesTo": "{username} ha cambiato le regole di accesso per ospiti con: {rules}", - "@changedTheGuestAccessRulesTo": { - "type": "text", - "placeholders": { - "username": {}, - "rules": {} - } - }, - "changedTheHistoryVisibility": "{username} ha cambiato la visibilità della cronologia", - "@changedTheHistoryVisibility": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheHistoryVisibilityTo": "{username} ha cambiato la visibilità della cronologia in: {rules}", - "@changedTheHistoryVisibilityTo": { - "type": "text", - "placeholders": { - "username": {}, - "rules": {} - } - }, - "changedTheJoinRules": "{username} ha cambiato le regole per unirsi", - "@changedTheJoinRules": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheJoinRulesTo": "{username} ha cambiato le regole per unirsi in: {joinRules}", - "@changedTheJoinRulesTo": { - "type": "text", - "placeholders": { - "username": {}, - "joinRules": {} - } - }, - "changedTheProfileAvatar": "{username} ha cambiato il loro avatar", - "@changedTheProfileAvatar": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheRoomAliases": "{username} ha cambiato il nome delle stanze", - "@changedTheRoomAliases": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheRoomInvitationLink": "{username} ha cambiato il link di invito", - "@changedTheRoomInvitationLink": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changePassword": "Cambia la password", - "@changePassword": { - "type": "text", - "placeholders": {} - }, - "changeTheHomeserver": "Cambia il server principale", - "@changeTheHomeserver": { - "type": "text", - "placeholders": {} - }, - "changeTheme": "Cambia il tuo stile", - "@changeTheme": { - "type": "text", - "placeholders": {} - }, - "changeTheNameOfTheGroup": "Cambia il nome del gruppo", - "@changeTheNameOfTheGroup": { - "type": "text", - "placeholders": {} - }, - "changeWallpaper": "Cambia sfondo", - "@changeWallpaper": { - "type": "text", - "placeholders": {} - }, - "channelCorruptedDecryptError": "La crittografia è corrotta", - "@channelCorruptedDecryptError": { - "type": "text", - "placeholders": {} - }, - "chat": "Chat", - "@chat": { - "type": "text", - "placeholders": {} - }, - "chatBackup": "Backup delle discussioni", - "@chatBackup": { - "type": "text", - "placeholders": {} - }, - "chatBackupDescription": "Il backup della discussione è protetto da una chiave di sicurezza. Assicurati di non perderla.", - "@chatBackupDescription": { - "type": "text", - "placeholders": {} - }, - "chatDetails": "Dettagli chat", - "@chatDetails": { - "type": "text", - "placeholders": {} - }, - "chats": "Discussioni", - "@chats": { - "type": "text", - "placeholders": {} - }, - "chooseAStrongPassword": "Scegli una password complessa", - "@chooseAStrongPassword": { - "type": "text", - "placeholders": {} - }, - "chooseAUsername": "Scegli un username", - "@chooseAUsername": { - "type": "text", - "placeholders": {} - }, - "close": "Chiudi", - "@close": { - "type": "text", - "placeholders": {} - }, - "compareEmojiMatch": "Confronta e assicurati che le seguenti emoji corrispondano a quelle dell'altro dispositivo:", - "@compareEmojiMatch": { - "type": "text", - "placeholders": {} - }, - "compareNumbersMatch": "Confronta e assicurati che le seguenti emoji corrispondano a quelle dell'altro dispositivo:", - "@compareNumbersMatch": { - "type": "text", - "placeholders": {} - }, - "configureChat": "Configura la discussione", - "@configureChat": { - "type": "text", - "placeholders": {} - }, - "confirm": "Conferma", - "@confirm": { - "type": "text", - "placeholders": {} - }, - "connect": "Connetti", - "@connect": { - "type": "text", - "placeholders": {} - }, - "contactHasBeenInvitedToTheGroup": "Il contatto è stato invitato nel gruppo", - "@contactHasBeenInvitedToTheGroup": { - "type": "text", - "placeholders": {} - }, - "containsDisplayName": "Contiene nome visibile", - "@containsDisplayName": { - "type": "text", - "placeholders": {} - }, - "containsUserName": "Contiene nome utente", - "@containsUserName": { - "type": "text", - "placeholders": {} - }, - "contentHasBeenReported": "Il contenuto è stato segnalato agli amministratori del server", - "@contentHasBeenReported": { - "type": "text", - "placeholders": {} - }, - "copiedToClipboard": "Copiato negli Appunti", - "@copiedToClipboard": { - "type": "text", - "placeholders": {} - }, - "copy": "Copia", - "@copy": { - "type": "text", - "placeholders": {} - }, - "copyToClipboard": "Copia negli appunti", - "@copyToClipboard": { - "type": "text", - "placeholders": {} - }, - "couldNotDecryptMessage": "Impossibile decriptare messaggio: {error}", - "@couldNotDecryptMessage": { - "type": "text", - "placeholders": { - "error": {} - } - }, - "countParticipants": "{count} partecipanti", - "@countParticipants": { - "type": "text", - "placeholders": { - "count": {} - } - }, - "create": "Crea", - "@create": { - "type": "text", - "placeholders": {} - }, - "createdTheChat": "{username} ha creato la chat", - "@createdTheChat": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "createNewGroup": "Crea un nuovo gruppo", - "@createNewGroup": { - "type": "text", - "placeholders": {} - }, - "currentlyActive": "Attualmente attivo", - "@currentlyActive": { - "type": "text", - "placeholders": {} - }, - "darkTheme": "Scuro", - "@darkTheme": { - "type": "text", - "placeholders": {} - }, - "dateAndTimeOfDay": "{date}, {timeOfDay}", - "@dateAndTimeOfDay": { - "type": "text", - "placeholders": { - "date": {}, - "timeOfDay": {} - } - }, - "dateWithoutYear": "{day}/{month}", - "@dateWithoutYear": { - "type": "text", - "placeholders": { - "month": {}, - "day": {} - } - }, - "dateWithYear": "{day}/{month}/{year}", - "@dateWithYear": { - "type": "text", - "placeholders": { - "year": {}, - "month": {}, - "day": {} - } - }, - "deactivateAccountWarning": "Disabiliterà il tuo account. Non puoi tornare indietro! Sei sicuro/a?", - "@deactivateAccountWarning": { - "type": "text", - "placeholders": {} - }, - "defaultPermissionLevel": "Livello di autorizzazione predefinito", - "@defaultPermissionLevel": { - "type": "text", - "placeholders": {} - }, - "delete": "Cancella", - "@delete": { - "type": "text", - "placeholders": {} - }, - "deleteAccount": "Elimina l'account", - "@deleteAccount": { - "type": "text", - "placeholders": {} - }, - "deleteMessage": "Elimina il messaggio", - "@deleteMessage": { - "type": "text", - "placeholders": {} - }, - "deny": "Declina", - "@deny": { - "type": "text", - "placeholders": {} - }, - "device": "Dispositivo", - "@device": { - "type": "text", - "placeholders": {} - }, - "deviceId": "ID del dispositivo", - "@deviceId": { - "type": "text", - "placeholders": {} - }, - "devices": "Dispositivi", - "@devices": { - "type": "text", - "placeholders": {} - }, - "directChats": "Discussioni dirette", - "@directChats": { - "type": "text", - "placeholders": {} - }, - "displaynameHasBeenChanged": "Il nominativo è stato cambiato", - "@displaynameHasBeenChanged": { - "type": "text", - "placeholders": {} - }, - "downloadFile": "Scarica il file", - "@downloadFile": { - "type": "text", - "placeholders": {} - }, - "edit": "Modifica", - "@edit": { - "type": "text", - "placeholders": {} - }, - "editBlockedServers": "Modifica i server bloccati", - "@editBlockedServers": { - "type": "text", - "placeholders": {} - }, - "editChatPermissions": "Modifica le autorizzazioni discussione", - "@editChatPermissions": { - "type": "text", - "placeholders": {} - }, - "editDisplayname": "Modifica il nominativo", - "@editDisplayname": { - "type": "text", - "placeholders": {} - }, - "editRoomAvatar": "Modifica l'avatar della stanza", - "@editRoomAvatar": { - "type": "text", - "placeholders": {} - }, - "emoteExists": "L'emote già esiste!", - "@emoteExists": { - "type": "text", - "placeholders": {} - }, - "emoteInvalid": "Shortcode emote invalido!", - "@emoteInvalid": { - "type": "text", - "placeholders": {} - }, - "emotePacks": "Pacchetti emotes della stanza", - "@emotePacks": { - "type": "text", - "placeholders": {} - }, - "emoteSettings": "Impostazioni emote", - "@emoteSettings": { - "type": "text", - "placeholders": {} - }, - "emoteShortcode": "Scorciatoia emote", - "@emoteShortcode": { - "type": "text", - "placeholders": {} - }, - "emoteWarnNeedToPick": "Devi scegliere una scorciatoia emote e aggiungere un immagine!", - "@emoteWarnNeedToPick": { - "type": "text", - "placeholders": {} - }, - "emptyChat": "Discussione vuota", - "@emptyChat": { - "type": "text", - "placeholders": {} - }, - "enableEmotesGlobally": "Abilita i pacchetti emotes globalmente", - "@enableEmotesGlobally": { - "type": "text", - "placeholders": {} - }, - "enableEncryption": "Abilita la crittografia", - "@enableEncryption": { - "type": "text", - "placeholders": {} - }, - "enableEncryptionWarning": "Non potrai disabilitare la crittografia in futuro. Sei sicuro?", - "@enableEncryptionWarning": { - "type": "text", - "placeholders": {} - }, - "encrypted": "Crittografato", - "@encrypted": { - "type": "text", - "placeholders": {} - }, - "encryption": "Crittografia", - "@encryption": { - "type": "text", - "placeholders": {} - }, - "encryptionNotEnabled": "Crittografia non abilitata", - "@encryptionNotEnabled": { - "type": "text", - "placeholders": {} - }, - "endedTheCall": "{senderName} è entrato in chiamata", - "@endedTheCall": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "enterAGroupName": "Inserisci un nome del gruppo", - "@enterAGroupName": { - "type": "text", - "placeholders": {} - }, - "enterAnEmailAddress": "Inserisci un indirizzo e-mail", - "@enterAnEmailAddress": { - "type": "text", - "placeholders": {} - }, - "enterYourHomeserver": "Inserisci il tuo server principale", - "@enterYourHomeserver": { - "type": "text", - "placeholders": {} - }, - "everythingReady": "Tutto pronto!", - "@everythingReady": { - "type": "text", - "placeholders": {} - }, - "extremeOffensive": "Estremamente offensivo", - "@extremeOffensive": { - "type": "text", - "placeholders": {} - }, - "fileName": "Nome del file", - "@fileName": { - "type": "text", - "placeholders": {} - }, - "fluffychat": "FluffyChat", - "@fluffychat": { - "type": "text", - "placeholders": {} - }, - "fontSize": "Dimensione carattere", - "@fontSize": { - "type": "text", - "placeholders": {} - }, - "forward": "Inoltra", - "@forward": { - "type": "text", - "placeholders": {} - }, - "fromJoining": "Dall'adesione", - "@fromJoining": { - "type": "text", - "placeholders": {} - }, - "fromTheInvitation": "Dall'invito", - "@fromTheInvitation": { - "type": "text", - "placeholders": {} - }, - "goToTheNewRoom": "Vai nella nuova stanza", - "@goToTheNewRoom": { - "type": "text", - "placeholders": {} - }, - "group": "Gruppo", - "@group": { - "type": "text", - "placeholders": {} - }, - "groupDescription": "Descrizione del gruppo", - "@groupDescription": { - "type": "text", - "placeholders": {} - }, - "groupDescriptionHasBeenChanged": "Descrizione del gruppo modificata", - "@groupDescriptionHasBeenChanged": { - "type": "text", - "placeholders": {} - }, - "groupIsPublic": "Il gruppo è pubblico", - "@groupIsPublic": { - "type": "text", - "placeholders": {} - }, - "groups": "Gruppi", - "@groups": { - "type": "text", - "placeholders": {} - }, - "groupWith": "Gruppo con {displayname}", - "@groupWith": { - "type": "text", - "placeholders": { - "displayname": {} - } - }, - "guestsAreForbidden": "Gli ospiti sono vietati", - "@guestsAreForbidden": { - "type": "text", - "placeholders": {} - }, - "guestsCanJoin": "Gli ospiti possono partecipare", - "@guestsCanJoin": { - "type": "text", - "placeholders": {} - }, - "hasWithdrawnTheInvitationFor": "{username} ha ritirato l'invito per {targetName}", - "@hasWithdrawnTheInvitationFor": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "help": "Aiuto", - "@help": { - "type": "text", - "placeholders": {} - }, - "hideRedactedEvents": "Nascondi gli eventi eliminati", - "@hideRedactedEvents": { - "type": "text", - "placeholders": {} - }, - "hideUnknownEvents": "Nascondi gli eventi sconosciuti", - "@hideUnknownEvents": { - "type": "text", - "placeholders": {} - }, - "howOffensiveIsThisContent": "Quanto è offensivo questo contenuto?", - "@howOffensiveIsThisContent": { - "type": "text", - "placeholders": {} - }, - "id": "ID", - "@id": { - "type": "text", - "placeholders": {} - }, - "identity": "Identità", - "@identity": { - "type": "text", - "placeholders": {} - }, - "ignore": "Ignora", - "@ignore": { - "type": "text", - "placeholders": {} - }, - "ignoredUsers": "Utenti ignorati", - "@ignoredUsers": { - "type": "text", - "placeholders": {} - }, - "ignoreListDescription": "Puoi ignorare gli utenti che ti stanno disturbando. Non sarai in grado di ricevere messaggi o inviti a stanze virtuali dagli utenti nel tuo elenco personale da ignorare.", - "@ignoreListDescription": { - "type": "text", - "placeholders": {} - }, - "ignoreUsername": "Ignora il nome utente", - "@ignoreUsername": { - "type": "text", - "placeholders": {} - }, - "iHaveClickedOnLink": "Ho cliccato sul collegamento", - "@iHaveClickedOnLink": { - "type": "text", - "placeholders": {} - }, - "incorrectPassphraseOrKey": "Frase segrata o chiave di ripristino errate", - "@incorrectPassphraseOrKey": { - "type": "text", - "placeholders": {} - }, - "inoffensive": "Inoffensivo", - "@inoffensive": { - "type": "text", - "placeholders": {} - }, - "inviteContact": "Invita contatto", - "@inviteContact": { - "type": "text", - "placeholders": {} - }, - "inviteContactToGroup": "Invita un contatto a {groupName}", - "@inviteContactToGroup": { - "type": "text", - "placeholders": { - "groupName": {} - } - }, - "invited": "Invitato/a", - "@invited": { - "type": "text", - "placeholders": {} - }, - "invitedUser": "{username} ha invitato {targetName}", - "@invitedUser": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "invitedUsersOnly": "Solo per gli utenti invitati", - "@invitedUsersOnly": { - "type": "text", - "placeholders": {} - }, - "inviteForMe": "Invita per me", - "@inviteForMe": { - "type": "text", - "placeholders": {} - }, - "inviteText": "{username} ti ha invitato/a a FluffyChat.\n1. Installa FluffyChat: https://fluffychat.im\n2. Iscriviti o accedi\n3. Apri il collegamento di invito: {link}", - "@inviteText": { - "type": "text", - "placeholders": { - "username": {}, - "link": {} - } - }, - "isTyping": "sta scrivendo…", - "@isTyping": { - "type": "text", - "placeholders": {} - }, - "joinedTheChat": "{username} si è unito/a alla chat", - "@joinedTheChat": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "joinRoom": "Unisciti alla stanza", - "@joinRoom": { - "type": "text", - "placeholders": {} - }, - "kicked": "{username} ha espulso {targetName}", - "@kicked": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "kickedAndBanned": "{username} ha espulso e bandito {targetName}", - "@kickedAndBanned": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "kickFromChat": "Espulsa dalla discussione", - "@kickFromChat": { - "type": "text", - "placeholders": {} - }, - "lastActiveAgo": "Ultima attività: {localizedTimeShort}", - "@lastActiveAgo": { - "type": "text", - "placeholders": { - "localizedTimeShort": {} - } - }, - "lastSeenLongTimeAgo": "Visto/a molto tempo fa", - "@lastSeenLongTimeAgo": { - "type": "text", - "placeholders": {} - }, - "leave": "Lascia", - "@leave": { - "type": "text", - "placeholders": {} - }, - "leftTheChat": "Ha lasciato la chat", - "@leftTheChat": { - "type": "text", - "placeholders": {} - }, - "license": "Licenza", - "@license": { - "type": "text", - "placeholders": {} - }, - "lightTheme": "Chiaro", - "@lightTheme": { - "type": "text", - "placeholders": {} - }, - "loadCountMoreParticipants": "Carica altri {count} partecipanti", - "@loadCountMoreParticipants": { - "type": "text", - "placeholders": { - "count": {} - } - }, - "loadingPleaseWait": "Caricamento… Attendere prego.", - "@loadingPleaseWait": { - "type": "text", - "placeholders": {} - }, - "loadMore": "Carica di più…", - "@loadMore": { - "type": "text", - "placeholders": {} - }, - "login": "Accedi", - "@login": { - "type": "text", - "placeholders": {} - }, - "logInTo": "Accedi a {homeserver}", - "@logInTo": { - "type": "text", - "placeholders": { - "homeserver": {} - } - }, - "logout": "Esci", - "@logout": { - "type": "text", - "placeholders": {} - }, - "makeSureTheIdentifierIsValid": "Assicurati che l'identificatore sia valido", - "@makeSureTheIdentifierIsValid": { - "type": "text", - "placeholders": {} - }, - "memberChanges": "Cambiamenti di membri", - "@memberChanges": { - "type": "text", - "placeholders": {} - }, - "mention": "Menzione", - "@mention": { - "type": "text", - "placeholders": {} - }, - "messages": "Messaggi", - "@messages": { - "type": "text", - "placeholders": {} - }, - "messageWillBeRemovedWarning": "Il messaggio verrà rimosso per tutti i partecipanti", - "@messageWillBeRemovedWarning": { - "type": "text", - "placeholders": {} - }, - "moderator": "Moderatore", - "@moderator": { - "type": "text", - "placeholders": {} - }, - "muteChat": "Silenzia discussione", - "@muteChat": { - "type": "text", - "placeholders": {} - }, - "needPantalaimonWarning": "Tieni presente che per ora hai bisogno di Pantalaimon per utilizzare la crittografia dall'inizio alla fine.", - "@needPantalaimonWarning": { - "type": "text", - "placeholders": {} - }, - "newChat": "Nuova discussione", - "@newChat": { - "type": "text", - "placeholders": {} - }, - "newMessageInFluffyChat": "Nuovo messaggio in FluffyChat", - "@newMessageInFluffyChat": { - "type": "text", - "placeholders": {} - }, - "newVerificationRequest": "Nuova richiesta di verifica!", - "@newVerificationRequest": { - "type": "text", - "placeholders": {} - }, - "next": "Avanti", - "@next": { - "type": "text", - "placeholders": {} - }, - "no": "No", - "@no": { - "type": "text", - "placeholders": {} - }, - "noConnectionToTheServer": "Nessuna connessione al server", - "@noConnectionToTheServer": { - "type": "text", - "placeholders": {} - }, - "noEmotesFound": "Nessun emote trovato. 😕", - "@noEmotesFound": { - "type": "text", - "placeholders": {} - }, - "noEncryptionForPublicRooms": "Puoi attivare la crittografia solo quando la stanza non è più accessibile pubblicamente.", - "@noEncryptionForPublicRooms": { - "type": "text", - "placeholders": {} - }, - "noGoogleServicesWarning": "Sembra che tu non abbia servizi Google sul tuo telefono. Questa è una buona decisione per la tua riservatezza! Per ricevere notifiche push in FluffyChat consigliamo di utilizzare https://microg.org/ o https://unifiedpush.org/.", - "@noGoogleServicesWarning": { - "type": "text", - "placeholders": {} - }, - "none": "Nessuno", - "@none": { - "type": "text", - "placeholders": {} - }, - "noPasswordRecoveryDescription": "Non hai ancora aggiunto un modo per recuperare la tua password.", - "@noPasswordRecoveryDescription": { - "type": "text", - "placeholders": {} - }, - "noPermission": "Nessuna autorizzazione", - "@noPermission": { - "type": "text", - "placeholders": {} - }, - "noRoomsFound": "Nessuna stanza trovata…", - "@noRoomsFound": { - "type": "text", - "placeholders": {} - }, - "notifications": "Notifiche", - "@notifications": { - "type": "text", - "placeholders": {} - }, - "notificationsEnabledForThisAccount": "Notifiche abilitate per questo account", - "@notificationsEnabledForThisAccount": { - "type": "text", - "placeholders": {} - }, - "numUsersTyping": "{count} utenti stanno scrivendo…", - "@numUsersTyping": { - "type": "text", - "placeholders": { - "count": {} - } - }, - "offensive": "Offensivo", - "@offensive": { - "type": "text", - "placeholders": {} - }, - "offline": "Fuori linea", - "@offline": { - "type": "text", - "placeholders": {} - }, - "ok": "OK", - "@ok": { - "type": "text", - "placeholders": {} - }, - "online": "In linea", - "@online": { - "type": "text", - "placeholders": {} - }, - "onlineKeyBackupEnabled": "Il backup delle chiavi in linea è abilitato", - "@onlineKeyBackupEnabled": { - "type": "text", - "placeholders": {} - }, - "oopsSomethingWentWrong": "Ops, qualcosa è andato storto…", - "@oopsSomethingWentWrong": { - "type": "text", - "placeholders": {} - }, - "openAppToReadMessages": "Apri l'app per leggere i messaggi", - "@openAppToReadMessages": { - "type": "text", - "placeholders": {} - }, - "openCamera": "Apri fotocamera", - "@openCamera": { - "type": "text", - "placeholders": {} - }, - "optionalGroupName": "(Opzionale) Nome del gruppo", - "@optionalGroupName": { - "type": "text", - "placeholders": {} - }, - "participant": "Partecipante", - "@participant": { - "type": "text", - "placeholders": {} - }, - "passphraseOrKey": "frase segreta o chiave di recupero", - "@passphraseOrKey": { - "type": "text", - "placeholders": {} - }, - "password": "Password", - "@password": { - "type": "text", - "placeholders": {} - }, - "passwordForgotten": "Password dimenticata", - "@passwordForgotten": { - "type": "text", - "placeholders": {} - }, - "passwordHasBeenChanged": "La password è stata cambiata", - "@passwordHasBeenChanged": { - "type": "text", - "placeholders": {} - }, - "passwordRecovery": "Recupero della password", - "@passwordRecovery": { - "type": "text", - "placeholders": {} - }, - "people": "Persone", - "@people": { - "type": "text", - "placeholders": {} - }, - "pickImage": "Scegli un'immagine", - "@pickImage": { - "type": "text", - "placeholders": {} - }, - "pin": "Fissa", - "@pin": { - "type": "text", - "placeholders": {} - }, - "play": "Riproduci {fileName}", - "@play": { - "type": "text", - "placeholders": { - "fileName": {} - } - }, - "pleaseChooseAPasscode": "Si prega di scegliere un codice di accesso", - "@pleaseChooseAPasscode": { - "type": "text", - "placeholders": {} - }, - "pleaseChooseAUsername": "Si prega di scegliere un nome utente", - "@pleaseChooseAUsername": { - "type": "text", - "placeholders": {} - }, - "pleaseClickOnLink": "Clicca sul collegamenti nell'e-mail e poi procedi.", - "@pleaseClickOnLink": { - "type": "text", - "placeholders": {} - }, - "pleaseEnter4Digits": "Inserisci 4 cifre o lascia vuoto per disabilitare il blocco dell'app.", - "@pleaseEnter4Digits": { - "type": "text", - "placeholders": {} - }, - "pleaseEnterAMatrixIdentifier": "Inserisci un identificatore Matrix.", - "@pleaseEnterAMatrixIdentifier": { - "type": "text", - "placeholders": {} - }, - "pleaseEnterYourPassword": "Inserisci la tua password", - "@pleaseEnterYourPassword": { - "type": "text", - "placeholders": {} - }, - "pleaseEnterYourUsername": "Inserisci il tuo nome utente", - "@pleaseEnterYourUsername": { - "type": "text", - "placeholders": {} - }, - "pleaseFollowInstructionsOnWeb": "Segui le istruzioni sul sito web e tocca Avanti.", - "@pleaseFollowInstructionsOnWeb": { - "type": "text", - "placeholders": {} - }, - "privacy": "Privacy", - "@privacy": { - "type": "text", - "placeholders": {} - }, - "publicRooms": "Stanze pubbliche", - "@publicRooms": { - "type": "text", - "placeholders": {} - }, - "pushRules": "Regole notifiche", - "@pushRules": { - "type": "text", - "placeholders": {} - }, - "reason": "Motivo", - "@reason": { - "type": "text", - "placeholders": {} - }, - "recording": "Registrazione", - "@recording": { - "type": "text", - "placeholders": {} - }, - "redactedAnEvent": "{username} ha eliminato un evento", - "@redactedAnEvent": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "redactMessage": "Elimina un messaggio", - "@redactMessage": { - "type": "text", - "placeholders": {} - }, - "reject": "Rifiuta", - "@reject": { - "type": "text", - "placeholders": {} - }, - "rejectedTheInvitation": "{username} ha rifiutato l'invito", - "@rejectedTheInvitation": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "rejoin": "Riunisciti", - "@rejoin": { - "type": "text", - "placeholders": {} - }, - "remove": "Rimuovi", - "@remove": { - "type": "text", - "placeholders": {} - }, - "removeAllOtherDevices": "Rimuovi tutti gli altri dispositivi", - "@removeAllOtherDevices": { - "type": "text", - "placeholders": {} - }, - "removedBy": "Rimosso da {username}", - "@removedBy": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "removeDevice": "Rimuovi il dispositivo", - "@removeDevice": { - "type": "text", - "placeholders": {} - }, - "unbanFromChat": "Rimuovi il ban dalla chat", - "@unbanFromChat": { - "type": "text", - "placeholders": {} - }, - "renderRichContent": "Mostra i contenuti ricchi dei messaggi", - "@renderRichContent": { - "type": "text", - "placeholders": {} - }, - "replaceRoomWithNewerVersion": "Sostituisci la stanza con la versione più recente", - "@replaceRoomWithNewerVersion": { - "type": "text", - "placeholders": {} - }, - "reply": "Rispondi", - "@reply": { - "type": "text", - "placeholders": {} - }, - "reportMessage": "Segnala il messaggio", - "@reportMessage": { - "type": "text", - "placeholders": {} - }, - "requestPermission": "Richiedi l'autorizzazione", - "@requestPermission": { - "type": "text", - "placeholders": {} - }, - "roomHasBeenUpgraded": "La stanza è stata aggiornata", - "@roomHasBeenUpgraded": { - "type": "text", - "placeholders": {} - }, - "roomVersion": "Versione della stanza", - "@roomVersion": { - "type": "text", - "placeholders": {} - }, - "search": "Cerca", - "@search": { - "type": "text", - "placeholders": {} - }, - "security": "Sicurezza", - "@security": { - "type": "text", - "placeholders": {} - }, - "seenByUser": "Visto da {username}", - "@seenByUser": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "seenByUserAndCountOthers": "{count, plural, other{Visto da {username} e {count} altri}}", - "@seenByUserAndCountOthers": { - "type": "text", - "placeholders": { - "username": {}, - "count": {} - } - }, - "seenByUserAndUser": "Visto da {username} e {username2}", - "@seenByUserAndUser": { - "type": "text", - "placeholders": { - "username": {}, - "username2": {} - } - }, - "send": "Invia", - "@send": { - "type": "text", - "placeholders": {} - }, - "sendAMessage": "Invia un messaggio", - "@sendAMessage": { - "type": "text", - "placeholders": {} - }, - "sendAudio": "Invia un file audio", - "@sendAudio": { - "type": "text", - "placeholders": {} - }, - "sendFile": "Invia un file", - "@sendFile": { - "type": "text", - "placeholders": {} - }, - "sendImage": "Invia un'immagine", - "@sendImage": { - "type": "text", - "placeholders": {} - }, - "sendMessages": "Invia messaggi", - "@sendMessages": { - "type": "text", - "placeholders": {} - }, - "sendOriginal": "Invia l'originale", - "@sendOriginal": { - "type": "text", - "placeholders": {} - }, - "sendVideo": "Invia un video", - "@sendVideo": { - "type": "text", - "placeholders": {} - }, - "sentAFile": "{username} ha inviato un file", - "@sentAFile": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sentAnAudio": "{username} ha inviato un file audio", - "@sentAnAudio": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sentAPicture": "{username} ha inviato un'immagine", - "@sentAPicture": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sentASticker": "{username} ha inviato un adesivo", - "@sentASticker": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sentAVideo": "{username} ha inviato un video", - "@sentAVideo": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sentCallInformations": "{senderName} ha inviato informazioni sulla chiamata", - "@sentCallInformations": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "setCustomEmotes": "Imposta emoticon personalizzate", - "@setCustomEmotes": { - "type": "text", - "placeholders": {} - }, - "setGroupDescription": "Imposta una descrizione del gruppo", - "@setGroupDescription": { - "type": "text", - "placeholders": {} - }, - "setInvitationLink": "Imposta il collegamento di invito", - "@setInvitationLink": { - "type": "text", - "placeholders": {} - }, - "setPermissionsLevel": "Imposta il livello di autorizzazione", - "@setPermissionsLevel": { - "type": "text", - "placeholders": {} - }, - "setStatus": "Imposta lo stato", - "@setStatus": { - "type": "text", - "placeholders": {} - }, - "settings": "Impostazioni", - "@settings": { - "type": "text", - "placeholders": {} - }, - "share": "Condividi", - "@share": { - "type": "text", - "placeholders": {} - }, - "sharedTheLocation": "{username} ha condiviso la sua posizione", - "@sharedTheLocation": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "showPassword": "Mostra la password", - "@showPassword": { - "type": "text", - "placeholders": {} - }, - "signUp": "Iscriviti", - "@signUp": { - "type": "text", - "placeholders": {} - }, - "skip": "Ignora", - "@skip": { - "type": "text", - "placeholders": {} - }, - "sourceCode": "Codice sorgente", - "@sourceCode": { - "type": "text", - "placeholders": {} - }, - "startedACall": "{senderName} ha iniziato una chiamata", - "@startedACall": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "status": "Stato", - "@status": { - "type": "text", - "placeholders": {} - }, - "statusExampleMessage": "Come stai oggi?", - "@statusExampleMessage": { - "type": "text", - "placeholders": {} - }, - "submit": "Invia", - "@submit": { - "type": "text", - "placeholders": {} - }, - "systemTheme": "Sistema", - "@systemTheme": { - "type": "text", - "placeholders": {} - }, - "theyDontMatch": "Non corrispondono", - "@theyDontMatch": { - "type": "text", - "placeholders": {} - }, - "theyMatch": "Corrispondono", - "@theyMatch": { - "type": "text", - "placeholders": {} - }, - "title": "FluffyChat", - "@title": { - "description": "Title for the application", - "type": "text", - "placeholders": {} - }, - "toggleFavorite": "Attiva/disattiva preferito", - "@toggleFavorite": { - "type": "text", - "placeholders": {} - }, - "toggleMuted": "Attiva/disattiva il silenziatore", - "@toggleMuted": { - "type": "text", - "placeholders": {} - }, - "toggleUnread": "Segna come letto / non letto", - "@toggleUnread": { - "type": "text", - "placeholders": {} - }, - "tooManyRequestsWarning": "Troppe richieste. Per favore riprova più tardi!", - "@tooManyRequestsWarning": { - "type": "text", - "placeholders": {} - }, - "transferFromAnotherDevice": "Trasferimento da un altro dispositivo", - "@transferFromAnotherDevice": { - "type": "text", - "placeholders": {} - }, - "tryToSendAgain": "Prova a inviare di nuovo", - "@tryToSendAgain": { - "type": "text", - "placeholders": {} - }, - "unavailable": "Non disponibile", - "@unavailable": { - "type": "text", - "placeholders": {} - }, - "unbannedUser": "{username} ha rimosso il bando di {targetName}", - "@unbannedUser": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "unblockDevice": "Sblocca il dispositivo", - "@unblockDevice": { - "type": "text", - "placeholders": {} - }, - "unknownDevice": "Dispositivo sconosciuto", - "@unknownDevice": { - "type": "text", - "placeholders": {} - }, - "unknownEncryptionAlgorithm": "Algoritmo di crittografia sconosciuto", - "@unknownEncryptionAlgorithm": { - "type": "text", - "placeholders": {} - }, - "unknownEvent": "Evento sconosciuto «{tipo}»", - "@unknownEvent": { - "type": "text", - "placeholders": { - "type": {} - } - }, - "unmuteChat": "Riattiva l'audio della discussione", - "@unmuteChat": { - "type": "text", - "placeholders": {} - }, - "unpin": "Rimuovi", - "@unpin": { - "type": "text", - "placeholders": {} - }, - "unreadChats": "{unreadCount, plural, other{{unreadCount} discussioni non lette}}", - "@unreadChats": { - "type": "text", - "placeholders": { - "unreadCount": {} - } - }, - "userAndOthersAreTyping": "{username} e {count} altri stanno scrivendo…", - "@userAndOthersAreTyping": { - "type": "text", - "placeholders": { - "username": {}, - "count": {} - } - }, - "userAndUserAreTyping": "{username} e {username2} stanno scrivendo…", - "@userAndUserAreTyping": { - "type": "text", - "placeholders": { - "username": {}, - "username2": {} - } - }, - "userIsTyping": "{username} sta scrivendo…", - "@userIsTyping": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "userLeftTheChat": "{username} ha lasciato la chat", - "@userLeftTheChat": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "username": "Nome utente", - "@username": { - "type": "text", - "placeholders": {} - }, - "userSentUnknownEvent": "{username} ha inviato un evento {type}", - "@userSentUnknownEvent": { - "type": "text", - "placeholders": { - "username": {}, - "type": {} - } - }, - "verified": "Verificato", - "@verified": { - "type": "text", - "placeholders": {} - }, - "verify": "Verifica", - "@verify": { - "type": "text", - "placeholders": {} - }, - "verifyStart": "Avvia la verifica", - "@verifyStart": { - "type": "text", - "placeholders": {} - }, - "verifySuccess": "Hai verificato con successo!", - "@verifySuccess": { - "type": "text", - "placeholders": {} - }, - "verifyTitle": "Verifica dell'altro account", - "@verifyTitle": { - "type": "text", - "placeholders": {} - }, - "videoCall": "Videochiamata", - "@videoCall": { - "type": "text", - "placeholders": {} - }, - "visibilityOfTheChatHistory": "Visibilità della cronologia della discussione", - "@visibilityOfTheChatHistory": { - "type": "text", - "placeholders": {} - }, - "visibleForAllParticipants": "Visibile a tutti i partecipanti", - "@visibleForAllParticipants": { - "type": "text", - "placeholders": {} - }, - "visibleForEveryone": "Visibile a tutti", - "@visibleForEveryone": { - "type": "text", - "placeholders": {} - }, - "voiceMessage": "Messaggio vocale", - "@voiceMessage": { - "type": "text", - "placeholders": {} - }, - "waitingPartnerAcceptRequest": "In attesa che il partner accetti la richiesta…", - "@waitingPartnerAcceptRequest": { - "type": "text", - "placeholders": {} - }, - "waitingPartnerEmoji": "In attesa che il partner accetti l'emoji…", - "@waitingPartnerEmoji": { - "type": "text", - "placeholders": {} - }, - "waitingPartnerNumbers": "In attesa che il partner accetti i numeri…", - "@waitingPartnerNumbers": { - "type": "text", - "placeholders": {} - }, - "wallpaper": "Immagine di sfondo", - "@wallpaper": { - "type": "text", - "placeholders": {} - }, - "warning": "Attenzione!", - "@warning": { - "type": "text", - "placeholders": {} - }, - "weSentYouAnEmail": "Ti abbiamo inviato un'e-mail", - "@weSentYouAnEmail": { - "type": "text", - "placeholders": {} - }, - "whoCanPerformWhichAction": "Chi può eseguire quale azione", - "@whoCanPerformWhichAction": { - "type": "text", - "placeholders": {} - }, - "whoIsAllowedToJoinThisGroup": "Chi è autorizzato a unirsi a questo gruppo", - "@whoIsAllowedToJoinThisGroup": { - "type": "text", - "placeholders": {} - }, - "whyDoYouWantToReportThis": "Perché vuoi segnalarlo?", - "@whyDoYouWantToReportThis": { - "type": "text", - "placeholders": {} - }, - "wipeChatBackup": "Cancellare il backup della discussione per creare una nuova chiave di sicurezza?", - "@wipeChatBackup": { - "type": "text", - "placeholders": {} - }, - "withTheseAddressesRecoveryDescription": "Con questi indirizzi puoi recuperare la tua password se necessario.", - "@withTheseAddressesRecoveryDescription": { - "type": "text", - "placeholders": {} - }, - "writeAMessage": "Scrivi un messaggio…", - "@writeAMessage": { - "type": "text", - "placeholders": {} - }, - "yes": "Sì", - "@yes": { - "type": "text", - "placeholders": {} - }, - "you": "Tu", - "@you": { - "type": "text", - "placeholders": {} - }, - "youAreInvitedToThisChat": "Sei invitato/a a questa chat", - "@youAreInvitedToThisChat": { - "type": "text", - "placeholders": {} - }, - "youAreNoLongerParticipatingInThisChat": "Non stai più partecipando a questa chat", - "@youAreNoLongerParticipatingInThisChat": { - "type": "text", - "placeholders": {} - }, - "youCannotInviteYourself": "Non puoi invitare te stesso", - "@youCannotInviteYourself": { - "type": "text", - "placeholders": {} - }, - "youHaveBeenBannedFromThisChat": "Sei stato/a bandito/a da questa chat", - "@youHaveBeenBannedFromThisChat": { - "type": "text", - "placeholders": {} - }, - "yourPublicKey": "La tua chiave pubblica", - "@yourPublicKey": { - "type": "text", - "placeholders": {} - }, - "singlesignon": "Accesso singolo", - "@singlesignon": { - "type": "text", - "placeholders": {} - }, - "setAsCanonicalAlias": "Imposta come alias principale", - "@setAsCanonicalAlias": { - "type": "text", - "placeholders": {} - }, - "removeYourAvatar": "Rimuovi il tuo avatar", - "@removeYourAvatar": { - "type": "text", - "placeholders": {} - }, - "register": "Registrati", - "@register": { - "type": "text", - "placeholders": {} - }, - "pleaseEnterYourPin": "Per favore inserisci il tuo PIN", - "@pleaseEnterYourPin": { - "type": "text", - "placeholders": {} - }, - "pleaseChoose": "Si prega di scegliere", - "@pleaseChoose": { - "type": "text", - "placeholders": {} - }, - "or": "O", - "@or": { - "type": "text", - "placeholders": {} - }, - "oopsPushError": "Ops! Purtroppo si è verificato un errore durante l'impostazione delle notifiche push.", - "@oopsPushError": { - "type": "text", - "placeholders": {} - }, - "loginWith": "Accedi con {brand}", - "@loginWith": { - "type": "text", - "placeholders": { - "brand": {} - } - }, - "editRoomAliases": "Modifica gli alias della stanza", - "@editRoomAliases": { - "type": "text", - "placeholders": {} - }, - "clearArchive": "Cancella archivio", - "@clearArchive": {}, - "changeYourAvatar": "Cambia il tuo avatar", - "@changeYourAvatar": { - "type": "text", - "placeholders": {} - }, - "allChats": "Tutte le chat", - "@allChats": { - "type": "text", - "placeholders": {} - }, - "addToSpace": "Aggiungi a uno spazio", - "@addToSpace": {}, - "passwordsDoNotMatch": "Le password non corrispondono!", - "@passwordsDoNotMatch": {}, - "pleaseEnterValidEmail": "Inserire un indirizzo email valido.", - "@pleaseEnterValidEmail": {}, - "commandHint_leave": "Lascia questa stanza", - "@commandHint_leave": { - "type": "text", - "description": "Usage hint for the command /leave" - }, - "commandHint_ban": "Banna l'utente specificato da questa stanza.", - "@commandHint_ban": { - "type": "text", - "description": "Usage hint for the command /ban" - }, - "sendSticker": "Invia sticker", - "@sendSticker": { - "type": "text", - "placeholders": {} - }, - "commandHint_html": "Invia testo formattato in HTML", - "@commandHint_html": { - "type": "text", - "description": "Usage hint for the command /html" - }, - "commandHint_plain": "Invia testo non formattato", - "@commandHint_plain": { - "type": "text", - "description": "Usage hint for the command /plain" - }, - "commandHint_send": "Invia testo", - "@commandHint_send": { - "type": "text", - "description": "Usage hint for the command /send" - }, - "locationDisabledNotice": "I servizi di localizzazione sono disabilitati. Per favore abilitali per poter condividere la tua posizione.", - "@locationDisabledNotice": { - "type": "text", - "placeholders": {} - }, - "saveFile": "Salva file", - "@saveFile": { - "type": "text", - "placeholders": {} - }, - "serverRequiresEmail": "Questo server ha bisogno di validare la tua email per la registrazione.", - "@serverRequiresEmail": {}, - "openInMaps": "Apri in maps", - "@openInMaps": { - "type": "text", - "placeholders": {} - }, - "scanQrCode": "Scansiona codice QR", - "@scanQrCode": {}, - "addAccount": "Aggiungi account", - "@addAccount": {}, - "unverified": "Non verificato", - "@unverified": {}, - "pleaseChooseAtLeastChars": "Per favore scegli almeno {min} caratteri.", - "@pleaseChooseAtLeastChars": { - "type": "text", - "placeholders": { - "min": {} - } - }, - "sendAsText": "Invia come testo", - "@sendAsText": { - "type": "text" - }, - "repeatPassword": "Ripeti password", - "@repeatPassword": {}, - "autoplayImages": "Riproduci automaticamente sticker animati ed emoticon", - "@autoplayImages": { - "type": "text", - "placeholder": {} - }, - "cantOpenUri": "Can't open the URI {uri}", - "@cantOpenUri": { - "type": "text", - "placeholders": { - "uri": {} - } - }, - "commandInvalid": "Comando non valido", - "@commandInvalid": { - "type": "text" - }, - "link": "Link", - "@link": {}, - "shareLocation": "Condividi posizione", - "@shareLocation": { - "type": "text", - "placeholders": {} - }, - "yourChatBackupHasBeenSetUp": "Il tuo backup delle chat è stato configurato.", - "@yourChatBackupHasBeenSetUp": {} -} \ No newline at end of file + "@@last_modified": "2021-08-14 12:41:09.992206", + "about": "Informazioni", + "@about": { + "type": "text", + "placeholders": {} + }, + "accept": "Accetta", + "@accept": { + "type": "text", + "placeholders": {} + }, + "acceptedTheInvitation": "{username} ha accettato l'invito", + "@acceptedTheInvitation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "account": "Account", + "@account": { + "type": "text", + "placeholders": {} + }, + "activatedEndToEndEncryption": "{username} ha abilitato la crittografia end to end", + "@activatedEndToEndEncryption": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "addEmail": "Aggiungi e-mail", + "@addEmail": { + "type": "text", + "placeholders": {} + }, + "addGroupDescription": "Aggiungi una descrizione al gruppo", + "@addGroupDescription": { + "type": "text", + "placeholders": {} + }, + "admin": "Amministratore", + "@admin": { + "type": "text", + "placeholders": {} + }, + "alias": "alias", + "@alias": { + "type": "text", + "placeholders": {} + }, + "all": "Tutto", + "@all": { + "type": "text", + "placeholders": {} + }, + "answeredTheCall": "{senderName} ha risposto alla chiamata", + "@answeredTheCall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "anyoneCanJoin": "Tutti possono partecipare", + "@anyoneCanJoin": { + "type": "text", + "placeholders": {} + }, + "appLock": "Blocco dell'app", + "@appLock": { + "type": "text", + "placeholders": {} + }, + "archive": "Archivia", + "@archive": { + "type": "text", + "placeholders": {} + }, + "areGuestsAllowedToJoin": "Gli utenti ospiti possono partecipare", + "@areGuestsAllowedToJoin": { + "type": "text", + "placeholders": {} + }, + "areYouSure": "Sei sicuro/a?", + "@areYouSure": { + "type": "text", + "placeholders": {} + }, + "areYouSureYouWantToLogout": "Sei sicuro/a di voler uscire?", + "@areYouSureYouWantToLogout": { + "type": "text", + "placeholders": {} + }, + "askSSSSSign": "Per far accedere l'altra persona, per favore inserisci la tua frase segreta o chiave di recupero.", + "@askSSSSSign": { + "type": "text", + "placeholders": {} + }, + "askVerificationRequest": "Accettare questa richiesta di verifica da {username}?", + "@askVerificationRequest": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "badServerLoginTypesException": "L'homeserver supporta i tipi di accesso:\n{serverVersions}\nMa questa applicazione supporta solo:\n{supportedVersions}", + "@badServerLoginTypesException": { + "type": "text", + "placeholders": { + "serverVersions": {}, + "supportedVersions": {} + } + }, + "badServerVersionsException": "L'homeserver supporta le versioni Spec:\n{serverVersions}\nMa questa applicazione supporta solo {supportedVersions}", + "@badServerVersionsException": { + "type": "text", + "placeholders": { + "serverVersions": {}, + "supportedVersions": {} + } + }, + "banFromChat": "Bandisci dalla chat", + "@banFromChat": { + "type": "text", + "placeholders": {} + }, + "banned": "Bandito", + "@banned": { + "type": "text", + "placeholders": {} + }, + "bannedUser": "{username} ha bandito {targetName}", + "@bannedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "blockDevice": "Blocca dispositivo", + "@blockDevice": { + "type": "text", + "placeholders": {} + }, + "blocked": "Bloccato", + "@blocked": { + "type": "text", + "placeholders": {} + }, + "botMessages": "Messaggi bot", + "@botMessages": { + "type": "text", + "placeholders": {} + }, + "cancel": "Cancella", + "@cancel": { + "type": "text", + "placeholders": {} + }, + "changeDeviceName": "Cambia nome dispositivo", + "@changeDeviceName": { + "type": "text", + "placeholders": {} + }, + "changedTheChatAvatar": "{username} ha cambiato l'avatar della discussione", + "@changedTheChatAvatar": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheChatDescriptionTo": "{username} ha cambiato la descrizione della chat in: «{description}»", + "@changedTheChatDescriptionTo": { + "type": "text", + "placeholders": { + "username": {}, + "description": {} + } + }, + "changedTheChatNameTo": "{username} ha cambiato il nome della discussione in: «{chatname}»", + "@changedTheChatNameTo": { + "type": "text", + "placeholders": { + "username": {}, + "chatname": {} + } + }, + "changedTheChatPermissions": "{username} ha cambiato i permessi della chat", + "@changedTheChatPermissions": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheDisplaynameTo": "{username} ha cambiato nome in: {displayname}", + "@changedTheDisplaynameTo": { + "type": "text", + "placeholders": { + "username": {}, + "displayname": {} + } + }, + "changedTheGuestAccessRules": "{username} ha cambiato le regole di accesso per ospiti", + "@changedTheGuestAccessRules": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheGuestAccessRulesTo": "{username} ha cambiato le regole di accesso per ospiti con: {rules}", + "@changedTheGuestAccessRulesTo": { + "type": "text", + "placeholders": { + "username": {}, + "rules": {} + } + }, + "changedTheHistoryVisibility": "{username} ha cambiato la visibilità della cronologia", + "@changedTheHistoryVisibility": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheHistoryVisibilityTo": "{username} ha cambiato la visibilità della cronologia in: {rules}", + "@changedTheHistoryVisibilityTo": { + "type": "text", + "placeholders": { + "username": {}, + "rules": {} + } + }, + "changedTheJoinRules": "{username} ha cambiato le regole per unirsi", + "@changedTheJoinRules": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheJoinRulesTo": "{username} ha cambiato le regole per unirsi in: {joinRules}", + "@changedTheJoinRulesTo": { + "type": "text", + "placeholders": { + "username": {}, + "joinRules": {} + } + }, + "changedTheProfileAvatar": "{username} ha cambiato il loro avatar", + "@changedTheProfileAvatar": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheRoomAliases": "{username} ha cambiato il nome delle stanze", + "@changedTheRoomAliases": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheRoomInvitationLink": "{username} ha cambiato il link di invito", + "@changedTheRoomInvitationLink": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changePassword": "Cambia la password", + "@changePassword": { + "type": "text", + "placeholders": {} + }, + "changeTheHomeserver": "Cambia il server principale", + "@changeTheHomeserver": { + "type": "text", + "placeholders": {} + }, + "changeTheme": "Cambia il tuo stile", + "@changeTheme": { + "type": "text", + "placeholders": {} + }, + "changeTheNameOfTheGroup": "Cambia il nome del gruppo", + "@changeTheNameOfTheGroup": { + "type": "text", + "placeholders": {} + }, + "changeWallpaper": "Cambia sfondo", + "@changeWallpaper": { + "type": "text", + "placeholders": {} + }, + "channelCorruptedDecryptError": "La crittografia è corrotta", + "@channelCorruptedDecryptError": { + "type": "text", + "placeholders": {} + }, + "chat": "Chat", + "@chat": { + "type": "text", + "placeholders": {} + }, + "chatBackup": "Backup delle discussioni", + "@chatBackup": { + "type": "text", + "placeholders": {} + }, + "chatBackupDescription": "Il backup della discussione è protetto da una chiave di sicurezza. Assicurati di non perderla.", + "@chatBackupDescription": { + "type": "text", + "placeholders": {} + }, + "chatDetails": "Dettagli chat", + "@chatDetails": { + "type": "text", + "placeholders": {} + }, + "chats": "Discussioni", + "@chats": { + "type": "text", + "placeholders": {} + }, + "chooseAStrongPassword": "Scegli una password complessa", + "@chooseAStrongPassword": { + "type": "text", + "placeholders": {} + }, + "chooseAUsername": "Scegli un username", + "@chooseAUsername": { + "type": "text", + "placeholders": {} + }, + "close": "Chiudi", + "@close": { + "type": "text", + "placeholders": {} + }, + "compareEmojiMatch": "Confronta e assicurati che le seguenti emoji corrispondano a quelle dell'altro dispositivo:", + "@compareEmojiMatch": { + "type": "text", + "placeholders": {} + }, + "compareNumbersMatch": "Confronta e assicurati che le seguenti emoji corrispondano a quelle dell'altro dispositivo:", + "@compareNumbersMatch": { + "type": "text", + "placeholders": {} + }, + "configureChat": "Configura la discussione", + "@configureChat": { + "type": "text", + "placeholders": {} + }, + "confirm": "Conferma", + "@confirm": { + "type": "text", + "placeholders": {} + }, + "connect": "Connetti", + "@connect": { + "type": "text", + "placeholders": {} + }, + "contactHasBeenInvitedToTheGroup": "Il contatto è stato invitato nel gruppo", + "@contactHasBeenInvitedToTheGroup": { + "type": "text", + "placeholders": {} + }, + "containsDisplayName": "Contiene nome visibile", + "@containsDisplayName": { + "type": "text", + "placeholders": {} + }, + "containsUserName": "Contiene nome utente", + "@containsUserName": { + "type": "text", + "placeholders": {} + }, + "contentHasBeenReported": "Il contenuto è stato segnalato agli amministratori del server", + "@contentHasBeenReported": { + "type": "text", + "placeholders": {} + }, + "copiedToClipboard": "Copiato negli Appunti", + "@copiedToClipboard": { + "type": "text", + "placeholders": {} + }, + "copy": "Copia", + "@copy": { + "type": "text", + "placeholders": {} + }, + "copyToClipboard": "Copia negli appunti", + "@copyToClipboard": { + "type": "text", + "placeholders": {} + }, + "couldNotDecryptMessage": "Impossibile decriptare messaggio: {error}", + "@couldNotDecryptMessage": { + "type": "text", + "placeholders": { + "error": {} + } + }, + "countParticipants": "{count} partecipanti", + "@countParticipants": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "create": "Crea", + "@create": { + "type": "text", + "placeholders": {} + }, + "createdTheChat": "{username} ha creato la chat", + "@createdTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "createNewGroup": "Crea un nuovo gruppo", + "@createNewGroup": { + "type": "text", + "placeholders": {} + }, + "currentlyActive": "Attualmente attivo", + "@currentlyActive": { + "type": "text", + "placeholders": {} + }, + "darkTheme": "Scuro", + "@darkTheme": { + "type": "text", + "placeholders": {} + }, + "dateAndTimeOfDay": "{date}, {timeOfDay}", + "@dateAndTimeOfDay": { + "type": "text", + "placeholders": { + "date": {}, + "timeOfDay": {} + } + }, + "dateWithoutYear": "{day}/{month}", + "@dateWithoutYear": { + "type": "text", + "placeholders": { + "month": {}, + "day": {} + } + }, + "dateWithYear": "{day}/{month}/{year}", + "@dateWithYear": { + "type": "text", + "placeholders": { + "year": {}, + "month": {}, + "day": {} + } + }, + "deactivateAccountWarning": "Disabiliterà il tuo account. Non puoi tornare indietro! Sei sicuro/a?", + "@deactivateAccountWarning": { + "type": "text", + "placeholders": {} + }, + "defaultPermissionLevel": "Livello di autorizzazione predefinito", + "@defaultPermissionLevel": { + "type": "text", + "placeholders": {} + }, + "delete": "Cancella", + "@delete": { + "type": "text", + "placeholders": {} + }, + "deleteAccount": "Elimina l'account", + "@deleteAccount": { + "type": "text", + "placeholders": {} + }, + "deleteMessage": "Elimina il messaggio", + "@deleteMessage": { + "type": "text", + "placeholders": {} + }, + "deny": "Declina", + "@deny": { + "type": "text", + "placeholders": {} + }, + "device": "Dispositivo", + "@device": { + "type": "text", + "placeholders": {} + }, + "deviceId": "ID del dispositivo", + "@deviceId": { + "type": "text", + "placeholders": {} + }, + "devices": "Dispositivi", + "@devices": { + "type": "text", + "placeholders": {} + }, + "directChats": "Discussioni dirette", + "@directChats": { + "type": "text", + "placeholders": {} + }, + "displaynameHasBeenChanged": "Il nominativo è stato cambiato", + "@displaynameHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "downloadFile": "Scarica il file", + "@downloadFile": { + "type": "text", + "placeholders": {} + }, + "edit": "Modifica", + "@edit": { + "type": "text", + "placeholders": {} + }, + "editBlockedServers": "Modifica i server bloccati", + "@editBlockedServers": { + "type": "text", + "placeholders": {} + }, + "editChatPermissions": "Modifica le autorizzazioni discussione", + "@editChatPermissions": { + "type": "text", + "placeholders": {} + }, + "editDisplayname": "Modifica il nominativo", + "@editDisplayname": { + "type": "text", + "placeholders": {} + }, + "editRoomAvatar": "Modifica l'avatar della stanza", + "@editRoomAvatar": { + "type": "text", + "placeholders": {} + }, + "emoteExists": "L'emote già esiste!", + "@emoteExists": { + "type": "text", + "placeholders": {} + }, + "emoteInvalid": "Shortcode emote invalido!", + "@emoteInvalid": { + "type": "text", + "placeholders": {} + }, + "emotePacks": "Pacchetti emotes della stanza", + "@emotePacks": { + "type": "text", + "placeholders": {} + }, + "emoteSettings": "Impostazioni emote", + "@emoteSettings": { + "type": "text", + "placeholders": {} + }, + "emoteShortcode": "Scorciatoia emote", + "@emoteShortcode": { + "type": "text", + "placeholders": {} + }, + "emoteWarnNeedToPick": "Devi scegliere una scorciatoia emote e aggiungere un immagine!", + "@emoteWarnNeedToPick": { + "type": "text", + "placeholders": {} + }, + "emptyChat": "Discussione vuota", + "@emptyChat": { + "type": "text", + "placeholders": {} + }, + "enableEmotesGlobally": "Abilita i pacchetti emotes globalmente", + "@enableEmotesGlobally": { + "type": "text", + "placeholders": {} + }, + "enableEncryption": "Abilita la crittografia", + "@enableEncryption": { + "type": "text", + "placeholders": {} + }, + "enableEncryptionWarning": "Non potrai disabilitare la crittografia in futuro. Sei sicuro?", + "@enableEncryptionWarning": { + "type": "text", + "placeholders": {} + }, + "encrypted": "Crittografato", + "@encrypted": { + "type": "text", + "placeholders": {} + }, + "encryption": "Crittografia", + "@encryption": { + "type": "text", + "placeholders": {} + }, + "encryptionNotEnabled": "Crittografia non abilitata", + "@encryptionNotEnabled": { + "type": "text", + "placeholders": {} + }, + "endedTheCall": "{senderName} è entrato in chiamata", + "@endedTheCall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "enterAGroupName": "Inserisci un nome del gruppo", + "@enterAGroupName": { + "type": "text", + "placeholders": {} + }, + "enterAnEmailAddress": "Inserisci un indirizzo e-mail", + "@enterAnEmailAddress": { + "type": "text", + "placeholders": {} + }, + "enterYourHomeserver": "Inserisci il tuo server principale", + "@enterYourHomeserver": { + "type": "text", + "placeholders": {} + }, + "everythingReady": "Tutto pronto!", + "@everythingReady": { + "type": "text", + "placeholders": {} + }, + "extremeOffensive": "Estremamente offensivo", + "@extremeOffensive": { + "type": "text", + "placeholders": {} + }, + "fileName": "Nome del file", + "@fileName": { + "type": "text", + "placeholders": {} + }, + "fluffychat": "FluffyChat", + "@fluffychat": { + "type": "text", + "placeholders": {} + }, + "fontSize": "Dimensione carattere", + "@fontSize": { + "type": "text", + "placeholders": {} + }, + "forward": "Inoltra", + "@forward": { + "type": "text", + "placeholders": {} + }, + "fromJoining": "Dall'adesione", + "@fromJoining": { + "type": "text", + "placeholders": {} + }, + "fromTheInvitation": "Dall'invito", + "@fromTheInvitation": { + "type": "text", + "placeholders": {} + }, + "goToTheNewRoom": "Vai nella nuova stanza", + "@goToTheNewRoom": { + "type": "text", + "placeholders": {} + }, + "group": "Gruppo", + "@group": { + "type": "text", + "placeholders": {} + }, + "groupDescription": "Descrizione del gruppo", + "@groupDescription": { + "type": "text", + "placeholders": {} + }, + "groupDescriptionHasBeenChanged": "Descrizione del gruppo modificata", + "@groupDescriptionHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "groupIsPublic": "Il gruppo è pubblico", + "@groupIsPublic": { + "type": "text", + "placeholders": {} + }, + "groups": "Gruppi", + "@groups": { + "type": "text", + "placeholders": {} + }, + "groupWith": "Gruppo con {displayname}", + "@groupWith": { + "type": "text", + "placeholders": { + "displayname": {} + } + }, + "guestsAreForbidden": "Gli ospiti sono vietati", + "@guestsAreForbidden": { + "type": "text", + "placeholders": {} + }, + "guestsCanJoin": "Gli ospiti possono partecipare", + "@guestsCanJoin": { + "type": "text", + "placeholders": {} + }, + "hasWithdrawnTheInvitationFor": "{username} ha ritirato l'invito per {targetName}", + "@hasWithdrawnTheInvitationFor": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "help": "Aiuto", + "@help": { + "type": "text", + "placeholders": {} + }, + "hideRedactedEvents": "Nascondi gli eventi eliminati", + "@hideRedactedEvents": { + "type": "text", + "placeholders": {} + }, + "hideUnknownEvents": "Nascondi gli eventi sconosciuti", + "@hideUnknownEvents": { + "type": "text", + "placeholders": {} + }, + "howOffensiveIsThisContent": "Quanto è offensivo questo contenuto?", + "@howOffensiveIsThisContent": { + "type": "text", + "placeholders": {} + }, + "id": "ID", + "@id": { + "type": "text", + "placeholders": {} + }, + "identity": "Identità", + "@identity": { + "type": "text", + "placeholders": {} + }, + "ignore": "Ignora", + "@ignore": { + "type": "text", + "placeholders": {} + }, + "ignoredUsers": "Utenti ignorati", + "@ignoredUsers": { + "type": "text", + "placeholders": {} + }, + "ignoreListDescription": "Puoi ignorare gli utenti che ti stanno disturbando. Non sarai in grado di ricevere messaggi o inviti a stanze virtuali dagli utenti nel tuo elenco personale da ignorare.", + "@ignoreListDescription": { + "type": "text", + "placeholders": {} + }, + "ignoreUsername": "Ignora il nome utente", + "@ignoreUsername": { + "type": "text", + "placeholders": {} + }, + "iHaveClickedOnLink": "Ho cliccato sul collegamento", + "@iHaveClickedOnLink": { + "type": "text", + "placeholders": {} + }, + "incorrectPassphraseOrKey": "Frase segrata o chiave di ripristino errate", + "@incorrectPassphraseOrKey": { + "type": "text", + "placeholders": {} + }, + "inoffensive": "Inoffensivo", + "@inoffensive": { + "type": "text", + "placeholders": {} + }, + "inviteContact": "Invita contatto", + "@inviteContact": { + "type": "text", + "placeholders": {} + }, + "inviteContactToGroup": "Invita un contatto a {groupName}", + "@inviteContactToGroup": { + "type": "text", + "placeholders": { + "groupName": {} + } + }, + "invited": "Invitato/a", + "@invited": { + "type": "text", + "placeholders": {} + }, + "invitedUser": "{username} ha invitato {targetName}", + "@invitedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "invitedUsersOnly": "Solo per gli utenti invitati", + "@invitedUsersOnly": { + "type": "text", + "placeholders": {} + }, + "inviteForMe": "Invita per me", + "@inviteForMe": { + "type": "text", + "placeholders": {} + }, + "inviteText": "{username} ti ha invitato/a a FluffyChat.\n1. Installa FluffyChat: https://fluffychat.im\n2. Iscriviti o accedi\n3. Apri il collegamento di invito: {link}", + "@inviteText": { + "type": "text", + "placeholders": { + "username": {}, + "link": {} + } + }, + "isTyping": "sta scrivendo…", + "@isTyping": { + "type": "text", + "placeholders": {} + }, + "joinedTheChat": "{username} si è unito/a alla chat", + "@joinedTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "joinRoom": "Unisciti alla stanza", + "@joinRoom": { + "type": "text", + "placeholders": {} + }, + "kicked": "{username} ha espulso {targetName}", + "@kicked": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "kickedAndBanned": "{username} ha espulso e bandito {targetName}", + "@kickedAndBanned": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "kickFromChat": "Espulsa dalla discussione", + "@kickFromChat": { + "type": "text", + "placeholders": {} + }, + "lastActiveAgo": "Ultima attività: {localizedTimeShort}", + "@lastActiveAgo": { + "type": "text", + "placeholders": { + "localizedTimeShort": {} + } + }, + "lastSeenLongTimeAgo": "Visto/a molto tempo fa", + "@lastSeenLongTimeAgo": { + "type": "text", + "placeholders": {} + }, + "leave": "Lascia", + "@leave": { + "type": "text", + "placeholders": {} + }, + "leftTheChat": "Ha lasciato la chat", + "@leftTheChat": { + "type": "text", + "placeholders": {} + }, + "license": "Licenza", + "@license": { + "type": "text", + "placeholders": {} + }, + "lightTheme": "Chiaro", + "@lightTheme": { + "type": "text", + "placeholders": {} + }, + "loadCountMoreParticipants": "Carica altri {count} partecipanti", + "@loadCountMoreParticipants": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "loadingPleaseWait": "Caricamento… Attendere prego.", + "@loadingPleaseWait": { + "type": "text", + "placeholders": {} + }, + "loadMore": "Carica di più…", + "@loadMore": { + "type": "text", + "placeholders": {} + }, + "login": "Accedi", + "@login": { + "type": "text", + "placeholders": {} + }, + "logInTo": "Accedi a {homeserver}", + "@logInTo": { + "type": "text", + "placeholders": { + "homeserver": {} + } + }, + "logout": "Esci", + "@logout": { + "type": "text", + "placeholders": {} + }, + "makeSureTheIdentifierIsValid": "Assicurati che l'identificatore sia valido", + "@makeSureTheIdentifierIsValid": { + "type": "text", + "placeholders": {} + }, + "memberChanges": "Cambiamenti di membri", + "@memberChanges": { + "type": "text", + "placeholders": {} + }, + "mention": "Menzione", + "@mention": { + "type": "text", + "placeholders": {} + }, + "messages": "Messaggi", + "@messages": { + "type": "text", + "placeholders": {} + }, + "messageWillBeRemovedWarning": "Il messaggio verrà rimosso per tutti i partecipanti", + "@messageWillBeRemovedWarning": { + "type": "text", + "placeholders": {} + }, + "moderator": "Moderatore", + "@moderator": { + "type": "text", + "placeholders": {} + }, + "muteChat": "Silenzia discussione", + "@muteChat": { + "type": "text", + "placeholders": {} + }, + "needPantalaimonWarning": "Tieni presente che per ora hai bisogno di Pantalaimon per utilizzare la crittografia dall'inizio alla fine.", + "@needPantalaimonWarning": { + "type": "text", + "placeholders": {} + }, + "newChat": "Nuova discussione", + "@newChat": { + "type": "text", + "placeholders": {} + }, + "newMessageInFluffyChat": "Nuovo messaggio in FluffyChat", + "@newMessageInFluffyChat": { + "type": "text", + "placeholders": {} + }, + "newVerificationRequest": "Nuova richiesta di verifica!", + "@newVerificationRequest": { + "type": "text", + "placeholders": {} + }, + "next": "Avanti", + "@next": { + "type": "text", + "placeholders": {} + }, + "no": "No", + "@no": { + "type": "text", + "placeholders": {} + }, + "noConnectionToTheServer": "Nessuna connessione al server", + "@noConnectionToTheServer": { + "type": "text", + "placeholders": {} + }, + "noEmotesFound": "Nessun emote trovato. 😕", + "@noEmotesFound": { + "type": "text", + "placeholders": {} + }, + "noEncryptionForPublicRooms": "Puoi attivare la crittografia solo quando la stanza non è più accessibile pubblicamente.", + "@noEncryptionForPublicRooms": { + "type": "text", + "placeholders": {} + }, + "noGoogleServicesWarning": "Sembra che tu non abbia servizi Google sul tuo telefono. Questa è una buona decisione per la tua riservatezza! Per ricevere notifiche push in FluffyChat consigliamo di utilizzare https://microg.org/ o https://unifiedpush.org/.", + "@noGoogleServicesWarning": { + "type": "text", + "placeholders": {} + }, + "none": "Nessuno", + "@none": { + "type": "text", + "placeholders": {} + }, + "noPasswordRecoveryDescription": "Non hai ancora aggiunto un modo per recuperare la tua password.", + "@noPasswordRecoveryDescription": { + "type": "text", + "placeholders": {} + }, + "noPermission": "Nessuna autorizzazione", + "@noPermission": { + "type": "text", + "placeholders": {} + }, + "noRoomsFound": "Nessuna stanza trovata…", + "@noRoomsFound": { + "type": "text", + "placeholders": {} + }, + "notifications": "Notifiche", + "@notifications": { + "type": "text", + "placeholders": {} + }, + "notificationsEnabledForThisAccount": "Notifiche abilitate per questo account", + "@notificationsEnabledForThisAccount": { + "type": "text", + "placeholders": {} + }, + "numUsersTyping": "{count} utenti stanno scrivendo…", + "@numUsersTyping": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "offensive": "Offensivo", + "@offensive": { + "type": "text", + "placeholders": {} + }, + "offline": "Fuori linea", + "@offline": { + "type": "text", + "placeholders": {} + }, + "ok": "OK", + "@ok": { + "type": "text", + "placeholders": {} + }, + "online": "In linea", + "@online": { + "type": "text", + "placeholders": {} + }, + "onlineKeyBackupEnabled": "Il backup delle chiavi in linea è abilitato", + "@onlineKeyBackupEnabled": { + "type": "text", + "placeholders": {} + }, + "oopsSomethingWentWrong": "Ops, qualcosa è andato storto…", + "@oopsSomethingWentWrong": { + "type": "text", + "placeholders": {} + }, + "openAppToReadMessages": "Apri l'app per leggere i messaggi", + "@openAppToReadMessages": { + "type": "text", + "placeholders": {} + }, + "openCamera": "Apri fotocamera", + "@openCamera": { + "type": "text", + "placeholders": {} + }, + "optionalGroupName": "(Opzionale) Nome del gruppo", + "@optionalGroupName": { + "type": "text", + "placeholders": {} + }, + "participant": "Partecipante", + "@participant": { + "type": "text", + "placeholders": {} + }, + "passphraseOrKey": "frase segreta o chiave di recupero", + "@passphraseOrKey": { + "type": "text", + "placeholders": {} + }, + "password": "Password", + "@password": { + "type": "text", + "placeholders": {} + }, + "passwordForgotten": "Password dimenticata", + "@passwordForgotten": { + "type": "text", + "placeholders": {} + }, + "passwordHasBeenChanged": "La password è stata cambiata", + "@passwordHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "passwordRecovery": "Recupero della password", + "@passwordRecovery": { + "type": "text", + "placeholders": {} + }, + "people": "Persone", + "@people": { + "type": "text", + "placeholders": {} + }, + "pickImage": "Scegli un'immagine", + "@pickImage": { + "type": "text", + "placeholders": {} + }, + "pin": "Fissa", + "@pin": { + "type": "text", + "placeholders": {} + }, + "play": "Riproduci {fileName}", + "@play": { + "type": "text", + "placeholders": { + "fileName": {} + } + }, + "pleaseChooseAPasscode": "Si prega di scegliere un codice di accesso", + "@pleaseChooseAPasscode": { + "type": "text", + "placeholders": {} + }, + "pleaseChooseAUsername": "Si prega di scegliere un nome utente", + "@pleaseChooseAUsername": { + "type": "text", + "placeholders": {} + }, + "pleaseClickOnLink": "Clicca sul collegamenti nell'e-mail e poi procedi.", + "@pleaseClickOnLink": { + "type": "text", + "placeholders": {} + }, + "pleaseEnter4Digits": "Inserisci 4 cifre o lascia vuoto per disabilitare il blocco dell'app.", + "@pleaseEnter4Digits": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterAMatrixIdentifier": "Inserisci un identificatore Matrix.", + "@pleaseEnterAMatrixIdentifier": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourPassword": "Inserisci la tua password", + "@pleaseEnterYourPassword": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourUsername": "Inserisci il tuo nome utente", + "@pleaseEnterYourUsername": { + "type": "text", + "placeholders": {} + }, + "pleaseFollowInstructionsOnWeb": "Segui le istruzioni sul sito web e tocca Avanti.", + "@pleaseFollowInstructionsOnWeb": { + "type": "text", + "placeholders": {} + }, + "privacy": "Privacy", + "@privacy": { + "type": "text", + "placeholders": {} + }, + "publicRooms": "Stanze pubbliche", + "@publicRooms": { + "type": "text", + "placeholders": {} + }, + "pushRules": "Regole notifiche", + "@pushRules": { + "type": "text", + "placeholders": {} + }, + "reason": "Motivo", + "@reason": { + "type": "text", + "placeholders": {} + }, + "recording": "Registrazione", + "@recording": { + "type": "text", + "placeholders": {} + }, + "redactedAnEvent": "{username} ha eliminato un evento", + "@redactedAnEvent": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "redactMessage": "Elimina un messaggio", + "@redactMessage": { + "type": "text", + "placeholders": {} + }, + "reject": "Rifiuta", + "@reject": { + "type": "text", + "placeholders": {} + }, + "rejectedTheInvitation": "{username} ha rifiutato l'invito", + "@rejectedTheInvitation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "rejoin": "Riunisciti", + "@rejoin": { + "type": "text", + "placeholders": {} + }, + "remove": "Rimuovi", + "@remove": { + "type": "text", + "placeholders": {} + }, + "removeAllOtherDevices": "Rimuovi tutti gli altri dispositivi", + "@removeAllOtherDevices": { + "type": "text", + "placeholders": {} + }, + "removedBy": "Rimosso da {username}", + "@removedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "removeDevice": "Rimuovi il dispositivo", + "@removeDevice": { + "type": "text", + "placeholders": {} + }, + "unbanFromChat": "Rimuovi il ban dalla chat", + "@unbanFromChat": { + "type": "text", + "placeholders": {} + }, + "renderRichContent": "Mostra i contenuti ricchi dei messaggi", + "@renderRichContent": { + "type": "text", + "placeholders": {} + }, + "replaceRoomWithNewerVersion": "Sostituisci la stanza con la versione più recente", + "@replaceRoomWithNewerVersion": { + "type": "text", + "placeholders": {} + }, + "reply": "Rispondi", + "@reply": { + "type": "text", + "placeholders": {} + }, + "reportMessage": "Segnala il messaggio", + "@reportMessage": { + "type": "text", + "placeholders": {} + }, + "requestPermission": "Richiedi l'autorizzazione", + "@requestPermission": { + "type": "text", + "placeholders": {} + }, + "roomHasBeenUpgraded": "La stanza è stata aggiornata", + "@roomHasBeenUpgraded": { + "type": "text", + "placeholders": {} + }, + "roomVersion": "Versione della stanza", + "@roomVersion": { + "type": "text", + "placeholders": {} + }, + "search": "Cerca", + "@search": { + "type": "text", + "placeholders": {} + }, + "security": "Sicurezza", + "@security": { + "type": "text", + "placeholders": {} + }, + "seenByUser": "Visto da {username}", + "@seenByUser": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "seenByUserAndCountOthers": "{count, plural, other{Visto da {username} e {count} altri}}", + "@seenByUserAndCountOthers": { + "type": "text", + "placeholders": { + "username": {}, + "count": {} + } + }, + "seenByUserAndUser": "Visto da {username} e {username2}", + "@seenByUserAndUser": { + "type": "text", + "placeholders": { + "username": {}, + "username2": {} + } + }, + "send": "Invia", + "@send": { + "type": "text", + "placeholders": {} + }, + "sendAMessage": "Invia un messaggio", + "@sendAMessage": { + "type": "text", + "placeholders": {} + }, + "sendAudio": "Invia un file audio", + "@sendAudio": { + "type": "text", + "placeholders": {} + }, + "sendFile": "Invia un file", + "@sendFile": { + "type": "text", + "placeholders": {} + }, + "sendImage": "Invia un'immagine", + "@sendImage": { + "type": "text", + "placeholders": {} + }, + "sendMessages": "Invia messaggi", + "@sendMessages": { + "type": "text", + "placeholders": {} + }, + "sendOriginal": "Invia l'originale", + "@sendOriginal": { + "type": "text", + "placeholders": {} + }, + "sendVideo": "Invia un video", + "@sendVideo": { + "type": "text", + "placeholders": {} + }, + "sentAFile": "{username} ha inviato un file", + "@sentAFile": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sentAnAudio": "{username} ha inviato un file audio", + "@sentAnAudio": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sentAPicture": "{username} ha inviato un'immagine", + "@sentAPicture": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sentASticker": "{username} ha inviato un adesivo", + "@sentASticker": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sentAVideo": "{username} ha inviato un video", + "@sentAVideo": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sentCallInformations": "{senderName} ha inviato informazioni sulla chiamata", + "@sentCallInformations": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "setCustomEmotes": "Imposta emoticon personalizzate", + "@setCustomEmotes": { + "type": "text", + "placeholders": {} + }, + "setGroupDescription": "Imposta una descrizione del gruppo", + "@setGroupDescription": { + "type": "text", + "placeholders": {} + }, + "setInvitationLink": "Imposta il collegamento di invito", + "@setInvitationLink": { + "type": "text", + "placeholders": {} + }, + "setPermissionsLevel": "Imposta il livello di autorizzazione", + "@setPermissionsLevel": { + "type": "text", + "placeholders": {} + }, + "setStatus": "Imposta lo stato", + "@setStatus": { + "type": "text", + "placeholders": {} + }, + "settings": "Impostazioni", + "@settings": { + "type": "text", + "placeholders": {} + }, + "share": "Condividi", + "@share": { + "type": "text", + "placeholders": {} + }, + "sharedTheLocation": "{username} ha condiviso la sua posizione", + "@sharedTheLocation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "showPassword": "Mostra la password", + "@showPassword": { + "type": "text", + "placeholders": {} + }, + "signUp": "Iscriviti", + "@signUp": { + "type": "text", + "placeholders": {} + }, + "skip": "Ignora", + "@skip": { + "type": "text", + "placeholders": {} + }, + "sourceCode": "Codice sorgente", + "@sourceCode": { + "type": "text", + "placeholders": {} + }, + "startedACall": "{senderName} ha iniziato una chiamata", + "@startedACall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "status": "Stato", + "@status": { + "type": "text", + "placeholders": {} + }, + "statusExampleMessage": "Come stai oggi?", + "@statusExampleMessage": { + "type": "text", + "placeholders": {} + }, + "submit": "Invia", + "@submit": { + "type": "text", + "placeholders": {} + }, + "systemTheme": "Sistema", + "@systemTheme": { + "type": "text", + "placeholders": {} + }, + "theyDontMatch": "Non corrispondono", + "@theyDontMatch": { + "type": "text", + "placeholders": {} + }, + "theyMatch": "Corrispondono", + "@theyMatch": { + "type": "text", + "placeholders": {} + }, + "title": "FluffyChat", + "@title": { + "description": "Title for the application", + "type": "text", + "placeholders": {} + }, + "toggleFavorite": "Attiva/disattiva preferito", + "@toggleFavorite": { + "type": "text", + "placeholders": {} + }, + "toggleMuted": "Attiva/disattiva il silenziatore", + "@toggleMuted": { + "type": "text", + "placeholders": {} + }, + "toggleUnread": "Segna come letto / non letto", + "@toggleUnread": { + "type": "text", + "placeholders": {} + }, + "tooManyRequestsWarning": "Troppe richieste. Per favore riprova più tardi!", + "@tooManyRequestsWarning": { + "type": "text", + "placeholders": {} + }, + "transferFromAnotherDevice": "Trasferimento da un altro dispositivo", + "@transferFromAnotherDevice": { + "type": "text", + "placeholders": {} + }, + "tryToSendAgain": "Prova a inviare di nuovo", + "@tryToSendAgain": { + "type": "text", + "placeholders": {} + }, + "unavailable": "Non disponibile", + "@unavailable": { + "type": "text", + "placeholders": {} + }, + "unbannedUser": "{username} ha rimosso il bando di {targetName}", + "@unbannedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "unblockDevice": "Sblocca il dispositivo", + "@unblockDevice": { + "type": "text", + "placeholders": {} + }, + "unknownDevice": "Dispositivo sconosciuto", + "@unknownDevice": { + "type": "text", + "placeholders": {} + }, + "unknownEncryptionAlgorithm": "Algoritmo di crittografia sconosciuto", + "@unknownEncryptionAlgorithm": { + "type": "text", + "placeholders": {} + }, + "unknownEvent": "Evento sconosciuto «{tipo}»", + "@unknownEvent": { + "type": "text", + "placeholders": { + "type": {} + } + }, + "unmuteChat": "Riattiva l'audio della discussione", + "@unmuteChat": { + "type": "text", + "placeholders": {} + }, + "unpin": "Rimuovi", + "@unpin": { + "type": "text", + "placeholders": {} + }, + "unreadChats": "{unreadCount, plural, other{{unreadCount} discussioni non lette}}", + "@unreadChats": { + "type": "text", + "placeholders": { + "unreadCount": {} + } + }, + "userAndOthersAreTyping": "{username} e {count} altri stanno scrivendo…", + "@userAndOthersAreTyping": { + "type": "text", + "placeholders": { + "username": {}, + "count": {} + } + }, + "userAndUserAreTyping": "{username} e {username2} stanno scrivendo…", + "@userAndUserAreTyping": { + "type": "text", + "placeholders": { + "username": {}, + "username2": {} + } + }, + "userIsTyping": "{username} sta scrivendo…", + "@userIsTyping": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "userLeftTheChat": "{username} ha lasciato la chat", + "@userLeftTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "username": "Nome utente", + "@username": { + "type": "text", + "placeholders": {} + }, + "userSentUnknownEvent": "{username} ha inviato un evento {type}", + "@userSentUnknownEvent": { + "type": "text", + "placeholders": { + "username": {}, + "type": {} + } + }, + "verified": "Verificato", + "@verified": { + "type": "text", + "placeholders": {} + }, + "verify": "Verifica", + "@verify": { + "type": "text", + "placeholders": {} + }, + "verifyStart": "Avvia la verifica", + "@verifyStart": { + "type": "text", + "placeholders": {} + }, + "verifySuccess": "Hai verificato con successo!", + "@verifySuccess": { + "type": "text", + "placeholders": {} + }, + "verifyTitle": "Verifica dell'altro account", + "@verifyTitle": { + "type": "text", + "placeholders": {} + }, + "videoCall": "Videochiamata", + "@videoCall": { + "type": "text", + "placeholders": {} + }, + "visibilityOfTheChatHistory": "Visibilità della cronologia della discussione", + "@visibilityOfTheChatHistory": { + "type": "text", + "placeholders": {} + }, + "visibleForAllParticipants": "Visibile a tutti i partecipanti", + "@visibleForAllParticipants": { + "type": "text", + "placeholders": {} + }, + "visibleForEveryone": "Visibile a tutti", + "@visibleForEveryone": { + "type": "text", + "placeholders": {} + }, + "voiceMessage": "Messaggio vocale", + "@voiceMessage": { + "type": "text", + "placeholders": {} + }, + "waitingPartnerAcceptRequest": "In attesa che il partner accetti la richiesta…", + "@waitingPartnerAcceptRequest": { + "type": "text", + "placeholders": {} + }, + "waitingPartnerEmoji": "In attesa che il partner accetti l'emoji…", + "@waitingPartnerEmoji": { + "type": "text", + "placeholders": {} + }, + "waitingPartnerNumbers": "In attesa che il partner accetti i numeri…", + "@waitingPartnerNumbers": { + "type": "text", + "placeholders": {} + }, + "wallpaper": "Immagine di sfondo", + "@wallpaper": { + "type": "text", + "placeholders": {} + }, + "warning": "Attenzione!", + "@warning": { + "type": "text", + "placeholders": {} + }, + "weSentYouAnEmail": "Ti abbiamo inviato un'e-mail", + "@weSentYouAnEmail": { + "type": "text", + "placeholders": {} + }, + "whoCanPerformWhichAction": "Chi può eseguire quale azione", + "@whoCanPerformWhichAction": { + "type": "text", + "placeholders": {} + }, + "whoIsAllowedToJoinThisGroup": "Chi è autorizzato a unirsi a questo gruppo", + "@whoIsAllowedToJoinThisGroup": { + "type": "text", + "placeholders": {} + }, + "whyDoYouWantToReportThis": "Perché vuoi segnalarlo?", + "@whyDoYouWantToReportThis": { + "type": "text", + "placeholders": {} + }, + "wipeChatBackup": "Cancellare il backup della discussione per creare una nuova chiave di sicurezza?", + "@wipeChatBackup": { + "type": "text", + "placeholders": {} + }, + "withTheseAddressesRecoveryDescription": "Con questi indirizzi puoi recuperare la tua password se necessario.", + "@withTheseAddressesRecoveryDescription": { + "type": "text", + "placeholders": {} + }, + "writeAMessage": "Scrivi un messaggio…", + "@writeAMessage": { + "type": "text", + "placeholders": {} + }, + "yes": "Sì", + "@yes": { + "type": "text", + "placeholders": {} + }, + "you": "Tu", + "@you": { + "type": "text", + "placeholders": {} + }, + "youAreInvitedToThisChat": "Sei invitato/a a questa chat", + "@youAreInvitedToThisChat": { + "type": "text", + "placeholders": {} + }, + "youAreNoLongerParticipatingInThisChat": "Non stai più partecipando a questa chat", + "@youAreNoLongerParticipatingInThisChat": { + "type": "text", + "placeholders": {} + }, + "youCannotInviteYourself": "Non puoi invitare te stesso", + "@youCannotInviteYourself": { + "type": "text", + "placeholders": {} + }, + "youHaveBeenBannedFromThisChat": "Sei stato/a bandito/a da questa chat", + "@youHaveBeenBannedFromThisChat": { + "type": "text", + "placeholders": {} + }, + "yourPublicKey": "La tua chiave pubblica", + "@yourPublicKey": { + "type": "text", + "placeholders": {} + }, + "singlesignon": "Accesso singolo", + "@singlesignon": { + "type": "text", + "placeholders": {} + }, + "setAsCanonicalAlias": "Imposta come alias principale", + "@setAsCanonicalAlias": { + "type": "text", + "placeholders": {} + }, + "removeYourAvatar": "Rimuovi il tuo avatar", + "@removeYourAvatar": { + "type": "text", + "placeholders": {} + }, + "register": "Registrati", + "@register": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourPin": "Per favore inserisci il tuo PIN", + "@pleaseEnterYourPin": { + "type": "text", + "placeholders": {} + }, + "pleaseChoose": "Si prega di scegliere", + "@pleaseChoose": { + "type": "text", + "placeholders": {} + }, + "or": "O", + "@or": { + "type": "text", + "placeholders": {} + }, + "oopsPushError": "Ops! Purtroppo si è verificato un errore durante l'impostazione delle notifiche push.", + "@oopsPushError": { + "type": "text", + "placeholders": {} + }, + "loginWith": "Accedi con {brand}", + "@loginWith": { + "type": "text", + "placeholders": { + "brand": {} + } + }, + "editRoomAliases": "Modifica gli alias della stanza", + "@editRoomAliases": { + "type": "text", + "placeholders": {} + }, + "clearArchive": "Cancella archivio", + "@clearArchive": {}, + "changeYourAvatar": "Cambia il tuo avatar", + "@changeYourAvatar": { + "type": "text", + "placeholders": {} + }, + "allChats": "Tutte le chat", + "@allChats": { + "type": "text", + "placeholders": {} + }, + "addToSpace": "Aggiungi a uno spazio", + "@addToSpace": {}, + "passwordsDoNotMatch": "Le password non corrispondono!", + "@passwordsDoNotMatch": {}, + "pleaseEnterValidEmail": "Inserire un indirizzo email valido.", + "@pleaseEnterValidEmail": {}, + "commandHint_leave": "Lascia questa stanza", + "@commandHint_leave": { + "type": "text", + "description": "Usage hint for the command /leave" + }, + "commandHint_ban": "Banna l'utente specificato da questa stanza.", + "@commandHint_ban": { + "type": "text", + "description": "Usage hint for the command /ban" + }, + "sendSticker": "Invia sticker", + "@sendSticker": { + "type": "text", + "placeholders": {} + }, + "commandHint_html": "Invia testo formattato in HTML", + "@commandHint_html": { + "type": "text", + "description": "Usage hint for the command /html" + }, + "commandHint_plain": "Invia testo non formattato", + "@commandHint_plain": { + "type": "text", + "description": "Usage hint for the command /plain" + }, + "commandHint_send": "Invia testo", + "@commandHint_send": { + "type": "text", + "description": "Usage hint for the command /send" + }, + "locationDisabledNotice": "I servizi di localizzazione sono disabilitati. Per favore abilitali per poter condividere la tua posizione.", + "@locationDisabledNotice": { + "type": "text", + "placeholders": {} + }, + "saveFile": "Salva file", + "@saveFile": { + "type": "text", + "placeholders": {} + }, + "serverRequiresEmail": "Questo server ha bisogno di validare la tua email per la registrazione.", + "@serverRequiresEmail": {}, + "openInMaps": "Apri in maps", + "@openInMaps": { + "type": "text", + "placeholders": {} + }, + "scanQrCode": "Scansiona codice QR", + "@scanQrCode": {}, + "addAccount": "Aggiungi account", + "@addAccount": {}, + "unverified": "Non verificato", + "@unverified": {}, + "pleaseChooseAtLeastChars": "Per favore scegli almeno {min} caratteri.", + "@pleaseChooseAtLeastChars": { + "type": "text", + "placeholders": { + "min": {} + } + }, + "sendAsText": "Invia come testo", + "@sendAsText": { + "type": "text" + }, + "repeatPassword": "Ripeti password", + "@repeatPassword": {}, + "autoplayImages": "Riproduci automaticamente sticker animati ed emoticon", + "@autoplayImages": { + "type": "text", + "placeholder": {} + }, + "cantOpenUri": "Can't open the URI {uri}", + "@cantOpenUri": { + "type": "text", + "placeholders": { + "uri": {} + } + }, + "commandInvalid": "Comando non valido", + "@commandInvalid": { + "type": "text" + }, + "link": "Link", + "@link": {}, + "shareLocation": "Condividi posizione", + "@shareLocation": { + "type": "text", + "placeholders": {} + }, + "yourChatBackupHasBeenSetUp": "Il tuo backup delle chat è stato configurato.", + "@yourChatBackupHasBeenSetUp": {}, + "discover": "", + "@discover": { + "type": "text", + "placeholders": {} + }, + "hugContent": "", + "@hugContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "jumpToLastReadMessage": "", + "@jumpToLastReadMessage": {}, + "allRooms": "", + "@allRooms": { + "type": "text", + "placeholders": {} + }, + "obtainingLocation": "", + "@obtainingLocation": { + "type": "text", + "placeholders": {} + }, + "whoCanSeeMyStories": "", + "@whoCanSeeMyStories": {}, + "commandHint_cuddle": "", + "@commandHint_cuddle": {}, + "widgetVideo": "", + "@widgetVideo": {}, + "dismiss": "", + "@dismiss": {}, + "reportErrorDescription": "", + "@reportErrorDescription": {}, + "chatHasBeenAddedToThisSpace": "", + "@chatHasBeenAddedToThisSpace": {}, + "unsupportedAndroidVersion": "", + "@unsupportedAndroidVersion": {}, + "enterASpacepName": "", + "@enterASpacepName": {}, + "widgetJitsi": "", + "@widgetJitsi": {}, + "messageType": "", + "@messageType": {}, + "noEmailWarning": "", + "@noEmailWarning": {}, + "indexedDbErrorLong": "", + "@indexedDbErrorLong": {}, + "oneClientLoggedOut": "", + "@oneClientLoggedOut": {}, + "startFirstChat": "", + "@startFirstChat": {}, + "callingAccount": "", + "@callingAccount": {}, + "setColorTheme": "", + "@setColorTheme": {}, + "nextAccount": "", + "@nextAccount": {}, + "commandHint_create": "", + "@commandHint_create": { + "type": "text", + "description": "Usage hint for the command /create" + }, + "allSpaces": "", + "@allSpaces": {}, + "supposedMxid": "", + "@supposedMxid": { + "type": "text", + "placeholders": { + "mxid": {} + } + }, + "user": "", + "@user": {}, + "youAcceptedTheInvitation": "", + "@youAcceptedTheInvitation": {}, + "noMatrixServer": "", + "@noMatrixServer": { + "type": "text", + "placeholders": { + "server1": {}, + "server2": {} + } + }, + "youInvitedBy": "", + "@youInvitedBy": { + "placeholders": { + "user": {} + } + }, + "banUserDescription": "", + "@banUserDescription": {}, + "requests": "", + "@requests": {}, + "widgetEtherpad": "", + "@widgetEtherpad": {}, + "stories": "", + "@stories": {}, + "addToStory": "", + "@addToStory": {}, + "removeDevicesDescription": "", + "@removeDevicesDescription": {}, + "separateChatTypes": "", + "@separateChatTypes": { + "type": "text", + "placeholders": {} + }, + "tryAgain": "", + "@tryAgain": {}, + "youKickedAndBanned": "", + "@youKickedAndBanned": { + "placeholders": { + "user": {} + } + }, + "showDirectChatsInSpaces": "", + "@showDirectChatsInSpaces": { + "type": "text", + "placeholders": {} + }, + "unbanUserDescription": "", + "@unbanUserDescription": {}, + "todoLists": "", + "@todoLists": {}, + "sendOnEnter": "", + "@sendOnEnter": {}, + "youRejectedTheInvitation": "", + "@youRejectedTheInvitation": {}, + "otherCallingPermissions": "", + "@otherCallingPermissions": {}, + "messagesStyle": "", + "@messagesStyle": {}, + "widgetUrlError": "", + "@widgetUrlError": {}, + "emailOrUsername": "", + "@emailOrUsername": {}, + "newSpaceDescription": "", + "@newSpaceDescription": {}, + "chatDescription": "", + "@chatDescription": {}, + "callingAccountDetails": "", + "@callingAccountDetails": {}, + "enterSpace": "", + "@enterSpace": {}, + "encryptThisChat": "", + "@encryptThisChat": {}, + "previousAccount": "", + "@previousAccount": {}, + "reopenChat": "", + "@reopenChat": {}, + "pleaseEnterRecoveryKey": "", + "@pleaseEnterRecoveryKey": {}, + "widgetNameError": "", + "@widgetNameError": {}, + "addToBundle": "", + "@addToBundle": {}, + "spaceIsPublic": "", + "@spaceIsPublic": { + "type": "text", + "placeholders": {} + }, + "addWidget": "", + "@addWidget": {}, + "countFiles": "", + "@countFiles": { + "placeholders": { + "count": {} + } + }, + "noKeyForThisMessage": "", + "@noKeyForThisMessage": {}, + "commandHint_markasgroup": "", + "@commandHint_markasgroup": {}, + "editTodo": "", + "@editTodo": {}, + "errorObtainingLocation": "", + "@errorObtainingLocation": { + "type": "text", + "placeholders": { + "error": {} + } + }, + "hydrateTor": "", + "@hydrateTor": {}, + "pushNotificationsNotAvailable": "", + "@pushNotificationsNotAvailable": {}, + "storeInAppleKeyChain": "", + "@storeInAppleKeyChain": {}, + "hydrate": "", + "@hydrate": {}, + "invalidServerName": "", + "@invalidServerName": {}, + "chatPermissions": "", + "@chatPermissions": {}, + "sender": "", + "@sender": {}, + "storeInAndroidKeystore": "", + "@storeInAndroidKeystore": {}, + "signInWithPassword": "", + "@signInWithPassword": {}, + "pleaseAddATitle": "", + "@pleaseAddATitle": {}, + "updateNow": "", + "@updateNow": {}, + "makeAdminDescription": "", + "@makeAdminDescription": {}, + "synchronizingPleaseWait": "", + "@synchronizingPleaseWait": { + "type": "text", + "placeholders": {} + }, + "commandHint_clearcache": "", + "@commandHint_clearcache": { + "type": "text", + "description": "Usage hint for the command /clearcache" + }, + "saveKeyManuallyDescription": "", + "@saveKeyManuallyDescription": {}, + "editBundlesForAccount": "", + "@editBundlesForAccount": {}, + "whyIsThisMessageEncrypted": "", + "@whyIsThisMessageEncrypted": {}, + "setChatDescription": "", + "@setChatDescription": {}, + "spaceName": "", + "@spaceName": { + "type": "text", + "placeholders": {} + }, + "importFromZipFile": "", + "@importFromZipFile": {}, + "dehydrateWarning": "", + "@dehydrateWarning": {}, + "noOtherDevicesFound": "", + "@noOtherDevicesFound": {}, + "addDescription": "", + "@addDescription": {}, + "redactedBy": "", + "@redactedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "videoCallsBetaWarning": "", + "@videoCallsBetaWarning": {}, + "storyPrivacyWarning": "", + "@storyPrivacyWarning": {}, + "matrixWidgets": "", + "@matrixWidgets": {}, + "signInWith": "", + "@signInWith": { + "type": "text", + "placeholders": { + "provider": {} + } + }, + "updateAvailable": "", + "@updateAvailable": {}, + "fileIsTooBigForServer": "", + "@fileIsTooBigForServer": {}, + "homeserver": "", + "@homeserver": {}, + "noTodosYet": "", + "@noTodosYet": {}, + "callingPermissions": "", + "@callingPermissions": {}, + "readUpToHere": "", + "@readUpToHere": {}, + "start": "", + "@start": {}, + "bubbleSize": "", + "@bubbleSize": { + "type": "text", + "placeholders": {} + }, + "unlockOldMessages": "", + "@unlockOldMessages": {}, + "numChats": "", + "@numChats": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "whatIsGoingOn": "", + "@whatIsGoingOn": {}, + "optionalRedactReason": "", + "@optionalRedactReason": {}, + "dehydrate": "", + "@dehydrate": {}, + "locationPermissionDeniedNotice": "", + "@locationPermissionDeniedNotice": { + "type": "text", + "placeholders": {} + }, + "archiveRoomDescription": "", + "@archiveRoomDescription": {}, + "exportEmotePack": "", + "@exportEmotePack": {}, + "switchToAccount": "", + "@switchToAccount": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "letsStart": "", + "@letsStart": {}, + "experimentalVideoCalls": "", + "@experimentalVideoCalls": {}, + "savedEmotePack": "", + "@savedEmotePack": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "pleaseEnterRecoveryKeyDescription": "", + "@pleaseEnterRecoveryKeyDescription": {}, + "inviteContactToGroupQuestion": "", + "@inviteContactToGroupQuestion": {}, + "redactedByBecause": "", + "@redactedByBecause": { + "type": "text", + "placeholders": { + "username": {}, + "reason": {} + } + }, + "youHaveWithdrawnTheInvitationFor": "", + "@youHaveWithdrawnTheInvitationFor": { + "placeholders": { + "user": {} + } + }, + "appearOnTopDetails": "", + "@appearOnTopDetails": {}, + "enterRoom": "", + "@enterRoom": {}, + "reportUser": "", + "@reportUser": {}, + "confirmEventUnpin": "", + "@confirmEventUnpin": {}, + "youInvitedUser": "", + "@youInvitedUser": { + "placeholders": { + "user": {} + } + }, + "fileHasBeenSavedAt": "", + "@fileHasBeenSavedAt": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "importZipFile": "", + "@importZipFile": {}, + "anyoneCanKnock": "", + "@anyoneCanKnock": {}, + "commandMissing": "", + "@commandMissing": { + "type": "text", + "placeholders": { + "command": {} + }, + "description": "State that {command} is not a valid /command." + }, + "redactMessageDescription": "", + "@redactMessageDescription": {}, + "recoveryKey": "", + "@recoveryKey": {}, + "commandHint_discardsession": "", + "@commandHint_discardsession": { + "type": "text", + "description": "Usage hint for the command /discardsession" + }, + "invalidInput": "", + "@invalidInput": {}, + "todosUnencrypted": "", + "@todosUnencrypted": {}, + "dehydrateTorLong": "", + "@dehydrateTorLong": {}, + "commandHint_myroomnick": "", + "@commandHint_myroomnick": { + "type": "text", + "description": "Usage hint for the command /myroomnick" + }, + "replyHasBeenSent": "", + "@replyHasBeenSent": {}, + "doNotShowAgain": "", + "@doNotShowAgain": {}, + "report": "", + "@report": {}, + "yourStory": "", + "@yourStory": {}, + "hideUnimportantStateEvents": "", + "@hideUnimportantStateEvents": {}, + "screenSharingTitle": "", + "@screenSharingTitle": {}, + "widgetCustom": "", + "@widgetCustom": {}, + "addToSpaceDescription": "", + "@addToSpaceDescription": {}, + "googlyEyesContent": "", + "@googlyEyesContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "whoCanSeeMyStoriesDesc": "", + "@whoCanSeeMyStoriesDesc": {}, + "youBannedUser": "", + "@youBannedUser": { + "placeholders": { + "user": {} + } + }, + "unsubscribeStories": "", + "@unsubscribeStories": {}, + "loginWithOneClick": "", + "@loginWithOneClick": {}, + "addChatDescription": "", + "@addChatDescription": {}, + "commandHint_myroomavatar": "", + "@commandHint_myroomavatar": { + "type": "text", + "description": "Usage hint for the command /myroomavatar" + }, + "hasKnocked": "", + "@hasKnocked": { + "placeholders": { + "user": {} + } + }, + "publish": "", + "@publish": {}, + "openLinkInBrowser": "", + "@openLinkInBrowser": {}, + "commandHint_react": "", + "@commandHint_react": { + "type": "text", + "description": "Usage hint for the command /react" + }, + "commandHint_me": "", + "@commandHint_me": { + "type": "text", + "description": "Usage hint for the command /me" + }, + "messageInfo": "", + "@messageInfo": {}, + "disableEncryptionWarning": "", + "@disableEncryptionWarning": {}, + "directChat": "", + "@directChat": {}, + "noOneCanJoin": "", + "@noOneCanJoin": {}, + "wrongPinEntered": "", + "@wrongPinEntered": { + "type": "text", + "placeholders": { + "seconds": {} + } + }, + "sendTypingNotifications": "", + "@sendTypingNotifications": {}, + "inviteGroupChat": "", + "@inviteGroupChat": {}, + "appearOnTop": "", + "@appearOnTop": {}, + "invitePrivateChat": "", + "@invitePrivateChat": {}, + "foregroundServiceRunning": "", + "@foregroundServiceRunning": {}, + "voiceCall": "", + "@voiceCall": {}, + "commandHint_kick": "", + "@commandHint_kick": { + "type": "text", + "description": "Usage hint for the command /kick" + }, + "createNewSpace": "", + "@createNewSpace": { + "type": "text", + "placeholders": {} + }, + "commandHint_unban": "", + "@commandHint_unban": { + "type": "text", + "description": "Usage hint for the command /unban" + }, + "importEmojis": "", + "@importEmojis": {}, + "wasDirectChatDisplayName": "", + "@wasDirectChatDisplayName": { + "type": "text", + "placeholders": { + "oldDisplayName": {} + } + }, + "noChatDescriptionYet": "", + "@noChatDescriptionYet": {}, + "newTodo": "", + "@newTodo": {}, + "removeFromBundle": "", + "@removeFromBundle": {}, + "confirmMatrixId": "", + "@confirmMatrixId": {}, + "learnMore": "", + "@learnMore": {}, + "notAnImage": "", + "@notAnImage": {}, + "users": "", + "@users": {}, + "openGallery": "", + "@openGallery": {}, + "chatDescriptionHasBeenChanged": "", + "@chatDescriptionHasBeenChanged": {}, + "newGroup": "", + "@newGroup": {}, + "bundleName": "", + "@bundleName": {}, + "dehydrateTor": "", + "@dehydrateTor": {}, + "todoListChangedError": "", + "@todoListChangedError": {}, + "removeFromSpace": "", + "@removeFromSpace": {}, + "enterInviteLinkOrMatrixId": "", + "@enterInviteLinkOrMatrixId": {}, + "commandHint_op": "", + "@commandHint_op": { + "type": "text", + "description": "Usage hint for the command /op" + }, + "commandHint_join": "", + "@commandHint_join": { + "type": "text", + "description": "Usage hint for the command /join" + }, + "roomUpgradeDescription": "", + "@roomUpgradeDescription": {}, + "commandHint_invite": "", + "@commandHint_invite": { + "type": "text", + "description": "Usage hint for the command /invite" + }, + "pleaseEnterANumber": "", + "@pleaseEnterANumber": {}, + "youKicked": "", + "@youKicked": { + "placeholders": { + "user": {} + } + }, + "profileNotFound": "", + "@profileNotFound": {}, + "jump": "", + "@jump": {}, + "reactedWith": "", + "@reactedWith": { + "type": "text", + "placeholders": { + "sender": {}, + "reaction": {} + } + }, + "sorryThatsNotPossible": "", + "@sorryThatsNotPossible": {}, + "storyFrom": "", + "@storyFrom": { + "type": "text", + "placeholders": { + "date": {}, + "body": {} + } + }, + "videoWithSize": "", + "@videoWithSize": { + "type": "text", + "placeholders": { + "size": {} + } + }, + "shareInviteLink": "", + "@shareInviteLink": {}, + "commandHint_markasdm": "", + "@commandHint_markasdm": {}, + "recoveryKeyLost": "", + "@recoveryKeyLost": {}, + "cuddleContent": "", + "@cuddleContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "deviceKeys": "", + "@deviceKeys": {}, + "emoteKeyboardNoRecents": "", + "@emoteKeyboardNoRecents": { + "type": "text", + "placeholders": {} + }, + "endToEndEncryption": "", + "@endToEndEncryption": {}, + "setTheme": "", + "@setTheme": {}, + "youJoinedTheChat": "", + "@youJoinedTheChat": {}, + "openVideoCamera": "", + "@openVideoCamera": { + "type": "text", + "placeholders": {} + }, + "thisUserHasNotPostedAnythingYet": "", + "@thisUserHasNotPostedAnythingYet": {}, + "markAsRead": "", + "@markAsRead": {}, + "widgetName": "", + "@widgetName": {}, + "errorAddingWidget": "", + "@errorAddingWidget": {}, + "commandHint_dm": "", + "@commandHint_dm": { + "type": "text", + "description": "Usage hint for the command /dm" + }, + "commandHint_hug": "", + "@commandHint_hug": {}, + "replace": "", + "@replace": {}, + "youUnbannedUser": "", + "@youUnbannedUser": { + "placeholders": { + "user": {} + } + }, + "newSpace": "", + "@newSpace": {}, + "emojis": "", + "@emojis": {}, + "commandHint_googly": "", + "@commandHint_googly": {}, + "pleaseTryAgainLaterOrChooseDifferentServer": "", + "@pleaseTryAgainLaterOrChooseDifferentServer": {}, + "createGroup": "", + "@createGroup": {}, + "hydrateTorLong": "", + "@hydrateTorLong": {}, + "time": "", + "@time": {}, + "custom": "", + "@custom": {}, + "noBackupWarning": "", + "@noBackupWarning": {}, + "editWidgets": "", + "@editWidgets": {}, + "storeInSecureStorageDescription": "", + "@storeInSecureStorageDescription": {}, + "openChat": "", + "@openChat": {}, + "kickUserDescription": "", + "@kickUserDescription": {}, + "importNow": "", + "@importNow": {}, + "pinMessage": "", + "@pinMessage": {}, + "invite": "", + "@invite": {}, + "enableMultiAccounts": "", + "@enableMultiAccounts": {}, + "continueWith": "", + "@continueWith": {}, + "indexedDbErrorTitle": "", + "@indexedDbErrorTitle": {}, + "unsupportedAndroidVersionLong": "", + "@unsupportedAndroidVersionLong": {}, + "storeSecurlyOnThisDevice": "", + "@storeSecurlyOnThisDevice": {}, + "iUnderstand": "", + "@iUnderstand": {}, + "screenSharingDetail": "", + "@screenSharingDetail": {}, + "placeCall": "", + "@placeCall": {} +} diff --git a/assets/l10n/intl_ja.arb b/assets/l10n/intl_ja.arb index 90030908d..1f66efd86 100644 --- a/assets/l10n/intl_ja.arb +++ b/assets/l10n/intl_ja.arb @@ -2395,5 +2395,260 @@ } }, "signInWithPassword": "パスワードでログイン", - "@signInWithPassword": {} + "@signInWithPassword": {}, + "discover": "", + "@discover": { + "type": "text", + "placeholders": {} + }, + "hugContent": "", + "@hugContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "jumpToLastReadMessage": "", + "@jumpToLastReadMessage": {}, + "allRooms": "", + "@allRooms": { + "type": "text", + "placeholders": {} + }, + "whoCanSeeMyStories": "", + "@whoCanSeeMyStories": {}, + "commandHint_cuddle": "", + "@commandHint_cuddle": {}, + "dismiss": "", + "@dismiss": {}, + "reportErrorDescription": "", + "@reportErrorDescription": {}, + "indexedDbErrorLong": "", + "@indexedDbErrorLong": {}, + "setColorTheme": "", + "@setColorTheme": {}, + "supposedMxid": "", + "@supposedMxid": { + "type": "text", + "placeholders": { + "mxid": {} + } + }, + "banUserDescription": "", + "@banUserDescription": {}, + "requests": "", + "@requests": {}, + "widgetEtherpad": "", + "@widgetEtherpad": {}, + "removeDevicesDescription": "", + "@removeDevicesDescription": {}, + "separateChatTypes": "", + "@separateChatTypes": { + "type": "text", + "placeholders": {} + }, + "tryAgain": "", + "@tryAgain": {}, + "unbanUserDescription": "", + "@unbanUserDescription": {}, + "todoLists": "", + "@todoLists": {}, + "messagesStyle": "", + "@messagesStyle": {}, + "newSpaceDescription": "", + "@newSpaceDescription": {}, + "chatDescription": "", + "@chatDescription": {}, + "callingAccountDetails": "", + "@callingAccountDetails": {}, + "noKeyForThisMessage": "", + "@noKeyForThisMessage": {}, + "editTodo": "", + "@editTodo": {}, + "pushNotificationsNotAvailable": "", + "@pushNotificationsNotAvailable": {}, + "invalidServerName": "", + "@invalidServerName": {}, + "chatPermissions": "", + "@chatPermissions": {}, + "pleaseAddATitle": "", + "@pleaseAddATitle": {}, + "makeAdminDescription": "", + "@makeAdminDescription": {}, + "saveKeyManuallyDescription": "", + "@saveKeyManuallyDescription": {}, + "setChatDescription": "", + "@setChatDescription": {}, + "importFromZipFile": "", + "@importFromZipFile": {}, + "redactedBy": "", + "@redactedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "fileIsTooBigForServer": "", + "@fileIsTooBigForServer": {}, + "noTodosYet": "", + "@noTodosYet": {}, + "readUpToHere": "", + "@readUpToHere": {}, + "whatIsGoingOn": "", + "@whatIsGoingOn": {}, + "optionalRedactReason": "", + "@optionalRedactReason": {}, + "archiveRoomDescription": "", + "@archiveRoomDescription": {}, + "exportEmotePack": "", + "@exportEmotePack": {}, + "savedEmotePack": "", + "@savedEmotePack": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "openInMaps": "", + "@openInMaps": { + "type": "text", + "placeholders": {} + }, + "inviteContactToGroupQuestion": "", + "@inviteContactToGroupQuestion": {}, + "redactedByBecause": "", + "@redactedByBecause": { + "type": "text", + "placeholders": { + "username": {}, + "reason": {} + } + }, + "fileHasBeenSavedAt": "", + "@fileHasBeenSavedAt": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "importZipFile": "", + "@importZipFile": {}, + "anyoneCanKnock": "", + "@anyoneCanKnock": {}, + "redactMessageDescription": "", + "@redactMessageDescription": {}, + "invalidInput": "", + "@invalidInput": {}, + "todosUnencrypted": "", + "@todosUnencrypted": {}, + "report": "", + "@report": {}, + "googlyEyesContent": "", + "@googlyEyesContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "addChatDescription": "", + "@addChatDescription": {}, + "hasKnocked": "", + "@hasKnocked": { + "placeholders": { + "user": {} + } + }, + "openLinkInBrowser": "", + "@openLinkInBrowser": {}, + "commandHint_me": "", + "@commandHint_me": { + "type": "text", + "description": "Usage hint for the command /me" + }, + "directChat": "", + "@directChat": {}, + "noOneCanJoin": "", + "@noOneCanJoin": {}, + "wrongPinEntered": "", + "@wrongPinEntered": { + "type": "text", + "placeholders": { + "seconds": {} + } + }, + "sendTypingNotifications": "", + "@sendTypingNotifications": {}, + "inviteGroupChat": "", + "@inviteGroupChat": {}, + "appearOnTop": "", + "@appearOnTop": {}, + "invitePrivateChat": "", + "@invitePrivateChat": {}, + "commandHint_kick": "", + "@commandHint_kick": { + "type": "text", + "description": "Usage hint for the command /kick" + }, + "commandHint_unban": "", + "@commandHint_unban": { + "type": "text", + "description": "Usage hint for the command /unban" + }, + "importEmojis": "", + "@importEmojis": {}, + "noChatDescriptionYet": "", + "@noChatDescriptionYet": {}, + "newTodo": "", + "@newTodo": {}, + "learnMore": "", + "@learnMore": {}, + "notAnImage": "", + "@notAnImage": {}, + "chatDescriptionHasBeenChanged": "", + "@chatDescriptionHasBeenChanged": {}, + "todoListChangedError": "", + "@todoListChangedError": {}, + "commandHint_op": "", + "@commandHint_op": { + "type": "text", + "description": "Usage hint for the command /op" + }, + "roomUpgradeDescription": "", + "@roomUpgradeDescription": {}, + "pleaseEnterANumber": "", + "@pleaseEnterANumber": {}, + "profileNotFound": "", + "@profileNotFound": {}, + "jump": "", + "@jump": {}, + "shareInviteLink": "", + "@shareInviteLink": {}, + "cuddleContent": "", + "@cuddleContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "emoteKeyboardNoRecents": "", + "@emoteKeyboardNoRecents": { + "type": "text", + "placeholders": {} + }, + "setTheme": "", + "@setTheme": {}, + "replace": "", + "@replace": {}, + "pleaseTryAgainLaterOrChooseDifferentServer": "", + "@pleaseTryAgainLaterOrChooseDifferentServer": {}, + "createGroup": "", + "@createGroup": {}, + "kickUserDescription": "", + "@kickUserDescription": {}, + "importNow": "", + "@importNow": {}, + "invite": "", + "@invite": {}, + "continueWith": "", + "@continueWith": {} } diff --git a/assets/l10n/intl_ko.arb b/assets/l10n/intl_ko.arb index 4fd9fe4cf..2ed77daaf 100644 --- a/assets/l10n/intl_ko.arb +++ b/assets/l10n/intl_ko.arb @@ -1,2236 +1,2660 @@ { - "@@last_modified": "2021-08-14 12:41:09.975135", - "about": "소개", - "@about": { - "type": "text", - "placeholders": {} - }, - "accept": "수락", - "@accept": { - "type": "text", - "placeholders": {} - }, - "allChats": "모든 채팅", - "@allChats": { - "type": "text", - "placeholders": {} - }, - "cantOpenUri": "URI {uri}를 열 수 없습니다", - "@cantOpenUri": { - "type": "text", - "placeholders": { - "uri": {} - } - }, - "chats": "채팅", - "@chats": { - "type": "text", - "placeholders": {} - }, - "commandHint_ban": "이 룸에서 주어진 유저 밴하기", - "@commandHint_ban": { - "type": "text", - "description": "Usage hint for the command /ban" - }, - "commandHint_html": "HTML 형식의 문자 보내기", - "@commandHint_html": { - "type": "text", - "description": "Usage hint for the command /html" - }, - "commandHint_invite": "주어진 유저 이 룸에 초대하기", - "@commandHint_invite": { - "type": "text", - "description": "Usage hint for the command /invite" - }, - "commandHint_leave": "이 룸 나가기", - "@commandHint_leave": { - "type": "text", - "description": "Usage hint for the command /leave" - }, - "commandHint_me": "자신을 소개하세요", - "@commandHint_me": { - "type": "text", - "description": "Usage hint for the command /me" - }, - "commandHint_plain": "형식이 지정되지 않은 문자 보내기", - "@commandHint_plain": { - "type": "text", - "description": "Usage hint for the command /plain" - }, - "commandHint_send": "문자 보내기", - "@commandHint_send": { - "type": "text", - "description": "Usage hint for the command /send" - }, - "commandHint_unban": "주어진 유저 이 룸에서 밴 해제하기", - "@commandHint_unban": { - "type": "text", - "description": "Usage hint for the command /unban" - }, - "loadMore": "더 불러오기…", - "@loadMore": { - "type": "text", - "placeholders": {} - }, - "loadCountMoreParticipants": "{count}명의 참가자 더 표시", - "@loadCountMoreParticipants": { - "type": "text", - "placeholders": { - "count": {} - } - }, - "lightTheme": "라이트", - "@lightTheme": { - "type": "text", - "placeholders": {} - }, - "license": "라이선스", - "@license": { - "type": "text", - "placeholders": {} - }, - "help": "도움", - "@help": { - "type": "text", - "placeholders": {} - }, - "guestsCanJoin": "게스트가 들어올 수 있음", - "@guestsCanJoin": { - "type": "text", - "placeholders": {} - }, - "groups": "그룹", - "@groups": { - "type": "text", - "placeholders": {} - }, - "groupIsPublic": "그룸 공개됨", - "@groupIsPublic": { - "type": "text", - "placeholders": {} - }, - "groupDescriptionHasBeenChanged": "그룹 설명 바뀜", - "@groupDescriptionHasBeenChanged": { - "type": "text", - "placeholders": {} - }, - "groupDescription": "그룹 설명", - "@groupDescription": { - "type": "text", - "placeholders": {} - }, - "group": "그룹", - "@group": { - "type": "text", - "placeholders": {} - }, - "goToTheNewRoom": "새로운 방 가기", - "@goToTheNewRoom": { - "type": "text", - "placeholders": {} - }, - "fromTheInvitation": "초대받은 후부터", - "@fromTheInvitation": { - "type": "text", - "placeholders": {} - }, - "fromJoining": "들어온 후부터", - "@fromJoining": { - "type": "text", - "placeholders": {} - }, - "forward": "전달", - "@forward": { - "type": "text", - "placeholders": {} - }, - "fontSize": "폰트 크기", - "@fontSize": { - "type": "text", - "placeholders": {} - }, - "fluffychat": "FluffyChat", - "@fluffychat": { - "type": "text", - "placeholders": {} - }, - "fileName": "파일 이름", - "@fileName": { - "type": "text", - "placeholders": {} - }, - "extremeOffensive": "매우 공격적임", - "@extremeOffensive": { - "type": "text", - "placeholders": {} - }, - "everythingReady": "모든 것이 준비됐어요!", - "@everythingReady": { - "type": "text", - "placeholders": {} - }, - "enterYourHomeserver": "당신의 홈서버를 입력하세요", - "@enterYourHomeserver": { - "type": "text", - "placeholders": {} - }, - "homeserver": "홈서버", - "@homeserver": {}, - "enterASpacepName": "스페이스 이름 입력", - "@enterASpacepName": {}, - "enterAnEmailAddress": "이메일 주소 입력", - "@enterAnEmailAddress": { - "type": "text", - "placeholders": {} - }, - "enterAGroupName": "그룹 이름 입력", - "@enterAGroupName": { - "type": "text", - "placeholders": {} - }, - "endedTheCall": "{senderName} 이 통화를 종료했습니다", - "@endedTheCall": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "encryptionNotEnabled": "암호화가 비활성화됨", - "@encryptionNotEnabled": { - "type": "text", - "placeholders": {} - }, - "encryption": "암호화", - "@encryption": { - "type": "text", - "placeholders": {} - }, - "encrypted": "암호화됨", - "@encrypted": { - "type": "text", - "placeholders": {} - }, - "enableEncryptionWarning": "당신은 다시 암호화를 비활성화할 수 없습니다. 확실한가요?", - "@enableEncryptionWarning": { - "type": "text", - "placeholders": {} - }, - "enableEncryption": "암호화 켜기", - "@enableEncryption": { - "type": "text", - "placeholders": {} - }, - "enableEmotesGlobally": "이모트 팩 항상 사용하기", - "@enableEmotesGlobally": { - "type": "text", - "placeholders": {} - }, - "emptyChat": "빈 채팅", - "@emptyChat": { - "type": "text", - "placeholders": {} - }, - "emoteWarnNeedToPick": "이모트 단축키와 이미지를 골라야 합니다!", - "@emoteWarnNeedToPick": { - "type": "text", - "placeholders": {} - }, - "emoteShortcode": "이모트 단축키", - "@emoteShortcode": { - "type": "text", - "placeholders": {} - }, - "emoteSettings": "이모트 설정", - "@emoteSettings": { - "type": "text", - "placeholders": {} - }, - "emotePacks": "방을 위한 이모트 팩", - "@emotePacks": { - "type": "text", - "placeholders": {} - }, - "emoteInvalid": "올바르지 않은 이모트 단축키!", - "@emoteInvalid": { - "type": "text", - "placeholders": {} - }, - "emoteExists": "이모트가 이미 존재합니다!", - "@emoteExists": { - "type": "text", - "placeholders": {} - }, - "editRoomAvatar": "방 아바타 수정", - "@editRoomAvatar": { - "type": "text", - "placeholders": {} - }, - "editRoomAliases": "방 별명 수정", - "@editRoomAliases": { - "type": "text", - "placeholders": {} - }, - "editDisplayname": "표시 이름 수정", - "@editDisplayname": { - "type": "text", - "placeholders": {} - }, - "editChatPermissions": "채팅 권한 수정", - "@editChatPermissions": { - "type": "text", - "placeholders": {} - }, - "edit": "수정", - "@edit": { - "type": "text", - "placeholders": {} - }, - "downloadFile": "파일 다운로드", - "@downloadFile": { - "type": "text", - "placeholders": {} - }, - "displaynameHasBeenChanged": "표시 이름이 변경되었습니다", - "@displaynameHasBeenChanged": { - "type": "text", - "placeholders": {} - }, - "devices": "기기", - "@devices": { - "type": "text", - "placeholders": {} - }, - "deviceId": "기기 ID", - "@deviceId": { - "type": "text", - "placeholders": {} - }, - "device": "기기", - "@device": { - "type": "text", - "placeholders": {} - }, - "deny": "거부", - "@deny": { - "type": "text", - "placeholders": {} - }, - "deleteMessage": "메시지 삭제", - "@deleteMessage": { - "type": "text", - "placeholders": {} - }, - "deleteAccount": "계정 삭제", - "@deleteAccount": { - "type": "text", - "placeholders": {} - }, - "delete": "삭제", - "@delete": { - "type": "text", - "placeholders": {} - }, - "defaultPermissionLevel": "기본 권한 레벨", - "@defaultPermissionLevel": { - "type": "text", - "placeholders": {} - }, - "deactivateAccountWarning": "이것은 당신의 계정을 비활성화할 것입니다. 이것은 되돌릴 수 없습니다! 확실한가요?", - "@deactivateAccountWarning": { - "type": "text", - "placeholders": {} - }, - "currentlyActive": "현재 활동 중", - "@currentlyActive": { - "type": "text", - "placeholders": {} - }, - "createNewSpace": "새로운 스페이스", - "@createNewSpace": { - "type": "text", - "placeholders": {} - }, - "createNewGroup": "새로운 그룹", - "@createNewGroup": { - "type": "text", - "placeholders": {} - }, - "createdTheChat": "💬 {username}님이 채팅을 생성함", - "@createdTheChat": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "create": "생성", - "@create": { - "type": "text", - "placeholders": {} - }, - "countParticipants": "{count} 참여자", - "@countParticipants": { - "type": "text", - "placeholders": { - "count": {} - } - }, - "couldNotDecryptMessage": "메시지 복호화할 수 없음: {error}", - "@couldNotDecryptMessage": { - "type": "text", - "placeholders": { - "error": {} - } - }, - "copyToClipboard": "클립보드에 복사", - "@copyToClipboard": { - "type": "text", - "placeholders": {} - }, - "copy": "복사", - "@copy": { - "type": "text", - "placeholders": {} - }, - "copiedToClipboard": "클립보드에 복사됨", - "@copiedToClipboard": { - "type": "text", - "placeholders": {} - }, - "contentHasBeenReported": "콘텐츠가 서버 운영자에게 신고되었습니다", - "@contentHasBeenReported": { - "type": "text", - "placeholders": {} - }, - "containsUserName": "유저 이름 포함", - "@containsUserName": { - "type": "text", - "placeholders": {} - }, - "containsDisplayName": "표시 이름 포함", - "@containsDisplayName": { - "type": "text", - "placeholders": {} - }, - "contactHasBeenInvitedToTheGroup": "연락처가 그룹에 초대되었습니다", - "@contactHasBeenInvitedToTheGroup": { - "type": "text", - "placeholders": {} - }, - "connect": "연결", - "@connect": { - "type": "text", - "placeholders": {} - }, - "confirm": "확인", - "@confirm": { - "type": "text", - "placeholders": {} - }, - "configureChat": "채팅 설정", - "@configureChat": { - "type": "text", - "placeholders": {} - }, - "compareNumbersMatch": "다른 기기에서도 아래의 숫자가 일치하는지 비교하세요:", - "@compareNumbersMatch": { - "type": "text", - "placeholders": {} - }, - "compareEmojiMatch": "다른 기기에서도 아래의 이모지가 일치하는지 비교하세요:", - "@compareEmojiMatch": { - "type": "text", - "placeholders": {} - }, - "commandMissing": "{command} 는 명령어가 아닙니다.", - "@commandMissing": { - "type": "text", - "placeholders": { - "command": {} - }, - "description": "State that {command} is not a valid /command." - }, - "commandInvalid": "잘못된 명령어", - "@commandInvalid": { - "type": "text" - }, - "commandHint_react": "답장 반응으로 보내기", - "@commandHint_react": { - "type": "text", - "description": "Usage hint for the command /react" - }, - "commandHint_op": "주어진 유저의 권한 레벨 설정 (기본:50)", - "@commandHint_op": { - "type": "text", - "description": "Usage hint for the command /op" - }, - "commandHint_myroomnick": "이 방의 표시 이름 설정하기", - "@commandHint_myroomnick": { - "type": "text", - "description": "Usage hint for the command /myroomnick" - }, - "commandHint_myroomavatar": "이 방의 사진 설정하기 (by mxc-uri)", - "@commandHint_myroomavatar": { - "type": "text", - "description": "Usage hint for the command /myroomavatar" - }, - "commandHint_kick": "주어진 유저 방에서 삭제하기", - "@commandHint_kick": { - "type": "text", - "description": "Usage hint for the command /kick" - }, - "commandHint_join": "주어진 방 들어가기", - "@commandHint_join": { - "type": "text", - "description": "Usage hint for the command /join" - }, - "close": "닫기", - "@close": { - "type": "text", - "placeholders": {} - }, - "clearArchive": "저장 지우기", - "@clearArchive": {}, - "chooseAUsername": "닉네임 고르기", - "@chooseAUsername": { - "type": "text", - "placeholders": {} - }, - "chooseAStrongPassword": "안전한 비밀번호를 설정하세요", - "@chooseAStrongPassword": { - "type": "text", - "placeholders": {} - }, - "chatHasBeenAddedToThisSpace": "이 스페이스에 채팅이 추가되었습니다", - "@chatHasBeenAddedToThisSpace": {}, - "chatDetails": "채팅 정보", - "@chatDetails": { - "type": "text", - "placeholders": {} - }, - "chatBackupDescription": "당신의 오래된 메시지는 보안 키로 보호됩니다. 이 키를 잃어버리지 마세요.", - "@chatBackupDescription": { - "type": "text", - "placeholders": {} - }, - "chatBackup": "채팅 백업", - "@chatBackup": { - "type": "text", - "placeholders": {} - }, - "chat": "채팅", - "@chat": { - "type": "text", - "placeholders": {} - }, - "channelCorruptedDecryptError": "암호화가 손상되었습니다", - "@channelCorruptedDecryptError": { - "type": "text", - "placeholders": {} - }, - "changeYourAvatar": "아바타 바꾸기", - "@changeYourAvatar": { - "type": "text", - "placeholders": {} - }, - "changeWallpaper": "배경 바꾸기", - "@changeWallpaper": { - "type": "text", - "placeholders": {} - }, - "changeTheNameOfTheGroup": "그룹의 이름 바꾸기", - "@changeTheNameOfTheGroup": { - "type": "text", - "placeholders": {} - }, - "changeTheme": "스타일 바꾸기", - "@changeTheme": { - "type": "text", - "placeholders": {} - }, - "changeTheHomeserver": "홈서버 바꾸기", - "@changeTheHomeserver": { - "type": "text", - "placeholders": {} - }, - "changePassword": "비밀번호 바꾸기", - "@changePassword": { - "type": "text", - "placeholders": {} - }, - "changedTheRoomInvitationLink": "{username}이 초대 링크 바꿈", - "@changedTheRoomInvitationLink": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheRoomAliases": "{username}이 방 별명을 바꿈", - "@changedTheRoomAliases": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheProfileAvatar": "{username}이 자신의 아바타를 바꿈", - "@changedTheProfileAvatar": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheJoinRulesTo": "{username}이 참가 규칙을 {joinRules} 로 바꿈", - "@changedTheJoinRulesTo": { - "type": "text", - "placeholders": { - "username": {}, - "joinRules": {} - } - }, - "changedTheJoinRules": "{username}이 참가 규칙을 바꿈", - "@changedTheJoinRules": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheHistoryVisibilityTo": "{username}이 대화 기록 설정을 {rules} 로 바꿈", - "@changedTheHistoryVisibilityTo": { - "type": "text", - "placeholders": { - "username": {}, - "rules": {} - } - }, - "changedTheHistoryVisibility": "{username}이 대화 기록 설정을 변경함", - "@changedTheHistoryVisibility": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheGuestAccessRulesTo": "{username}이 게스트 접근 규칙을 {rules} 로 변경함", - "@changedTheGuestAccessRulesTo": { - "type": "text", - "placeholders": { - "username": {}, - "rules": {} - } - }, - "changedTheGuestAccessRules": "{username}이 게스트 접근 규칙을 변경함", - "@changedTheGuestAccessRules": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheDisplaynameTo": "{username}이 닉네임을 '{displayname}' 으로 바꿈", - "@changedTheDisplaynameTo": { - "type": "text", - "placeholders": { - "username": {}, - "displayname": {} - } - }, - "changedTheChatPermissions": "{username}이 채팅 권한을 바꿈", - "@changedTheChatPermissions": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheChatNameTo": "{username}이 채팅 이름을 '{chatname}' 으로 바꿈", - "@changedTheChatNameTo": { - "type": "text", - "placeholders": { - "username": {}, - "chatname": {} - } - }, - "changedTheChatDescriptionTo": "{username}이 채팅 설명을 '{description}' 으로 변경함", - "@changedTheChatDescriptionTo": { - "type": "text", - "placeholders": { - "username": {}, - "description": {} - } - }, - "changedTheChatAvatar": "{username}이 채팅 아바타 바꿈", - "@changedTheChatAvatar": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changeDeviceName": "기기 이름 바꾸기", - "@changeDeviceName": { - "type": "text", - "placeholders": {} - }, - "cancel": "취소", - "@cancel": { - "type": "text", - "placeholders": {} - }, - "botMessages": "봇 메시지", - "@botMessages": { - "type": "text", - "placeholders": {} - }, - "blocked": "차단됨", - "@blocked": { - "type": "text", - "placeholders": {} - }, - "blockDevice": "기기 차단", - "@blockDevice": { - "type": "text", - "placeholders": {} - }, - "bannedUser": "{username}이 {targetName} 밴함", - "@bannedUser": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "banned": "밴됨", - "@banned": { - "type": "text", - "placeholders": {} - }, - "banFromChat": "채팅에서 밴", - "@banFromChat": { - "type": "text", - "placeholders": {} - }, - "badServerVersionsException": "이 홈서버가 지원하는 Spec 버전:\n{serverVersions}\n하지만 이 앱은 {supportedVersions}만 지원합니다", - "@badServerVersionsException": { - "type": "text", - "placeholders": { - "serverVersions": {}, - "supportedVersions": {} - } - }, - "sendOnEnter": "엔터로 보내기", - "@sendOnEnter": {}, - "badServerLoginTypesException": "홈서버가 지원하는 로그인 유형:\n{serverVersions}\n하지만 이 앱에서 지원하는 것은:\n{supportedVersions}", - "@badServerLoginTypesException": { - "type": "text", - "placeholders": { - "serverVersions": {}, - "supportedVersions": {} - } - }, - "autoplayImages": "자동으로 움직이는 스티커와 이모트 재생", - "@autoplayImages": { - "type": "text", - "placeholder": {} - }, - "askVerificationRequest": "{username}의 인증 요청을 수락할까요?", - "@askVerificationRequest": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "askSSSSSign": "다른 사람을 서명하기 위해서, 저장 비밀번호나 복구 키를 입력해주세요.", - "@askSSSSSign": { - "type": "text", - "placeholders": {} - }, - "areYouSureYouWantToLogout": "로그아웃하고 싶은 것이 확실한가요?", - "@areYouSureYouWantToLogout": { - "type": "text", - "placeholders": {} - }, - "areYouSure": "확실한가요?", - "@areYouSure": { - "type": "text", - "placeholders": {} - }, - "areGuestsAllowedToJoin": "게스트 유저가 참가 여부", - "@areGuestsAllowedToJoin": { - "type": "text", - "placeholders": {} - }, - "archive": "저장", - "@archive": { - "type": "text", - "placeholders": {} - }, - "appLock": "앱 잠금", - "@appLock": { - "type": "text", - "placeholders": {} - }, - "anyoneCanJoin": "누구나 들어올 수 있음", - "@anyoneCanJoin": { - "type": "text", - "placeholders": {} - }, - "answeredTheCall": "{senderName} 가 전화에 응답했습니다", - "@answeredTheCall": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "alias": "별명", - "@alias": { - "type": "text", - "placeholders": {} - }, - "admin": "관리자", - "@admin": { - "type": "text", - "placeholders": {} - }, - "addToSpace": "스페이스에 추가", - "@addToSpace": {}, - "addGroupDescription": "그룹 소개 추가", - "@addGroupDescription": { - "type": "text", - "placeholders": {} - }, - "addEmail": "이메일 추가", - "@addEmail": { - "type": "text", - "placeholders": {} - }, - "activatedEndToEndEncryption": "🔐 {username}님이 종단간 암호화를 활성화함", - "@activatedEndToEndEncryption": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "account": "계정", - "@account": { - "type": "text", - "placeholders": {} - }, - "acceptedTheInvitation": "👍 {username}님이 초대를 수락함", - "@acceptedTheInvitation": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "ignore": "무시", - "@ignore": { - "type": "text", - "placeholders": {} - }, - "identity": "신원", - "@identity": { - "type": "text", - "placeholders": {} - }, - "id": "ID", - "@id": { - "type": "text", - "placeholders": {} - }, - "howOffensiveIsThisContent": "이 콘텐츠가 얼마나 모욕적인가요?", - "@howOffensiveIsThisContent": { - "type": "text", - "placeholders": {} - }, - "hideUnknownEvents": "알 수 없는 이벤트 숨기기", - "@hideUnknownEvents": { - "type": "text", - "placeholders": {} - }, - "hideRedactedEvents": "지워진 이벤트 숨기기", - "@hideRedactedEvents": { - "type": "text", - "placeholders": {} - }, - "hasWithdrawnTheInvitationFor": "{username}이 {targetName}에 대한 초대를 철회함", - "@hasWithdrawnTheInvitationFor": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "guestsAreForbidden": "게스트는 금지되어 있습니다", - "@guestsAreForbidden": { - "type": "text", - "placeholders": {} - }, - "groupWith": "{displayname} 과의 그룹", - "@groupWith": { - "type": "text", - "placeholders": { - "displayname": {} - } - }, - "errorObtainingLocation": "위치 얻는 중 오류: {error}", - "@errorObtainingLocation": { - "type": "text", - "placeholders": { - "error": {} - } - }, - "editBlockedServers": "차단된 서버 수정", - "@editBlockedServers": { - "type": "text", - "placeholders": {} - }, - "directChats": "다이렉트 채팅", - "@directChats": { - "type": "text", - "placeholders": {} - }, - "dateWithYear": "{year}-{month}-{day}", - "@dateWithYear": { - "type": "text", - "placeholders": { - "year": {}, - "month": {}, - "day": {} - } - }, - "dateWithoutYear": "{month}-{day}", - "@dateWithoutYear": { - "type": "text", - "placeholders": { - "month": {}, - "day": {} - } - }, - "dateAndTimeOfDay": "{date}, {timeOfDay}", - "@dateAndTimeOfDay": { - "type": "text", - "placeholders": { - "date": {}, - "timeOfDay": {} - } - }, - "darkTheme": "다크", - "@darkTheme": { - "type": "text", - "placeholders": {} - }, - "youAreInvitedToThisChat": "당신은 이 채팅에 초대되었습니다", - "@youAreInvitedToThisChat": { - "type": "text", - "placeholders": {} - }, - "yes": "확인", - "@yes": { - "type": "text", - "placeholders": {} - }, - "writeAMessage": "메시지 작성…", - "@writeAMessage": { - "type": "text", - "placeholders": {} - }, - "withTheseAddressesRecoveryDescription": "이 주소로 당신의 비밀번호를 복구할 수 있습니다.", - "@withTheseAddressesRecoveryDescription": { - "type": "text", - "placeholders": {} - }, - "wipeChatBackup": "새로운 보안 키를 생성하기 위해 채팅 백업을 초기화할까요?", - "@wipeChatBackup": { - "type": "text", - "placeholders": {} - }, - "whyDoYouWantToReportThis": "왜 이것을 신고하려고 하나요?", - "@whyDoYouWantToReportThis": { - "type": "text", - "placeholders": {} - }, - "whoIsAllowedToJoinThisGroup": "누가 이 그룹에 들어오도록 허용할지", - "@whoIsAllowedToJoinThisGroup": { - "type": "text", - "placeholders": {} - }, - "whoCanPerformWhichAction": "누가 어떤 행동을 할 수 있는지", - "@whoCanPerformWhichAction": { - "type": "text", - "placeholders": {} - }, - "weSentYouAnEmail": "우리가 당신에게 이메일을 보냈습니다", - "@weSentYouAnEmail": { - "type": "text", - "placeholders": {} - }, - "warning": "경고!", - "@warning": { - "type": "text", - "placeholders": {} - }, - "wallpaper": "배경", - "@wallpaper": { - "type": "text", - "placeholders": {} - }, - "waitingPartnerNumbers": "상대가 숫자를 수락하길 기다리는 중…", - "@waitingPartnerNumbers": { - "type": "text", - "placeholders": {} - }, - "waitingPartnerEmoji": "상대가 이모지를 수락하길 기다리는 중…", - "@waitingPartnerEmoji": { - "type": "text", - "placeholders": {} - }, - "waitingPartnerAcceptRequest": "상대가 요청을 수락하길 기다리는 중…", - "@waitingPartnerAcceptRequest": { - "type": "text", - "placeholders": {} - }, - "voiceMessage": "음성 메시지", - "@voiceMessage": { - "type": "text", - "placeholders": {} - }, - "visibleForEveryone": "모두에게 보임", - "@visibleForEveryone": { - "type": "text", - "placeholders": {} - }, - "visibleForAllParticipants": "모든 참가자에게 보임", - "@visibleForAllParticipants": { - "type": "text", - "placeholders": {} - }, - "videoCall": "영상 통화", - "@videoCall": { - "type": "text", - "placeholders": {} - }, - "verifyTitle": "다른 계정 확인 중", - "@verifyTitle": { - "type": "text", - "placeholders": {} - }, - "verifySuccess": "성공적으로 확인했어요!", - "@verifySuccess": { - "type": "text", - "placeholders": {} - }, - "verifyStart": "확인 시작", - "@verifyStart": { - "type": "text", - "placeholders": {} - }, - "verify": "확인", - "@verify": { - "type": "text", - "placeholders": {} - }, - "verified": "확인됨", - "@verified": { - "type": "text", - "placeholders": {} - }, - "username": "유저 이름", - "@username": { - "type": "text", - "placeholders": {} - }, - "userLeftTheChat": "{username}이 채팅을 나감", - "@userLeftTheChat": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "userIsTyping": "{username}이 입력 중…", - "@userIsTyping": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "userAndUserAreTyping": "{username}과 {username2}가 입력 중…", - "@userAndUserAreTyping": { - "type": "text", - "placeholders": { - "username": {}, - "username2": {} - } - }, - "userAndOthersAreTyping": "{username}과 {count}명이 입력 중…", - "@userAndOthersAreTyping": { - "type": "text", - "placeholders": { - "username": {}, - "count": {} - } - }, - "unpin": "고정 해제", - "@unpin": { - "type": "text", - "placeholders": {} - }, - "unknownEncryptionAlgorithm": "알 수 없는 암호화 알고리즘", - "@unknownEncryptionAlgorithm": { - "type": "text", - "placeholders": {} - }, - "unblockDevice": "기기 차단 해제", - "@unblockDevice": { - "type": "text", - "placeholders": {} - }, - "pin": "고정", - "@pin": { - "type": "text", - "placeholders": {} - }, - "pickImage": "이미지 고르기", - "@pickImage": { - "type": "text", - "placeholders": {} - }, - "passwordRecovery": "비밀번호 복구", - "@passwordRecovery": { - "type": "text", - "placeholders": {} - }, - "passwordForgotten": "비밀번호 까먹음", - "@passwordForgotten": { - "type": "text", - "placeholders": {} - }, - "password": "비밀번호", - "@password": { - "type": "text", - "placeholders": {} - }, - "participant": "참여자", - "@participant": { - "type": "text", - "placeholders": {} - }, - "optionalGroupName": "(선택) 그룹 이름", - "@optionalGroupName": { - "type": "text", - "placeholders": {} - }, - "openInMaps": "지도에서 열기", - "@openInMaps": { - "type": "text", - "placeholders": {} - }, - "addAccount": "계정 추가", - "@addAccount": {}, - "openCamera": "카메라 열기", - "@openCamera": { - "type": "text", - "placeholders": {} - }, - "openAppToReadMessages": "앱을 열어서 메시지를 읽으세요", - "@openAppToReadMessages": { - "type": "text", - "placeholders": {} - }, - "oopsSomethingWentWrong": "앗, 무언가가 잘못되었습니다…", - "@oopsSomethingWentWrong": { - "type": "text", - "placeholders": {} - }, - "oopsPushError": "앗! 안타깝게도, 푸시 알림을 설정하는 중 오류가 발생했습니다.", - "@oopsPushError": { - "type": "text", - "placeholders": {} - }, - "online": "온라인", - "@online": { - "type": "text", - "placeholders": {} - }, - "ok": "확인", - "@ok": { - "type": "text", - "placeholders": {} - }, - "offline": "오프라인", - "@offline": { - "type": "text", - "placeholders": {} - }, - "offensive": "모욕적임", - "@offensive": { - "type": "text", - "placeholders": {} - }, - "obtainingLocation": "위치 얻는 중…", - "@obtainingLocation": { - "type": "text", - "placeholders": {} - }, - "numUsersTyping": "{count}명이 입력 중…", - "@numUsersTyping": { - "type": "text", - "placeholders": { - "count": {} - } - }, - "notificationsEnabledForThisAccount": "이 계정에서 알림이 활성화되었습니다", - "@notificationsEnabledForThisAccount": { - "type": "text", - "placeholders": {} - }, - "notifications": "알림", - "@notifications": { - "type": "text", - "placeholders": {} - }, - "noPermission": "권한 없음", - "@noPermission": { - "type": "text", - "placeholders": {} - }, - "scanQrCode": "QR 코드 스캔", - "@scanQrCode": {}, - "shareYourInviteLink": "당신의 초대 링크 공유", - "@shareYourInviteLink": {}, - "noMatrixServer": "{server1}은 matrix 서버가 아닙니다, {server2}를 대신 사용할까요?", - "@noMatrixServer": { - "type": "text", - "placeholders": { - "server1": {}, - "server2": {} - } - }, - "next": "다음", - "@next": { - "type": "text", - "placeholders": {} - }, - "loginWith": "{brand} 로 로그인", - "@loginWith": { - "type": "text", - "placeholders": { - "brand": {} - } - }, - "logInTo": "{homeserver} 에 로그인", - "@logInTo": { - "type": "text", - "placeholders": { - "homeserver": {} - } - }, - "login": "로그인", - "@login": { - "type": "text", - "placeholders": {} - }, - "locationPermissionDeniedNotice": "위치 권한이 거부되었습니다. 위치를 공유하기 위해서 허용해주세요.", - "@locationPermissionDeniedNotice": { - "type": "text", - "placeholders": {} - }, - "locationDisabledNotice": "위치 서비스가 비활성화되었습니다. 위치를 공유하려면 활성화시켜주세요.", - "@locationDisabledNotice": { - "type": "text", - "placeholders": {} - }, - "no": "아니요", - "@no": { - "type": "text", - "placeholders": {} - }, - "newVerificationRequest": "새로운 확인 요청!", - "@newVerificationRequest": { - "type": "text", - "placeholders": {} - }, - "newMessageInFluffyChat": "FluffyChat에서 새로운 메시지", - "@newMessageInFluffyChat": { - "type": "text", - "placeholders": {} - }, - "newChat": "새로운 채팅", - "@newChat": { - "type": "text", - "placeholders": {} - }, - "muteChat": "채팅 음소거", - "@muteChat": { - "type": "text", - "placeholders": {} - }, - "messageWillBeRemovedWarning": "모든 참여자에게서 메시지가 지워집니다", - "@messageWillBeRemovedWarning": { - "type": "text", - "placeholders": {} - }, - "messages": "메시지", - "@messages": { - "type": "text", - "placeholders": {} - }, - "mention": "멘션", - "@mention": { - "type": "text", - "placeholders": {} - }, - "logout": "로그아웃", - "@logout": { - "type": "text", - "placeholders": {} - }, - "unreadChats": "{unreadCount, plural, =1{읽지 않은 채팅 1} other{{unreadCount} 개}}", - "@unreadChats": { - "type": "text", - "placeholders": { - "unreadCount": {} - } - }, - "renderRichContent": "풍부한 메시지 콘텐츠 렌더링", - "@renderRichContent": { - "type": "text", - "placeholders": {} - }, - "unavailable": "사용할 수 없음", - "@unavailable": { - "type": "text", - "placeholders": {} - }, - "makeSureTheIdentifierIsValid": "식별자가 유효한지 확인하세요", - "@makeSureTheIdentifierIsValid": { - "type": "text", - "placeholders": {} - }, - "all": "모두", - "@all": { - "type": "text", - "placeholders": {} - }, - "yourPublicKey": "당신의 공개 키", - "@yourPublicKey": { - "type": "text", - "placeholders": {} - }, - "youHaveBeenBannedFromThisChat": "당신은 이 채팅에서 밴되었습니다", - "@youHaveBeenBannedFromThisChat": { - "type": "text", - "placeholders": {} - }, - "youCannotInviteYourself": "자신을 초대할 수 없습니다", - "@youCannotInviteYourself": { - "type": "text", - "placeholders": {} - }, - "youAreNoLongerParticipatingInThisChat": "당신은 더 이상 이 채팅에 참여하지 않습니다", - "@youAreNoLongerParticipatingInThisChat": { - "type": "text", - "placeholders": {} - }, - "you": "당신", - "@you": { - "type": "text", - "placeholders": {} - }, - "visibilityOfTheChatHistory": "대화 기록 설정", - "@visibilityOfTheChatHistory": { - "type": "text", - "placeholders": {} - }, - "userSentUnknownEvent": "{username}이 {type} 이벤트 보냄", - "@userSentUnknownEvent": { - "type": "text", - "placeholders": { - "username": {}, - "type": {} - } - }, - "unmuteChat": "음소거 해제", - "@unmuteChat": { - "type": "text", - "placeholders": {} - }, - "unknownEvent": "알 수 없는 이벤트 '{type}'", - "@unknownEvent": { - "type": "text", - "placeholders": { - "type": {} - } - }, - "unknownDevice": "알 수 없는 기기", - "@unknownDevice": { - "type": "text", - "placeholders": {} - }, - "unbannedUser": "{username}이 {targetName} 밴 해제함", - "@unbannedUser": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "tryToSendAgain": "다시 보내도록 시도", - "@tryToSendAgain": { - "type": "text", - "placeholders": {} - }, - "transferFromAnotherDevice": "다른 기기에서 가져오기", - "@transferFromAnotherDevice": { - "type": "text", - "placeholders": {} - }, - "tooManyRequestsWarning": "너무 많은 요청. 잠시 후에 다시 시도해주세요!", - "@tooManyRequestsWarning": { - "type": "text", - "placeholders": {} - }, - "toggleUnread": "메시지 안/읽음 으로 표시", - "@toggleUnread": { - "type": "text", - "placeholders": {} - }, - "toggleMuted": "음소거 토글", - "@toggleMuted": { - "type": "text", - "placeholders": {} - }, - "toggleFavorite": "즐겨찾기 토글", - "@toggleFavorite": { - "type": "text", - "placeholders": {} - }, - "title": "FluffyChat", - "@title": { - "description": "Title for the application", - "type": "text", - "placeholders": {} - }, - "theyMatch": "일치합니다", - "@theyMatch": { - "type": "text", - "placeholders": {} - }, - "theyDontMatch": "일치하지 않습니다", - "@theyDontMatch": { - "type": "text", - "placeholders": {} - }, - "systemTheme": "시스템", - "@systemTheme": { - "type": "text", - "placeholders": {} - }, - "synchronizingPleaseWait": "동기화 중... 기다려주세요.", - "@synchronizingPleaseWait": { - "type": "text", - "placeholders": {} - }, - "submit": "제출", - "@submit": { - "type": "text", - "placeholders": {} - }, - "statusExampleMessage": "오늘은 어떤 기분인가요?", - "@statusExampleMessage": { - "type": "text", - "placeholders": {} - }, - "status": "상태", - "@status": { - "type": "text", - "placeholders": {} - }, - "startedACall": "{senderName} 가 통화 시작함", - "@startedACall": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "spaceName": "스페이스 이름", - "@spaceName": { - "type": "text", - "placeholders": {} - }, - "spaceIsPublic": "스페이스가 공개됨", - "@spaceIsPublic": { - "type": "text", - "placeholders": {} - }, - "singlesignon": "단일 계정 로그인(SSO)", - "@singlesignon": { - "type": "text", - "placeholders": {} - }, - "seenByUserAndCountOthers": "{count, plural, other{{username}과 이외 {count}명이 읽음}}", - "@seenByUserAndCountOthers": { - "type": "text", - "placeholders": { - "username": {}, - "count": {} - } - }, - "pushRules": "푸시 규칙", - "@pushRules": { - "type": "text", - "placeholders": {} - }, - "pleaseEnterAMatrixIdentifier": "Matrix ID를 입력해주세요.", - "@pleaseEnterAMatrixIdentifier": { - "type": "text", - "placeholders": {} - }, - "lastActiveAgo": "마지막 활동: {localizedTimeShort}", - "@lastActiveAgo": { - "type": "text", - "placeholders": { - "localizedTimeShort": {} - } - }, - "ignoredUsers": "무시된 사용자", - "@ignoredUsers": { - "type": "text", - "placeholders": {} - }, - "pleaseEnter4Digits": "4자리 숫자를 입력하거나 앱 잠금을 사용하지 않도록 하려면 비워두세요.", - "@pleaseEnter4Digits": { - "type": "text", - "placeholders": {} - }, - "pleaseChooseAPasscode": "비밀번호를 골라주세요", - "@pleaseChooseAPasscode": { - "type": "text", - "placeholders": {} - }, - "pleaseChoose": "선택해주세요", - "@pleaseChoose": { - "type": "text", - "placeholders": {} - }, - "play": "{fileName} 재생", - "@play": { - "type": "text", - "placeholders": { - "fileName": {} - } - }, - "people": "사람들", - "@people": { - "type": "text", - "placeholders": {} - }, - "passwordHasBeenChanged": "비밀번호가 변경됨", - "@passwordHasBeenChanged": { - "type": "text", - "placeholders": {} - }, - "passphraseOrKey": "비밀번호나 복구 키", - "@passphraseOrKey": { - "type": "text", - "placeholders": {} - }, - "or": "이나", - "@or": { - "type": "text", - "placeholders": {} - }, - "serverRequiresEmail": "이 서버는 가입을 위해 당신의 이메일을 확인해야 합니다.", - "@serverRequiresEmail": {}, - "enableMultiAccounts": "(베타) 이 기기에서 다중 계정 활성화", - "@enableMultiAccounts": {}, - "bundleName": "번들 이름", - "@bundleName": {}, - "removeFromBundle": "이 번들에서 삭제", - "@removeFromBundle": {}, - "addToBundle": "번들에 추가", - "@addToBundle": {}, - "editBundlesForAccount": "이 계정의 번들 수정", - "@editBundlesForAccount": {}, - "oneClientLoggedOut": "당신의 클라이언트 중 하나가 로그아웃 됨", - "@oneClientLoggedOut": {}, - "onlineKeyBackupEnabled": "온라인 키 백업이 활성화됨", - "@onlineKeyBackupEnabled": { - "type": "text", - "placeholders": {} - }, - "noRoomsFound": "아무 방도 발견되지 않았어요…", - "@noRoomsFound": { - "type": "text", - "placeholders": {} - }, - "noPasswordRecoveryDescription": "당신은 비밀번호를 복구할 방법을 추가하지 않았습니다.", - "@noPasswordRecoveryDescription": { - "type": "text", - "placeholders": {} - }, - "none": "없음", - "@none": { - "type": "text", - "placeholders": {} - }, - "noGoogleServicesWarning": "이 휴대폰에 Google 서비스가 없는 것 같습니다. 프라이버시를 위해 좋은 결정이죠! FluffyChat에서 푸시 알림을 받으려면 https://microg.org/ 이나 https://unifiedpush.org/ 을 사용하는 것을 권장합니다.", - "@noGoogleServicesWarning": { - "type": "text", - "placeholders": {} - }, - "noEncryptionForPublicRooms": "당신은 방이 공개적으로 접근 가능하지 않을 때만 암호화를 켤 수 있습니다.", - "@noEncryptionForPublicRooms": { - "type": "text", - "placeholders": {} - }, - "noEmotesFound": "이모트 발견되지 않음. 😕", - "@noEmotesFound": { - "type": "text", - "placeholders": {} - }, - "noConnectionToTheServer": "서버에 연결 없음", - "@noConnectionToTheServer": { - "type": "text", - "placeholders": {} - }, - "needPantalaimonWarning": "지금 종단간 암호화를 사용하기 위해서는 Pantalaimon이 필요하다는 것을 알아주세요.", - "@needPantalaimonWarning": { - "type": "text", - "placeholders": {} - }, - "moderator": "관리자", - "@moderator": { - "type": "text", - "placeholders": {} - }, - "memberChanges": "참가자 변경", - "@memberChanges": { - "type": "text", - "placeholders": {} - }, - "loadingPleaseWait": "로딩 중... 기다려 주세요.", - "@loadingPleaseWait": { - "type": "text", - "placeholders": {} - }, - "leftTheChat": "채팅을 나갔습니다", - "@leftTheChat": { - "type": "text", - "placeholders": {} - }, - "leave": "나가기", - "@leave": { - "type": "text", - "placeholders": {} - }, - "lastSeenLongTimeAgo": "오래 전 접속", - "@lastSeenLongTimeAgo": { - "type": "text", - "placeholders": {} - }, - "sourceCode": "소스 코드", - "@sourceCode": { - "type": "text", - "placeholders": {} - }, - "skip": "스킵", - "@skip": { - "type": "text", - "placeholders": {} - }, - "signUp": "가입", - "@signUp": { - "type": "text", - "placeholders": {} - }, - "showPassword": "비밀번호 보이기", - "@showPassword": { - "type": "text", - "placeholders": {} - }, - "shareLocation": "위치 보내기", - "@shareLocation": { - "type": "text", - "placeholders": {} - }, - "sharedTheLocation": "{username}이 위치 공유함", - "@sharedTheLocation": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "share": "공유", - "@share": { - "type": "text", - "placeholders": {} - }, - "settings": "설정", - "@settings": { - "type": "text", - "placeholders": {} - }, - "setStatus": "상태 설정", - "@setStatus": { - "type": "text", - "placeholders": {} - }, - "setPermissionsLevel": "권한 레벨 설정", - "@setPermissionsLevel": { - "type": "text", - "placeholders": {} - }, - "setInvitationLink": "초대 링크 설정", - "@setInvitationLink": { - "type": "text", - "placeholders": {} - }, - "setGroupDescription": "그룹 설명 설정", - "@setGroupDescription": { - "type": "text", - "placeholders": {} - }, - "setCustomEmotes": "맞춤 이모트 설정", - "@setCustomEmotes": { - "type": "text", - "placeholders": {} - }, - "setAsCanonicalAlias": "주 별명으로 설정", - "@setAsCanonicalAlias": { - "type": "text", - "placeholders": {} - }, - "sentCallInformations": "{senderName} 이 통화 정보 보냄", - "@sentCallInformations": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "sentAVideo": "{username}이 영상 보냄", - "@sentAVideo": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sendOriginal": "원본 보내기", - "@sendOriginal": { - "type": "text", - "placeholders": {} - }, - "sendMessages": "메시지 보내기", - "@sendMessages": { - "type": "text", - "placeholders": {} - }, - "sendImage": "이미지 보내기", - "@sendImage": { - "type": "text", - "placeholders": {} - }, - "sendFile": "파일 보내기", - "@sendFile": { - "type": "text", - "placeholders": {} - }, - "sendAudio": "오디오 보내기", - "@sendAudio": { - "type": "text", - "placeholders": {} - }, - "sendAsText": "텍스트로 보내기", - "@sendAsText": { - "type": "text" - }, - "sendAMessage": "메시지 보내기", - "@sendAMessage": { - "type": "text", - "placeholders": {} - }, - "send": "보내기", - "@send": { - "type": "text", - "placeholders": {} - }, - "seenByUserAndUser": "{username}, {username2}가 읽음", - "@seenByUserAndUser": { - "type": "text", - "placeholders": { - "username": {}, - "username2": {} - } - }, - "seenByUser": "{username}이 읽음", - "@seenByUser": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "security": "보안", - "@security": { - "type": "text", - "placeholders": {} - }, - "search": "검색", - "@search": { - "type": "text", - "placeholders": {} - }, - "saveFile": "파일 저장", - "@saveFile": { - "type": "text", - "placeholders": {} - }, - "roomVersion": "방 버전", - "@roomVersion": { - "type": "text", - "placeholders": {} - }, - "roomHasBeenUpgraded": "방이 업그레이드되었습니다", - "@roomHasBeenUpgraded": { - "type": "text", - "placeholders": {} - }, - "requestPermission": "권한 요청", - "@requestPermission": { - "type": "text", - "placeholders": {} - }, - "reason": "이유", - "@reason": { - "type": "text", - "placeholders": {} - }, - "publicRooms": "공개 방", - "@publicRooms": { - "type": "text", - "placeholders": {} - }, - "privacy": "프라이버시", - "@privacy": { - "type": "text", - "placeholders": {} - }, - "pleaseFollowInstructionsOnWeb": "웹사이트의 가이드를 따르고 다음 버튼을 눌러주세요.", - "@pleaseFollowInstructionsOnWeb": { - "type": "text", - "placeholders": {} - }, - "pleaseEnterYourUsername": "유저 이름을 입력해주세요", - "@pleaseEnterYourUsername": { - "type": "text", - "placeholders": {} - }, - "pleaseEnterYourPin": "PIN을 입력해주세요", - "@pleaseEnterYourPin": { - "type": "text", - "placeholders": {} - }, - "pleaseEnterYourPassword": "비밀번호를 입력해주세요", - "@pleaseEnterYourPassword": { - "type": "text", - "placeholders": {} - }, - "joinRoom": "방 들어가기", - "@joinRoom": { - "type": "text", - "placeholders": {} - }, - "joinedTheChat": "👋 {username}님이 채팅에 참가함", - "@joinedTheChat": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "isTyping": "가 입력 중…", - "@isTyping": { - "type": "text", - "placeholders": {} - }, - "inviteText": "{username}이 당신을 FluffyChat에 초대했습니다.\n1. FluffyChat 설치: https://fluffychat.im\n2. 가입하거나 로그인\n3. 초대 링크 열기: {link}", - "@inviteText": { - "type": "text", - "placeholders": { - "username": {}, - "link": {} - } - }, - "inviteForMe": "나를 위해 초대", - "@inviteForMe": { - "type": "text", - "placeholders": {} - }, - "invitedUsersOnly": "초대한 사용자만", - "@invitedUsersOnly": { - "type": "text", - "placeholders": {} - }, - "invitedUser": "📩 {username}님이 {targetName}님을 초대함", - "@invitedUser": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "invited": "초대됨", - "@invited": { - "type": "text", - "placeholders": {} - }, - "inviteContactToGroup": "연락처 {groupName} 에 초대", - "@inviteContactToGroup": { - "type": "text", - "placeholders": { - "groupName": {} - } - }, - "inviteContact": "연락처 초대", - "@inviteContact": { - "type": "text", - "placeholders": {} - }, - "inoffensive": "모욕적이지 않음", - "@inoffensive": { - "type": "text", - "placeholders": {} - }, - "incorrectPassphraseOrKey": "올바르지 않은 복구 키나 비밀번호", - "@incorrectPassphraseOrKey": { - "type": "text", - "placeholders": {} - }, - "iHaveClickedOnLink": "링크를 클릭했어요", - "@iHaveClickedOnLink": { - "type": "text", - "placeholders": {} - }, - "ignoreUsername": "유저 이름 무시", - "@ignoreUsername": { - "type": "text", - "placeholders": {} - }, - "ignoreListDescription": "당신을 방해하는 사용자들을 무시할 수 있습니다. 당신의 개인 무시 리스트에 있는 사용자들에게서 메시지나 방 초대를 수신할 수 없습니다.", - "@ignoreListDescription": { - "type": "text", - "placeholders": {} - }, - "sentASticker": "{username}이 스티커 보냄", - "@sentASticker": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sentAPicture": "{username}이 사진 보냄", - "@sentAPicture": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sentAnAudio": "{username}이 오디오 보냄", - "@sentAnAudio": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sentAFile": "{username}이 파일 보냄", - "@sentAFile": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sendVideo": "영상 보내기", - "@sendVideo": { - "type": "text", - "placeholders": {} - }, - "sendSticker": "스티커 보내기", - "@sendSticker": { - "type": "text", - "placeholders": {} - }, - "reportMessage": "메시지 신고", - "@reportMessage": { - "type": "text", - "placeholders": {} - }, - "reply": "답장", - "@reply": { - "type": "text", - "placeholders": {} - }, - "replaceRoomWithNewerVersion": "방 새로운 버전으로 대체하기", - "@replaceRoomWithNewerVersion": { - "type": "text", - "placeholders": {} - }, - "removeYourAvatar": "아바타 지우기", - "@removeYourAvatar": { - "type": "text", - "placeholders": {} - }, - "unbanFromChat": "채팅에서 밴 해제", - "@unbanFromChat": { - "type": "text", - "placeholders": {} - }, - "removeDevice": "기기 삭제", - "@removeDevice": { - "type": "text", - "placeholders": {} - }, - "removedBy": "{username}에 의해 지워짐", - "@removedBy": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "removeAllOtherDevices": "모든 다른 기기에서 지우기", - "@removeAllOtherDevices": { - "type": "text", - "placeholders": {} - }, - "remove": "지우기", - "@remove": { - "type": "text", - "placeholders": {} - }, - "rejoin": "다시 가입", - "@rejoin": { - "type": "text", - "placeholders": {} - }, - "rejectedTheInvitation": "{username}이 초대를 거절함", - "@rejectedTheInvitation": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "reject": "거절", - "@reject": { - "type": "text", - "placeholders": {} - }, - "register": "가입", - "@register": { - "type": "text", - "placeholders": {} - }, - "redactMessage": "메시지 지우기", - "@redactMessage": { - "type": "text", - "placeholders": {} - }, - "redactedAnEvent": "{username}이 이벤트를 지움", - "@redactedAnEvent": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "recording": "녹음", - "@recording": { - "type": "text", - "placeholders": {} - }, - "pleaseClickOnLink": "이메일의 링크를 클릭하고 진행해주세요.", - "@pleaseClickOnLink": { - "type": "text", - "placeholders": {} - }, - "pleaseChooseAUsername": "유저 이름을 골라주세요", - "@pleaseChooseAUsername": { - "type": "text", - "placeholders": {} - }, - "kickFromChat": "채팅에서 추방", - "@kickFromChat": { - "type": "text", - "placeholders": {} - }, - "kickedAndBanned": "🙅 {username}님이 {targetName}님을 추방하고 차단함", - "@kickedAndBanned": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "kicked": "👞 {username}님이 {targetName}님을 추방함", - "@kicked": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "link": "링크", - "@link": {}, - "unverified": "확인되지 않음", - "@unverified": {}, - "yourChatBackupHasBeenSetUp": "당신의 채팅 백업이 설정되었습니다.", - "@yourChatBackupHasBeenSetUp": {}, - "time": "시간", - "@time": {}, - "messageType": "메시지 유형", - "@messageType": {}, - "openGallery": "갤러리 열기", - "@openGallery": {}, - "sender": "발신자", - "@sender": {}, - "passwordsDoNotMatch": "비밀번호가 일치하지 않습니다!", - "@passwordsDoNotMatch": {}, - "pleaseChooseAtLeastChars": "최소 {min}자를 선택하세요.", - "@pleaseChooseAtLeastChars": { - "type": "text", - "placeholders": { - "min": {} - } - }, - "messageInfo": "메시지 정보", - "@messageInfo": {}, - "pleaseEnterValidEmail": "유효한 이메일 주소를 입력해주세요.", - "@pleaseEnterValidEmail": {}, - "repeatPassword": "비밀번호 다시 입력", - "@repeatPassword": {}, - "loginWithOneClick": "클릭 한 번으로 로그인", - "@loginWithOneClick": {}, - "start": "시작", - "@start": {}, - "removeFromSpace": "스페이스에서 삭제", - "@removeFromSpace": {}, - "addToSpaceDescription": "이 채팅을 추가할 스페이스를 선택하세요.", - "@addToSpaceDescription": {}, - "commandHint_discardsession": "세션 삭제", - "@commandHint_discardsession": { - "type": "text", - "description": "Usage hint for the command /discardsession" - }, - "commandHint_dm": "다이렉트 채팅 시작\t\n--no-encryption을 사용해 암호화 비활성화", - "@commandHint_dm": { - "type": "text", - "description": "Usage hint for the command /dm" - }, - "commandHint_clearcache": "캐시 지우기", - "@commandHint_clearcache": { - "type": "text", - "description": "Usage hint for the command /clearcache" - }, - "commandHint_create": "빈 그룹 채팅을 생성\t\n--no-encryption을 사용해 암호화를 비활성화", - "@commandHint_create": { - "type": "text", - "description": "Usage hint for the command /create" - }, - "openVideoCamera": "영상용 카메라 열기", - "@openVideoCamera": { - "type": "text", - "placeholders": {} - }, - "addToStory": "스토리에 추가", - "@addToStory": {}, - "publish": "공개", - "@publish": {}, - "yourStory": "내 스토리", - "@yourStory": {}, - "replyHasBeenSent": "답장을 보냈습니다", - "@replyHasBeenSent": {}, - "videoWithSize": "영상 ({size})", - "@videoWithSize": { - "type": "text", - "placeholders": { - "size": {} - } - }, - "storyFrom": "{date}의 스토리:\n{body}", - "@storyFrom": { - "type": "text", - "placeholders": { - "date": {}, - "body": {} - } - }, - "whoCanSeeMyStoriesDesc": "스토리에서 사람들이 서로를 보고 연락할 수 있다는 점에 유의하십시오.", - "@whoCanSeeMyStoriesDesc": {}, - "whatIsGoingOn": "무슨 일이 일어나고 있나요?", - "@whatIsGoingOn": {}, - "addDescription": "설명 추가", - "@addDescription": {}, - "whoCanSeeMyStories": "누가 내 스토리를 볼 수 있나요?", - "@whoCanSeeMyStories": {}, - "unsubscribeStories": "스토리 구독 해제", - "@unsubscribeStories": {}, - "thisUserHasNotPostedAnythingYet": "이 유저는 스토리에 아무것도 올리지 않았습니다", - "@thisUserHasNotPostedAnythingYet": {}, - "bubbleSize": "버블 크기", - "@bubbleSize": { - "type": "text", - "placeholders": {} - }, - "dismiss": "닫기", - "@dismiss": {}, - "matrixWidgets": "Matrix 위젯", - "@matrixWidgets": {}, - "markAsRead": "읽음으로 표시하기", - "@markAsRead": {}, - "reportUser": "사용자 신고", - "@reportUser": {}, - "openChat": "채팅 열기", - "@openChat": {}, - "storyPrivacyWarning": "사람들이 서로를 보고 연락할 수 있다는 점에 유의해주세요. 스토리는 24시간 동안 보이지만 모든 기기와 서버에서 삭제된다는 보장은 없습니다.", - "@storyPrivacyWarning": {}, - "iUnderstand": "동의합니다", - "@iUnderstand": {}, - "reactedWith": "{sender}가 {reaction}로 반응함", - "@reactedWith": { - "type": "text", - "placeholders": { - "sender": {}, - "reaction": {} - } - }, - "confirmEventUnpin": "이벤트를 영구적으로 고정 해제할 것이 확실한가요?", - "@confirmEventUnpin": {}, - "pinMessage": "방에 고정", - "@pinMessage": {}, - "emojis": "이모지", - "@emojis": {}, - "voiceCall": "음성 통화", - "@voiceCall": {}, - "placeCall": "전화 걸기", - "@placeCall": {}, - "experimentalVideoCalls": "실험적인 영상 통화", - "@experimentalVideoCalls": {}, - "unsupportedAndroidVersion": "지원되지 않는 안드로이드 버전", - "@unsupportedAndroidVersion": {}, - "unsupportedAndroidVersionLong": "이 기능은 새로운 안드로이드 버전을 요구합니다. Lineage OS 지원이나 업데이트를 확인해주세요.", - "@unsupportedAndroidVersionLong": {}, - "videoCallsBetaWarning": "영상 통화는 베타임을 확인해주세요. 의도한 대로 작동하지 않거나 모든 플랫폼에서 작동하지 않을 수 있습니다.", - "@videoCallsBetaWarning": {}, - "emailOrUsername": "이메일이나 유저 이름", - "@emailOrUsername": {}, - "updateAvailable": "FluffyChat 업데이트 이용가능", - "@updateAvailable": {}, - "updateNow": "백그라운드에서 업데이트 시작", - "@updateNow": {}, - "confirmMatrixId": "계정을 삭제하려면 Matrix ID를 확인해 주세요.", - "@confirmMatrixId": {}, - "commandHint_googly": "왕눈이 눈알 보내기", - "@commandHint_googly": {}, - "googlyEyesContent": "{senderName} 님이 왕눈이 눈알을 보냈습니다", - "@googlyEyesContent": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "commandHint_markasgroup": "", - "@commandHint_markasgroup": {}, - "dehydrate": "세션을 내보내고 기기 초기화 하기", - "@dehydrate": {}, - "dehydrateWarning": "이 동작은 되돌릴 수 없습니다. 백업 파일을 꼭 안전하게 보관하세요.", - "@dehydrateWarning": {} -} \ No newline at end of file + "@@last_modified": "2021-08-14 12:41:09.975135", + "about": "소개", + "@about": { + "type": "text", + "placeholders": {} + }, + "accept": "수락", + "@accept": { + "type": "text", + "placeholders": {} + }, + "allChats": "모든 채팅", + "@allChats": { + "type": "text", + "placeholders": {} + }, + "cantOpenUri": "URI {uri}를 열 수 없습니다", + "@cantOpenUri": { + "type": "text", + "placeholders": { + "uri": {} + } + }, + "chats": "채팅", + "@chats": { + "type": "text", + "placeholders": {} + }, + "commandHint_ban": "이 룸에서 주어진 유저 밴하기", + "@commandHint_ban": { + "type": "text", + "description": "Usage hint for the command /ban" + }, + "commandHint_html": "HTML 형식의 문자 보내기", + "@commandHint_html": { + "type": "text", + "description": "Usage hint for the command /html" + }, + "commandHint_invite": "주어진 유저 이 룸에 초대하기", + "@commandHint_invite": { + "type": "text", + "description": "Usage hint for the command /invite" + }, + "commandHint_leave": "이 룸 나가기", + "@commandHint_leave": { + "type": "text", + "description": "Usage hint for the command /leave" + }, + "commandHint_me": "자신을 소개하세요", + "@commandHint_me": { + "type": "text", + "description": "Usage hint for the command /me" + }, + "commandHint_plain": "형식이 지정되지 않은 문자 보내기", + "@commandHint_plain": { + "type": "text", + "description": "Usage hint for the command /plain" + }, + "commandHint_send": "문자 보내기", + "@commandHint_send": { + "type": "text", + "description": "Usage hint for the command /send" + }, + "commandHint_unban": "주어진 유저 이 룸에서 밴 해제하기", + "@commandHint_unban": { + "type": "text", + "description": "Usage hint for the command /unban" + }, + "loadMore": "더 불러오기…", + "@loadMore": { + "type": "text", + "placeholders": {} + }, + "loadCountMoreParticipants": "{count}명의 참가자 더 표시", + "@loadCountMoreParticipants": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "lightTheme": "라이트", + "@lightTheme": { + "type": "text", + "placeholders": {} + }, + "license": "라이선스", + "@license": { + "type": "text", + "placeholders": {} + }, + "help": "도움", + "@help": { + "type": "text", + "placeholders": {} + }, + "guestsCanJoin": "게스트가 들어올 수 있음", + "@guestsCanJoin": { + "type": "text", + "placeholders": {} + }, + "groups": "그룹", + "@groups": { + "type": "text", + "placeholders": {} + }, + "groupIsPublic": "그룸 공개됨", + "@groupIsPublic": { + "type": "text", + "placeholders": {} + }, + "groupDescriptionHasBeenChanged": "그룹 설명 바뀜", + "@groupDescriptionHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "groupDescription": "그룹 설명", + "@groupDescription": { + "type": "text", + "placeholders": {} + }, + "group": "그룹", + "@group": { + "type": "text", + "placeholders": {} + }, + "goToTheNewRoom": "새로운 방 가기", + "@goToTheNewRoom": { + "type": "text", + "placeholders": {} + }, + "fromTheInvitation": "초대받은 후부터", + "@fromTheInvitation": { + "type": "text", + "placeholders": {} + }, + "fromJoining": "들어온 후부터", + "@fromJoining": { + "type": "text", + "placeholders": {} + }, + "forward": "전달", + "@forward": { + "type": "text", + "placeholders": {} + }, + "fontSize": "폰트 크기", + "@fontSize": { + "type": "text", + "placeholders": {} + }, + "fluffychat": "FluffyChat", + "@fluffychat": { + "type": "text", + "placeholders": {} + }, + "fileName": "파일 이름", + "@fileName": { + "type": "text", + "placeholders": {} + }, + "extremeOffensive": "매우 공격적임", + "@extremeOffensive": { + "type": "text", + "placeholders": {} + }, + "everythingReady": "모든 것이 준비됐어요!", + "@everythingReady": { + "type": "text", + "placeholders": {} + }, + "enterYourHomeserver": "당신의 홈서버를 입력하세요", + "@enterYourHomeserver": { + "type": "text", + "placeholders": {} + }, + "homeserver": "홈서버", + "@homeserver": {}, + "enterASpacepName": "스페이스 이름 입력", + "@enterASpacepName": {}, + "enterAnEmailAddress": "이메일 주소 입력", + "@enterAnEmailAddress": { + "type": "text", + "placeholders": {} + }, + "enterAGroupName": "그룹 이름 입력", + "@enterAGroupName": { + "type": "text", + "placeholders": {} + }, + "endedTheCall": "{senderName} 이 통화를 종료했습니다", + "@endedTheCall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "encryptionNotEnabled": "암호화가 비활성화됨", + "@encryptionNotEnabled": { + "type": "text", + "placeholders": {} + }, + "encryption": "암호화", + "@encryption": { + "type": "text", + "placeholders": {} + }, + "encrypted": "암호화됨", + "@encrypted": { + "type": "text", + "placeholders": {} + }, + "enableEncryptionWarning": "당신은 다시 암호화를 비활성화할 수 없습니다. 확실한가요?", + "@enableEncryptionWarning": { + "type": "text", + "placeholders": {} + }, + "enableEncryption": "암호화 켜기", + "@enableEncryption": { + "type": "text", + "placeholders": {} + }, + "enableEmotesGlobally": "이모트 팩 항상 사용하기", + "@enableEmotesGlobally": { + "type": "text", + "placeholders": {} + }, + "emptyChat": "빈 채팅", + "@emptyChat": { + "type": "text", + "placeholders": {} + }, + "emoteWarnNeedToPick": "이모트 단축키와 이미지를 골라야 합니다!", + "@emoteWarnNeedToPick": { + "type": "text", + "placeholders": {} + }, + "emoteShortcode": "이모트 단축키", + "@emoteShortcode": { + "type": "text", + "placeholders": {} + }, + "emoteSettings": "이모트 설정", + "@emoteSettings": { + "type": "text", + "placeholders": {} + }, + "emotePacks": "방을 위한 이모트 팩", + "@emotePacks": { + "type": "text", + "placeholders": {} + }, + "emoteInvalid": "올바르지 않은 이모트 단축키!", + "@emoteInvalid": { + "type": "text", + "placeholders": {} + }, + "emoteExists": "이모트가 이미 존재합니다!", + "@emoteExists": { + "type": "text", + "placeholders": {} + }, + "editRoomAvatar": "방 아바타 수정", + "@editRoomAvatar": { + "type": "text", + "placeholders": {} + }, + "editRoomAliases": "방 별명 수정", + "@editRoomAliases": { + "type": "text", + "placeholders": {} + }, + "editDisplayname": "표시 이름 수정", + "@editDisplayname": { + "type": "text", + "placeholders": {} + }, + "editChatPermissions": "채팅 권한 수정", + "@editChatPermissions": { + "type": "text", + "placeholders": {} + }, + "edit": "수정", + "@edit": { + "type": "text", + "placeholders": {} + }, + "downloadFile": "파일 다운로드", + "@downloadFile": { + "type": "text", + "placeholders": {} + }, + "displaynameHasBeenChanged": "표시 이름이 변경되었습니다", + "@displaynameHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "devices": "기기", + "@devices": { + "type": "text", + "placeholders": {} + }, + "deviceId": "기기 ID", + "@deviceId": { + "type": "text", + "placeholders": {} + }, + "device": "기기", + "@device": { + "type": "text", + "placeholders": {} + }, + "deny": "거부", + "@deny": { + "type": "text", + "placeholders": {} + }, + "deleteMessage": "메시지 삭제", + "@deleteMessage": { + "type": "text", + "placeholders": {} + }, + "deleteAccount": "계정 삭제", + "@deleteAccount": { + "type": "text", + "placeholders": {} + }, + "delete": "삭제", + "@delete": { + "type": "text", + "placeholders": {} + }, + "defaultPermissionLevel": "기본 권한 레벨", + "@defaultPermissionLevel": { + "type": "text", + "placeholders": {} + }, + "deactivateAccountWarning": "이것은 당신의 계정을 비활성화할 것입니다. 이것은 되돌릴 수 없습니다! 확실한가요?", + "@deactivateAccountWarning": { + "type": "text", + "placeholders": {} + }, + "currentlyActive": "현재 활동 중", + "@currentlyActive": { + "type": "text", + "placeholders": {} + }, + "createNewSpace": "새로운 스페이스", + "@createNewSpace": { + "type": "text", + "placeholders": {} + }, + "createNewGroup": "새로운 그룹", + "@createNewGroup": { + "type": "text", + "placeholders": {} + }, + "createdTheChat": "💬 {username}님이 채팅을 생성함", + "@createdTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "create": "생성", + "@create": { + "type": "text", + "placeholders": {} + }, + "countParticipants": "{count} 참여자", + "@countParticipants": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "couldNotDecryptMessage": "메시지 복호화할 수 없음: {error}", + "@couldNotDecryptMessage": { + "type": "text", + "placeholders": { + "error": {} + } + }, + "copyToClipboard": "클립보드에 복사", + "@copyToClipboard": { + "type": "text", + "placeholders": {} + }, + "copy": "복사", + "@copy": { + "type": "text", + "placeholders": {} + }, + "copiedToClipboard": "클립보드에 복사됨", + "@copiedToClipboard": { + "type": "text", + "placeholders": {} + }, + "contentHasBeenReported": "콘텐츠가 서버 운영자에게 신고되었습니다", + "@contentHasBeenReported": { + "type": "text", + "placeholders": {} + }, + "containsUserName": "유저 이름 포함", + "@containsUserName": { + "type": "text", + "placeholders": {} + }, + "containsDisplayName": "표시 이름 포함", + "@containsDisplayName": { + "type": "text", + "placeholders": {} + }, + "contactHasBeenInvitedToTheGroup": "연락처가 그룹에 초대되었습니다", + "@contactHasBeenInvitedToTheGroup": { + "type": "text", + "placeholders": {} + }, + "connect": "연결", + "@connect": { + "type": "text", + "placeholders": {} + }, + "confirm": "확인", + "@confirm": { + "type": "text", + "placeholders": {} + }, + "configureChat": "채팅 설정", + "@configureChat": { + "type": "text", + "placeholders": {} + }, + "compareNumbersMatch": "다른 기기에서도 아래의 숫자가 일치하는지 비교하세요:", + "@compareNumbersMatch": { + "type": "text", + "placeholders": {} + }, + "compareEmojiMatch": "다른 기기에서도 아래의 이모지가 일치하는지 비교하세요:", + "@compareEmojiMatch": { + "type": "text", + "placeholders": {} + }, + "commandMissing": "{command} 는 명령어가 아닙니다.", + "@commandMissing": { + "type": "text", + "placeholders": { + "command": {} + }, + "description": "State that {command} is not a valid /command." + }, + "commandInvalid": "잘못된 명령어", + "@commandInvalid": { + "type": "text" + }, + "commandHint_react": "답장 반응으로 보내기", + "@commandHint_react": { + "type": "text", + "description": "Usage hint for the command /react" + }, + "commandHint_op": "주어진 유저의 권한 레벨 설정 (기본:50)", + "@commandHint_op": { + "type": "text", + "description": "Usage hint for the command /op" + }, + "commandHint_myroomnick": "이 방의 표시 이름 설정하기", + "@commandHint_myroomnick": { + "type": "text", + "description": "Usage hint for the command /myroomnick" + }, + "commandHint_myroomavatar": "이 방의 사진 설정하기 (by mxc-uri)", + "@commandHint_myroomavatar": { + "type": "text", + "description": "Usage hint for the command /myroomavatar" + }, + "commandHint_kick": "주어진 유저 방에서 삭제하기", + "@commandHint_kick": { + "type": "text", + "description": "Usage hint for the command /kick" + }, + "commandHint_join": "주어진 방 들어가기", + "@commandHint_join": { + "type": "text", + "description": "Usage hint for the command /join" + }, + "close": "닫기", + "@close": { + "type": "text", + "placeholders": {} + }, + "clearArchive": "저장 지우기", + "@clearArchive": {}, + "chooseAUsername": "닉네임 고르기", + "@chooseAUsername": { + "type": "text", + "placeholders": {} + }, + "chooseAStrongPassword": "안전한 비밀번호를 설정하세요", + "@chooseAStrongPassword": { + "type": "text", + "placeholders": {} + }, + "chatHasBeenAddedToThisSpace": "이 스페이스에 채팅이 추가되었습니다", + "@chatHasBeenAddedToThisSpace": {}, + "chatDetails": "채팅 정보", + "@chatDetails": { + "type": "text", + "placeholders": {} + }, + "chatBackupDescription": "당신의 오래된 메시지는 보안 키로 보호됩니다. 이 키를 잃어버리지 마세요.", + "@chatBackupDescription": { + "type": "text", + "placeholders": {} + }, + "chatBackup": "채팅 백업", + "@chatBackup": { + "type": "text", + "placeholders": {} + }, + "chat": "채팅", + "@chat": { + "type": "text", + "placeholders": {} + }, + "channelCorruptedDecryptError": "암호화가 손상되었습니다", + "@channelCorruptedDecryptError": { + "type": "text", + "placeholders": {} + }, + "changeYourAvatar": "아바타 바꾸기", + "@changeYourAvatar": { + "type": "text", + "placeholders": {} + }, + "changeWallpaper": "배경 바꾸기", + "@changeWallpaper": { + "type": "text", + "placeholders": {} + }, + "changeTheNameOfTheGroup": "그룹의 이름 바꾸기", + "@changeTheNameOfTheGroup": { + "type": "text", + "placeholders": {} + }, + "changeTheme": "스타일 바꾸기", + "@changeTheme": { + "type": "text", + "placeholders": {} + }, + "changeTheHomeserver": "홈서버 바꾸기", + "@changeTheHomeserver": { + "type": "text", + "placeholders": {} + }, + "changePassword": "비밀번호 바꾸기", + "@changePassword": { + "type": "text", + "placeholders": {} + }, + "changedTheRoomInvitationLink": "{username}이 초대 링크 바꿈", + "@changedTheRoomInvitationLink": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheRoomAliases": "{username}이 방 별명을 바꿈", + "@changedTheRoomAliases": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheProfileAvatar": "{username}이 자신의 아바타를 바꿈", + "@changedTheProfileAvatar": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheJoinRulesTo": "{username}이 참가 규칙을 {joinRules} 로 바꿈", + "@changedTheJoinRulesTo": { + "type": "text", + "placeholders": { + "username": {}, + "joinRules": {} + } + }, + "changedTheJoinRules": "{username}이 참가 규칙을 바꿈", + "@changedTheJoinRules": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheHistoryVisibilityTo": "{username}이 대화 기록 설정을 {rules} 로 바꿈", + "@changedTheHistoryVisibilityTo": { + "type": "text", + "placeholders": { + "username": {}, + "rules": {} + } + }, + "changedTheHistoryVisibility": "{username}이 대화 기록 설정을 변경함", + "@changedTheHistoryVisibility": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheGuestAccessRulesTo": "{username}이 게스트 접근 규칙을 {rules} 로 변경함", + "@changedTheGuestAccessRulesTo": { + "type": "text", + "placeholders": { + "username": {}, + "rules": {} + } + }, + "changedTheGuestAccessRules": "{username}이 게스트 접근 규칙을 변경함", + "@changedTheGuestAccessRules": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheDisplaynameTo": "{username}이 닉네임을 '{displayname}' 으로 바꿈", + "@changedTheDisplaynameTo": { + "type": "text", + "placeholders": { + "username": {}, + "displayname": {} + } + }, + "changedTheChatPermissions": "{username}이 채팅 권한을 바꿈", + "@changedTheChatPermissions": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheChatNameTo": "{username}이 채팅 이름을 '{chatname}' 으로 바꿈", + "@changedTheChatNameTo": { + "type": "text", + "placeholders": { + "username": {}, + "chatname": {} + } + }, + "changedTheChatDescriptionTo": "{username}이 채팅 설명을 '{description}' 으로 변경함", + "@changedTheChatDescriptionTo": { + "type": "text", + "placeholders": { + "username": {}, + "description": {} + } + }, + "changedTheChatAvatar": "{username}이 채팅 아바타 바꿈", + "@changedTheChatAvatar": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changeDeviceName": "기기 이름 바꾸기", + "@changeDeviceName": { + "type": "text", + "placeholders": {} + }, + "cancel": "취소", + "@cancel": { + "type": "text", + "placeholders": {} + }, + "botMessages": "봇 메시지", + "@botMessages": { + "type": "text", + "placeholders": {} + }, + "blocked": "차단됨", + "@blocked": { + "type": "text", + "placeholders": {} + }, + "blockDevice": "기기 차단", + "@blockDevice": { + "type": "text", + "placeholders": {} + }, + "bannedUser": "{username}이 {targetName} 밴함", + "@bannedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "banned": "밴됨", + "@banned": { + "type": "text", + "placeholders": {} + }, + "banFromChat": "채팅에서 밴", + "@banFromChat": { + "type": "text", + "placeholders": {} + }, + "badServerVersionsException": "이 홈서버가 지원하는 Spec 버전:\n{serverVersions}\n하지만 이 앱은 {supportedVersions}만 지원합니다", + "@badServerVersionsException": { + "type": "text", + "placeholders": { + "serverVersions": {}, + "supportedVersions": {} + } + }, + "sendOnEnter": "엔터로 보내기", + "@sendOnEnter": {}, + "badServerLoginTypesException": "홈서버가 지원하는 로그인 유형:\n{serverVersions}\n하지만 이 앱에서 지원하는 것은:\n{supportedVersions}", + "@badServerLoginTypesException": { + "type": "text", + "placeholders": { + "serverVersions": {}, + "supportedVersions": {} + } + }, + "autoplayImages": "자동으로 움직이는 스티커와 이모트 재생", + "@autoplayImages": { + "type": "text", + "placeholder": {} + }, + "askVerificationRequest": "{username}의 인증 요청을 수락할까요?", + "@askVerificationRequest": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "askSSSSSign": "다른 사람을 서명하기 위해서, 저장 비밀번호나 복구 키를 입력해주세요.", + "@askSSSSSign": { + "type": "text", + "placeholders": {} + }, + "areYouSureYouWantToLogout": "로그아웃하고 싶은 것이 확실한가요?", + "@areYouSureYouWantToLogout": { + "type": "text", + "placeholders": {} + }, + "areYouSure": "확실한가요?", + "@areYouSure": { + "type": "text", + "placeholders": {} + }, + "areGuestsAllowedToJoin": "게스트 유저가 참가 여부", + "@areGuestsAllowedToJoin": { + "type": "text", + "placeholders": {} + }, + "archive": "저장", + "@archive": { + "type": "text", + "placeholders": {} + }, + "appLock": "앱 잠금", + "@appLock": { + "type": "text", + "placeholders": {} + }, + "anyoneCanJoin": "누구나 들어올 수 있음", + "@anyoneCanJoin": { + "type": "text", + "placeholders": {} + }, + "answeredTheCall": "{senderName} 가 전화에 응답했습니다", + "@answeredTheCall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "alias": "별명", + "@alias": { + "type": "text", + "placeholders": {} + }, + "admin": "관리자", + "@admin": { + "type": "text", + "placeholders": {} + }, + "addToSpace": "스페이스에 추가", + "@addToSpace": {}, + "addGroupDescription": "그룹 소개 추가", + "@addGroupDescription": { + "type": "text", + "placeholders": {} + }, + "addEmail": "이메일 추가", + "@addEmail": { + "type": "text", + "placeholders": {} + }, + "activatedEndToEndEncryption": "🔐 {username}님이 종단간 암호화를 활성화함", + "@activatedEndToEndEncryption": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "account": "계정", + "@account": { + "type": "text", + "placeholders": {} + }, + "acceptedTheInvitation": "👍 {username}님이 초대를 수락함", + "@acceptedTheInvitation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "ignore": "무시", + "@ignore": { + "type": "text", + "placeholders": {} + }, + "identity": "신원", + "@identity": { + "type": "text", + "placeholders": {} + }, + "id": "ID", + "@id": { + "type": "text", + "placeholders": {} + }, + "howOffensiveIsThisContent": "이 콘텐츠가 얼마나 모욕적인가요?", + "@howOffensiveIsThisContent": { + "type": "text", + "placeholders": {} + }, + "hideUnknownEvents": "알 수 없는 이벤트 숨기기", + "@hideUnknownEvents": { + "type": "text", + "placeholders": {} + }, + "hideRedactedEvents": "지워진 이벤트 숨기기", + "@hideRedactedEvents": { + "type": "text", + "placeholders": {} + }, + "hasWithdrawnTheInvitationFor": "{username}이 {targetName}에 대한 초대를 철회함", + "@hasWithdrawnTheInvitationFor": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "guestsAreForbidden": "게스트는 금지되어 있습니다", + "@guestsAreForbidden": { + "type": "text", + "placeholders": {} + }, + "groupWith": "{displayname} 과의 그룹", + "@groupWith": { + "type": "text", + "placeholders": { + "displayname": {} + } + }, + "errorObtainingLocation": "위치 얻는 중 오류: {error}", + "@errorObtainingLocation": { + "type": "text", + "placeholders": { + "error": {} + } + }, + "editBlockedServers": "차단된 서버 수정", + "@editBlockedServers": { + "type": "text", + "placeholders": {} + }, + "directChats": "다이렉트 채팅", + "@directChats": { + "type": "text", + "placeholders": {} + }, + "dateWithYear": "{year}-{month}-{day}", + "@dateWithYear": { + "type": "text", + "placeholders": { + "year": {}, + "month": {}, + "day": {} + } + }, + "dateWithoutYear": "{month}-{day}", + "@dateWithoutYear": { + "type": "text", + "placeholders": { + "month": {}, + "day": {} + } + }, + "dateAndTimeOfDay": "{date}, {timeOfDay}", + "@dateAndTimeOfDay": { + "type": "text", + "placeholders": { + "date": {}, + "timeOfDay": {} + } + }, + "darkTheme": "다크", + "@darkTheme": { + "type": "text", + "placeholders": {} + }, + "youAreInvitedToThisChat": "당신은 이 채팅에 초대되었습니다", + "@youAreInvitedToThisChat": { + "type": "text", + "placeholders": {} + }, + "yes": "확인", + "@yes": { + "type": "text", + "placeholders": {} + }, + "writeAMessage": "메시지 작성…", + "@writeAMessage": { + "type": "text", + "placeholders": {} + }, + "withTheseAddressesRecoveryDescription": "이 주소로 당신의 비밀번호를 복구할 수 있습니다.", + "@withTheseAddressesRecoveryDescription": { + "type": "text", + "placeholders": {} + }, + "wipeChatBackup": "새로운 보안 키를 생성하기 위해 채팅 백업을 초기화할까요?", + "@wipeChatBackup": { + "type": "text", + "placeholders": {} + }, + "whyDoYouWantToReportThis": "왜 이것을 신고하려고 하나요?", + "@whyDoYouWantToReportThis": { + "type": "text", + "placeholders": {} + }, + "whoIsAllowedToJoinThisGroup": "누가 이 그룹에 들어오도록 허용할지", + "@whoIsAllowedToJoinThisGroup": { + "type": "text", + "placeholders": {} + }, + "whoCanPerformWhichAction": "누가 어떤 행동을 할 수 있는지", + "@whoCanPerformWhichAction": { + "type": "text", + "placeholders": {} + }, + "weSentYouAnEmail": "우리가 당신에게 이메일을 보냈습니다", + "@weSentYouAnEmail": { + "type": "text", + "placeholders": {} + }, + "warning": "경고!", + "@warning": { + "type": "text", + "placeholders": {} + }, + "wallpaper": "배경", + "@wallpaper": { + "type": "text", + "placeholders": {} + }, + "waitingPartnerNumbers": "상대가 숫자를 수락하길 기다리는 중…", + "@waitingPartnerNumbers": { + "type": "text", + "placeholders": {} + }, + "waitingPartnerEmoji": "상대가 이모지를 수락하길 기다리는 중…", + "@waitingPartnerEmoji": { + "type": "text", + "placeholders": {} + }, + "waitingPartnerAcceptRequest": "상대가 요청을 수락하길 기다리는 중…", + "@waitingPartnerAcceptRequest": { + "type": "text", + "placeholders": {} + }, + "voiceMessage": "음성 메시지", + "@voiceMessage": { + "type": "text", + "placeholders": {} + }, + "visibleForEveryone": "모두에게 보임", + "@visibleForEveryone": { + "type": "text", + "placeholders": {} + }, + "visibleForAllParticipants": "모든 참가자에게 보임", + "@visibleForAllParticipants": { + "type": "text", + "placeholders": {} + }, + "videoCall": "영상 통화", + "@videoCall": { + "type": "text", + "placeholders": {} + }, + "verifyTitle": "다른 계정 확인 중", + "@verifyTitle": { + "type": "text", + "placeholders": {} + }, + "verifySuccess": "성공적으로 확인했어요!", + "@verifySuccess": { + "type": "text", + "placeholders": {} + }, + "verifyStart": "확인 시작", + "@verifyStart": { + "type": "text", + "placeholders": {} + }, + "verify": "확인", + "@verify": { + "type": "text", + "placeholders": {} + }, + "verified": "확인됨", + "@verified": { + "type": "text", + "placeholders": {} + }, + "username": "유저 이름", + "@username": { + "type": "text", + "placeholders": {} + }, + "userLeftTheChat": "{username}이 채팅을 나감", + "@userLeftTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "userIsTyping": "{username}이 입력 중…", + "@userIsTyping": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "userAndUserAreTyping": "{username}과 {username2}가 입력 중…", + "@userAndUserAreTyping": { + "type": "text", + "placeholders": { + "username": {}, + "username2": {} + } + }, + "userAndOthersAreTyping": "{username}과 {count}명이 입력 중…", + "@userAndOthersAreTyping": { + "type": "text", + "placeholders": { + "username": {}, + "count": {} + } + }, + "unpin": "고정 해제", + "@unpin": { + "type": "text", + "placeholders": {} + }, + "unknownEncryptionAlgorithm": "알 수 없는 암호화 알고리즘", + "@unknownEncryptionAlgorithm": { + "type": "text", + "placeholders": {} + }, + "unblockDevice": "기기 차단 해제", + "@unblockDevice": { + "type": "text", + "placeholders": {} + }, + "pin": "고정", + "@pin": { + "type": "text", + "placeholders": {} + }, + "pickImage": "이미지 고르기", + "@pickImage": { + "type": "text", + "placeholders": {} + }, + "passwordRecovery": "비밀번호 복구", + "@passwordRecovery": { + "type": "text", + "placeholders": {} + }, + "passwordForgotten": "비밀번호 까먹음", + "@passwordForgotten": { + "type": "text", + "placeholders": {} + }, + "password": "비밀번호", + "@password": { + "type": "text", + "placeholders": {} + }, + "participant": "참여자", + "@participant": { + "type": "text", + "placeholders": {} + }, + "optionalGroupName": "(선택) 그룹 이름", + "@optionalGroupName": { + "type": "text", + "placeholders": {} + }, + "openInMaps": "지도에서 열기", + "@openInMaps": { + "type": "text", + "placeholders": {} + }, + "addAccount": "계정 추가", + "@addAccount": {}, + "openCamera": "카메라 열기", + "@openCamera": { + "type": "text", + "placeholders": {} + }, + "openAppToReadMessages": "앱을 열어서 메시지를 읽으세요", + "@openAppToReadMessages": { + "type": "text", + "placeholders": {} + }, + "oopsSomethingWentWrong": "앗, 무언가가 잘못되었습니다…", + "@oopsSomethingWentWrong": { + "type": "text", + "placeholders": {} + }, + "oopsPushError": "앗! 안타깝게도, 푸시 알림을 설정하는 중 오류가 발생했습니다.", + "@oopsPushError": { + "type": "text", + "placeholders": {} + }, + "online": "온라인", + "@online": { + "type": "text", + "placeholders": {} + }, + "ok": "확인", + "@ok": { + "type": "text", + "placeholders": {} + }, + "offline": "오프라인", + "@offline": { + "type": "text", + "placeholders": {} + }, + "offensive": "모욕적임", + "@offensive": { + "type": "text", + "placeholders": {} + }, + "obtainingLocation": "위치 얻는 중…", + "@obtainingLocation": { + "type": "text", + "placeholders": {} + }, + "numUsersTyping": "{count}명이 입력 중…", + "@numUsersTyping": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "notificationsEnabledForThisAccount": "이 계정에서 알림이 활성화되었습니다", + "@notificationsEnabledForThisAccount": { + "type": "text", + "placeholders": {} + }, + "notifications": "알림", + "@notifications": { + "type": "text", + "placeholders": {} + }, + "noPermission": "권한 없음", + "@noPermission": { + "type": "text", + "placeholders": {} + }, + "scanQrCode": "QR 코드 스캔", + "@scanQrCode": {}, + "shareYourInviteLink": "당신의 초대 링크 공유", + "@shareYourInviteLink": {}, + "noMatrixServer": "{server1}은 matrix 서버가 아닙니다, {server2}를 대신 사용할까요?", + "@noMatrixServer": { + "type": "text", + "placeholders": { + "server1": {}, + "server2": {} + } + }, + "next": "다음", + "@next": { + "type": "text", + "placeholders": {} + }, + "loginWith": "{brand} 로 로그인", + "@loginWith": { + "type": "text", + "placeholders": { + "brand": {} + } + }, + "logInTo": "{homeserver} 에 로그인", + "@logInTo": { + "type": "text", + "placeholders": { + "homeserver": {} + } + }, + "login": "로그인", + "@login": { + "type": "text", + "placeholders": {} + }, + "locationPermissionDeniedNotice": "위치 권한이 거부되었습니다. 위치를 공유하기 위해서 허용해주세요.", + "@locationPermissionDeniedNotice": { + "type": "text", + "placeholders": {} + }, + "locationDisabledNotice": "위치 서비스가 비활성화되었습니다. 위치를 공유하려면 활성화시켜주세요.", + "@locationDisabledNotice": { + "type": "text", + "placeholders": {} + }, + "no": "아니요", + "@no": { + "type": "text", + "placeholders": {} + }, + "newVerificationRequest": "새로운 확인 요청!", + "@newVerificationRequest": { + "type": "text", + "placeholders": {} + }, + "newMessageInFluffyChat": "FluffyChat에서 새로운 메시지", + "@newMessageInFluffyChat": { + "type": "text", + "placeholders": {} + }, + "newChat": "새로운 채팅", + "@newChat": { + "type": "text", + "placeholders": {} + }, + "muteChat": "채팅 음소거", + "@muteChat": { + "type": "text", + "placeholders": {} + }, + "messageWillBeRemovedWarning": "모든 참여자에게서 메시지가 지워집니다", + "@messageWillBeRemovedWarning": { + "type": "text", + "placeholders": {} + }, + "messages": "메시지", + "@messages": { + "type": "text", + "placeholders": {} + }, + "mention": "멘션", + "@mention": { + "type": "text", + "placeholders": {} + }, + "logout": "로그아웃", + "@logout": { + "type": "text", + "placeholders": {} + }, + "unreadChats": "{unreadCount, plural, =1{읽지 않은 채팅 1} other{{unreadCount} 개}}", + "@unreadChats": { + "type": "text", + "placeholders": { + "unreadCount": {} + } + }, + "renderRichContent": "풍부한 메시지 콘텐츠 렌더링", + "@renderRichContent": { + "type": "text", + "placeholders": {} + }, + "unavailable": "사용할 수 없음", + "@unavailable": { + "type": "text", + "placeholders": {} + }, + "makeSureTheIdentifierIsValid": "식별자가 유효한지 확인하세요", + "@makeSureTheIdentifierIsValid": { + "type": "text", + "placeholders": {} + }, + "all": "모두", + "@all": { + "type": "text", + "placeholders": {} + }, + "yourPublicKey": "당신의 공개 키", + "@yourPublicKey": { + "type": "text", + "placeholders": {} + }, + "youHaveBeenBannedFromThisChat": "당신은 이 채팅에서 밴되었습니다", + "@youHaveBeenBannedFromThisChat": { + "type": "text", + "placeholders": {} + }, + "youCannotInviteYourself": "자신을 초대할 수 없습니다", + "@youCannotInviteYourself": { + "type": "text", + "placeholders": {} + }, + "youAreNoLongerParticipatingInThisChat": "당신은 더 이상 이 채팅에 참여하지 않습니다", + "@youAreNoLongerParticipatingInThisChat": { + "type": "text", + "placeholders": {} + }, + "you": "당신", + "@you": { + "type": "text", + "placeholders": {} + }, + "visibilityOfTheChatHistory": "대화 기록 설정", + "@visibilityOfTheChatHistory": { + "type": "text", + "placeholders": {} + }, + "userSentUnknownEvent": "{username}이 {type} 이벤트 보냄", + "@userSentUnknownEvent": { + "type": "text", + "placeholders": { + "username": {}, + "type": {} + } + }, + "unmuteChat": "음소거 해제", + "@unmuteChat": { + "type": "text", + "placeholders": {} + }, + "unknownEvent": "알 수 없는 이벤트 '{type}'", + "@unknownEvent": { + "type": "text", + "placeholders": { + "type": {} + } + }, + "unknownDevice": "알 수 없는 기기", + "@unknownDevice": { + "type": "text", + "placeholders": {} + }, + "unbannedUser": "{username}이 {targetName} 밴 해제함", + "@unbannedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "tryToSendAgain": "다시 보내도록 시도", + "@tryToSendAgain": { + "type": "text", + "placeholders": {} + }, + "transferFromAnotherDevice": "다른 기기에서 가져오기", + "@transferFromAnotherDevice": { + "type": "text", + "placeholders": {} + }, + "tooManyRequestsWarning": "너무 많은 요청. 잠시 후에 다시 시도해주세요!", + "@tooManyRequestsWarning": { + "type": "text", + "placeholders": {} + }, + "toggleUnread": "메시지 안/읽음 으로 표시", + "@toggleUnread": { + "type": "text", + "placeholders": {} + }, + "toggleMuted": "음소거 토글", + "@toggleMuted": { + "type": "text", + "placeholders": {} + }, + "toggleFavorite": "즐겨찾기 토글", + "@toggleFavorite": { + "type": "text", + "placeholders": {} + }, + "title": "FluffyChat", + "@title": { + "description": "Title for the application", + "type": "text", + "placeholders": {} + }, + "theyMatch": "일치합니다", + "@theyMatch": { + "type": "text", + "placeholders": {} + }, + "theyDontMatch": "일치하지 않습니다", + "@theyDontMatch": { + "type": "text", + "placeholders": {} + }, + "systemTheme": "시스템", + "@systemTheme": { + "type": "text", + "placeholders": {} + }, + "synchronizingPleaseWait": "동기화 중... 기다려주세요.", + "@synchronizingPleaseWait": { + "type": "text", + "placeholders": {} + }, + "submit": "제출", + "@submit": { + "type": "text", + "placeholders": {} + }, + "statusExampleMessage": "오늘은 어떤 기분인가요?", + "@statusExampleMessage": { + "type": "text", + "placeholders": {} + }, + "status": "상태", + "@status": { + "type": "text", + "placeholders": {} + }, + "startedACall": "{senderName} 가 통화 시작함", + "@startedACall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "spaceName": "스페이스 이름", + "@spaceName": { + "type": "text", + "placeholders": {} + }, + "spaceIsPublic": "스페이스가 공개됨", + "@spaceIsPublic": { + "type": "text", + "placeholders": {} + }, + "singlesignon": "단일 계정 로그인(SSO)", + "@singlesignon": { + "type": "text", + "placeholders": {} + }, + "seenByUserAndCountOthers": "{count, plural, other{{username}과 이외 {count}명이 읽음}}", + "@seenByUserAndCountOthers": { + "type": "text", + "placeholders": { + "username": {}, + "count": {} + } + }, + "pushRules": "푸시 규칙", + "@pushRules": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterAMatrixIdentifier": "Matrix ID를 입력해주세요.", + "@pleaseEnterAMatrixIdentifier": { + "type": "text", + "placeholders": {} + }, + "lastActiveAgo": "마지막 활동: {localizedTimeShort}", + "@lastActiveAgo": { + "type": "text", + "placeholders": { + "localizedTimeShort": {} + } + }, + "ignoredUsers": "무시된 사용자", + "@ignoredUsers": { + "type": "text", + "placeholders": {} + }, + "pleaseEnter4Digits": "4자리 숫자를 입력하거나 앱 잠금을 사용하지 않도록 하려면 비워두세요.", + "@pleaseEnter4Digits": { + "type": "text", + "placeholders": {} + }, + "pleaseChooseAPasscode": "비밀번호를 골라주세요", + "@pleaseChooseAPasscode": { + "type": "text", + "placeholders": {} + }, + "pleaseChoose": "선택해주세요", + "@pleaseChoose": { + "type": "text", + "placeholders": {} + }, + "play": "{fileName} 재생", + "@play": { + "type": "text", + "placeholders": { + "fileName": {} + } + }, + "people": "사람들", + "@people": { + "type": "text", + "placeholders": {} + }, + "passwordHasBeenChanged": "비밀번호가 변경됨", + "@passwordHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "passphraseOrKey": "비밀번호나 복구 키", + "@passphraseOrKey": { + "type": "text", + "placeholders": {} + }, + "or": "이나", + "@or": { + "type": "text", + "placeholders": {} + }, + "serverRequiresEmail": "이 서버는 가입을 위해 당신의 이메일을 확인해야 합니다.", + "@serverRequiresEmail": {}, + "enableMultiAccounts": "(베타) 이 기기에서 다중 계정 활성화", + "@enableMultiAccounts": {}, + "bundleName": "번들 이름", + "@bundleName": {}, + "removeFromBundle": "이 번들에서 삭제", + "@removeFromBundle": {}, + "addToBundle": "번들에 추가", + "@addToBundle": {}, + "editBundlesForAccount": "이 계정의 번들 수정", + "@editBundlesForAccount": {}, + "oneClientLoggedOut": "당신의 클라이언트 중 하나가 로그아웃 됨", + "@oneClientLoggedOut": {}, + "onlineKeyBackupEnabled": "온라인 키 백업이 활성화됨", + "@onlineKeyBackupEnabled": { + "type": "text", + "placeholders": {} + }, + "noRoomsFound": "아무 방도 발견되지 않았어요…", + "@noRoomsFound": { + "type": "text", + "placeholders": {} + }, + "noPasswordRecoveryDescription": "당신은 비밀번호를 복구할 방법을 추가하지 않았습니다.", + "@noPasswordRecoveryDescription": { + "type": "text", + "placeholders": {} + }, + "none": "없음", + "@none": { + "type": "text", + "placeholders": {} + }, + "noGoogleServicesWarning": "이 휴대폰에 Google 서비스가 없는 것 같습니다. 프라이버시를 위해 좋은 결정이죠! FluffyChat에서 푸시 알림을 받으려면 https://microg.org/ 이나 https://unifiedpush.org/ 을 사용하는 것을 권장합니다.", + "@noGoogleServicesWarning": { + "type": "text", + "placeholders": {} + }, + "noEncryptionForPublicRooms": "당신은 방이 공개적으로 접근 가능하지 않을 때만 암호화를 켤 수 있습니다.", + "@noEncryptionForPublicRooms": { + "type": "text", + "placeholders": {} + }, + "noEmotesFound": "이모트 발견되지 않음. 😕", + "@noEmotesFound": { + "type": "text", + "placeholders": {} + }, + "noConnectionToTheServer": "서버에 연결 없음", + "@noConnectionToTheServer": { + "type": "text", + "placeholders": {} + }, + "needPantalaimonWarning": "지금 종단간 암호화를 사용하기 위해서는 Pantalaimon이 필요하다는 것을 알아주세요.", + "@needPantalaimonWarning": { + "type": "text", + "placeholders": {} + }, + "moderator": "관리자", + "@moderator": { + "type": "text", + "placeholders": {} + }, + "memberChanges": "참가자 변경", + "@memberChanges": { + "type": "text", + "placeholders": {} + }, + "loadingPleaseWait": "로딩 중... 기다려 주세요.", + "@loadingPleaseWait": { + "type": "text", + "placeholders": {} + }, + "leftTheChat": "채팅을 나갔습니다", + "@leftTheChat": { + "type": "text", + "placeholders": {} + }, + "leave": "나가기", + "@leave": { + "type": "text", + "placeholders": {} + }, + "lastSeenLongTimeAgo": "오래 전 접속", + "@lastSeenLongTimeAgo": { + "type": "text", + "placeholders": {} + }, + "sourceCode": "소스 코드", + "@sourceCode": { + "type": "text", + "placeholders": {} + }, + "skip": "스킵", + "@skip": { + "type": "text", + "placeholders": {} + }, + "signUp": "가입", + "@signUp": { + "type": "text", + "placeholders": {} + }, + "showPassword": "비밀번호 보이기", + "@showPassword": { + "type": "text", + "placeholders": {} + }, + "shareLocation": "위치 보내기", + "@shareLocation": { + "type": "text", + "placeholders": {} + }, + "sharedTheLocation": "{username}이 위치 공유함", + "@sharedTheLocation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "share": "공유", + "@share": { + "type": "text", + "placeholders": {} + }, + "settings": "설정", + "@settings": { + "type": "text", + "placeholders": {} + }, + "setStatus": "상태 설정", + "@setStatus": { + "type": "text", + "placeholders": {} + }, + "setPermissionsLevel": "권한 레벨 설정", + "@setPermissionsLevel": { + "type": "text", + "placeholders": {} + }, + "setInvitationLink": "초대 링크 설정", + "@setInvitationLink": { + "type": "text", + "placeholders": {} + }, + "setGroupDescription": "그룹 설명 설정", + "@setGroupDescription": { + "type": "text", + "placeholders": {} + }, + "setCustomEmotes": "맞춤 이모트 설정", + "@setCustomEmotes": { + "type": "text", + "placeholders": {} + }, + "setAsCanonicalAlias": "주 별명으로 설정", + "@setAsCanonicalAlias": { + "type": "text", + "placeholders": {} + }, + "sentCallInformations": "{senderName} 이 통화 정보 보냄", + "@sentCallInformations": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "sentAVideo": "{username}이 영상 보냄", + "@sentAVideo": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sendOriginal": "원본 보내기", + "@sendOriginal": { + "type": "text", + "placeholders": {} + }, + "sendMessages": "메시지 보내기", + "@sendMessages": { + "type": "text", + "placeholders": {} + }, + "sendImage": "이미지 보내기", + "@sendImage": { + "type": "text", + "placeholders": {} + }, + "sendFile": "파일 보내기", + "@sendFile": { + "type": "text", + "placeholders": {} + }, + "sendAudio": "오디오 보내기", + "@sendAudio": { + "type": "text", + "placeholders": {} + }, + "sendAsText": "텍스트로 보내기", + "@sendAsText": { + "type": "text" + }, + "sendAMessage": "메시지 보내기", + "@sendAMessage": { + "type": "text", + "placeholders": {} + }, + "send": "보내기", + "@send": { + "type": "text", + "placeholders": {} + }, + "seenByUserAndUser": "{username}, {username2}가 읽음", + "@seenByUserAndUser": { + "type": "text", + "placeholders": { + "username": {}, + "username2": {} + } + }, + "seenByUser": "{username}이 읽음", + "@seenByUser": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "security": "보안", + "@security": { + "type": "text", + "placeholders": {} + }, + "search": "검색", + "@search": { + "type": "text", + "placeholders": {} + }, + "saveFile": "파일 저장", + "@saveFile": { + "type": "text", + "placeholders": {} + }, + "roomVersion": "방 버전", + "@roomVersion": { + "type": "text", + "placeholders": {} + }, + "roomHasBeenUpgraded": "방이 업그레이드되었습니다", + "@roomHasBeenUpgraded": { + "type": "text", + "placeholders": {} + }, + "requestPermission": "권한 요청", + "@requestPermission": { + "type": "text", + "placeholders": {} + }, + "reason": "이유", + "@reason": { + "type": "text", + "placeholders": {} + }, + "publicRooms": "공개 방", + "@publicRooms": { + "type": "text", + "placeholders": {} + }, + "privacy": "프라이버시", + "@privacy": { + "type": "text", + "placeholders": {} + }, + "pleaseFollowInstructionsOnWeb": "웹사이트의 가이드를 따르고 다음 버튼을 눌러주세요.", + "@pleaseFollowInstructionsOnWeb": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourUsername": "유저 이름을 입력해주세요", + "@pleaseEnterYourUsername": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourPin": "PIN을 입력해주세요", + "@pleaseEnterYourPin": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourPassword": "비밀번호를 입력해주세요", + "@pleaseEnterYourPassword": { + "type": "text", + "placeholders": {} + }, + "joinRoom": "방 들어가기", + "@joinRoom": { + "type": "text", + "placeholders": {} + }, + "joinedTheChat": "👋 {username}님이 채팅에 참가함", + "@joinedTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "isTyping": "가 입력 중…", + "@isTyping": { + "type": "text", + "placeholders": {} + }, + "inviteText": "{username}이 당신을 FluffyChat에 초대했습니다.\n1. FluffyChat 설치: https://fluffychat.im\n2. 가입하거나 로그인\n3. 초대 링크 열기: {link}", + "@inviteText": { + "type": "text", + "placeholders": { + "username": {}, + "link": {} + } + }, + "inviteForMe": "나를 위해 초대", + "@inviteForMe": { + "type": "text", + "placeholders": {} + }, + "invitedUsersOnly": "초대한 사용자만", + "@invitedUsersOnly": { + "type": "text", + "placeholders": {} + }, + "invitedUser": "📩 {username}님이 {targetName}님을 초대함", + "@invitedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "invited": "초대됨", + "@invited": { + "type": "text", + "placeholders": {} + }, + "inviteContactToGroup": "연락처 {groupName} 에 초대", + "@inviteContactToGroup": { + "type": "text", + "placeholders": { + "groupName": {} + } + }, + "inviteContact": "연락처 초대", + "@inviteContact": { + "type": "text", + "placeholders": {} + }, + "inoffensive": "모욕적이지 않음", + "@inoffensive": { + "type": "text", + "placeholders": {} + }, + "incorrectPassphraseOrKey": "올바르지 않은 복구 키나 비밀번호", + "@incorrectPassphraseOrKey": { + "type": "text", + "placeholders": {} + }, + "iHaveClickedOnLink": "링크를 클릭했어요", + "@iHaveClickedOnLink": { + "type": "text", + "placeholders": {} + }, + "ignoreUsername": "유저 이름 무시", + "@ignoreUsername": { + "type": "text", + "placeholders": {} + }, + "ignoreListDescription": "당신을 방해하는 사용자들을 무시할 수 있습니다. 당신의 개인 무시 리스트에 있는 사용자들에게서 메시지나 방 초대를 수신할 수 없습니다.", + "@ignoreListDescription": { + "type": "text", + "placeholders": {} + }, + "sentASticker": "{username}이 스티커 보냄", + "@sentASticker": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sentAPicture": "{username}이 사진 보냄", + "@sentAPicture": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sentAnAudio": "{username}이 오디오 보냄", + "@sentAnAudio": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sentAFile": "{username}이 파일 보냄", + "@sentAFile": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sendVideo": "영상 보내기", + "@sendVideo": { + "type": "text", + "placeholders": {} + }, + "sendSticker": "스티커 보내기", + "@sendSticker": { + "type": "text", + "placeholders": {} + }, + "reportMessage": "메시지 신고", + "@reportMessage": { + "type": "text", + "placeholders": {} + }, + "reply": "답장", + "@reply": { + "type": "text", + "placeholders": {} + }, + "replaceRoomWithNewerVersion": "방 새로운 버전으로 대체하기", + "@replaceRoomWithNewerVersion": { + "type": "text", + "placeholders": {} + }, + "removeYourAvatar": "아바타 지우기", + "@removeYourAvatar": { + "type": "text", + "placeholders": {} + }, + "unbanFromChat": "채팅에서 밴 해제", + "@unbanFromChat": { + "type": "text", + "placeholders": {} + }, + "removeDevice": "기기 삭제", + "@removeDevice": { + "type": "text", + "placeholders": {} + }, + "removedBy": "{username}에 의해 지워짐", + "@removedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "removeAllOtherDevices": "모든 다른 기기에서 지우기", + "@removeAllOtherDevices": { + "type": "text", + "placeholders": {} + }, + "remove": "지우기", + "@remove": { + "type": "text", + "placeholders": {} + }, + "rejoin": "다시 가입", + "@rejoin": { + "type": "text", + "placeholders": {} + }, + "rejectedTheInvitation": "{username}이 초대를 거절함", + "@rejectedTheInvitation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "reject": "거절", + "@reject": { + "type": "text", + "placeholders": {} + }, + "register": "가입", + "@register": { + "type": "text", + "placeholders": {} + }, + "redactMessage": "메시지 지우기", + "@redactMessage": { + "type": "text", + "placeholders": {} + }, + "redactedAnEvent": "{username}이 이벤트를 지움", + "@redactedAnEvent": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "recording": "녹음", + "@recording": { + "type": "text", + "placeholders": {} + }, + "pleaseClickOnLink": "이메일의 링크를 클릭하고 진행해주세요.", + "@pleaseClickOnLink": { + "type": "text", + "placeholders": {} + }, + "pleaseChooseAUsername": "유저 이름을 골라주세요", + "@pleaseChooseAUsername": { + "type": "text", + "placeholders": {} + }, + "kickFromChat": "채팅에서 추방", + "@kickFromChat": { + "type": "text", + "placeholders": {} + }, + "kickedAndBanned": "🙅 {username}님이 {targetName}님을 추방하고 차단함", + "@kickedAndBanned": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "kicked": "👞 {username}님이 {targetName}님을 추방함", + "@kicked": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "link": "링크", + "@link": {}, + "unverified": "확인되지 않음", + "@unverified": {}, + "yourChatBackupHasBeenSetUp": "당신의 채팅 백업이 설정되었습니다.", + "@yourChatBackupHasBeenSetUp": {}, + "time": "시간", + "@time": {}, + "messageType": "메시지 유형", + "@messageType": {}, + "openGallery": "갤러리 열기", + "@openGallery": {}, + "sender": "발신자", + "@sender": {}, + "passwordsDoNotMatch": "비밀번호가 일치하지 않습니다!", + "@passwordsDoNotMatch": {}, + "pleaseChooseAtLeastChars": "최소 {min}자를 선택하세요.", + "@pleaseChooseAtLeastChars": { + "type": "text", + "placeholders": { + "min": {} + } + }, + "messageInfo": "메시지 정보", + "@messageInfo": {}, + "pleaseEnterValidEmail": "유효한 이메일 주소를 입력해주세요.", + "@pleaseEnterValidEmail": {}, + "repeatPassword": "비밀번호 다시 입력", + "@repeatPassword": {}, + "loginWithOneClick": "클릭 한 번으로 로그인", + "@loginWithOneClick": {}, + "start": "시작", + "@start": {}, + "removeFromSpace": "스페이스에서 삭제", + "@removeFromSpace": {}, + "addToSpaceDescription": "이 채팅을 추가할 스페이스를 선택하세요.", + "@addToSpaceDescription": {}, + "commandHint_discardsession": "세션 삭제", + "@commandHint_discardsession": { + "type": "text", + "description": "Usage hint for the command /discardsession" + }, + "commandHint_dm": "다이렉트 채팅 시작\t\n--no-encryption을 사용해 암호화 비활성화", + "@commandHint_dm": { + "type": "text", + "description": "Usage hint for the command /dm" + }, + "commandHint_clearcache": "캐시 지우기", + "@commandHint_clearcache": { + "type": "text", + "description": "Usage hint for the command /clearcache" + }, + "commandHint_create": "빈 그룹 채팅을 생성\t\n--no-encryption을 사용해 암호화를 비활성화", + "@commandHint_create": { + "type": "text", + "description": "Usage hint for the command /create" + }, + "openVideoCamera": "영상용 카메라 열기", + "@openVideoCamera": { + "type": "text", + "placeholders": {} + }, + "addToStory": "스토리에 추가", + "@addToStory": {}, + "publish": "공개", + "@publish": {}, + "yourStory": "내 스토리", + "@yourStory": {}, + "replyHasBeenSent": "답장을 보냈습니다", + "@replyHasBeenSent": {}, + "videoWithSize": "영상 ({size})", + "@videoWithSize": { + "type": "text", + "placeholders": { + "size": {} + } + }, + "storyFrom": "{date}의 스토리:\n{body}", + "@storyFrom": { + "type": "text", + "placeholders": { + "date": {}, + "body": {} + } + }, + "whoCanSeeMyStoriesDesc": "스토리에서 사람들이 서로를 보고 연락할 수 있다는 점에 유의하십시오.", + "@whoCanSeeMyStoriesDesc": {}, + "whatIsGoingOn": "무슨 일이 일어나고 있나요?", + "@whatIsGoingOn": {}, + "addDescription": "설명 추가", + "@addDescription": {}, + "whoCanSeeMyStories": "누가 내 스토리를 볼 수 있나요?", + "@whoCanSeeMyStories": {}, + "unsubscribeStories": "스토리 구독 해제", + "@unsubscribeStories": {}, + "thisUserHasNotPostedAnythingYet": "이 유저는 스토리에 아무것도 올리지 않았습니다", + "@thisUserHasNotPostedAnythingYet": {}, + "bubbleSize": "버블 크기", + "@bubbleSize": { + "type": "text", + "placeholders": {} + }, + "dismiss": "닫기", + "@dismiss": {}, + "matrixWidgets": "Matrix 위젯", + "@matrixWidgets": {}, + "markAsRead": "읽음으로 표시하기", + "@markAsRead": {}, + "reportUser": "사용자 신고", + "@reportUser": {}, + "openChat": "채팅 열기", + "@openChat": {}, + "storyPrivacyWarning": "사람들이 서로를 보고 연락할 수 있다는 점에 유의해주세요. 스토리는 24시간 동안 보이지만 모든 기기와 서버에서 삭제된다는 보장은 없습니다.", + "@storyPrivacyWarning": {}, + "iUnderstand": "동의합니다", + "@iUnderstand": {}, + "reactedWith": "{sender}가 {reaction}로 반응함", + "@reactedWith": { + "type": "text", + "placeholders": { + "sender": {}, + "reaction": {} + } + }, + "confirmEventUnpin": "이벤트를 영구적으로 고정 해제할 것이 확실한가요?", + "@confirmEventUnpin": {}, + "pinMessage": "방에 고정", + "@pinMessage": {}, + "emojis": "이모지", + "@emojis": {}, + "voiceCall": "음성 통화", + "@voiceCall": {}, + "placeCall": "전화 걸기", + "@placeCall": {}, + "experimentalVideoCalls": "실험적인 영상 통화", + "@experimentalVideoCalls": {}, + "unsupportedAndroidVersion": "지원되지 않는 안드로이드 버전", + "@unsupportedAndroidVersion": {}, + "unsupportedAndroidVersionLong": "이 기능은 새로운 안드로이드 버전을 요구합니다. Lineage OS 지원이나 업데이트를 확인해주세요.", + "@unsupportedAndroidVersionLong": {}, + "videoCallsBetaWarning": "영상 통화는 베타임을 확인해주세요. 의도한 대로 작동하지 않거나 모든 플랫폼에서 작동하지 않을 수 있습니다.", + "@videoCallsBetaWarning": {}, + "emailOrUsername": "이메일이나 유저 이름", + "@emailOrUsername": {}, + "updateAvailable": "FluffyChat 업데이트 이용가능", + "@updateAvailable": {}, + "updateNow": "백그라운드에서 업데이트 시작", + "@updateNow": {}, + "confirmMatrixId": "계정을 삭제하려면 Matrix ID를 확인해 주세요.", + "@confirmMatrixId": {}, + "commandHint_googly": "왕눈이 눈알 보내기", + "@commandHint_googly": {}, + "googlyEyesContent": "{senderName} 님이 왕눈이 눈알을 보냈습니다", + "@googlyEyesContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "commandHint_markasgroup": "", + "@commandHint_markasgroup": {}, + "dehydrate": "세션을 내보내고 기기 초기화 하기", + "@dehydrate": {}, + "dehydrateWarning": "이 동작은 되돌릴 수 없습니다. 백업 파일을 꼭 안전하게 보관하세요.", + "@dehydrateWarning": {}, + "discover": "", + "@discover": { + "type": "text", + "placeholders": {} + }, + "hugContent": "", + "@hugContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "jumpToLastReadMessage": "", + "@jumpToLastReadMessage": {}, + "allRooms": "", + "@allRooms": { + "type": "text", + "placeholders": {} + }, + "commandHint_cuddle": "", + "@commandHint_cuddle": {}, + "widgetVideo": "", + "@widgetVideo": {}, + "reportErrorDescription": "", + "@reportErrorDescription": {}, + "widgetJitsi": "", + "@widgetJitsi": {}, + "noEmailWarning": "", + "@noEmailWarning": {}, + "indexedDbErrorLong": "", + "@indexedDbErrorLong": {}, + "startFirstChat": "", + "@startFirstChat": {}, + "callingAccount": "", + "@callingAccount": {}, + "setColorTheme": "", + "@setColorTheme": {}, + "nextAccount": "", + "@nextAccount": {}, + "allSpaces": "", + "@allSpaces": {}, + "supposedMxid": "", + "@supposedMxid": { + "type": "text", + "placeholders": { + "mxid": {} + } + }, + "user": "", + "@user": {}, + "youAcceptedTheInvitation": "", + "@youAcceptedTheInvitation": {}, + "youInvitedBy": "", + "@youInvitedBy": { + "placeholders": { + "user": {} + } + }, + "banUserDescription": "", + "@banUserDescription": {}, + "requests": "", + "@requests": {}, + "widgetEtherpad": "", + "@widgetEtherpad": {}, + "stories": "", + "@stories": {}, + "removeDevicesDescription": "", + "@removeDevicesDescription": {}, + "separateChatTypes": "", + "@separateChatTypes": { + "type": "text", + "placeholders": {} + }, + "tryAgain": "", + "@tryAgain": {}, + "youKickedAndBanned": "", + "@youKickedAndBanned": { + "placeholders": { + "user": {} + } + }, + "showDirectChatsInSpaces": "", + "@showDirectChatsInSpaces": { + "type": "text", + "placeholders": {} + }, + "unbanUserDescription": "", + "@unbanUserDescription": {}, + "todoLists": "", + "@todoLists": {}, + "youRejectedTheInvitation": "", + "@youRejectedTheInvitation": {}, + "otherCallingPermissions": "", + "@otherCallingPermissions": {}, + "messagesStyle": "", + "@messagesStyle": {}, + "widgetUrlError": "", + "@widgetUrlError": {}, + "newSpaceDescription": "", + "@newSpaceDescription": {}, + "chatDescription": "", + "@chatDescription": {}, + "callingAccountDetails": "", + "@callingAccountDetails": {}, + "enterSpace": "", + "@enterSpace": {}, + "encryptThisChat": "", + "@encryptThisChat": {}, + "previousAccount": "", + "@previousAccount": {}, + "reopenChat": "", + "@reopenChat": {}, + "pleaseEnterRecoveryKey": "", + "@pleaseEnterRecoveryKey": {}, + "widgetNameError": "", + "@widgetNameError": {}, + "addWidget": "", + "@addWidget": {}, + "countFiles": "", + "@countFiles": { + "placeholders": { + "count": {} + } + }, + "noKeyForThisMessage": "", + "@noKeyForThisMessage": {}, + "editTodo": "", + "@editTodo": {}, + "hydrateTor": "", + "@hydrateTor": {}, + "pushNotificationsNotAvailable": "", + "@pushNotificationsNotAvailable": {}, + "storeInAppleKeyChain": "", + "@storeInAppleKeyChain": {}, + "hydrate": "", + "@hydrate": {}, + "invalidServerName": "", + "@invalidServerName": {}, + "chatPermissions": "", + "@chatPermissions": {}, + "storeInAndroidKeystore": "", + "@storeInAndroidKeystore": {}, + "signInWithPassword": "", + "@signInWithPassword": {}, + "pleaseAddATitle": "", + "@pleaseAddATitle": {}, + "makeAdminDescription": "", + "@makeAdminDescription": {}, + "saveKeyManuallyDescription": "", + "@saveKeyManuallyDescription": {}, + "whyIsThisMessageEncrypted": "", + "@whyIsThisMessageEncrypted": {}, + "setChatDescription": "", + "@setChatDescription": {}, + "importFromZipFile": "", + "@importFromZipFile": {}, + "noOtherDevicesFound": "", + "@noOtherDevicesFound": {}, + "redactedBy": "", + "@redactedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "signInWith": "", + "@signInWith": { + "type": "text", + "placeholders": { + "provider": {} + } + }, + "fileIsTooBigForServer": "", + "@fileIsTooBigForServer": {}, + "noTodosYet": "", + "@noTodosYet": {}, + "callingPermissions": "", + "@callingPermissions": {}, + "readUpToHere": "", + "@readUpToHere": {}, + "unlockOldMessages": "", + "@unlockOldMessages": {}, + "numChats": "", + "@numChats": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "optionalRedactReason": "", + "@optionalRedactReason": {}, + "archiveRoomDescription": "", + "@archiveRoomDescription": {}, + "exportEmotePack": "", + "@exportEmotePack": {}, + "switchToAccount": "", + "@switchToAccount": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "letsStart": "", + "@letsStart": {}, + "savedEmotePack": "", + "@savedEmotePack": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "pleaseEnterRecoveryKeyDescription": "", + "@pleaseEnterRecoveryKeyDescription": {}, + "inviteContactToGroupQuestion": "", + "@inviteContactToGroupQuestion": {}, + "redactedByBecause": "", + "@redactedByBecause": { + "type": "text", + "placeholders": { + "username": {}, + "reason": {} + } + }, + "youHaveWithdrawnTheInvitationFor": "", + "@youHaveWithdrawnTheInvitationFor": { + "placeholders": { + "user": {} + } + }, + "appearOnTopDetails": "", + "@appearOnTopDetails": {}, + "enterRoom": "", + "@enterRoom": {}, + "youInvitedUser": "", + "@youInvitedUser": { + "placeholders": { + "user": {} + } + }, + "fileHasBeenSavedAt": "", + "@fileHasBeenSavedAt": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "importZipFile": "", + "@importZipFile": {}, + "anyoneCanKnock": "", + "@anyoneCanKnock": {}, + "redactMessageDescription": "", + "@redactMessageDescription": {}, + "recoveryKey": "", + "@recoveryKey": {}, + "invalidInput": "", + "@invalidInput": {}, + "todosUnencrypted": "", + "@todosUnencrypted": {}, + "dehydrateTorLong": "", + "@dehydrateTorLong": {}, + "doNotShowAgain": "", + "@doNotShowAgain": {}, + "report": "", + "@report": {}, + "hideUnimportantStateEvents": "", + "@hideUnimportantStateEvents": {}, + "screenSharingTitle": "", + "@screenSharingTitle": {}, + "widgetCustom": "", + "@widgetCustom": {}, + "youBannedUser": "", + "@youBannedUser": { + "placeholders": { + "user": {} + } + }, + "addChatDescription": "", + "@addChatDescription": {}, + "hasKnocked": "", + "@hasKnocked": { + "placeholders": { + "user": {} + } + }, + "openLinkInBrowser": "", + "@openLinkInBrowser": {}, + "disableEncryptionWarning": "", + "@disableEncryptionWarning": {}, + "directChat": "", + "@directChat": {}, + "noOneCanJoin": "", + "@noOneCanJoin": {}, + "wrongPinEntered": "", + "@wrongPinEntered": { + "type": "text", + "placeholders": { + "seconds": {} + } + }, + "sendTypingNotifications": "", + "@sendTypingNotifications": {}, + "inviteGroupChat": "", + "@inviteGroupChat": {}, + "appearOnTop": "", + "@appearOnTop": {}, + "invitePrivateChat": "", + "@invitePrivateChat": {}, + "foregroundServiceRunning": "", + "@foregroundServiceRunning": {}, + "importEmojis": "", + "@importEmojis": {}, + "wasDirectChatDisplayName": "", + "@wasDirectChatDisplayName": { + "type": "text", + "placeholders": { + "oldDisplayName": {} + } + }, + "noChatDescriptionYet": "", + "@noChatDescriptionYet": {}, + "newTodo": "", + "@newTodo": {}, + "learnMore": "", + "@learnMore": {}, + "notAnImage": "", + "@notAnImage": {}, + "users": "", + "@users": {}, + "chatDescriptionHasBeenChanged": "", + "@chatDescriptionHasBeenChanged": {}, + "newGroup": "", + "@newGroup": {}, + "dehydrateTor": "", + "@dehydrateTor": {}, + "todoListChangedError": "", + "@todoListChangedError": {}, + "enterInviteLinkOrMatrixId": "", + "@enterInviteLinkOrMatrixId": {}, + "roomUpgradeDescription": "", + "@roomUpgradeDescription": {}, + "pleaseEnterANumber": "", + "@pleaseEnterANumber": {}, + "youKicked": "", + "@youKicked": { + "placeholders": { + "user": {} + } + }, + "profileNotFound": "", + "@profileNotFound": {}, + "jump": "", + "@jump": {}, + "sorryThatsNotPossible": "", + "@sorryThatsNotPossible": {}, + "shareInviteLink": "", + "@shareInviteLink": {}, + "commandHint_markasdm": "", + "@commandHint_markasdm": {}, + "recoveryKeyLost": "", + "@recoveryKeyLost": {}, + "cuddleContent": "", + "@cuddleContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "deviceKeys": "", + "@deviceKeys": {}, + "emoteKeyboardNoRecents": "", + "@emoteKeyboardNoRecents": { + "type": "text", + "placeholders": {} + }, + "endToEndEncryption": "", + "@endToEndEncryption": {}, + "setTheme": "", + "@setTheme": {}, + "youJoinedTheChat": "", + "@youJoinedTheChat": {}, + "widgetName": "", + "@widgetName": {}, + "errorAddingWidget": "", + "@errorAddingWidget": {}, + "commandHint_hug": "", + "@commandHint_hug": {}, + "replace": "", + "@replace": {}, + "youUnbannedUser": "", + "@youUnbannedUser": { + "placeholders": { + "user": {} + } + }, + "newSpace": "", + "@newSpace": {}, + "pleaseTryAgainLaterOrChooseDifferentServer": "", + "@pleaseTryAgainLaterOrChooseDifferentServer": {}, + "createGroup": "", + "@createGroup": {}, + "hydrateTorLong": "", + "@hydrateTorLong": {}, + "custom": "", + "@custom": {}, + "noBackupWarning": "", + "@noBackupWarning": {}, + "editWidgets": "", + "@editWidgets": {}, + "storeInSecureStorageDescription": "", + "@storeInSecureStorageDescription": {}, + "kickUserDescription": "", + "@kickUserDescription": {}, + "importNow": "", + "@importNow": {}, + "invite": "", + "@invite": {}, + "continueWith": "", + "@continueWith": {}, + "indexedDbErrorTitle": "", + "@indexedDbErrorTitle": {}, + "storeSecurlyOnThisDevice": "", + "@storeSecurlyOnThisDevice": {}, + "screenSharingDetail": "", + "@screenSharingDetail": {} +} diff --git a/assets/l10n/intl_lt.arb b/assets/l10n/intl_lt.arb index bec00b0eb..1569ad13d 100644 --- a/assets/l10n/intl_lt.arb +++ b/assets/l10n/intl_lt.arb @@ -1,2408 +1,2652 @@ { - "commandHint_leave": "Palikti pokalbių kambarį", - "@commandHint_leave": { - "type": "text", - "description": "Usage hint for the command /leave" - }, - "confirm": "Patvirtinti", - "@confirm": { - "type": "text", - "placeholders": {} - }, - "cancel": "Atšaukti", - "@cancel": { - "type": "text", - "placeholders": {} - }, - "edit": "Redaguoti", - "@edit": { - "type": "text", - "placeholders": {} - }, - "downloadFile": "Atsisiųsti failą", - "@downloadFile": { - "type": "text", - "placeholders": {} - }, - "about": "Apie", - "@about": { - "type": "text", - "placeholders": {} - }, - "all": "Visi", - "@all": { - "type": "text", - "placeholders": {} - }, - "fluffychat": "FluffyChat", - "@fluffychat": { - "type": "text", - "placeholders": {} - }, - "fileName": "Failo vardas", - "@fileName": { - "type": "text", - "placeholders": {} - }, - "changePassword": "Keisti slaptažodį", - "@changePassword": { - "type": "text", - "placeholders": {} - }, - "close": "Uždaryti", - "@close": { - "type": "text", - "placeholders": {} - }, - "archive": "Archyvas", - "@archive": { - "type": "text", - "placeholders": {} - }, - "skip": "Praleisti", - "@skip": { - "type": "text", - "placeholders": {} - }, - "share": "Bendrinti", - "@share": { - "type": "text", - "placeholders": {} - }, - "showPassword": "Rodyti slaptažodį", - "@showPassword": { - "type": "text", - "placeholders": {} - }, - "time": "Laikas", - "@time": {}, - "settings": "Nustatytmai", - "@settings": { - "type": "text", - "placeholders": {} - }, - "sender": "Siuntėjas", - "@sender": {}, - "yes": "Taip", - "@yes": { - "type": "text", - "placeholders": {} - }, - "you": "Jūs", - "@you": { - "type": "text", - "placeholders": {} - }, - "logout": "Atsijungti", - "@logout": { - "type": "text", - "placeholders": {} - }, - "messages": "Žinutės", - "@messages": { - "type": "text", - "placeholders": {} - }, - "scanQrCode": "Nuskanuokite QR kodą", - "@scanQrCode": {}, - "ok": "OK", - "@ok": { - "type": "text", - "placeholders": {} - }, - "addAccount": "Pridėti paskyrą", - "@addAccount": {}, - "or": "Arba", - "@or": { - "type": "text", - "placeholders": {} - }, - "password": "Slaptažodis", - "@password": { - "type": "text", - "placeholders": {} - }, - "passwordHasBeenChanged": "Slaptažodis pakeistas", - "@passwordHasBeenChanged": { - "type": "text", - "placeholders": {} - }, - "pleaseEnterYourPassword": "Įveskite savo slaptažodį", - "@pleaseEnterYourPassword": { - "type": "text", - "placeholders": {} - }, - "pleaseEnterYourUsername": "Įveskite savo vartotojo vardą", - "@pleaseEnterYourUsername": { - "type": "text", - "placeholders": {} - }, - "reply": "Atsakyti", - "@reply": { - "type": "text", - "placeholders": {} - }, - "blockDevice": "Blokuoti įrenginį", - "@blockDevice": { - "type": "text", - "placeholders": {} - }, - "blocked": "Užblokuotas", - "@blocked": { - "type": "text", - "placeholders": {} - }, - "chooseAStrongPassword": "Pasirinkite saugų slaptažodį", - "@chooseAStrongPassword": { - "type": "text", - "placeholders": {} - }, - "createNewGroup": "Sukurti naują grupę", - "@createNewGroup": { - "type": "text", - "placeholders": {} - }, - "deleteMessage": "Ištrinti žinutę", - "@deleteMessage": { - "type": "text", - "placeholders": {} - }, - "deny": "Atmesti", - "@deny": { - "type": "text", - "placeholders": {} - }, - "device": "Įrenginys", - "@device": { - "type": "text", - "placeholders": {} - }, - "deviceId": "Įrenginio ID", - "@deviceId": { - "type": "text", - "placeholders": {} - }, - "devices": "Įrenginiai", - "@devices": { - "type": "text", - "placeholders": {} - }, - "homeserver": "Namų serveris", - "@homeserver": {}, - "enterYourHomeserver": "Įveskite namų serverį", - "@enterYourHomeserver": { - "type": "text", - "placeholders": {} - }, - "everythingReady": "Viskas paruošta!", - "@everythingReady": { - "type": "text", - "placeholders": {} - }, - "fontSize": "Šrifto dydis", - "@fontSize": { - "type": "text", - "placeholders": {} - }, - "clearArchive": "Išvalyti archyvą", - "@clearArchive": {}, - "create": "Sukurti", - "@create": { - "type": "text", - "placeholders": {} - }, - "connect": "Prisijungti", - "@connect": { - "type": "text", - "placeholders": {} - }, - "people": "Žmonės", - "@people": { - "type": "text", - "placeholders": {} - }, - "messageWillBeRemovedWarning": "Žinutė bus pašalinta visiem dalyviams", - "@messageWillBeRemovedWarning": { - "type": "text", - "placeholders": {} - }, - "moderator": "Moderatorius", - "@moderator": { - "type": "text", - "placeholders": {} - }, - "muteChat": "Nutildyti pokalbį", - "@muteChat": { - "type": "text", - "placeholders": {} - }, - "newChat": "Naujas pokalbis", - "@newChat": { - "type": "text", - "placeholders": {} - }, - "shareYourInviteLink": "Bendrinti savo pakvietimo nuorodą", - "@shareYourInviteLink": {}, - "none": "Nė vienas", - "@none": { - "type": "text", - "placeholders": {} - }, - "noPermission": "Nėra leidimo", - "@noPermission": { - "type": "text", - "placeholders": {} - }, - "noRoomsFound": "Nerasta kambarių…", - "@noRoomsFound": { - "type": "text", - "placeholders": {} - }, - "notifications": "Pranešimai", - "@notifications": { - "type": "text", - "placeholders": {} - }, - "notificationsEnabledForThisAccount": "Pranešimai aktyvuoti šitai paskyrai", - "@notificationsEnabledForThisAccount": { - "type": "text", - "placeholders": {} - }, - "obtainingLocation": "Gaunama vieta…", - "@obtainingLocation": { - "type": "text", - "placeholders": {} - }, - "offensive": "Agresyvus", - "@offensive": { - "type": "text", - "placeholders": {} - }, - "offline": "Neprisijungta", - "@offline": { - "type": "text", - "placeholders": {} - }, - "online": "Prisijungta", - "@online": { - "type": "text", - "placeholders": {} - }, - "oopsPushError": "Oi! Deja, nustatant tiesioginius pranešimus įvyko klaida.", - "@oopsPushError": { - "type": "text", - "placeholders": {} - }, - "oopsSomethingWentWrong": "Oi, kažkas nutiko ne taip…", - "@oopsSomethingWentWrong": { - "type": "text", - "placeholders": {} - }, - "openAppToReadMessages": "Atidarykite programėlę, kad perskaityti žinutes", - "@openAppToReadMessages": { - "type": "text", - "placeholders": {} - }, - "link": "Nuoroda", - "@link": {}, - "participant": "Dalyvis", - "@participant": { - "type": "text", - "placeholders": {} - }, - "passphraseOrKey": "Slapta frazė arba atkūrimo raktas", - "@passphraseOrKey": { - "type": "text", - "placeholders": {} - }, - "passwordForgotten": "Slaptažodis užmirštas", - "@passwordForgotten": { - "type": "text", - "placeholders": {} - }, - "passwordRecovery": "Slaptažodžio atkūrimas", - "@passwordRecovery": { - "type": "text", - "placeholders": {} - }, - "pickImage": "Pasirinkite paveiksliuką", - "@pickImage": { - "type": "text", - "placeholders": {} - }, - "pin": "Prisegti", - "@pin": { - "type": "text", - "placeholders": {} - }, - "pleaseChoose": "Prašome pasirinkti", - "@pleaseChoose": { - "type": "text", - "placeholders": {} - }, - "pleaseChooseAPasscode": "Pasirinkite slaptą kodą", - "@pleaseChooseAPasscode": { - "type": "text", - "placeholders": {} - }, - "pleaseChooseAUsername": "Pasirinkite vartotojo vardą", - "@pleaseChooseAUsername": { - "type": "text", - "placeholders": {} - }, - "pleaseClickOnLink": "Paspauskite nuorodą el. pašte ir tęskite toliau.", - "@pleaseClickOnLink": { - "type": "text", - "placeholders": {} - }, - "pleaseEnter4Digits": "Įveskite 4 skaitmenis arba palikite tuščią, jei norite išjungti programėlės užraktą.", - "@pleaseEnter4Digits": { - "type": "text", - "placeholders": {} - }, - "pleaseEnterAMatrixIdentifier": "Įveskite Matrix ID.", - "@pleaseEnterAMatrixIdentifier": { - "type": "text", - "placeholders": {} - }, - "pleaseEnterYourPin": "Įveskite savo PIN kodą", - "@pleaseEnterYourPin": { - "type": "text", - "placeholders": {} - }, - "pleaseFollowInstructionsOnWeb": "Vadovaukitės svetainėje pateiktais nurodymais ir bakstelėkite Toliau.", - "@pleaseFollowInstructionsOnWeb": { - "type": "text", - "placeholders": {} - }, - "privacy": "Privatumas", - "@privacy": { - "type": "text", - "placeholders": {} - }, - "publicRooms": "Vieši kambariai", - "@publicRooms": { - "type": "text", - "placeholders": {} - }, - "reason": "Priežastis", - "@reason": { - "type": "text", - "placeholders": {} - }, - "recording": "Įrašymas", - "@recording": { - "type": "text", - "placeholders": {} - }, - "redactMessage": "Pašalinti žinutę", - "@redactMessage": { - "type": "text", - "placeholders": {} - }, - "register": "Registruotis", - "@register": { - "type": "text", - "placeholders": {} - }, - "reject": "Atmesti", - "@reject": { - "type": "text", - "placeholders": {} - }, - "rejoin": "Vėl prisijungti", - "@rejoin": { - "type": "text", - "placeholders": {} - }, - "remove": "Pašalinti", - "@remove": { - "type": "text", - "placeholders": {} - }, - "removeAllOtherDevices": "Pašalinti visus kitus įrenginius", - "@removeAllOtherDevices": { - "type": "text", - "placeholders": {} - }, - "removeDevice": "Pašalinti įrenginį", - "@removeDevice": { - "type": "text", - "placeholders": {} - }, - "removeYourAvatar": "Pašalinti savo avatarą", - "@removeYourAvatar": { - "type": "text", - "placeholders": {} - }, - "replaceRoomWithNewerVersion": "Pakeisti kambarį naujesne versija", - "@replaceRoomWithNewerVersion": { - "type": "text", - "placeholders": {} - }, - "requestPermission": "Prašyti leidimo", - "@requestPermission": { - "type": "text", - "placeholders": {} - }, - "roomHasBeenUpgraded": "Kambarys buvo atnaujintas", - "@roomHasBeenUpgraded": { - "type": "text", - "placeholders": {} - }, - "roomVersion": "Kambario versija", - "@roomVersion": { - "type": "text", - "placeholders": {} - }, - "search": "Ieškoti", - "@search": { - "type": "text", - "placeholders": {} - }, - "accept": "Sutinku", - "@accept": { - "type": "text", - "placeholders": {} - }, - "passwordsDoNotMatch": "Slaptažodžiai nesutampa!", - "@passwordsDoNotMatch": {}, - "pleaseEnterValidEmail": "Įveskite teisingą el. pašto adresą.", - "@pleaseEnterValidEmail": {}, - "repeatPassword": "Pakartokite slaptažodį", - "@repeatPassword": {}, - "addEmail": "Pridėti el. paštą", - "@addEmail": { - "type": "text", - "placeholders": {} - }, - "addGroupDescription": "Pridėkite grupės aprašymą", - "@addGroupDescription": { - "type": "text", - "placeholders": {} - }, - "admin": "Administratorius", - "@admin": { - "type": "text", - "placeholders": {} - }, - "alias": "slapyvardis", - "@alias": { - "type": "text", - "placeholders": {} - }, - "allChats": "Visi pokalbiai", - "@allChats": { - "type": "text", - "placeholders": {} - }, - "anyoneCanJoin": "Bet kas gali prisijungti", - "@anyoneCanJoin": { - "type": "text", - "placeholders": {} - }, - "areYouSure": "Ar esate tikri?", - "@areYouSure": { - "type": "text", - "placeholders": {} - }, - "areYouSureYouWantToLogout": "Ar tikrai norite atsijungti?", - "@areYouSureYouWantToLogout": { - "type": "text", - "placeholders": {} - }, - "changeTheHomeserver": "Pakeisti namų serverį", - "@changeTheHomeserver": { - "type": "text", - "placeholders": {} - }, - "changeTheme": "Keisti savo stilių", - "@changeTheme": { - "type": "text", - "placeholders": {} - }, - "changeTheNameOfTheGroup": "Keisti grupės pavadinimą", - "@changeTheNameOfTheGroup": { - "type": "text", - "placeholders": {} - }, - "changeWallpaper": "Keisti ekrano užsklandą", - "@changeWallpaper": { - "type": "text", - "placeholders": {} - }, - "changeYourAvatar": "Keisti savo avatarą", - "@changeYourAvatar": { - "type": "text", - "placeholders": {} - }, - "chat": "Pokalbis", - "@chat": { - "type": "text", - "placeholders": {} - }, - "chatDetails": "Pokalbio detalės", - "@chatDetails": { - "type": "text", - "placeholders": {} - }, - "chats": "Pokalbiai", - "@chats": { - "type": "text", - "placeholders": {} - }, - "commandHint_ban": "Užblokuoti vartotoją šiame kambaryje", - "@commandHint_ban": { - "type": "text", - "description": "Usage hint for the command /ban" - }, - "commandHint_clearcache": "Išvalyti laikiną talpyklą", - "@commandHint_clearcache": { - "type": "text", - "description": "Usage hint for the command /clearcache" - }, - "commandHint_discardsession": "Atmesti sesiją", - "@commandHint_discardsession": { - "type": "text", - "description": "Usage hint for the command /discardsession" - }, - "commandHint_html": "Siųsti tekstą HTML formatu", - "@commandHint_html": { - "type": "text", - "description": "Usage hint for the command /html" - }, - "commandHint_invite": "Pakviesti vartotoją į šitą kambarį", - "@commandHint_invite": { - "type": "text", - "description": "Usage hint for the command /invite" - }, - "commandHint_join": "Prisijungti prie nurodyto kambario", - "@commandHint_join": { - "type": "text", - "description": "Usage hint for the command /join" - }, - "commandHint_kick": "Pašalinti vartotoja iš šito kambario", - "@commandHint_kick": { - "type": "text", - "description": "Usage hint for the command /kick" - }, - "commandHint_myroomnick": "Nustatyti savo rodomą vardą šiame kambaryje", - "@commandHint_myroomnick": { - "type": "text", - "description": "Usage hint for the command /myroomnick" - }, - "commandHint_plain": "Siųsti neformatuotą tekstą", - "@commandHint_plain": { - "type": "text", - "description": "Usage hint for the command /plain" - }, - "commandHint_send": "Siųsti tekstą", - "@commandHint_send": { - "type": "text", - "description": "Usage hint for the command /send" - }, - "commandHint_unban": "Atblokuoti vartotoją šiame kambaryje", - "@commandHint_unban": { - "type": "text", - "description": "Usage hint for the command /unban" - }, - "commandInvalid": "Neteisinga komanda", - "@commandInvalid": { - "type": "text" - }, - "configureChat": "Konfigūruoti pokalbį", - "@configureChat": { - "type": "text", - "placeholders": {} - }, - "copiedToClipboard": "Nukopijuota į iškarpinę", - "@copiedToClipboard": { - "type": "text", - "placeholders": {} - }, - "copy": "Kopijuoti", - "@copy": { - "type": "text", - "placeholders": {} - }, - "copyToClipboard": "Koipjuoti į iškarpinę", - "@copyToClipboard": { - "type": "text", - "placeholders": {} - }, - "currentlyActive": "Šiuo metu aktyvus", - "@currentlyActive": { - "type": "text", - "placeholders": {} - }, - "darkTheme": "Tamsi", - "@darkTheme": { - "type": "text", - "placeholders": {} - }, - "delete": "Ištrinti", - "@delete": { - "type": "text", - "placeholders": {} - }, - "deleteAccount": "Panaikinti paskyra", - "@deleteAccount": { - "type": "text", - "placeholders": {} - }, - "directChats": "Tiesioginiai pokalbiai", - "@directChats": { - "type": "text", - "placeholders": {} - }, - "encrypted": "Užšifruotas", - "@encrypted": { - "type": "text", - "placeholders": {} - }, - "encryptionNotEnabled": "Šifravimas aktyvuotas", - "@encryptionNotEnabled": { - "type": "text", - "placeholders": {} - }, - "enterAGroupName": "Įveskite grupės vardą", - "@enterAGroupName": { - "type": "text", - "placeholders": {} - }, - "enterAnEmailAddress": "Įveskite el. pašto adresą", - "@enterAnEmailAddress": { - "type": "text", - "placeholders": {} - }, - "extremeOffensive": "Itin įžeidžiantis", - "@extremeOffensive": { - "type": "text", - "placeholders": {} - }, - "forward": "Toliau", - "@forward": { - "type": "text", - "placeholders": {} - }, - "fromJoining": "Nuo prisijungimo", - "@fromJoining": { - "type": "text", - "placeholders": {} - }, - "fromTheInvitation": "Nuo pakvietimo", - "@fromTheInvitation": { - "type": "text", - "placeholders": {} - }, - "goToTheNewRoom": "Eiti į naują kambarį", - "@goToTheNewRoom": { - "type": "text", - "placeholders": {} - }, - "group": "Grupė", - "@group": { - "type": "text", - "placeholders": {} - }, - "groupDescription": "Grupės aprašymas", - "@groupDescription": { - "type": "text", - "placeholders": {} - }, - "groupDescriptionHasBeenChanged": "Grupės aprašymas pakeistas", - "@groupDescriptionHasBeenChanged": { - "type": "text", - "placeholders": {} - }, - "groupIsPublic": "Grupė yra vieša", - "@groupIsPublic": { - "type": "text", - "placeholders": {} - }, - "groups": "Grupės", - "@groups": { - "type": "text", - "placeholders": {} - }, - "guestsAreForbidden": "Svečiams draudžiama", - "@guestsAreForbidden": { - "type": "text", - "placeholders": {} - }, - "guestsCanJoin": "Svečiai gali prisijungti", - "@guestsCanJoin": { - "type": "text", - "placeholders": {} - }, - "help": "Pagalba", - "@help": { - "type": "text", - "placeholders": {} - }, - "hideRedactedEvents": "Slėpti pašalintus įvykius", - "@hideRedactedEvents": { - "type": "text", - "placeholders": {} - }, - "hideUnknownEvents": "Slėpti nežinomus įvykius", - "@hideUnknownEvents": { - "type": "text", - "placeholders": {} - }, - "identity": "Tapatybė", - "@identity": { - "type": "text", - "placeholders": {} - }, - "ignore": "Ignoruoti", - "@ignore": { - "type": "text", - "placeholders": {} - }, - "ignoredUsers": "Ignoruoti vartotojai", - "@ignoredUsers": { - "type": "text", - "placeholders": {} - }, - "leave": "Palikti", - "@leave": { - "type": "text", - "placeholders": {} - }, - "loginWithOneClick": "Prisijungti vienu paspaudimu", - "@loginWithOneClick": {}, - "makeSureTheIdentifierIsValid": "Įsitikinkite, kad indentifikatorius galiojantis", - "@makeSureTheIdentifierIsValid": { - "type": "text", - "placeholders": {} - }, - "memberChanges": "Narių pokyčiai", - "@memberChanges": { - "type": "text", - "placeholders": {} - }, - "mention": "Paminėti", - "@mention": { - "type": "text", - "placeholders": {} - }, - "encryption": "Šifravimas", - "@encryption": { - "type": "text", - "placeholders": {} - }, - "enableEncryption": "Aktyvuoti šifravimą", - "@enableEncryption": { - "type": "text", - "placeholders": {} - }, - "editBlockedServers": "Redaguoti blokuotus serverius", - "@editBlockedServers": { - "type": "text", - "placeholders": {} - }, - "editChatPermissions": "Redaguoti pokalbio leidimus", - "@editChatPermissions": { - "type": "text", - "placeholders": {} - }, - "login": "Prisijungti", - "@login": { - "type": "text", - "placeholders": {} - }, - "sendOnEnter": "Išsiųsti paspaudus Enter", - "@sendOnEnter": {}, - "banFromChat": "Užblokuoti iš pokalbio", - "@banFromChat": { - "type": "text", - "placeholders": {} - }, - "banned": "Užblokuotas", - "@banned": { - "type": "text", - "placeholders": {} - }, - "changeDeviceName": "Pakeisti įrenginio vardą", - "@changeDeviceName": { - "type": "text", - "placeholders": {} - }, - "yourChatBackupHasBeenSetUp": "Jūsų pokalbio atsarginė kopija buvo nustatyta.", - "@yourChatBackupHasBeenSetUp": {}, - "chatBackup": "Pokalbio atsargine kopija", - "@chatBackup": { - "type": "text", - "placeholders": {} - }, - "commandHint_me": "Apibūdinkite save", - "@commandHint_me": { - "type": "text", - "description": "Usage hint for the command /me" - }, - "displaynameHasBeenChanged": "Rodomas vardas buvo pakeistas", - "@displaynameHasBeenChanged": { - "type": "text", - "placeholders": {} - }, - "editDisplayname": "Redaguoti rodomą vardą", - "@editDisplayname": { - "type": "text", - "placeholders": {} - }, - "editRoomAliases": "Redaguoti kambario pseudonimus", - "@editRoomAliases": { - "type": "text", - "placeholders": {} - }, - "editRoomAvatar": "Redaguoti kambario avatarą", - "@editRoomAvatar": { - "type": "text", - "placeholders": {} - }, - "howOffensiveIsThisContent": "Kiek įžeižiantis šis turinys?", - "@howOffensiveIsThisContent": { - "type": "text", - "placeholders": {} - }, - "id": "ID", - "@id": { - "type": "text", - "placeholders": {} - }, - "ignoreUsername": "Ignoruoti vartotoją", - "@ignoreUsername": { - "type": "text", - "placeholders": {} - }, - "iHaveClickedOnLink": "Aš paspaudžiau nuorodą", - "@iHaveClickedOnLink": { - "type": "text", - "placeholders": {} - }, - "incorrectPassphraseOrKey": "Neteisinga slaptafrazė arba atkūrimo raktas", - "@incorrectPassphraseOrKey": { - "type": "text", - "placeholders": {} - }, - "inoffensive": "Neįžeidžiantis", - "@inoffensive": { - "type": "text", - "placeholders": {} - }, - "inviteContact": "Pakviesti kontaktą", - "@inviteContact": { - "type": "text", - "placeholders": {} - }, - "invited": "Pakviestas", - "@invited": { - "type": "text", - "placeholders": {} - }, - "invitedUsersOnly": "Tik pakviesti vartotojai", - "@invitedUsersOnly": { - "type": "text", - "placeholders": {} - }, - "isTyping": "rašo…", - "@isTyping": { - "type": "text", - "placeholders": {} - }, - "joinRoom": "Prisijungti prie kambario", - "@joinRoom": { - "type": "text", - "placeholders": {} - }, - "kickFromChat": "Išmesti iš pokalbio", - "@kickFromChat": { - "type": "text", - "placeholders": {} - }, - "lastSeenLongTimeAgo": "Seniai matytas", - "@lastSeenLongTimeAgo": { - "type": "text", - "placeholders": {} - }, - "leftTheChat": "Paliko pokalbį", - "@leftTheChat": { - "type": "text", - "placeholders": {} - }, - "license": "Licencija", - "@license": { - "type": "text", - "placeholders": {} - }, - "lightTheme": "Šviesi", - "@lightTheme": { - "type": "text", - "placeholders": {} - }, - "loadingPleaseWait": "Kraunama… Prašome palaukti.", - "@loadingPleaseWait": { - "type": "text", - "placeholders": {} - }, - "loadMore": "Rodyti daugiau…", - "@loadMore": { - "type": "text", - "placeholders": {} - }, - "newMessageInFluffyChat": "💬 Nauja žinutė FluffyChat'e", - "@newMessageInFluffyChat": { - "type": "text", - "placeholders": {} - }, - "newVerificationRequest": "Nauja patvirtinimo užklausa!", - "@newVerificationRequest": { - "type": "text", - "placeholders": {} - }, - "next": "Toliau", - "@next": { - "type": "text", - "placeholders": {} - }, - "no": "Ne", - "@no": { - "type": "text", - "placeholders": {} - }, - "noConnectionToTheServer": "Nėra ryšio su serveriu", - "@noConnectionToTheServer": { - "type": "text", - "placeholders": {} - }, - "setGroupDescription": "Nustatyti grupės aprašymą", - "@setGroupDescription": { - "type": "text", - "placeholders": {} - }, - "setInvitationLink": "Nustatyti pakvietimo nuorodą", - "@setInvitationLink": { - "type": "text", - "placeholders": {} - }, - "singlesignon": "Vienkartinis prisijungimas", - "@singlesignon": { - "type": "text", - "placeholders": {} - }, - "sourceCode": "Programinis kodas", - "@sourceCode": { - "type": "text", - "placeholders": {} - }, - "spaceIsPublic": "Erdvė yra vieša", - "@spaceIsPublic": { - "type": "text", - "placeholders": {} - }, - "spaceName": "Erdvės pavadinimas", - "@spaceName": { - "type": "text", - "placeholders": {} - }, - "status": "Būsena", - "@status": { - "type": "text", - "placeholders": {} - }, - "statusExampleMessage": "Kaip sekasi šiandien?", - "@statusExampleMessage": { - "type": "text", - "placeholders": {} - }, - "submit": "Pateikti", - "@submit": { - "type": "text", - "placeholders": {} - }, - "synchronizingPleaseWait": "Sinchronizuojama… Prašome palaukti.", - "@synchronizingPleaseWait": { - "type": "text", - "placeholders": {} - }, - "transferFromAnotherDevice": "Perkėlimas iš kito įrenginio", - "@transferFromAnotherDevice": { - "type": "text", - "placeholders": {} - }, - "verify": "Patvirtinti", - "@verify": { - "type": "text", - "placeholders": {} - }, - "verifyStart": "Pradėti patvirtinimą", - "@verifyStart": { - "type": "text", - "placeholders": {} - }, - "verifySuccess": "Jūs sėkmingai patvirtinote!", - "@verifySuccess": { - "type": "text", - "placeholders": {} - }, - "verifyTitle": "Patvirtinama kita paskyra", - "@verifyTitle": { - "type": "text", - "placeholders": {} - }, - "visibilityOfTheChatHistory": "Pokalbių istorijos matomumas", - "@visibilityOfTheChatHistory": { - "type": "text", - "placeholders": {} - }, - "visibleForAllParticipants": "Matoma visiems dalyviams", - "@visibleForAllParticipants": { - "type": "text", - "placeholders": {} - }, - "waitingPartnerAcceptRequest": "Laukiama, kol dalyvis priims užklausą…", - "@waitingPartnerAcceptRequest": { - "type": "text", - "placeholders": {} - }, - "writeAMessage": "Rašyti žinutę…", - "@writeAMessage": { - "type": "text", - "placeholders": {} - }, - "youAreInvitedToThisChat": "Esate pakviesti į šį pokalbį", - "@youAreInvitedToThisChat": { - "type": "text", - "placeholders": {} - }, - "youAreNoLongerParticipatingInThisChat": "Jūs nebedalyvaujate šiame pokalbyje", - "@youAreNoLongerParticipatingInThisChat": { - "type": "text", - "placeholders": {} - }, - "youCannotInviteYourself": "Jūs negalite pakviesti savęs", - "@youCannotInviteYourself": { - "type": "text", - "placeholders": {} - }, - "youHaveBeenBannedFromThisChat": "Jums buvo uždrausta dalyvauti šiame pokalbyje", - "@youHaveBeenBannedFromThisChat": { - "type": "text", - "placeholders": {} - }, - "messageInfo": "Žinutės informacija", - "@messageInfo": {}, - "removeFromSpace": "Pašalinti iš erdvės", - "@removeFromSpace": {}, - "security": "Apsauga", - "@security": { - "type": "text", - "placeholders": {} - }, - "sendAsText": "Siųsti kaip tekstą", - "@sendAsText": { - "type": "text" - }, - "sendAudio": "Siųsti garso įrašą", - "@sendAudio": { - "type": "text", - "placeholders": {} - }, - "sendImage": "Siųsti paveiksliuką", - "@sendImage": { - "type": "text", - "placeholders": {} - }, - "sendFile": "Sųsti bylą", - "@sendFile": { - "type": "text", - "placeholders": {} - }, - "sendMessages": "Siųsti žinutes", - "@sendMessages": { - "type": "text", - "placeholders": {} - }, - "sendOriginal": "Siųsti originalą", - "@sendOriginal": { - "type": "text", - "placeholders": {} - }, - "sendVideo": "Siųsti video", - "@sendVideo": { - "type": "text", - "placeholders": {} - }, - "separateChatTypes": "Atskirti tiesioginius pokalbius ir grupes", - "@separateChatTypes": { - "type": "text", - "placeholders": {} - }, - "setAsCanonicalAlias": "Nustatyti kaip pagrindinį slapyvardį", - "@setAsCanonicalAlias": { - "type": "text", - "placeholders": {} - }, - "setPermissionsLevel": "Nustatyti leidimų lygį", - "@setPermissionsLevel": { - "type": "text", - "placeholders": {} - }, - "setStatus": "Nustatyti būseną", - "@setStatus": { - "type": "text", - "placeholders": {} - }, - "shareLocation": "Bendrinti vietą", - "@shareLocation": { - "type": "text", - "placeholders": {} - }, - "showDirectChatsInSpaces": "Rodyti susijusius tiesioginius pokalbius erdvėse", - "@showDirectChatsInSpaces": { - "type": "text", - "placeholders": {} - }, - "signUp": "Registruotis", - "@signUp": { - "type": "text", - "placeholders": {} - }, - "systemTheme": "Sistema", - "@systemTheme": { - "type": "text", - "placeholders": {} - }, - "unavailable": "Nepasiekiamas", - "@unavailable": { - "type": "text", - "placeholders": {} - }, - "unblockDevice": "Atblokuoti įrenginį", - "@unblockDevice": { - "type": "text", - "placeholders": {} - }, - "unknownEncryptionAlgorithm": "Nežinomas šifravimo algoritmas", - "@unknownEncryptionAlgorithm": { - "type": "text", - "placeholders": {} - }, - "unmuteChat": "Įjungti pokalbio garsą", - "@unmuteChat": { - "type": "text", - "placeholders": {} - }, - "unpin": "Atsegti", - "@unpin": { - "type": "text", - "placeholders": {} - }, - "username": "Vartotojo vardas", - "@username": { - "type": "text", - "placeholders": {} - }, - "unverified": "Nepatvirtinta", - "@unverified": {}, - "verified": "Patvirtinta", - "@verified": { - "type": "text", - "placeholders": {} - }, - "videoCall": "Vaizdo skambutis", - "@videoCall": { - "type": "text", - "placeholders": {} - }, - "yourPublicKey": "Jūsų viešasis raktas", - "@yourPublicKey": { - "type": "text", - "placeholders": {} - }, - "addToSpaceDescription": "Pasirinkite erdvę, kad prie jos pridėtumėte šį pokalbį.", - "@addToSpaceDescription": {}, - "start": "Pradžia", - "@start": {}, - "account": "Paskyra", - "@account": { - "type": "text", - "placeholders": {} - }, - "addToSpace": "Pridėti į erdvę", - "@addToSpace": {}, - "appLock": "Programos užraktas", - "@appLock": { - "type": "text", - "placeholders": {} - }, - "areGuestsAllowedToJoin": "Ar svečiams leidžiama prisijungti", - "@areGuestsAllowedToJoin": { - "type": "text", - "placeholders": {} - }, - "botMessages": "Botų žinutės", - "@botMessages": { - "type": "text", - "placeholders": {} - }, - "bubbleSize": "Burbulo dydis", - "@bubbleSize": { - "type": "text", - "placeholders": {} - }, - "channelCorruptedDecryptError": "Šifravimas buvo sugadintas", - "@channelCorruptedDecryptError": { - "type": "text", - "placeholders": {} - }, - "chatHasBeenAddedToThisSpace": "Pokalbis buvo pridėtas prie šios erdvės", - "@chatHasBeenAddedToThisSpace": {}, - "compareEmojiMatch": "Palyginkite jaustukus", - "@compareEmojiMatch": { - "type": "text", - "placeholders": {} - }, - "compareNumbersMatch": "Palyginkite skaičius", - "@compareNumbersMatch": { - "type": "text", - "placeholders": {} - }, - "contactHasBeenInvitedToTheGroup": "Kontaktas buvo pakviestas į grupę", - "@contactHasBeenInvitedToTheGroup": { - "type": "text", - "placeholders": {} - }, - "contentHasBeenReported": "Apie turinį pranešta serverio administratoriams", - "@contentHasBeenReported": { - "type": "text", - "placeholders": {} - }, - "createNewSpace": "Nauja erdvė", - "@createNewSpace": { - "type": "text", - "placeholders": {} - }, - "deactivateAccountWarning": "Tai deaktyvuos jūsų vartotojo paskyrą. Tai negali būti atšaukta! Ar jūs tuo tikri?", - "@deactivateAccountWarning": { - "type": "text", - "placeholders": {} - }, - "defaultPermissionLevel": "Numatytasis teisių lygis", - "@defaultPermissionLevel": { - "type": "text", - "placeholders": {} - }, - "enableEncryptionWarning": "Šifravimo nebegalėsite išjungti. Ar jūs tuo tikri?", - "@enableEncryptionWarning": { - "type": "text", - "placeholders": {} - }, - "enterASpacepName": "Įveskite erdvės vardą", - "@enterASpacepName": {}, - "send": "Siųsti", - "@send": { - "type": "text", - "placeholders": {} - }, - "sendAMessage": "Siųsti žinutę", - "@sendAMessage": { - "type": "text", - "placeholders": {} - }, - "toggleUnread": "Pažymėti kaip skaitytą/neskaitytą", - "@toggleUnread": { - "type": "text", - "placeholders": {} - }, - "tooManyRequestsWarning": "Per daug užklausų. Pabandykite dar kartą vėliau!", - "@tooManyRequestsWarning": { - "type": "text", - "placeholders": {} - }, - "waitingPartnerEmoji": "Laukiama, kol dalyvis priims jaustukus…", - "@waitingPartnerEmoji": { - "type": "text", - "placeholders": {} - }, - "waitingPartnerNumbers": "Laukiama, kol dalyvis priims skaičius…", - "@waitingPartnerNumbers": { - "type": "text", - "placeholders": {} - }, - "wallpaper": "Užsklanda", - "@wallpaper": { - "type": "text", - "placeholders": {} - }, - "warning": "Įspėjimas!", - "@warning": { - "type": "text", - "placeholders": {} - }, - "weSentYouAnEmail": "Išsiuntėme jums el. laišką", - "@weSentYouAnEmail": { - "type": "text", - "placeholders": {} - }, - "whoCanPerformWhichAction": "Kas gali atlikti kokį veiksmą", - "@whoCanPerformWhichAction": { - "type": "text", - "placeholders": {} - }, - "whoIsAllowedToJoinThisGroup": "Kam leidžiama prisijungti prie šios grupės", - "@whoIsAllowedToJoinThisGroup": { - "type": "text", - "placeholders": {} - }, - "whyDoYouWantToReportThis": "Kodėl norite apie tai pranešti?", - "@whyDoYouWantToReportThis": { - "type": "text", - "placeholders": {} - }, - "wipeChatBackup": "Ištrinti atsarginę pokalbių kopiją, kad sukurti naują atkūrimo raktą?", - "@wipeChatBackup": { - "type": "text", - "placeholders": {} - }, - "withTheseAddressesRecoveryDescription": "Naudodami šiuos adresus galite atkurti savo slaptažodį.", - "@withTheseAddressesRecoveryDescription": { - "type": "text", - "placeholders": {} - }, - "messageType": "Žinutės tipas", - "@messageType": {}, - "openGallery": "Atverti galeriją", - "@openGallery": {}, - "chooseAUsername": "Pasirinkite vartotojo vardą", - "@chooseAUsername": { - "type": "text", - "placeholders": {} - }, - "unknownDevice": "Nežinomas įrenginys", - "@unknownDevice": { - "type": "text", - "placeholders": {} - }, - "voiceMessage": "Balso žinutė", - "@voiceMessage": { - "type": "text", - "placeholders": {} - }, - "title": "FluffyChat", - "@title": { - "description": "Title for the application", - "type": "text", - "placeholders": {} - }, - "visibleForEveryone": "Matoma visiems", - "@visibleForEveryone": { - "type": "text", - "placeholders": {} - }, - "tryToSendAgain": "Pabandykite išsiųsti dar kartą", - "@tryToSendAgain": { - "type": "text", - "placeholders": {} - }, - "locationPermissionDeniedNotice": "Vietos leidimas atmestas. Suteikite leidimą kad galėtumėte bendrinti savo vietą.", - "@locationPermissionDeniedNotice": { - "type": "text", - "placeholders": {} - }, - "needPantalaimonWarning": "Atminkite, kad norint naudoti end-to-end šifravimą, reikalingas Pantalaimon.", - "@needPantalaimonWarning": { - "type": "text", - "placeholders": {} - }, - "noEncryptionForPublicRooms": "Šifravimą galite suaktyvinti tik tada, kai kambarys nebebus viešai pasiekiamas.", - "@noEncryptionForPublicRooms": { - "type": "text", - "placeholders": {} - }, - "noEmotesFound": "Nerasta jaustukų. 😕", - "@noEmotesFound": { - "type": "text", - "placeholders": {} - }, - "noGoogleServicesWarning": "Atrodo, kad jūsų telefone nėra Google Services. Tai geras sprendimas jūsų privatumui! Norėdami gauti tiesioginius pranešimus FluffyChat, rekomenduojame naudoti https://microg.org/ arba https://unifiedpush.org/.", - "@noGoogleServicesWarning": { - "type": "text", - "placeholders": {} - }, - "noPasswordRecoveryDescription": "Dar nepridėjote slaptažodžio atkūrimo būdo.", - "@noPasswordRecoveryDescription": { - "type": "text", - "placeholders": {} - }, - "oneClientLoggedOut": "Vienas iš jūsų klientų atsijungė", - "@oneClientLoggedOut": {}, - "onlineKeyBackupEnabled": "Internetinė atsarginė raktų kopija įjungta", - "@onlineKeyBackupEnabled": { - "type": "text", - "placeholders": {} - }, - "openCamera": "Atidarykite kamerą", - "@openCamera": { - "type": "text", - "placeholders": {} - }, - "openVideoCamera": "Atidarykite kamerą vaizdo įrašui", - "@openVideoCamera": { - "type": "text", - "placeholders": {} - }, - "editBundlesForAccount": "Redaguoti šios paskyros paketus", - "@editBundlesForAccount": {}, - "serverRequiresEmail": "Šis serveris turi patvirtinti jūsų el. pašto adresą registracijai.", - "@serverRequiresEmail": {}, - "optionalGroupName": "(Nebūtina) Grupės pavadinimas", - "@optionalGroupName": { - "type": "text", - "placeholders": {} - }, - "addToBundle": "Pridėti prie paketų", - "@addToBundle": {}, - "removeFromBundle": "Pašalinkite iš šio paketo", - "@removeFromBundle": {}, - "bundleName": "Paketo vardas", - "@bundleName": {}, - "play": "Groti {fileName}", - "@play": { - "type": "text", - "placeholders": { - "fileName": {} - } - }, - "redactedAnEvent": "{username} pašalino įvykį", - "@redactedAnEvent": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "rejectedTheInvitation": "{username} atmetė kvietimą", - "@rejectedTheInvitation": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "removedBy": "Pašalino vartotojas {username}", - "@removedBy": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "unbanFromChat": "Atblokuoti pokalbyje", - "@unbanFromChat": { - "type": "text", - "placeholders": {} - }, - "renderRichContent": "Atvaizduoti turtingą žinutės turinį", - "@renderRichContent": { - "type": "text", - "placeholders": {} - }, - "reportMessage": "Pranešti apie žinutę", - "@reportMessage": { - "type": "text", - "placeholders": {} - }, - "saveFile": "Išsaugoti failą", - "@saveFile": { - "type": "text", - "placeholders": {} - }, - "seenByUser": "Matė {username}", - "@seenByUser": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sendSticker": "Siųsti lipduką", - "@sendSticker": { - "type": "text", - "placeholders": {} - }, - "sentAFile": "📁 {username} atsiuntė failą", - "@sentAFile": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sentAnAudio": "🎤 {username} atsiuntė garso įrašą", - "@sentAnAudio": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sentASticker": "😊 {username} atsiuntė lipduką", - "@sentASticker": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sharedTheLocation": "{username} bendrino savo vietą", - "@sharedTheLocation": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "startedACall": "{senderName} pradėjo skambutį", - "@startedACall": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "theyDontMatch": "Jie nesutampa", - "@theyDontMatch": { - "type": "text", - "placeholders": {} - }, - "theyMatch": "Jie sutampa", - "@theyMatch": { - "type": "text", - "placeholders": {} - }, - "unbannedUser": "{username} atblokavo {targetName}", - "@unbannedUser": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "unknownEvent": "Nežinomas įvykis '{type}'", - "@unknownEvent": { - "type": "text", - "placeholders": { - "type": {} - } - }, - "userAndOthersAreTyping": "{username} ir dar {count} kiti rašo…", - "@userAndOthersAreTyping": { - "type": "text", - "placeholders": { - "username": {}, - "count": {} - } - }, - "userAndUserAreTyping": "{username} ir {username2} rašo…", - "@userAndUserAreTyping": { - "type": "text", - "placeholders": { - "username": {}, - "username2": {} - } - }, - "userIsTyping": "{username} rašo…", - "@userIsTyping": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "userSentUnknownEvent": "{username} išsiuntė {type} įvykį", - "@userSentUnknownEvent": { - "type": "text", - "placeholders": { - "username": {}, - "type": {} - } - }, - "addToStory": "Pridėti prie istorijos", - "@addToStory": {}, - "publish": "Paskelbti", - "@publish": {}, - "whoCanSeeMyStories": "Kas gali matyti mano istorijas?", - "@whoCanSeeMyStories": {}, - "unsubscribeStories": "Atsisakyti istorijų prenumeratos", - "@unsubscribeStories": {}, - "thisUserHasNotPostedAnythingYet": "Šis vartotojas dar nieko nepaskelbė savo istorijoje", - "@thisUserHasNotPostedAnythingYet": {}, - "storyPrivacyWarning": "Atminkite, kad žmonės gali matyti vienas kitą ir susisiekti tarpusavyje jūsų istorijoje. Jūsų istorijos bus matomos 24 valandas, tačiau nėra garantijos, kad jos bus ištrintos iš visų įrenginių ir serverių.", - "@storyPrivacyWarning": {}, - "openChat": "Atverti pokalbį", - "@openChat": {}, - "reportUser": "Pranešti apie vartotoją", - "@reportUser": {}, - "dismiss": "Atsisakyti", - "@dismiss": {}, - "reactedWith": "{sender} sureagavo su {reaction}", - "@reactedWith": { - "type": "text", - "placeholders": { - "sender": {}, - "reaction": {} - } - }, - "unsupportedAndroidVersion": "Nepalaikoma Android versija", - "@unsupportedAndroidVersion": {}, - "emailOrUsername": "El. paštas arba vartotojo vardas", - "@emailOrUsername": {}, - "widgetVideo": "Video", - "@widgetVideo": {}, - "widgetNameError": "Pateikite rodomą vardą.", - "@widgetNameError": {}, - "pleaseChooseAtLeastChars": "Pasirinkite bent {min} simbolius.", - "@pleaseChooseAtLeastChars": { - "type": "text", - "placeholders": { - "min": {} - } - }, - "acceptedTheInvitation": "👍 {username} priėmė kvietimą", - "@acceptedTheInvitation": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "activatedEndToEndEncryption": "🔐 {username} aktyvavo visapusį šifravimą", - "@activatedEndToEndEncryption": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "answeredTheCall": "{senderName} atsiliepė į skambutį", - "@answeredTheCall": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "askVerificationRequest": "Priimti šią patvirtinimo užklausą iš {username}?", - "@askVerificationRequest": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "badServerLoginTypesException": "Namų serveris palaiko šiuos prisijungimo tipus:\n{serverVersions}\nTačiau ši programa palaiko tik:\n{supportedVersions}", - "@badServerLoginTypesException": { - "type": "text", - "placeholders": { - "serverVersions": {}, - "supportedVersions": {} - } - }, - "badServerVersionsException": "Namų serveris palaiko spec. versijas:\n{serverVersions}\nTačiau ši programa palaiko tik {supportedVersions}", - "@badServerVersionsException": { - "type": "text", - "placeholders": { - "serverVersions": {}, - "supportedVersions": {} - } - }, - "bannedUser": "{username} užblokavo {targetName}", - "@bannedUser": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "changedTheHistoryVisibility": "{username} pakeitė istorijos matomumą", - "@changedTheHistoryVisibility": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheHistoryVisibilityTo": "{username} pakeitė istorijos matomumą į: {rules}", - "@changedTheHistoryVisibilityTo": { - "type": "text", - "placeholders": { - "username": {}, - "rules": {} - } - }, - "chatBackupDescription": "Jūsų senos žinutės yra apsaugotos atkūrimo raktu. Pasirūpinkite, kad jo neprarastumėte.", - "@chatBackupDescription": { - "type": "text", - "placeholders": {} - }, - "commandHint_create": "Sukurti tuščią grupinį pokalbį\nNaudokite --no-encryption kad išjungti šifravimą", - "@commandHint_create": { - "type": "text", - "description": "Usage hint for the command /create" - }, - "commandHint_dm": "Pradėti tiesioginį pokalbį\nNaudokite --no-encryption kad išjungti šifravimą", - "@commandHint_dm": { - "type": "text", - "description": "Usage hint for the command /dm" - }, - "commandHint_myroomavatar": "Nustatyti savo nuotrauką šiame kambaryje (su mxc-uri)", - "@commandHint_myroomavatar": { - "type": "text", - "description": "Usage hint for the command /myroomavatar" - }, - "commandHint_op": "Nustatyti naudotojo galios lygį (numatytasis: 50)", - "@commandHint_op": { - "type": "text", - "description": "Usage hint for the command /op" - }, - "commandHint_react": "Siųsti atsakymą kaip reakciją", - "@commandHint_react": { - "type": "text", - "description": "Usage hint for the command /react" - }, - "commandMissing": "{command} nėra komanda.", - "@commandMissing": { - "type": "text", - "placeholders": { - "command": {} - }, - "description": "State that {command} is not a valid /command." - }, - "containsDisplayName": "Turi rodomą vardą", - "@containsDisplayName": { - "type": "text", - "placeholders": {} - }, - "containsUserName": "Turi vartotojo vardą", - "@containsUserName": { - "type": "text", - "placeholders": {} - }, - "couldNotDecryptMessage": "Nepavyko iššifruoti pranešimo: {error}", - "@couldNotDecryptMessage": { - "type": "text", - "placeholders": { - "error": {} - } - }, - "countParticipants": "{count} dalyviai", - "@countParticipants": { - "type": "text", - "placeholders": { - "count": {} - } - }, - "createdTheChat": "💬 {username} sukūrė pokalbį", - "@createdTheChat": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "emptyChat": "Tuščias pokalbis", - "@emptyChat": { - "type": "text", - "placeholders": {} - }, - "emoteExists": "Jaustukas jau egzistuoja!", - "@emoteExists": { - "type": "text", - "placeholders": {} - }, - "emoteInvalid": "Neteisingas jaustuko trumpasis kodas!", - "@emoteInvalid": { - "type": "text", - "placeholders": {} - }, - "emotePacks": "Jaustukų paketai kambariui", - "@emotePacks": { - "type": "text", - "placeholders": {} - }, - "emoteSettings": "Jaustukų nustatymai", - "@emoteSettings": { - "type": "text", - "placeholders": {} - }, - "emoteShortcode": "Jaustuko trumpasis kodas", - "@emoteShortcode": { - "type": "text", - "placeholders": {} - }, - "emoteWarnNeedToPick": "Turite pasirinkti jaustuko trumpąjį kodą ir paveiksliuką!", - "@emoteWarnNeedToPick": { - "type": "text", - "placeholders": {} - }, - "enableEmotesGlobally": "Įgalinti jaustukų paketą visur", - "@enableEmotesGlobally": { - "type": "text", - "placeholders": {} - }, - "endedTheCall": "{senderName} baigė skambutį", - "@endedTheCall": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "errorObtainingLocation": "Klaida nustatant vietą: {error}", - "@errorObtainingLocation": { - "type": "text", - "placeholders": { - "error": {} - } - }, - "groupWith": "Grupė su {displayname}", - "@groupWith": { - "type": "text", - "placeholders": { - "displayname": {} - } - }, - "hasWithdrawnTheInvitationFor": "{username} atšaukė {targetName} kvietimą", - "@hasWithdrawnTheInvitationFor": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "inviteForMe": "Pakvietimas man", - "@inviteForMe": { - "type": "text", - "placeholders": {} - }, - "inviteContactToGroup": "Pakviesti kontaktą į {groupName}", - "@inviteContactToGroup": { - "type": "text", - "placeholders": { - "groupName": {} - } - }, - "invitedUser": "📩 {username} pakvietė {targetName}", - "@invitedUser": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "inviteText": "{username} pakvietė jus prisijungti prie FluffyChat. \n1. Įdiekite FluffyChat: https://fluffychat.im \n2. Prisiregistruokite arba prisijunkite \n3. Atidarykite pakvietimo nuorodą: {link}", - "@inviteText": { - "type": "text", - "placeholders": { - "username": {}, - "link": {} - } - }, - "joinedTheChat": "👋 {username} prisijungė prie pokalbio", - "@joinedTheChat": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "kicked": "👞 {username} išmetė {targetName}", - "@kicked": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "kickedAndBanned": "🙅 {username} išmetė ir užblokavo {targetName}", - "@kickedAndBanned": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "lastActiveAgo": "Paskutinis aktyvumas: {localizedTimeShort}", - "@lastActiveAgo": { - "type": "text", - "placeholders": { - "localizedTimeShort": {} - } - }, - "loadCountMoreParticipants": "Įkelti dar {count} dalyvius", - "@loadCountMoreParticipants": { - "type": "text", - "placeholders": { - "count": {} - } - }, - "logInTo": "Prisijungti prie {homeserver}", - "@logInTo": { - "type": "text", - "placeholders": { - "homeserver": {} - } - }, - "seenByUserAndUser": "Matė {username} ir {username2}", - "@seenByUserAndUser": { - "type": "text", - "placeholders": { - "username": {}, - "username2": {} - } - }, - "toggleFavorite": "Perjungti parankinius", - "@toggleFavorite": { - "type": "text", - "placeholders": {} - }, - "toggleMuted": "Perjungti nutildytą", - "@toggleMuted": { - "type": "text", - "placeholders": {} - }, - "cantOpenUri": "Nepavyksta atidaryti URI {uri}", - "@cantOpenUri": { - "type": "text", - "placeholders": { - "uri": {} - } - }, - "changedTheChatAvatar": "{username} pakeitė pokalbio avatarą", - "@changedTheChatAvatar": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheChatDescriptionTo": "{username} pakeitė pokalbio aprašymą į: '{description}'", - "@changedTheChatDescriptionTo": { - "type": "text", - "placeholders": { - "username": {}, - "description": {} - } - }, - "changedTheChatNameTo": "{username} pakeitė pokalbio pavadinimą į: '{chatname}'", - "@changedTheChatNameTo": { - "type": "text", - "placeholders": { - "username": {}, - "chatname": {} - } - }, - "changedTheChatPermissions": "{username} pakeitė pokalbių leidimus", - "@changedTheChatPermissions": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheDisplaynameTo": "{username} pakeitė rodomą vardą į: '{displayname}'", - "@changedTheDisplaynameTo": { - "type": "text", - "placeholders": { - "username": {}, - "displayname": {} - } - }, - "changedTheGuestAccessRules": "{username} pakeitė svečio prieigos taisykles", - "@changedTheGuestAccessRules": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheGuestAccessRulesTo": "{username} pakeitė svečio prieigos taisykles į: {rules}", - "@changedTheGuestAccessRulesTo": { - "type": "text", - "placeholders": { - "username": {}, - "rules": {} - } - }, - "changedTheJoinRules": "{username} pakeitė prisijungimo taisykles", - "@changedTheJoinRules": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheJoinRulesTo": "{username} pakeitė prisijungimo taisykles į: {joinRules}", - "@changedTheJoinRulesTo": { - "type": "text", - "placeholders": { - "username": {}, - "joinRules": {} - } - }, - "changedTheProfileAvatar": "{username} pakeitė savo avatarą", - "@changedTheProfileAvatar": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheRoomAliases": "{username} pakeitė kambario pseudonimus", - "@changedTheRoomAliases": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheRoomInvitationLink": "{username} pakeitė pakvietimo nuorodą", - "@changedTheRoomInvitationLink": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "yourStory": "Tavo istorija", - "@yourStory": {}, - "replyHasBeenSent": "Atsakymas išsiųstas", - "@replyHasBeenSent": {}, - "videoWithSize": "Vaizdo įrašas ({size})", - "@videoWithSize": { - "type": "text", - "placeholders": { - "size": {} - } - }, - "storyFrom": "Istorija nuo {date}: \n{body}", - "@storyFrom": { - "type": "text", - "placeholders": { - "date": {}, - "body": {} - } - }, - "whoCanSeeMyStoriesDesc": "Atminkite, kad žmonės gali matyti vienas kitą ir susisiekti tarpusavyje jūsų istorijoje.", - "@whoCanSeeMyStoriesDesc": {}, - "whatIsGoingOn": "Kas vyksta?", - "@whatIsGoingOn": {}, - "addDescription": "Pridėti aprašymą", - "@addDescription": {}, - "iUnderstand": "Aš suprantu", - "@iUnderstand": {}, - "pinMessage": "Prisegti prie kambario", - "@pinMessage": {}, - "confirmEventUnpin": "Ar tikrai norite visam laikui atsegti įvykį?", - "@confirmEventUnpin": {}, - "emojis": "Jaustukai", - "@emojis": {}, - "placeCall": "Skambinti", - "@placeCall": {}, - "voiceCall": "Balso skambutis", - "@voiceCall": {}, - "unsupportedAndroidVersionLong": "Šiai funkcijai reikalinga naujesnė Android versija. Patikrinkite, ar nėra naujinimų arba Lineage OS palaikymo.", - "@unsupportedAndroidVersionLong": {}, - "videoCallsBetaWarning": "Atminkite, kad vaizdo skambučiai šiuo metu yra beta versijos. Jie gali neveikti taip kaip tikėtasi, arba iš viso neveikti visose platformose.", - "@videoCallsBetaWarning": {}, - "experimentalVideoCalls": "Eksperimentiniai vaizdo skambučiai", - "@experimentalVideoCalls": {}, - "switchToAccount": "Perjungti paskyrą į {number}", - "@switchToAccount": { - "type": "number", - "placeholders": { - "number": {} - } - }, - "nextAccount": "Kita paskyra", - "@nextAccount": {}, - "previousAccount": "Ankstesnė paskyra", - "@previousAccount": {}, - "widgetEtherpad": "Teksto pastaba", - "@widgetEtherpad": {}, - "widgetJitsi": "Jitsi Meet", - "@widgetJitsi": {}, - "widgetName": "Vardas", - "@widgetName": {}, - "widgetUrlError": "Netinkamas URL.", - "@widgetUrlError": {}, - "youRejectedTheInvitation": "Jūs atmetėte kvietimą", - "@youRejectedTheInvitation": {}, - "youJoinedTheChat": "Jūs prisijungėte prie pokalbio", - "@youJoinedTheChat": {}, - "youAcceptedTheInvitation": "👍 Jūs priėmėte kvietimą", - "@youAcceptedTheInvitation": {}, - "youBannedUser": "Jūs užblokavote {user}", - "@youBannedUser": { - "placeholders": { - "user": {} - } - }, - "youHaveWithdrawnTheInvitationFor": "Jūs atšaukėte kvietimą {user}", - "@youHaveWithdrawnTheInvitationFor": { - "placeholders": { - "user": {} - } - }, - "youInvitedBy": "📩 Jus pakvietė {user}", - "@youInvitedBy": { - "placeholders": { - "user": {} - } - }, - "youKicked": "👞 Jūs išmetėte {user}", - "@youKicked": { - "placeholders": { - "user": {} - } - }, - "youInvitedUser": "📩 Pakvietėte {user}", - "@youInvitedUser": { - "placeholders": { - "user": {} - } - }, - "youKickedAndBanned": "🙅 Jūs išmetėte ir užblokavote {user}", - "@youKickedAndBanned": { - "placeholders": { - "user": {} - } - }, - "youUnbannedUser": "Jūs atblokavote {user}", - "@youUnbannedUser": { - "placeholders": { - "user": {} - } - }, - "dateAndTimeOfDay": "{date}, {timeOfDay}", - "@dateAndTimeOfDay": { - "type": "text", - "placeholders": { - "date": {}, - "timeOfDay": {} - } - }, - "dateWithoutYear": "{month}-{day}", - "@dateWithoutYear": { - "type": "text", - "placeholders": { - "month": {}, - "day": {} - } - }, - "dateWithYear": "{year}-{month}-{day}", - "@dateWithYear": { - "type": "text", - "placeholders": { - "year": {}, - "month": {}, - "day": {} - } - }, - "locationDisabledNotice": "Vietos nustatymo paslaugos yra išjungtos. Kad galėtumėte bendrinti savo buvimo vietą, įjunkite jas.", - "@locationDisabledNotice": { - "type": "text", - "placeholders": {} - }, - "noMatrixServer": "{server1} nėra Matrix serveris, ar vietoj jo naudoti {server2}?", - "@noMatrixServer": { - "type": "text", - "placeholders": { - "server1": {}, - "server2": {} - } - }, - "numUsersTyping": "{count} vartotojai rašo…", - "@numUsersTyping": { - "type": "text", - "placeholders": { - "count": {} - } - }, - "enableMultiAccounts": "(BETA) Įgalinkite kelias paskyras šiame įrenginyje", - "@enableMultiAccounts": {}, - "openInMaps": "Atidaryti žemėlapiuose", - "@openInMaps": { - "type": "text", - "placeholders": {} - }, - "sentAPicture": "🖼️ {username} atsiuntė nuotrauką", - "@sentAPicture": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sentAVideo": "🎥 {username} atsiuntė vaizdo įrašą", - "@sentAVideo": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sentCallInformations": "{senderName} išsiuntė skambučio informaciją", - "@sentCallInformations": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "setCustomEmotes": "Nustatyti pasirinktinius jaustukus", - "@setCustomEmotes": { - "type": "text", - "placeholders": {} - }, - "userLeftTheChat": "🚪 {username} paliko pokalbį", - "@userLeftTheChat": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "markAsRead": "Žymėti kaip skaitytą", - "@markAsRead": {}, - "pushRules": "Tiesioginių pranešimų taisyklės", - "@pushRules": { - "type": "text", - "placeholders": {} - }, - "seenByUserAndCountOthers": "{count, plural, other{Matė {username} ir {count} kiti}}", - "@seenByUserAndCountOthers": { - "type": "text", - "placeholders": { - "username": {}, - "count": {} - } - }, - "unreadChats": "{unreadCount, plural, =1{1 unread chat} other{{unreadCount} neperskaityti pokalbiai}}", - "@unreadChats": { - "type": "text", - "placeholders": { - "unreadCount": {} - } - }, - "matrixWidgets": "Matrix valdikliai", - "@matrixWidgets": {}, - "editWidgets": "Redaguoti programėles", - "@editWidgets": {}, - "addWidget": "Pridėti programėlę", - "@addWidget": {}, - "widgetCustom": "Pasirinktinis", - "@widgetCustom": {}, - "errorAddingWidget": "Pridedant valdiklį įvyko klaida.", - "@errorAddingWidget": {}, - "askSSSSSign": "Kad galėtumėte prijungti kitą asmenį, įveskite savo saugyklos slaptafrazę arba atkūrimo raktą.", - "@askSSSSSign": { - "type": "text", - "placeholders": {} - }, - "autoplayImages": "Automatiškai leisti animuotus lipdukus ir jaustukus", - "@autoplayImages": { - "type": "text", - "placeholder": {} - }, - "ignoreListDescription": "Galite ignoruoti vartotojus, kurie jums trukdo. Negalėsite gauti jokių pranešimų ar kvietimų į kambarį iš vartotojų, įtrauktų į asmeninį ignoruojamųjų sąrašą.", - "@ignoreListDescription": { - "type": "text", - "placeholders": {} - }, - "commandHint_markasdm": "Pažymėti kaip tiesioginio pokalbio kambarį", - "@commandHint_markasdm": {}, - "dehydrateTorLong": "TOR naudotojams rekomenduojama eksportuoti sesiją prieš uždarant langą.", - "@dehydrateTorLong": {}, - "dehydrateWarning": "Šio veiksmo negalima atšaukti. Įsitikinkite, kad saugiai saugote atsarginę kopiją.", - "@dehydrateWarning": {}, - "hydrateTorLong": "Ar paskutinį kartą eksportavote savo sesiją naudodami TOR? Greitai ją importuokite ir tęskite pokalbį.", - "@hydrateTorLong": {}, - "commandHint_markasgroup": "Pažymėti kaip grupę", - "@commandHint_markasgroup": {}, - "pleaseEnterRecoveryKeyDescription": "Norėdami atrakinti senas žinutes, įveskite atkūrimo raktą, kuris buvo sukurtas ankstesnės sesijos metu. Atkūrimo raktas NĖRA jūsų slaptažodis.", - "@pleaseEnterRecoveryKeyDescription": {}, - "callingPermissions": "Skambinimo leidimai", - "@callingPermissions": {}, - "storeInAppleKeyChain": "Saugoti Apple raktų grandinėje", - "@storeInAppleKeyChain": {}, - "callingAccount": "Skambinimo paskyra", - "@callingAccount": {}, - "newSpace": "Nauja erdvė", - "@newSpace": {}, - "callingAccountDetails": "Leidžia FluffyChat naudoti vietinę Android rinkiklio programą.", - "@callingAccountDetails": {}, - "appearOnTop": "Rodyti viršuje", - "@appearOnTop": {}, - "enterSpace": "Įeiti į erdvę", - "@enterSpace": {}, - "enterRoom": "Įeiti į kambarį", - "@enterRoom": {}, - "allSpaces": "Visos erdvės", - "@allSpaces": {}, - "user": "Vartotojas", - "@user": {}, - "custom": "Pasirinktinis", - "@custom": {}, - "confirmMatrixId": "Norėdami ištrinti savo paskyrą, patvirtinkite savo Matrix ID.", - "@confirmMatrixId": {}, - "supposedMxid": "Tai turėtų būti {mxid}", - "@supposedMxid": { - "type": "text", - "placeholders": { - "mxid": {} - } - }, - "dehydrate": "Eksportuoti sesiją ir išvalyti įrenginį", - "@dehydrate": {}, - "dehydrateTor": "TOR Naudotojai: Eksportuoti sesiją", - "@dehydrateTor": {}, - "hydrateTor": "TOR Naudotojai: Importuoti sesijos eksportą", - "@hydrateTor": {}, - "hydrate": "Atkurti iš atsarginės kopijos failo", - "@hydrate": {}, - "pleaseEnterRecoveryKey": "Įveskite savo atkūrimo raktą:", - "@pleaseEnterRecoveryKey": {}, - "recoveryKey": "Atkūrimo raktas", - "@recoveryKey": {}, - "recoveryKeyLost": "Pamestas atkūrimo raktas?", - "@recoveryKeyLost": {}, - "indexedDbErrorLong": "Deja, pagal numatytuosius nustatymus žinučių saugojimas privačiame režime nėra įjungtas.\nPrašome apsilankyti\n - about:config\n - nustatykite dom.indexedDB.privateBrowsing.enabled į true\nPriešingu atveju FluffyChat paleisti neįmanoma.", - "@indexedDbErrorLong": {}, - "noEmailWarning": "Įveskite galiojantį el. pašto adresą. Priešingu atveju negalėsite iš naujo nustatyti slaptažodžio. Jei nenorite, dar kartą bakstelėkite mygtuką, kad galėtumėte tęsti.", - "@noEmailWarning": {}, - "countFiles": "{count} failai", - "@countFiles": { - "placeholders": { - "count": {} - } - }, - "updateAvailable": "Galimas FluffyChat atnaujinimas", - "@updateAvailable": {}, - "updateNow": "Pradėti atnaujinimą fone", - "@updateNow": {}, - "storeInSecureStorageDescription": "Atkūrimo raktą laikyti saugioje šio prietaiso saugykloje.", - "@storeInSecureStorageDescription": {}, - "saveKeyManuallyDescription": "Įrašykite šį raktą rankiniu būdu, įjungę sistemos bendrinimo dialogo langą arba iškarpinę.", - "@saveKeyManuallyDescription": {}, - "users": "Vartotojai", - "@users": {}, - "stories": "Istorijos", - "@stories": {}, - "storeSecurlyOnThisDevice": "Saugiai laikyti šiame prietaise", - "@storeSecurlyOnThisDevice": {}, - "unlockOldMessages": "Atrakinti senas žinutes", - "@unlockOldMessages": {}, - "storeInAndroidKeystore": "Saugoti Android raktų saugykloje", - "@storeInAndroidKeystore": {}, - "indexedDbErrorTitle": "Privataus režimo problemos", - "@indexedDbErrorTitle": {}, - "noKeyForThisMessage": "Taip gali atsitikti, jei žinutė buvo išsiųsta prieš prisijungiant prie paskyros šiame prietaise.\n\nTaip pat gali būti, kad siuntėjas užblokavo jūsų prietaisą arba kažkas sutriko su interneto ryšiu.\n\nAr galite perskaityti žinutę kitoje sesijoje? Tada galite perkelti žinutę iš jos! Eikite į Nustatymai > Prietaisai ir įsitikinkite, kad jūsų prietaisai patvirtino vienas kitą. Kai kitą kartą atidarysite kambarį ir abi sesijos bus pirmame plane, raktai bus perduoti automatiškai.\n\nNenorite prarasti raktų atsijungdami arba keisdami įrenginius? Įsitikinkite, kad nustatymuose įjungėte pokalbių atsarginę kopiją.", - "@noKeyForThisMessage": {}, - "foregroundServiceRunning": "Šis pranešimas rodomas, kai veikia pirmojo plano paslauga.", - "@foregroundServiceRunning": {}, - "screenSharingTitle": "ekrano bendrinimas", - "@screenSharingTitle": {}, - "appearOnTopDetails": "Leidžia programėlę rodyti viršuje (nebūtina, jei jau esate nustatę Fluffychat kaip skambinimo paskyrą)", - "@appearOnTopDetails": {}, - "otherCallingPermissions": "Mikrofonas, kamera ir kiti FluffyChat leidimai", - "@otherCallingPermissions": {}, - "whyIsThisMessageEncrypted": "Kodėl ši žinutė neperskaitoma?", - "@whyIsThisMessageEncrypted": {}, - "newGroup": "Nauja grupė", - "@newGroup": {}, - "screenSharingDetail": "Bendrinate savo ekraną per FuffyChat", - "@screenSharingDetail": {}, - "numChats": "{number} pokalbiai", - "@numChats": { - "type": "number", - "placeholders": { - "number": {} - } - }, - "hideUnimportantStateEvents": "Slėpti nesvarbius būsenos įvykius", - "@hideUnimportantStateEvents": {} -} \ No newline at end of file + "commandHint_leave": "Palikti pokalbių kambarį", + "@commandHint_leave": { + "type": "text", + "description": "Usage hint for the command /leave" + }, + "confirm": "Patvirtinti", + "@confirm": { + "type": "text", + "placeholders": {} + }, + "cancel": "Atšaukti", + "@cancel": { + "type": "text", + "placeholders": {} + }, + "edit": "Redaguoti", + "@edit": { + "type": "text", + "placeholders": {} + }, + "downloadFile": "Atsisiųsti failą", + "@downloadFile": { + "type": "text", + "placeholders": {} + }, + "about": "Apie", + "@about": { + "type": "text", + "placeholders": {} + }, + "all": "Visi", + "@all": { + "type": "text", + "placeholders": {} + }, + "fluffychat": "FluffyChat", + "@fluffychat": { + "type": "text", + "placeholders": {} + }, + "fileName": "Failo vardas", + "@fileName": { + "type": "text", + "placeholders": {} + }, + "changePassword": "Keisti slaptažodį", + "@changePassword": { + "type": "text", + "placeholders": {} + }, + "close": "Uždaryti", + "@close": { + "type": "text", + "placeholders": {} + }, + "archive": "Archyvas", + "@archive": { + "type": "text", + "placeholders": {} + }, + "skip": "Praleisti", + "@skip": { + "type": "text", + "placeholders": {} + }, + "share": "Bendrinti", + "@share": { + "type": "text", + "placeholders": {} + }, + "showPassword": "Rodyti slaptažodį", + "@showPassword": { + "type": "text", + "placeholders": {} + }, + "time": "Laikas", + "@time": {}, + "settings": "Nustatytmai", + "@settings": { + "type": "text", + "placeholders": {} + }, + "sender": "Siuntėjas", + "@sender": {}, + "yes": "Taip", + "@yes": { + "type": "text", + "placeholders": {} + }, + "you": "Jūs", + "@you": { + "type": "text", + "placeholders": {} + }, + "logout": "Atsijungti", + "@logout": { + "type": "text", + "placeholders": {} + }, + "messages": "Žinutės", + "@messages": { + "type": "text", + "placeholders": {} + }, + "scanQrCode": "Nuskanuokite QR kodą", + "@scanQrCode": {}, + "ok": "OK", + "@ok": { + "type": "text", + "placeholders": {} + }, + "addAccount": "Pridėti paskyrą", + "@addAccount": {}, + "or": "Arba", + "@or": { + "type": "text", + "placeholders": {} + }, + "password": "Slaptažodis", + "@password": { + "type": "text", + "placeholders": {} + }, + "passwordHasBeenChanged": "Slaptažodis pakeistas", + "@passwordHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourPassword": "Įveskite savo slaptažodį", + "@pleaseEnterYourPassword": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourUsername": "Įveskite savo vartotojo vardą", + "@pleaseEnterYourUsername": { + "type": "text", + "placeholders": {} + }, + "reply": "Atsakyti", + "@reply": { + "type": "text", + "placeholders": {} + }, + "blockDevice": "Blokuoti įrenginį", + "@blockDevice": { + "type": "text", + "placeholders": {} + }, + "blocked": "Užblokuotas", + "@blocked": { + "type": "text", + "placeholders": {} + }, + "chooseAStrongPassword": "Pasirinkite saugų slaptažodį", + "@chooseAStrongPassword": { + "type": "text", + "placeholders": {} + }, + "createNewGroup": "Sukurti naują grupę", + "@createNewGroup": { + "type": "text", + "placeholders": {} + }, + "deleteMessage": "Ištrinti žinutę", + "@deleteMessage": { + "type": "text", + "placeholders": {} + }, + "deny": "Atmesti", + "@deny": { + "type": "text", + "placeholders": {} + }, + "device": "Įrenginys", + "@device": { + "type": "text", + "placeholders": {} + }, + "deviceId": "Įrenginio ID", + "@deviceId": { + "type": "text", + "placeholders": {} + }, + "devices": "Įrenginiai", + "@devices": { + "type": "text", + "placeholders": {} + }, + "homeserver": "Namų serveris", + "@homeserver": {}, + "enterYourHomeserver": "Įveskite namų serverį", + "@enterYourHomeserver": { + "type": "text", + "placeholders": {} + }, + "everythingReady": "Viskas paruošta!", + "@everythingReady": { + "type": "text", + "placeholders": {} + }, + "fontSize": "Šrifto dydis", + "@fontSize": { + "type": "text", + "placeholders": {} + }, + "clearArchive": "Išvalyti archyvą", + "@clearArchive": {}, + "create": "Sukurti", + "@create": { + "type": "text", + "placeholders": {} + }, + "connect": "Prisijungti", + "@connect": { + "type": "text", + "placeholders": {} + }, + "people": "Žmonės", + "@people": { + "type": "text", + "placeholders": {} + }, + "messageWillBeRemovedWarning": "Žinutė bus pašalinta visiem dalyviams", + "@messageWillBeRemovedWarning": { + "type": "text", + "placeholders": {} + }, + "moderator": "Moderatorius", + "@moderator": { + "type": "text", + "placeholders": {} + }, + "muteChat": "Nutildyti pokalbį", + "@muteChat": { + "type": "text", + "placeholders": {} + }, + "newChat": "Naujas pokalbis", + "@newChat": { + "type": "text", + "placeholders": {} + }, + "shareYourInviteLink": "Bendrinti savo pakvietimo nuorodą", + "@shareYourInviteLink": {}, + "none": "Nė vienas", + "@none": { + "type": "text", + "placeholders": {} + }, + "noPermission": "Nėra leidimo", + "@noPermission": { + "type": "text", + "placeholders": {} + }, + "noRoomsFound": "Nerasta kambarių…", + "@noRoomsFound": { + "type": "text", + "placeholders": {} + }, + "notifications": "Pranešimai", + "@notifications": { + "type": "text", + "placeholders": {} + }, + "notificationsEnabledForThisAccount": "Pranešimai aktyvuoti šitai paskyrai", + "@notificationsEnabledForThisAccount": { + "type": "text", + "placeholders": {} + }, + "obtainingLocation": "Gaunama vieta…", + "@obtainingLocation": { + "type": "text", + "placeholders": {} + }, + "offensive": "Agresyvus", + "@offensive": { + "type": "text", + "placeholders": {} + }, + "offline": "Neprisijungta", + "@offline": { + "type": "text", + "placeholders": {} + }, + "online": "Prisijungta", + "@online": { + "type": "text", + "placeholders": {} + }, + "oopsPushError": "Oi! Deja, nustatant tiesioginius pranešimus įvyko klaida.", + "@oopsPushError": { + "type": "text", + "placeholders": {} + }, + "oopsSomethingWentWrong": "Oi, kažkas nutiko ne taip…", + "@oopsSomethingWentWrong": { + "type": "text", + "placeholders": {} + }, + "openAppToReadMessages": "Atidarykite programėlę, kad perskaityti žinutes", + "@openAppToReadMessages": { + "type": "text", + "placeholders": {} + }, + "link": "Nuoroda", + "@link": {}, + "participant": "Dalyvis", + "@participant": { + "type": "text", + "placeholders": {} + }, + "passphraseOrKey": "Slapta frazė arba atkūrimo raktas", + "@passphraseOrKey": { + "type": "text", + "placeholders": {} + }, + "passwordForgotten": "Slaptažodis užmirštas", + "@passwordForgotten": { + "type": "text", + "placeholders": {} + }, + "passwordRecovery": "Slaptažodžio atkūrimas", + "@passwordRecovery": { + "type": "text", + "placeholders": {} + }, + "pickImage": "Pasirinkite paveiksliuką", + "@pickImage": { + "type": "text", + "placeholders": {} + }, + "pin": "Prisegti", + "@pin": { + "type": "text", + "placeholders": {} + }, + "pleaseChoose": "Prašome pasirinkti", + "@pleaseChoose": { + "type": "text", + "placeholders": {} + }, + "pleaseChooseAPasscode": "Pasirinkite slaptą kodą", + "@pleaseChooseAPasscode": { + "type": "text", + "placeholders": {} + }, + "pleaseChooseAUsername": "Pasirinkite vartotojo vardą", + "@pleaseChooseAUsername": { + "type": "text", + "placeholders": {} + }, + "pleaseClickOnLink": "Paspauskite nuorodą el. pašte ir tęskite toliau.", + "@pleaseClickOnLink": { + "type": "text", + "placeholders": {} + }, + "pleaseEnter4Digits": "Įveskite 4 skaitmenis arba palikite tuščią, jei norite išjungti programėlės užraktą.", + "@pleaseEnter4Digits": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterAMatrixIdentifier": "Įveskite Matrix ID.", + "@pleaseEnterAMatrixIdentifier": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourPin": "Įveskite savo PIN kodą", + "@pleaseEnterYourPin": { + "type": "text", + "placeholders": {} + }, + "pleaseFollowInstructionsOnWeb": "Vadovaukitės svetainėje pateiktais nurodymais ir bakstelėkite Toliau.", + "@pleaseFollowInstructionsOnWeb": { + "type": "text", + "placeholders": {} + }, + "privacy": "Privatumas", + "@privacy": { + "type": "text", + "placeholders": {} + }, + "publicRooms": "Vieši kambariai", + "@publicRooms": { + "type": "text", + "placeholders": {} + }, + "reason": "Priežastis", + "@reason": { + "type": "text", + "placeholders": {} + }, + "recording": "Įrašymas", + "@recording": { + "type": "text", + "placeholders": {} + }, + "redactMessage": "Pašalinti žinutę", + "@redactMessage": { + "type": "text", + "placeholders": {} + }, + "register": "Registruotis", + "@register": { + "type": "text", + "placeholders": {} + }, + "reject": "Atmesti", + "@reject": { + "type": "text", + "placeholders": {} + }, + "rejoin": "Vėl prisijungti", + "@rejoin": { + "type": "text", + "placeholders": {} + }, + "remove": "Pašalinti", + "@remove": { + "type": "text", + "placeholders": {} + }, + "removeAllOtherDevices": "Pašalinti visus kitus įrenginius", + "@removeAllOtherDevices": { + "type": "text", + "placeholders": {} + }, + "removeDevice": "Pašalinti įrenginį", + "@removeDevice": { + "type": "text", + "placeholders": {} + }, + "removeYourAvatar": "Pašalinti savo avatarą", + "@removeYourAvatar": { + "type": "text", + "placeholders": {} + }, + "replaceRoomWithNewerVersion": "Pakeisti kambarį naujesne versija", + "@replaceRoomWithNewerVersion": { + "type": "text", + "placeholders": {} + }, + "requestPermission": "Prašyti leidimo", + "@requestPermission": { + "type": "text", + "placeholders": {} + }, + "roomHasBeenUpgraded": "Kambarys buvo atnaujintas", + "@roomHasBeenUpgraded": { + "type": "text", + "placeholders": {} + }, + "roomVersion": "Kambario versija", + "@roomVersion": { + "type": "text", + "placeholders": {} + }, + "search": "Ieškoti", + "@search": { + "type": "text", + "placeholders": {} + }, + "accept": "Sutinku", + "@accept": { + "type": "text", + "placeholders": {} + }, + "passwordsDoNotMatch": "Slaptažodžiai nesutampa!", + "@passwordsDoNotMatch": {}, + "pleaseEnterValidEmail": "Įveskite teisingą el. pašto adresą.", + "@pleaseEnterValidEmail": {}, + "repeatPassword": "Pakartokite slaptažodį", + "@repeatPassword": {}, + "addEmail": "Pridėti el. paštą", + "@addEmail": { + "type": "text", + "placeholders": {} + }, + "addGroupDescription": "Pridėkite grupės aprašymą", + "@addGroupDescription": { + "type": "text", + "placeholders": {} + }, + "admin": "Administratorius", + "@admin": { + "type": "text", + "placeholders": {} + }, + "alias": "slapyvardis", + "@alias": { + "type": "text", + "placeholders": {} + }, + "allChats": "Visi pokalbiai", + "@allChats": { + "type": "text", + "placeholders": {} + }, + "anyoneCanJoin": "Bet kas gali prisijungti", + "@anyoneCanJoin": { + "type": "text", + "placeholders": {} + }, + "areYouSure": "Ar esate tikri?", + "@areYouSure": { + "type": "text", + "placeholders": {} + }, + "areYouSureYouWantToLogout": "Ar tikrai norite atsijungti?", + "@areYouSureYouWantToLogout": { + "type": "text", + "placeholders": {} + }, + "changeTheHomeserver": "Pakeisti namų serverį", + "@changeTheHomeserver": { + "type": "text", + "placeholders": {} + }, + "changeTheme": "Keisti savo stilių", + "@changeTheme": { + "type": "text", + "placeholders": {} + }, + "changeTheNameOfTheGroup": "Keisti grupės pavadinimą", + "@changeTheNameOfTheGroup": { + "type": "text", + "placeholders": {} + }, + "changeWallpaper": "Keisti ekrano užsklandą", + "@changeWallpaper": { + "type": "text", + "placeholders": {} + }, + "changeYourAvatar": "Keisti savo avatarą", + "@changeYourAvatar": { + "type": "text", + "placeholders": {} + }, + "chat": "Pokalbis", + "@chat": { + "type": "text", + "placeholders": {} + }, + "chatDetails": "Pokalbio detalės", + "@chatDetails": { + "type": "text", + "placeholders": {} + }, + "chats": "Pokalbiai", + "@chats": { + "type": "text", + "placeholders": {} + }, + "commandHint_ban": "Užblokuoti vartotoją šiame kambaryje", + "@commandHint_ban": { + "type": "text", + "description": "Usage hint for the command /ban" + }, + "commandHint_clearcache": "Išvalyti laikiną talpyklą", + "@commandHint_clearcache": { + "type": "text", + "description": "Usage hint for the command /clearcache" + }, + "commandHint_discardsession": "Atmesti sesiją", + "@commandHint_discardsession": { + "type": "text", + "description": "Usage hint for the command /discardsession" + }, + "commandHint_html": "Siųsti tekstą HTML formatu", + "@commandHint_html": { + "type": "text", + "description": "Usage hint for the command /html" + }, + "commandHint_invite": "Pakviesti vartotoją į šitą kambarį", + "@commandHint_invite": { + "type": "text", + "description": "Usage hint for the command /invite" + }, + "commandHint_join": "Prisijungti prie nurodyto kambario", + "@commandHint_join": { + "type": "text", + "description": "Usage hint for the command /join" + }, + "commandHint_kick": "Pašalinti vartotoja iš šito kambario", + "@commandHint_kick": { + "type": "text", + "description": "Usage hint for the command /kick" + }, + "commandHint_myroomnick": "Nustatyti savo rodomą vardą šiame kambaryje", + "@commandHint_myroomnick": { + "type": "text", + "description": "Usage hint for the command /myroomnick" + }, + "commandHint_plain": "Siųsti neformatuotą tekstą", + "@commandHint_plain": { + "type": "text", + "description": "Usage hint for the command /plain" + }, + "commandHint_send": "Siųsti tekstą", + "@commandHint_send": { + "type": "text", + "description": "Usage hint for the command /send" + }, + "commandHint_unban": "Atblokuoti vartotoją šiame kambaryje", + "@commandHint_unban": { + "type": "text", + "description": "Usage hint for the command /unban" + }, + "commandInvalid": "Neteisinga komanda", + "@commandInvalid": { + "type": "text" + }, + "configureChat": "Konfigūruoti pokalbį", + "@configureChat": { + "type": "text", + "placeholders": {} + }, + "copiedToClipboard": "Nukopijuota į iškarpinę", + "@copiedToClipboard": { + "type": "text", + "placeholders": {} + }, + "copy": "Kopijuoti", + "@copy": { + "type": "text", + "placeholders": {} + }, + "copyToClipboard": "Koipjuoti į iškarpinę", + "@copyToClipboard": { + "type": "text", + "placeholders": {} + }, + "currentlyActive": "Šiuo metu aktyvus", + "@currentlyActive": { + "type": "text", + "placeholders": {} + }, + "darkTheme": "Tamsi", + "@darkTheme": { + "type": "text", + "placeholders": {} + }, + "delete": "Ištrinti", + "@delete": { + "type": "text", + "placeholders": {} + }, + "deleteAccount": "Panaikinti paskyra", + "@deleteAccount": { + "type": "text", + "placeholders": {} + }, + "directChats": "Tiesioginiai pokalbiai", + "@directChats": { + "type": "text", + "placeholders": {} + }, + "encrypted": "Užšifruotas", + "@encrypted": { + "type": "text", + "placeholders": {} + }, + "encryptionNotEnabled": "Šifravimas aktyvuotas", + "@encryptionNotEnabled": { + "type": "text", + "placeholders": {} + }, + "enterAGroupName": "Įveskite grupės vardą", + "@enterAGroupName": { + "type": "text", + "placeholders": {} + }, + "enterAnEmailAddress": "Įveskite el. pašto adresą", + "@enterAnEmailAddress": { + "type": "text", + "placeholders": {} + }, + "extremeOffensive": "Itin įžeidžiantis", + "@extremeOffensive": { + "type": "text", + "placeholders": {} + }, + "forward": "Toliau", + "@forward": { + "type": "text", + "placeholders": {} + }, + "fromJoining": "Nuo prisijungimo", + "@fromJoining": { + "type": "text", + "placeholders": {} + }, + "fromTheInvitation": "Nuo pakvietimo", + "@fromTheInvitation": { + "type": "text", + "placeholders": {} + }, + "goToTheNewRoom": "Eiti į naują kambarį", + "@goToTheNewRoom": { + "type": "text", + "placeholders": {} + }, + "group": "Grupė", + "@group": { + "type": "text", + "placeholders": {} + }, + "groupDescription": "Grupės aprašymas", + "@groupDescription": { + "type": "text", + "placeholders": {} + }, + "groupDescriptionHasBeenChanged": "Grupės aprašymas pakeistas", + "@groupDescriptionHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "groupIsPublic": "Grupė yra vieša", + "@groupIsPublic": { + "type": "text", + "placeholders": {} + }, + "groups": "Grupės", + "@groups": { + "type": "text", + "placeholders": {} + }, + "guestsAreForbidden": "Svečiams draudžiama", + "@guestsAreForbidden": { + "type": "text", + "placeholders": {} + }, + "guestsCanJoin": "Svečiai gali prisijungti", + "@guestsCanJoin": { + "type": "text", + "placeholders": {} + }, + "help": "Pagalba", + "@help": { + "type": "text", + "placeholders": {} + }, + "hideRedactedEvents": "Slėpti pašalintus įvykius", + "@hideRedactedEvents": { + "type": "text", + "placeholders": {} + }, + "hideUnknownEvents": "Slėpti nežinomus įvykius", + "@hideUnknownEvents": { + "type": "text", + "placeholders": {} + }, + "identity": "Tapatybė", + "@identity": { + "type": "text", + "placeholders": {} + }, + "ignore": "Ignoruoti", + "@ignore": { + "type": "text", + "placeholders": {} + }, + "ignoredUsers": "Ignoruoti vartotojai", + "@ignoredUsers": { + "type": "text", + "placeholders": {} + }, + "leave": "Palikti", + "@leave": { + "type": "text", + "placeholders": {} + }, + "loginWithOneClick": "Prisijungti vienu paspaudimu", + "@loginWithOneClick": {}, + "makeSureTheIdentifierIsValid": "Įsitikinkite, kad indentifikatorius galiojantis", + "@makeSureTheIdentifierIsValid": { + "type": "text", + "placeholders": {} + }, + "memberChanges": "Narių pokyčiai", + "@memberChanges": { + "type": "text", + "placeholders": {} + }, + "mention": "Paminėti", + "@mention": { + "type": "text", + "placeholders": {} + }, + "encryption": "Šifravimas", + "@encryption": { + "type": "text", + "placeholders": {} + }, + "enableEncryption": "Aktyvuoti šifravimą", + "@enableEncryption": { + "type": "text", + "placeholders": {} + }, + "editBlockedServers": "Redaguoti blokuotus serverius", + "@editBlockedServers": { + "type": "text", + "placeholders": {} + }, + "editChatPermissions": "Redaguoti pokalbio leidimus", + "@editChatPermissions": { + "type": "text", + "placeholders": {} + }, + "login": "Prisijungti", + "@login": { + "type": "text", + "placeholders": {} + }, + "sendOnEnter": "Išsiųsti paspaudus Enter", + "@sendOnEnter": {}, + "banFromChat": "Užblokuoti iš pokalbio", + "@banFromChat": { + "type": "text", + "placeholders": {} + }, + "banned": "Užblokuotas", + "@banned": { + "type": "text", + "placeholders": {} + }, + "changeDeviceName": "Pakeisti įrenginio vardą", + "@changeDeviceName": { + "type": "text", + "placeholders": {} + }, + "yourChatBackupHasBeenSetUp": "Jūsų pokalbio atsarginė kopija buvo nustatyta.", + "@yourChatBackupHasBeenSetUp": {}, + "chatBackup": "Pokalbio atsargine kopija", + "@chatBackup": { + "type": "text", + "placeholders": {} + }, + "commandHint_me": "Apibūdinkite save", + "@commandHint_me": { + "type": "text", + "description": "Usage hint for the command /me" + }, + "displaynameHasBeenChanged": "Rodomas vardas buvo pakeistas", + "@displaynameHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "editDisplayname": "Redaguoti rodomą vardą", + "@editDisplayname": { + "type": "text", + "placeholders": {} + }, + "editRoomAliases": "Redaguoti kambario pseudonimus", + "@editRoomAliases": { + "type": "text", + "placeholders": {} + }, + "editRoomAvatar": "Redaguoti kambario avatarą", + "@editRoomAvatar": { + "type": "text", + "placeholders": {} + }, + "howOffensiveIsThisContent": "Kiek įžeižiantis šis turinys?", + "@howOffensiveIsThisContent": { + "type": "text", + "placeholders": {} + }, + "id": "ID", + "@id": { + "type": "text", + "placeholders": {} + }, + "ignoreUsername": "Ignoruoti vartotoją", + "@ignoreUsername": { + "type": "text", + "placeholders": {} + }, + "iHaveClickedOnLink": "Aš paspaudžiau nuorodą", + "@iHaveClickedOnLink": { + "type": "text", + "placeholders": {} + }, + "incorrectPassphraseOrKey": "Neteisinga slaptafrazė arba atkūrimo raktas", + "@incorrectPassphraseOrKey": { + "type": "text", + "placeholders": {} + }, + "inoffensive": "Neįžeidžiantis", + "@inoffensive": { + "type": "text", + "placeholders": {} + }, + "inviteContact": "Pakviesti kontaktą", + "@inviteContact": { + "type": "text", + "placeholders": {} + }, + "invited": "Pakviestas", + "@invited": { + "type": "text", + "placeholders": {} + }, + "invitedUsersOnly": "Tik pakviesti vartotojai", + "@invitedUsersOnly": { + "type": "text", + "placeholders": {} + }, + "isTyping": "rašo…", + "@isTyping": { + "type": "text", + "placeholders": {} + }, + "joinRoom": "Prisijungti prie kambario", + "@joinRoom": { + "type": "text", + "placeholders": {} + }, + "kickFromChat": "Išmesti iš pokalbio", + "@kickFromChat": { + "type": "text", + "placeholders": {} + }, + "lastSeenLongTimeAgo": "Seniai matytas", + "@lastSeenLongTimeAgo": { + "type": "text", + "placeholders": {} + }, + "leftTheChat": "Paliko pokalbį", + "@leftTheChat": { + "type": "text", + "placeholders": {} + }, + "license": "Licencija", + "@license": { + "type": "text", + "placeholders": {} + }, + "lightTheme": "Šviesi", + "@lightTheme": { + "type": "text", + "placeholders": {} + }, + "loadingPleaseWait": "Kraunama… Prašome palaukti.", + "@loadingPleaseWait": { + "type": "text", + "placeholders": {} + }, + "loadMore": "Rodyti daugiau…", + "@loadMore": { + "type": "text", + "placeholders": {} + }, + "newMessageInFluffyChat": "💬 Nauja žinutė FluffyChat'e", + "@newMessageInFluffyChat": { + "type": "text", + "placeholders": {} + }, + "newVerificationRequest": "Nauja patvirtinimo užklausa!", + "@newVerificationRequest": { + "type": "text", + "placeholders": {} + }, + "next": "Toliau", + "@next": { + "type": "text", + "placeholders": {} + }, + "no": "Ne", + "@no": { + "type": "text", + "placeholders": {} + }, + "noConnectionToTheServer": "Nėra ryšio su serveriu", + "@noConnectionToTheServer": { + "type": "text", + "placeholders": {} + }, + "setGroupDescription": "Nustatyti grupės aprašymą", + "@setGroupDescription": { + "type": "text", + "placeholders": {} + }, + "setInvitationLink": "Nustatyti pakvietimo nuorodą", + "@setInvitationLink": { + "type": "text", + "placeholders": {} + }, + "singlesignon": "Vienkartinis prisijungimas", + "@singlesignon": { + "type": "text", + "placeholders": {} + }, + "sourceCode": "Programinis kodas", + "@sourceCode": { + "type": "text", + "placeholders": {} + }, + "spaceIsPublic": "Erdvė yra vieša", + "@spaceIsPublic": { + "type": "text", + "placeholders": {} + }, + "spaceName": "Erdvės pavadinimas", + "@spaceName": { + "type": "text", + "placeholders": {} + }, + "status": "Būsena", + "@status": { + "type": "text", + "placeholders": {} + }, + "statusExampleMessage": "Kaip sekasi šiandien?", + "@statusExampleMessage": { + "type": "text", + "placeholders": {} + }, + "submit": "Pateikti", + "@submit": { + "type": "text", + "placeholders": {} + }, + "synchronizingPleaseWait": "Sinchronizuojama… Prašome palaukti.", + "@synchronizingPleaseWait": { + "type": "text", + "placeholders": {} + }, + "transferFromAnotherDevice": "Perkėlimas iš kito įrenginio", + "@transferFromAnotherDevice": { + "type": "text", + "placeholders": {} + }, + "verify": "Patvirtinti", + "@verify": { + "type": "text", + "placeholders": {} + }, + "verifyStart": "Pradėti patvirtinimą", + "@verifyStart": { + "type": "text", + "placeholders": {} + }, + "verifySuccess": "Jūs sėkmingai patvirtinote!", + "@verifySuccess": { + "type": "text", + "placeholders": {} + }, + "verifyTitle": "Patvirtinama kita paskyra", + "@verifyTitle": { + "type": "text", + "placeholders": {} + }, + "visibilityOfTheChatHistory": "Pokalbių istorijos matomumas", + "@visibilityOfTheChatHistory": { + "type": "text", + "placeholders": {} + }, + "visibleForAllParticipants": "Matoma visiems dalyviams", + "@visibleForAllParticipants": { + "type": "text", + "placeholders": {} + }, + "waitingPartnerAcceptRequest": "Laukiama, kol dalyvis priims užklausą…", + "@waitingPartnerAcceptRequest": { + "type": "text", + "placeholders": {} + }, + "writeAMessage": "Rašyti žinutę…", + "@writeAMessage": { + "type": "text", + "placeholders": {} + }, + "youAreInvitedToThisChat": "Esate pakviesti į šį pokalbį", + "@youAreInvitedToThisChat": { + "type": "text", + "placeholders": {} + }, + "youAreNoLongerParticipatingInThisChat": "Jūs nebedalyvaujate šiame pokalbyje", + "@youAreNoLongerParticipatingInThisChat": { + "type": "text", + "placeholders": {} + }, + "youCannotInviteYourself": "Jūs negalite pakviesti savęs", + "@youCannotInviteYourself": { + "type": "text", + "placeholders": {} + }, + "youHaveBeenBannedFromThisChat": "Jums buvo uždrausta dalyvauti šiame pokalbyje", + "@youHaveBeenBannedFromThisChat": { + "type": "text", + "placeholders": {} + }, + "messageInfo": "Žinutės informacija", + "@messageInfo": {}, + "removeFromSpace": "Pašalinti iš erdvės", + "@removeFromSpace": {}, + "security": "Apsauga", + "@security": { + "type": "text", + "placeholders": {} + }, + "sendAsText": "Siųsti kaip tekstą", + "@sendAsText": { + "type": "text" + }, + "sendAudio": "Siųsti garso įrašą", + "@sendAudio": { + "type": "text", + "placeholders": {} + }, + "sendImage": "Siųsti paveiksliuką", + "@sendImage": { + "type": "text", + "placeholders": {} + }, + "sendFile": "Sųsti bylą", + "@sendFile": { + "type": "text", + "placeholders": {} + }, + "sendMessages": "Siųsti žinutes", + "@sendMessages": { + "type": "text", + "placeholders": {} + }, + "sendOriginal": "Siųsti originalą", + "@sendOriginal": { + "type": "text", + "placeholders": {} + }, + "sendVideo": "Siųsti video", + "@sendVideo": { + "type": "text", + "placeholders": {} + }, + "separateChatTypes": "Atskirti tiesioginius pokalbius ir grupes", + "@separateChatTypes": { + "type": "text", + "placeholders": {} + }, + "setAsCanonicalAlias": "Nustatyti kaip pagrindinį slapyvardį", + "@setAsCanonicalAlias": { + "type": "text", + "placeholders": {} + }, + "setPermissionsLevel": "Nustatyti leidimų lygį", + "@setPermissionsLevel": { + "type": "text", + "placeholders": {} + }, + "setStatus": "Nustatyti būseną", + "@setStatus": { + "type": "text", + "placeholders": {} + }, + "shareLocation": "Bendrinti vietą", + "@shareLocation": { + "type": "text", + "placeholders": {} + }, + "showDirectChatsInSpaces": "Rodyti susijusius tiesioginius pokalbius erdvėse", + "@showDirectChatsInSpaces": { + "type": "text", + "placeholders": {} + }, + "signUp": "Registruotis", + "@signUp": { + "type": "text", + "placeholders": {} + }, + "systemTheme": "Sistema", + "@systemTheme": { + "type": "text", + "placeholders": {} + }, + "unavailable": "Nepasiekiamas", + "@unavailable": { + "type": "text", + "placeholders": {} + }, + "unblockDevice": "Atblokuoti įrenginį", + "@unblockDevice": { + "type": "text", + "placeholders": {} + }, + "unknownEncryptionAlgorithm": "Nežinomas šifravimo algoritmas", + "@unknownEncryptionAlgorithm": { + "type": "text", + "placeholders": {} + }, + "unmuteChat": "Įjungti pokalbio garsą", + "@unmuteChat": { + "type": "text", + "placeholders": {} + }, + "unpin": "Atsegti", + "@unpin": { + "type": "text", + "placeholders": {} + }, + "username": "Vartotojo vardas", + "@username": { + "type": "text", + "placeholders": {} + }, + "unverified": "Nepatvirtinta", + "@unverified": {}, + "verified": "Patvirtinta", + "@verified": { + "type": "text", + "placeholders": {} + }, + "videoCall": "Vaizdo skambutis", + "@videoCall": { + "type": "text", + "placeholders": {} + }, + "yourPublicKey": "Jūsų viešasis raktas", + "@yourPublicKey": { + "type": "text", + "placeholders": {} + }, + "addToSpaceDescription": "Pasirinkite erdvę, kad prie jos pridėtumėte šį pokalbį.", + "@addToSpaceDescription": {}, + "start": "Pradžia", + "@start": {}, + "account": "Paskyra", + "@account": { + "type": "text", + "placeholders": {} + }, + "addToSpace": "Pridėti į erdvę", + "@addToSpace": {}, + "appLock": "Programos užraktas", + "@appLock": { + "type": "text", + "placeholders": {} + }, + "areGuestsAllowedToJoin": "Ar svečiams leidžiama prisijungti", + "@areGuestsAllowedToJoin": { + "type": "text", + "placeholders": {} + }, + "botMessages": "Botų žinutės", + "@botMessages": { + "type": "text", + "placeholders": {} + }, + "bubbleSize": "Burbulo dydis", + "@bubbleSize": { + "type": "text", + "placeholders": {} + }, + "channelCorruptedDecryptError": "Šifravimas buvo sugadintas", + "@channelCorruptedDecryptError": { + "type": "text", + "placeholders": {} + }, + "chatHasBeenAddedToThisSpace": "Pokalbis buvo pridėtas prie šios erdvės", + "@chatHasBeenAddedToThisSpace": {}, + "compareEmojiMatch": "Palyginkite jaustukus", + "@compareEmojiMatch": { + "type": "text", + "placeholders": {} + }, + "compareNumbersMatch": "Palyginkite skaičius", + "@compareNumbersMatch": { + "type": "text", + "placeholders": {} + }, + "contactHasBeenInvitedToTheGroup": "Kontaktas buvo pakviestas į grupę", + "@contactHasBeenInvitedToTheGroup": { + "type": "text", + "placeholders": {} + }, + "contentHasBeenReported": "Apie turinį pranešta serverio administratoriams", + "@contentHasBeenReported": { + "type": "text", + "placeholders": {} + }, + "createNewSpace": "Nauja erdvė", + "@createNewSpace": { + "type": "text", + "placeholders": {} + }, + "deactivateAccountWarning": "Tai deaktyvuos jūsų vartotojo paskyrą. Tai negali būti atšaukta! Ar jūs tuo tikri?", + "@deactivateAccountWarning": { + "type": "text", + "placeholders": {} + }, + "defaultPermissionLevel": "Numatytasis teisių lygis", + "@defaultPermissionLevel": { + "type": "text", + "placeholders": {} + }, + "enableEncryptionWarning": "Šifravimo nebegalėsite išjungti. Ar jūs tuo tikri?", + "@enableEncryptionWarning": { + "type": "text", + "placeholders": {} + }, + "enterASpacepName": "Įveskite erdvės vardą", + "@enterASpacepName": {}, + "send": "Siųsti", + "@send": { + "type": "text", + "placeholders": {} + }, + "sendAMessage": "Siųsti žinutę", + "@sendAMessage": { + "type": "text", + "placeholders": {} + }, + "toggleUnread": "Pažymėti kaip skaitytą/neskaitytą", + "@toggleUnread": { + "type": "text", + "placeholders": {} + }, + "tooManyRequestsWarning": "Per daug užklausų. Pabandykite dar kartą vėliau!", + "@tooManyRequestsWarning": { + "type": "text", + "placeholders": {} + }, + "waitingPartnerEmoji": "Laukiama, kol dalyvis priims jaustukus…", + "@waitingPartnerEmoji": { + "type": "text", + "placeholders": {} + }, + "waitingPartnerNumbers": "Laukiama, kol dalyvis priims skaičius…", + "@waitingPartnerNumbers": { + "type": "text", + "placeholders": {} + }, + "wallpaper": "Užsklanda", + "@wallpaper": { + "type": "text", + "placeholders": {} + }, + "warning": "Įspėjimas!", + "@warning": { + "type": "text", + "placeholders": {} + }, + "weSentYouAnEmail": "Išsiuntėme jums el. laišką", + "@weSentYouAnEmail": { + "type": "text", + "placeholders": {} + }, + "whoCanPerformWhichAction": "Kas gali atlikti kokį veiksmą", + "@whoCanPerformWhichAction": { + "type": "text", + "placeholders": {} + }, + "whoIsAllowedToJoinThisGroup": "Kam leidžiama prisijungti prie šios grupės", + "@whoIsAllowedToJoinThisGroup": { + "type": "text", + "placeholders": {} + }, + "whyDoYouWantToReportThis": "Kodėl norite apie tai pranešti?", + "@whyDoYouWantToReportThis": { + "type": "text", + "placeholders": {} + }, + "wipeChatBackup": "Ištrinti atsarginę pokalbių kopiją, kad sukurti naują atkūrimo raktą?", + "@wipeChatBackup": { + "type": "text", + "placeholders": {} + }, + "withTheseAddressesRecoveryDescription": "Naudodami šiuos adresus galite atkurti savo slaptažodį.", + "@withTheseAddressesRecoveryDescription": { + "type": "text", + "placeholders": {} + }, + "messageType": "Žinutės tipas", + "@messageType": {}, + "openGallery": "Atverti galeriją", + "@openGallery": {}, + "chooseAUsername": "Pasirinkite vartotojo vardą", + "@chooseAUsername": { + "type": "text", + "placeholders": {} + }, + "unknownDevice": "Nežinomas įrenginys", + "@unknownDevice": { + "type": "text", + "placeholders": {} + }, + "voiceMessage": "Balso žinutė", + "@voiceMessage": { + "type": "text", + "placeholders": {} + }, + "title": "FluffyChat", + "@title": { + "description": "Title for the application", + "type": "text", + "placeholders": {} + }, + "visibleForEveryone": "Matoma visiems", + "@visibleForEveryone": { + "type": "text", + "placeholders": {} + }, + "tryToSendAgain": "Pabandykite išsiųsti dar kartą", + "@tryToSendAgain": { + "type": "text", + "placeholders": {} + }, + "locationPermissionDeniedNotice": "Vietos leidimas atmestas. Suteikite leidimą kad galėtumėte bendrinti savo vietą.", + "@locationPermissionDeniedNotice": { + "type": "text", + "placeholders": {} + }, + "needPantalaimonWarning": "Atminkite, kad norint naudoti end-to-end šifravimą, reikalingas Pantalaimon.", + "@needPantalaimonWarning": { + "type": "text", + "placeholders": {} + }, + "noEncryptionForPublicRooms": "Šifravimą galite suaktyvinti tik tada, kai kambarys nebebus viešai pasiekiamas.", + "@noEncryptionForPublicRooms": { + "type": "text", + "placeholders": {} + }, + "noEmotesFound": "Nerasta jaustukų. 😕", + "@noEmotesFound": { + "type": "text", + "placeholders": {} + }, + "noGoogleServicesWarning": "Atrodo, kad jūsų telefone nėra Google Services. Tai geras sprendimas jūsų privatumui! Norėdami gauti tiesioginius pranešimus FluffyChat, rekomenduojame naudoti https://microg.org/ arba https://unifiedpush.org/.", + "@noGoogleServicesWarning": { + "type": "text", + "placeholders": {} + }, + "noPasswordRecoveryDescription": "Dar nepridėjote slaptažodžio atkūrimo būdo.", + "@noPasswordRecoveryDescription": { + "type": "text", + "placeholders": {} + }, + "oneClientLoggedOut": "Vienas iš jūsų klientų atsijungė", + "@oneClientLoggedOut": {}, + "onlineKeyBackupEnabled": "Internetinė atsarginė raktų kopija įjungta", + "@onlineKeyBackupEnabled": { + "type": "text", + "placeholders": {} + }, + "openCamera": "Atidarykite kamerą", + "@openCamera": { + "type": "text", + "placeholders": {} + }, + "openVideoCamera": "Atidarykite kamerą vaizdo įrašui", + "@openVideoCamera": { + "type": "text", + "placeholders": {} + }, + "editBundlesForAccount": "Redaguoti šios paskyros paketus", + "@editBundlesForAccount": {}, + "serverRequiresEmail": "Šis serveris turi patvirtinti jūsų el. pašto adresą registracijai.", + "@serverRequiresEmail": {}, + "optionalGroupName": "(Nebūtina) Grupės pavadinimas", + "@optionalGroupName": { + "type": "text", + "placeholders": {} + }, + "addToBundle": "Pridėti prie paketų", + "@addToBundle": {}, + "removeFromBundle": "Pašalinkite iš šio paketo", + "@removeFromBundle": {}, + "bundleName": "Paketo vardas", + "@bundleName": {}, + "play": "Groti {fileName}", + "@play": { + "type": "text", + "placeholders": { + "fileName": {} + } + }, + "redactedAnEvent": "{username} pašalino įvykį", + "@redactedAnEvent": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "rejectedTheInvitation": "{username} atmetė kvietimą", + "@rejectedTheInvitation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "removedBy": "Pašalino vartotojas {username}", + "@removedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "unbanFromChat": "Atblokuoti pokalbyje", + "@unbanFromChat": { + "type": "text", + "placeholders": {} + }, + "renderRichContent": "Atvaizduoti turtingą žinutės turinį", + "@renderRichContent": { + "type": "text", + "placeholders": {} + }, + "reportMessage": "Pranešti apie žinutę", + "@reportMessage": { + "type": "text", + "placeholders": {} + }, + "saveFile": "Išsaugoti failą", + "@saveFile": { + "type": "text", + "placeholders": {} + }, + "seenByUser": "Matė {username}", + "@seenByUser": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sendSticker": "Siųsti lipduką", + "@sendSticker": { + "type": "text", + "placeholders": {} + }, + "sentAFile": "📁 {username} atsiuntė failą", + "@sentAFile": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sentAnAudio": "🎤 {username} atsiuntė garso įrašą", + "@sentAnAudio": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sentASticker": "😊 {username} atsiuntė lipduką", + "@sentASticker": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sharedTheLocation": "{username} bendrino savo vietą", + "@sharedTheLocation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "startedACall": "{senderName} pradėjo skambutį", + "@startedACall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "theyDontMatch": "Jie nesutampa", + "@theyDontMatch": { + "type": "text", + "placeholders": {} + }, + "theyMatch": "Jie sutampa", + "@theyMatch": { + "type": "text", + "placeholders": {} + }, + "unbannedUser": "{username} atblokavo {targetName}", + "@unbannedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "unknownEvent": "Nežinomas įvykis '{type}'", + "@unknownEvent": { + "type": "text", + "placeholders": { + "type": {} + } + }, + "userAndOthersAreTyping": "{username} ir dar {count} kiti rašo…", + "@userAndOthersAreTyping": { + "type": "text", + "placeholders": { + "username": {}, + "count": {} + } + }, + "userAndUserAreTyping": "{username} ir {username2} rašo…", + "@userAndUserAreTyping": { + "type": "text", + "placeholders": { + "username": {}, + "username2": {} + } + }, + "userIsTyping": "{username} rašo…", + "@userIsTyping": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "userSentUnknownEvent": "{username} išsiuntė {type} įvykį", + "@userSentUnknownEvent": { + "type": "text", + "placeholders": { + "username": {}, + "type": {} + } + }, + "addToStory": "Pridėti prie istorijos", + "@addToStory": {}, + "publish": "Paskelbti", + "@publish": {}, + "whoCanSeeMyStories": "Kas gali matyti mano istorijas?", + "@whoCanSeeMyStories": {}, + "unsubscribeStories": "Atsisakyti istorijų prenumeratos", + "@unsubscribeStories": {}, + "thisUserHasNotPostedAnythingYet": "Šis vartotojas dar nieko nepaskelbė savo istorijoje", + "@thisUserHasNotPostedAnythingYet": {}, + "storyPrivacyWarning": "Atminkite, kad žmonės gali matyti vienas kitą ir susisiekti tarpusavyje jūsų istorijoje. Jūsų istorijos bus matomos 24 valandas, tačiau nėra garantijos, kad jos bus ištrintos iš visų įrenginių ir serverių.", + "@storyPrivacyWarning": {}, + "openChat": "Atverti pokalbį", + "@openChat": {}, + "reportUser": "Pranešti apie vartotoją", + "@reportUser": {}, + "dismiss": "Atsisakyti", + "@dismiss": {}, + "reactedWith": "{sender} sureagavo su {reaction}", + "@reactedWith": { + "type": "text", + "placeholders": { + "sender": {}, + "reaction": {} + } + }, + "unsupportedAndroidVersion": "Nepalaikoma Android versija", + "@unsupportedAndroidVersion": {}, + "emailOrUsername": "El. paštas arba vartotojo vardas", + "@emailOrUsername": {}, + "widgetVideo": "Video", + "@widgetVideo": {}, + "widgetNameError": "Pateikite rodomą vardą.", + "@widgetNameError": {}, + "pleaseChooseAtLeastChars": "Pasirinkite bent {min} simbolius.", + "@pleaseChooseAtLeastChars": { + "type": "text", + "placeholders": { + "min": {} + } + }, + "acceptedTheInvitation": "👍 {username} priėmė kvietimą", + "@acceptedTheInvitation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "activatedEndToEndEncryption": "🔐 {username} aktyvavo visapusį šifravimą", + "@activatedEndToEndEncryption": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "answeredTheCall": "{senderName} atsiliepė į skambutį", + "@answeredTheCall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "askVerificationRequest": "Priimti šią patvirtinimo užklausą iš {username}?", + "@askVerificationRequest": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "badServerLoginTypesException": "Namų serveris palaiko šiuos prisijungimo tipus:\n{serverVersions}\nTačiau ši programa palaiko tik:\n{supportedVersions}", + "@badServerLoginTypesException": { + "type": "text", + "placeholders": { + "serverVersions": {}, + "supportedVersions": {} + } + }, + "badServerVersionsException": "Namų serveris palaiko spec. versijas:\n{serverVersions}\nTačiau ši programa palaiko tik {supportedVersions}", + "@badServerVersionsException": { + "type": "text", + "placeholders": { + "serverVersions": {}, + "supportedVersions": {} + } + }, + "bannedUser": "{username} užblokavo {targetName}", + "@bannedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "changedTheHistoryVisibility": "{username} pakeitė istorijos matomumą", + "@changedTheHistoryVisibility": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheHistoryVisibilityTo": "{username} pakeitė istorijos matomumą į: {rules}", + "@changedTheHistoryVisibilityTo": { + "type": "text", + "placeholders": { + "username": {}, + "rules": {} + } + }, + "chatBackupDescription": "Jūsų senos žinutės yra apsaugotos atkūrimo raktu. Pasirūpinkite, kad jo neprarastumėte.", + "@chatBackupDescription": { + "type": "text", + "placeholders": {} + }, + "commandHint_create": "Sukurti tuščią grupinį pokalbį\nNaudokite --no-encryption kad išjungti šifravimą", + "@commandHint_create": { + "type": "text", + "description": "Usage hint for the command /create" + }, + "commandHint_dm": "Pradėti tiesioginį pokalbį\nNaudokite --no-encryption kad išjungti šifravimą", + "@commandHint_dm": { + "type": "text", + "description": "Usage hint for the command /dm" + }, + "commandHint_myroomavatar": "Nustatyti savo nuotrauką šiame kambaryje (su mxc-uri)", + "@commandHint_myroomavatar": { + "type": "text", + "description": "Usage hint for the command /myroomavatar" + }, + "commandHint_op": "Nustatyti naudotojo galios lygį (numatytasis: 50)", + "@commandHint_op": { + "type": "text", + "description": "Usage hint for the command /op" + }, + "commandHint_react": "Siųsti atsakymą kaip reakciją", + "@commandHint_react": { + "type": "text", + "description": "Usage hint for the command /react" + }, + "commandMissing": "{command} nėra komanda.", + "@commandMissing": { + "type": "text", + "placeholders": { + "command": {} + }, + "description": "State that {command} is not a valid /command." + }, + "containsDisplayName": "Turi rodomą vardą", + "@containsDisplayName": { + "type": "text", + "placeholders": {} + }, + "containsUserName": "Turi vartotojo vardą", + "@containsUserName": { + "type": "text", + "placeholders": {} + }, + "couldNotDecryptMessage": "Nepavyko iššifruoti pranešimo: {error}", + "@couldNotDecryptMessage": { + "type": "text", + "placeholders": { + "error": {} + } + }, + "countParticipants": "{count} dalyviai", + "@countParticipants": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "createdTheChat": "💬 {username} sukūrė pokalbį", + "@createdTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "emptyChat": "Tuščias pokalbis", + "@emptyChat": { + "type": "text", + "placeholders": {} + }, + "emoteExists": "Jaustukas jau egzistuoja!", + "@emoteExists": { + "type": "text", + "placeholders": {} + }, + "emoteInvalid": "Neteisingas jaustuko trumpasis kodas!", + "@emoteInvalid": { + "type": "text", + "placeholders": {} + }, + "emotePacks": "Jaustukų paketai kambariui", + "@emotePacks": { + "type": "text", + "placeholders": {} + }, + "emoteSettings": "Jaustukų nustatymai", + "@emoteSettings": { + "type": "text", + "placeholders": {} + }, + "emoteShortcode": "Jaustuko trumpasis kodas", + "@emoteShortcode": { + "type": "text", + "placeholders": {} + }, + "emoteWarnNeedToPick": "Turite pasirinkti jaustuko trumpąjį kodą ir paveiksliuką!", + "@emoteWarnNeedToPick": { + "type": "text", + "placeholders": {} + }, + "enableEmotesGlobally": "Įgalinti jaustukų paketą visur", + "@enableEmotesGlobally": { + "type": "text", + "placeholders": {} + }, + "endedTheCall": "{senderName} baigė skambutį", + "@endedTheCall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "errorObtainingLocation": "Klaida nustatant vietą: {error}", + "@errorObtainingLocation": { + "type": "text", + "placeholders": { + "error": {} + } + }, + "groupWith": "Grupė su {displayname}", + "@groupWith": { + "type": "text", + "placeholders": { + "displayname": {} + } + }, + "hasWithdrawnTheInvitationFor": "{username} atšaukė {targetName} kvietimą", + "@hasWithdrawnTheInvitationFor": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "inviteForMe": "Pakvietimas man", + "@inviteForMe": { + "type": "text", + "placeholders": {} + }, + "inviteContactToGroup": "Pakviesti kontaktą į {groupName}", + "@inviteContactToGroup": { + "type": "text", + "placeholders": { + "groupName": {} + } + }, + "invitedUser": "📩 {username} pakvietė {targetName}", + "@invitedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "inviteText": "{username} pakvietė jus prisijungti prie FluffyChat. \n1. Įdiekite FluffyChat: https://fluffychat.im \n2. Prisiregistruokite arba prisijunkite \n3. Atidarykite pakvietimo nuorodą: {link}", + "@inviteText": { + "type": "text", + "placeholders": { + "username": {}, + "link": {} + } + }, + "joinedTheChat": "👋 {username} prisijungė prie pokalbio", + "@joinedTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "kicked": "👞 {username} išmetė {targetName}", + "@kicked": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "kickedAndBanned": "🙅 {username} išmetė ir užblokavo {targetName}", + "@kickedAndBanned": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "lastActiveAgo": "Paskutinis aktyvumas: {localizedTimeShort}", + "@lastActiveAgo": { + "type": "text", + "placeholders": { + "localizedTimeShort": {} + } + }, + "loadCountMoreParticipants": "Įkelti dar {count} dalyvius", + "@loadCountMoreParticipants": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "logInTo": "Prisijungti prie {homeserver}", + "@logInTo": { + "type": "text", + "placeholders": { + "homeserver": {} + } + }, + "seenByUserAndUser": "Matė {username} ir {username2}", + "@seenByUserAndUser": { + "type": "text", + "placeholders": { + "username": {}, + "username2": {} + } + }, + "toggleFavorite": "Perjungti parankinius", + "@toggleFavorite": { + "type": "text", + "placeholders": {} + }, + "toggleMuted": "Perjungti nutildytą", + "@toggleMuted": { + "type": "text", + "placeholders": {} + }, + "cantOpenUri": "Nepavyksta atidaryti URI {uri}", + "@cantOpenUri": { + "type": "text", + "placeholders": { + "uri": {} + } + }, + "changedTheChatAvatar": "{username} pakeitė pokalbio avatarą", + "@changedTheChatAvatar": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheChatDescriptionTo": "{username} pakeitė pokalbio aprašymą į: '{description}'", + "@changedTheChatDescriptionTo": { + "type": "text", + "placeholders": { + "username": {}, + "description": {} + } + }, + "changedTheChatNameTo": "{username} pakeitė pokalbio pavadinimą į: '{chatname}'", + "@changedTheChatNameTo": { + "type": "text", + "placeholders": { + "username": {}, + "chatname": {} + } + }, + "changedTheChatPermissions": "{username} pakeitė pokalbių leidimus", + "@changedTheChatPermissions": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheDisplaynameTo": "{username} pakeitė rodomą vardą į: '{displayname}'", + "@changedTheDisplaynameTo": { + "type": "text", + "placeholders": { + "username": {}, + "displayname": {} + } + }, + "changedTheGuestAccessRules": "{username} pakeitė svečio prieigos taisykles", + "@changedTheGuestAccessRules": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheGuestAccessRulesTo": "{username} pakeitė svečio prieigos taisykles į: {rules}", + "@changedTheGuestAccessRulesTo": { + "type": "text", + "placeholders": { + "username": {}, + "rules": {} + } + }, + "changedTheJoinRules": "{username} pakeitė prisijungimo taisykles", + "@changedTheJoinRules": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheJoinRulesTo": "{username} pakeitė prisijungimo taisykles į: {joinRules}", + "@changedTheJoinRulesTo": { + "type": "text", + "placeholders": { + "username": {}, + "joinRules": {} + } + }, + "changedTheProfileAvatar": "{username} pakeitė savo avatarą", + "@changedTheProfileAvatar": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheRoomAliases": "{username} pakeitė kambario pseudonimus", + "@changedTheRoomAliases": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheRoomInvitationLink": "{username} pakeitė pakvietimo nuorodą", + "@changedTheRoomInvitationLink": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "yourStory": "Tavo istorija", + "@yourStory": {}, + "replyHasBeenSent": "Atsakymas išsiųstas", + "@replyHasBeenSent": {}, + "videoWithSize": "Vaizdo įrašas ({size})", + "@videoWithSize": { + "type": "text", + "placeholders": { + "size": {} + } + }, + "storyFrom": "Istorija nuo {date}: \n{body}", + "@storyFrom": { + "type": "text", + "placeholders": { + "date": {}, + "body": {} + } + }, + "whoCanSeeMyStoriesDesc": "Atminkite, kad žmonės gali matyti vienas kitą ir susisiekti tarpusavyje jūsų istorijoje.", + "@whoCanSeeMyStoriesDesc": {}, + "whatIsGoingOn": "Kas vyksta?", + "@whatIsGoingOn": {}, + "addDescription": "Pridėti aprašymą", + "@addDescription": {}, + "iUnderstand": "Aš suprantu", + "@iUnderstand": {}, + "pinMessage": "Prisegti prie kambario", + "@pinMessage": {}, + "confirmEventUnpin": "Ar tikrai norite visam laikui atsegti įvykį?", + "@confirmEventUnpin": {}, + "emojis": "Jaustukai", + "@emojis": {}, + "placeCall": "Skambinti", + "@placeCall": {}, + "voiceCall": "Balso skambutis", + "@voiceCall": {}, + "unsupportedAndroidVersionLong": "Šiai funkcijai reikalinga naujesnė Android versija. Patikrinkite, ar nėra naujinimų arba Lineage OS palaikymo.", + "@unsupportedAndroidVersionLong": {}, + "videoCallsBetaWarning": "Atminkite, kad vaizdo skambučiai šiuo metu yra beta versijos. Jie gali neveikti taip kaip tikėtasi, arba iš viso neveikti visose platformose.", + "@videoCallsBetaWarning": {}, + "experimentalVideoCalls": "Eksperimentiniai vaizdo skambučiai", + "@experimentalVideoCalls": {}, + "switchToAccount": "Perjungti paskyrą į {number}", + "@switchToAccount": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "nextAccount": "Kita paskyra", + "@nextAccount": {}, + "previousAccount": "Ankstesnė paskyra", + "@previousAccount": {}, + "widgetEtherpad": "Teksto pastaba", + "@widgetEtherpad": {}, + "widgetJitsi": "Jitsi Meet", + "@widgetJitsi": {}, + "widgetName": "Vardas", + "@widgetName": {}, + "widgetUrlError": "Netinkamas URL.", + "@widgetUrlError": {}, + "youRejectedTheInvitation": "Jūs atmetėte kvietimą", + "@youRejectedTheInvitation": {}, + "youJoinedTheChat": "Jūs prisijungėte prie pokalbio", + "@youJoinedTheChat": {}, + "youAcceptedTheInvitation": "👍 Jūs priėmėte kvietimą", + "@youAcceptedTheInvitation": {}, + "youBannedUser": "Jūs užblokavote {user}", + "@youBannedUser": { + "placeholders": { + "user": {} + } + }, + "youHaveWithdrawnTheInvitationFor": "Jūs atšaukėte kvietimą {user}", + "@youHaveWithdrawnTheInvitationFor": { + "placeholders": { + "user": {} + } + }, + "youInvitedBy": "📩 Jus pakvietė {user}", + "@youInvitedBy": { + "placeholders": { + "user": {} + } + }, + "youKicked": "👞 Jūs išmetėte {user}", + "@youKicked": { + "placeholders": { + "user": {} + } + }, + "youInvitedUser": "📩 Pakvietėte {user}", + "@youInvitedUser": { + "placeholders": { + "user": {} + } + }, + "youKickedAndBanned": "🙅 Jūs išmetėte ir užblokavote {user}", + "@youKickedAndBanned": { + "placeholders": { + "user": {} + } + }, + "youUnbannedUser": "Jūs atblokavote {user}", + "@youUnbannedUser": { + "placeholders": { + "user": {} + } + }, + "dateAndTimeOfDay": "{date}, {timeOfDay}", + "@dateAndTimeOfDay": { + "type": "text", + "placeholders": { + "date": {}, + "timeOfDay": {} + } + }, + "dateWithoutYear": "{month}-{day}", + "@dateWithoutYear": { + "type": "text", + "placeholders": { + "month": {}, + "day": {} + } + }, + "dateWithYear": "{year}-{month}-{day}", + "@dateWithYear": { + "type": "text", + "placeholders": { + "year": {}, + "month": {}, + "day": {} + } + }, + "locationDisabledNotice": "Vietos nustatymo paslaugos yra išjungtos. Kad galėtumėte bendrinti savo buvimo vietą, įjunkite jas.", + "@locationDisabledNotice": { + "type": "text", + "placeholders": {} + }, + "noMatrixServer": "{server1} nėra Matrix serveris, ar vietoj jo naudoti {server2}?", + "@noMatrixServer": { + "type": "text", + "placeholders": { + "server1": {}, + "server2": {} + } + }, + "numUsersTyping": "{count} vartotojai rašo…", + "@numUsersTyping": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "enableMultiAccounts": "(BETA) Įgalinkite kelias paskyras šiame įrenginyje", + "@enableMultiAccounts": {}, + "openInMaps": "Atidaryti žemėlapiuose", + "@openInMaps": { + "type": "text", + "placeholders": {} + }, + "sentAPicture": "🖼️ {username} atsiuntė nuotrauką", + "@sentAPicture": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sentAVideo": "🎥 {username} atsiuntė vaizdo įrašą", + "@sentAVideo": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sentCallInformations": "{senderName} išsiuntė skambučio informaciją", + "@sentCallInformations": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "setCustomEmotes": "Nustatyti pasirinktinius jaustukus", + "@setCustomEmotes": { + "type": "text", + "placeholders": {} + }, + "userLeftTheChat": "🚪 {username} paliko pokalbį", + "@userLeftTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "markAsRead": "Žymėti kaip skaitytą", + "@markAsRead": {}, + "pushRules": "Tiesioginių pranešimų taisyklės", + "@pushRules": { + "type": "text", + "placeholders": {} + }, + "seenByUserAndCountOthers": "{count, plural, other{Matė {username} ir {count} kiti}}", + "@seenByUserAndCountOthers": { + "type": "text", + "placeholders": { + "username": {}, + "count": {} + } + }, + "unreadChats": "{unreadCount, plural, =1{1 unread chat} other{{unreadCount} neperskaityti pokalbiai}}", + "@unreadChats": { + "type": "text", + "placeholders": { + "unreadCount": {} + } + }, + "matrixWidgets": "Matrix valdikliai", + "@matrixWidgets": {}, + "editWidgets": "Redaguoti programėles", + "@editWidgets": {}, + "addWidget": "Pridėti programėlę", + "@addWidget": {}, + "widgetCustom": "Pasirinktinis", + "@widgetCustom": {}, + "errorAddingWidget": "Pridedant valdiklį įvyko klaida.", + "@errorAddingWidget": {}, + "askSSSSSign": "Kad galėtumėte prijungti kitą asmenį, įveskite savo saugyklos slaptafrazę arba atkūrimo raktą.", + "@askSSSSSign": { + "type": "text", + "placeholders": {} + }, + "autoplayImages": "Automatiškai leisti animuotus lipdukus ir jaustukus", + "@autoplayImages": { + "type": "text", + "placeholder": {} + }, + "ignoreListDescription": "Galite ignoruoti vartotojus, kurie jums trukdo. Negalėsite gauti jokių pranešimų ar kvietimų į kambarį iš vartotojų, įtrauktų į asmeninį ignoruojamųjų sąrašą.", + "@ignoreListDescription": { + "type": "text", + "placeholders": {} + }, + "commandHint_markasdm": "Pažymėti kaip tiesioginio pokalbio kambarį", + "@commandHint_markasdm": {}, + "dehydrateTorLong": "TOR naudotojams rekomenduojama eksportuoti sesiją prieš uždarant langą.", + "@dehydrateTorLong": {}, + "dehydrateWarning": "Šio veiksmo negalima atšaukti. Įsitikinkite, kad saugiai saugote atsarginę kopiją.", + "@dehydrateWarning": {}, + "hydrateTorLong": "Ar paskutinį kartą eksportavote savo sesiją naudodami TOR? Greitai ją importuokite ir tęskite pokalbį.", + "@hydrateTorLong": {}, + "commandHint_markasgroup": "Pažymėti kaip grupę", + "@commandHint_markasgroup": {}, + "pleaseEnterRecoveryKeyDescription": "Norėdami atrakinti senas žinutes, įveskite atkūrimo raktą, kuris buvo sukurtas ankstesnės sesijos metu. Atkūrimo raktas NĖRA jūsų slaptažodis.", + "@pleaseEnterRecoveryKeyDescription": {}, + "callingPermissions": "Skambinimo leidimai", + "@callingPermissions": {}, + "storeInAppleKeyChain": "Saugoti Apple raktų grandinėje", + "@storeInAppleKeyChain": {}, + "callingAccount": "Skambinimo paskyra", + "@callingAccount": {}, + "newSpace": "Nauja erdvė", + "@newSpace": {}, + "callingAccountDetails": "Leidžia FluffyChat naudoti vietinę Android rinkiklio programą.", + "@callingAccountDetails": {}, + "appearOnTop": "Rodyti viršuje", + "@appearOnTop": {}, + "enterSpace": "Įeiti į erdvę", + "@enterSpace": {}, + "enterRoom": "Įeiti į kambarį", + "@enterRoom": {}, + "allSpaces": "Visos erdvės", + "@allSpaces": {}, + "user": "Vartotojas", + "@user": {}, + "custom": "Pasirinktinis", + "@custom": {}, + "confirmMatrixId": "Norėdami ištrinti savo paskyrą, patvirtinkite savo Matrix ID.", + "@confirmMatrixId": {}, + "supposedMxid": "Tai turėtų būti {mxid}", + "@supposedMxid": { + "type": "text", + "placeholders": { + "mxid": {} + } + }, + "dehydrate": "Eksportuoti sesiją ir išvalyti įrenginį", + "@dehydrate": {}, + "dehydrateTor": "TOR Naudotojai: Eksportuoti sesiją", + "@dehydrateTor": {}, + "hydrateTor": "TOR Naudotojai: Importuoti sesijos eksportą", + "@hydrateTor": {}, + "hydrate": "Atkurti iš atsarginės kopijos failo", + "@hydrate": {}, + "pleaseEnterRecoveryKey": "Įveskite savo atkūrimo raktą:", + "@pleaseEnterRecoveryKey": {}, + "recoveryKey": "Atkūrimo raktas", + "@recoveryKey": {}, + "recoveryKeyLost": "Pamestas atkūrimo raktas?", + "@recoveryKeyLost": {}, + "indexedDbErrorLong": "Deja, pagal numatytuosius nustatymus žinučių saugojimas privačiame režime nėra įjungtas.\nPrašome apsilankyti\n - about:config\n - nustatykite dom.indexedDB.privateBrowsing.enabled į true\nPriešingu atveju FluffyChat paleisti neįmanoma.", + "@indexedDbErrorLong": {}, + "noEmailWarning": "Įveskite galiojantį el. pašto adresą. Priešingu atveju negalėsite iš naujo nustatyti slaptažodžio. Jei nenorite, dar kartą bakstelėkite mygtuką, kad galėtumėte tęsti.", + "@noEmailWarning": {}, + "countFiles": "{count} failai", + "@countFiles": { + "placeholders": { + "count": {} + } + }, + "updateAvailable": "Galimas FluffyChat atnaujinimas", + "@updateAvailable": {}, + "updateNow": "Pradėti atnaujinimą fone", + "@updateNow": {}, + "storeInSecureStorageDescription": "Atkūrimo raktą laikyti saugioje šio prietaiso saugykloje.", + "@storeInSecureStorageDescription": {}, + "saveKeyManuallyDescription": "Įrašykite šį raktą rankiniu būdu, įjungę sistemos bendrinimo dialogo langą arba iškarpinę.", + "@saveKeyManuallyDescription": {}, + "users": "Vartotojai", + "@users": {}, + "stories": "Istorijos", + "@stories": {}, + "storeSecurlyOnThisDevice": "Saugiai laikyti šiame prietaise", + "@storeSecurlyOnThisDevice": {}, + "unlockOldMessages": "Atrakinti senas žinutes", + "@unlockOldMessages": {}, + "storeInAndroidKeystore": "Saugoti Android raktų saugykloje", + "@storeInAndroidKeystore": {}, + "indexedDbErrorTitle": "Privataus režimo problemos", + "@indexedDbErrorTitle": {}, + "noKeyForThisMessage": "Taip gali atsitikti, jei žinutė buvo išsiųsta prieš prisijungiant prie paskyros šiame prietaise.\n\nTaip pat gali būti, kad siuntėjas užblokavo jūsų prietaisą arba kažkas sutriko su interneto ryšiu.\n\nAr galite perskaityti žinutę kitoje sesijoje? Tada galite perkelti žinutę iš jos! Eikite į Nustatymai > Prietaisai ir įsitikinkite, kad jūsų prietaisai patvirtino vienas kitą. Kai kitą kartą atidarysite kambarį ir abi sesijos bus pirmame plane, raktai bus perduoti automatiškai.\n\nNenorite prarasti raktų atsijungdami arba keisdami įrenginius? Įsitikinkite, kad nustatymuose įjungėte pokalbių atsarginę kopiją.", + "@noKeyForThisMessage": {}, + "foregroundServiceRunning": "Šis pranešimas rodomas, kai veikia pirmojo plano paslauga.", + "@foregroundServiceRunning": {}, + "screenSharingTitle": "ekrano bendrinimas", + "@screenSharingTitle": {}, + "appearOnTopDetails": "Leidžia programėlę rodyti viršuje (nebūtina, jei jau esate nustatę Fluffychat kaip skambinimo paskyrą)", + "@appearOnTopDetails": {}, + "otherCallingPermissions": "Mikrofonas, kamera ir kiti FluffyChat leidimai", + "@otherCallingPermissions": {}, + "whyIsThisMessageEncrypted": "Kodėl ši žinutė neperskaitoma?", + "@whyIsThisMessageEncrypted": {}, + "newGroup": "Nauja grupė", + "@newGroup": {}, + "screenSharingDetail": "Bendrinate savo ekraną per FuffyChat", + "@screenSharingDetail": {}, + "numChats": "{number} pokalbiai", + "@numChats": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "hideUnimportantStateEvents": "Slėpti nesvarbius būsenos įvykius", + "@hideUnimportantStateEvents": {}, + "discover": "", + "@discover": { + "type": "text", + "placeholders": {} + }, + "hugContent": "", + "@hugContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "jumpToLastReadMessage": "", + "@jumpToLastReadMessage": {}, + "allRooms": "", + "@allRooms": { + "type": "text", + "placeholders": {} + }, + "commandHint_cuddle": "", + "@commandHint_cuddle": {}, + "reportErrorDescription": "", + "@reportErrorDescription": {}, + "startFirstChat": "", + "@startFirstChat": {}, + "setColorTheme": "", + "@setColorTheme": {}, + "banUserDescription": "", + "@banUserDescription": {}, + "requests": "", + "@requests": {}, + "removeDevicesDescription": "", + "@removeDevicesDescription": {}, + "tryAgain": "", + "@tryAgain": {}, + "unbanUserDescription": "", + "@unbanUserDescription": {}, + "todoLists": "", + "@todoLists": {}, + "messagesStyle": "", + "@messagesStyle": {}, + "newSpaceDescription": "", + "@newSpaceDescription": {}, + "chatDescription": "", + "@chatDescription": {}, + "encryptThisChat": "", + "@encryptThisChat": {}, + "reopenChat": "", + "@reopenChat": {}, + "editTodo": "", + "@editTodo": {}, + "pushNotificationsNotAvailable": "", + "@pushNotificationsNotAvailable": {}, + "invalidServerName": "", + "@invalidServerName": {}, + "chatPermissions": "", + "@chatPermissions": {}, + "signInWithPassword": "", + "@signInWithPassword": {}, + "pleaseAddATitle": "", + "@pleaseAddATitle": {}, + "makeAdminDescription": "", + "@makeAdminDescription": {}, + "setChatDescription": "", + "@setChatDescription": {}, + "importFromZipFile": "", + "@importFromZipFile": {}, + "noOtherDevicesFound": "", + "@noOtherDevicesFound": {}, + "redactedBy": "", + "@redactedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "signInWith": "", + "@signInWith": { + "type": "text", + "placeholders": { + "provider": {} + } + }, + "fileIsTooBigForServer": "", + "@fileIsTooBigForServer": {}, + "noTodosYet": "", + "@noTodosYet": {}, + "readUpToHere": "", + "@readUpToHere": {}, + "optionalRedactReason": "", + "@optionalRedactReason": {}, + "archiveRoomDescription": "", + "@archiveRoomDescription": {}, + "exportEmotePack": "", + "@exportEmotePack": {}, + "letsStart": "", + "@letsStart": {}, + "savedEmotePack": "", + "@savedEmotePack": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "inviteContactToGroupQuestion": "", + "@inviteContactToGroupQuestion": {}, + "redactedByBecause": "", + "@redactedByBecause": { + "type": "text", + "placeholders": { + "username": {}, + "reason": {} + } + }, + "fileHasBeenSavedAt": "", + "@fileHasBeenSavedAt": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "importZipFile": "", + "@importZipFile": {}, + "anyoneCanKnock": "", + "@anyoneCanKnock": {}, + "redactMessageDescription": "", + "@redactMessageDescription": {}, + "invalidInput": "", + "@invalidInput": {}, + "todosUnencrypted": "", + "@todosUnencrypted": {}, + "doNotShowAgain": "", + "@doNotShowAgain": {}, + "report": "", + "@report": {}, + "googlyEyesContent": "", + "@googlyEyesContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "addChatDescription": "", + "@addChatDescription": {}, + "hasKnocked": "", + "@hasKnocked": { + "placeholders": { + "user": {} + } + }, + "openLinkInBrowser": "", + "@openLinkInBrowser": {}, + "disableEncryptionWarning": "", + "@disableEncryptionWarning": {}, + "directChat": "", + "@directChat": {}, + "noOneCanJoin": "", + "@noOneCanJoin": {}, + "wrongPinEntered": "", + "@wrongPinEntered": { + "type": "text", + "placeholders": { + "seconds": {} + } + }, + "sendTypingNotifications": "", + "@sendTypingNotifications": {}, + "inviteGroupChat": "", + "@inviteGroupChat": {}, + "invitePrivateChat": "", + "@invitePrivateChat": {}, + "importEmojis": "", + "@importEmojis": {}, + "wasDirectChatDisplayName": "", + "@wasDirectChatDisplayName": { + "type": "text", + "placeholders": { + "oldDisplayName": {} + } + }, + "noChatDescriptionYet": "", + "@noChatDescriptionYet": {}, + "newTodo": "", + "@newTodo": {}, + "learnMore": "", + "@learnMore": {}, + "notAnImage": "", + "@notAnImage": {}, + "chatDescriptionHasBeenChanged": "", + "@chatDescriptionHasBeenChanged": {}, + "todoListChangedError": "", + "@todoListChangedError": {}, + "enterInviteLinkOrMatrixId": "", + "@enterInviteLinkOrMatrixId": {}, + "roomUpgradeDescription": "", + "@roomUpgradeDescription": {}, + "pleaseEnterANumber": "", + "@pleaseEnterANumber": {}, + "profileNotFound": "", + "@profileNotFound": {}, + "jump": "", + "@jump": {}, + "sorryThatsNotPossible": "", + "@sorryThatsNotPossible": {}, + "shareInviteLink": "", + "@shareInviteLink": {}, + "cuddleContent": "", + "@cuddleContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "deviceKeys": "", + "@deviceKeys": {}, + "emoteKeyboardNoRecents": "", + "@emoteKeyboardNoRecents": { + "type": "text", + "placeholders": {} + }, + "endToEndEncryption": "", + "@endToEndEncryption": {}, + "setTheme": "", + "@setTheme": {}, + "commandHint_hug": "", + "@commandHint_hug": {}, + "replace": "", + "@replace": {}, + "commandHint_googly": "", + "@commandHint_googly": {}, + "pleaseTryAgainLaterOrChooseDifferentServer": "", + "@pleaseTryAgainLaterOrChooseDifferentServer": {}, + "createGroup": "", + "@createGroup": {}, + "noBackupWarning": "", + "@noBackupWarning": {}, + "kickUserDescription": "", + "@kickUserDescription": {}, + "importNow": "", + "@importNow": {}, + "invite": "", + "@invite": {}, + "continueWith": "", + "@continueWith": {} +} diff --git a/assets/l10n/intl_lv.arb b/assets/l10n/intl_lv.arb index 0967ef424..d138084cf 100644 --- a/assets/l10n/intl_lv.arb +++ b/assets/l10n/intl_lv.arb @@ -1 +1,2620 @@ -{} +{ + "showPassword": "", + "@showPassword": { + "type": "text", + "placeholders": {} + }, + "hugContent": "", + "@hugContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "darkTheme": "", + "@darkTheme": { + "type": "text", + "placeholders": {} + }, + "passphraseOrKey": "", + "@passphraseOrKey": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourPassword": "", + "@pleaseEnterYourPassword": { + "type": "text", + "placeholders": {} + }, + "theyMatch": "", + "@theyMatch": { + "type": "text", + "placeholders": {} + }, + "connect": "", + "@connect": { + "type": "text", + "placeholders": {} + }, + "jumpToLastReadMessage": "", + "@jumpToLastReadMessage": {}, + "allRooms": "", + "@allRooms": { + "type": "text", + "placeholders": {} + }, + "obtainingLocation": "", + "@obtainingLocation": { + "type": "text", + "placeholders": {} + }, + "whoCanSeeMyStories": "", + "@whoCanSeeMyStories": {}, + "commandHint_cuddle": "", + "@commandHint_cuddle": {}, + "chats": "", + "@chats": { + "type": "text", + "placeholders": {} + }, + "widgetVideo": "", + "@widgetVideo": {}, + "dismiss": "", + "@dismiss": {}, + "unknownDevice": "", + "@unknownDevice": { + "type": "text", + "placeholders": {} + }, + "emoteShortcode": "", + "@emoteShortcode": { + "type": "text", + "placeholders": {} + }, + "noEncryptionForPublicRooms": "", + "@noEncryptionForPublicRooms": { + "type": "text", + "placeholders": {} + }, + "admin": "", + "@admin": { + "type": "text", + "placeholders": {} + }, + "reportErrorDescription": "", + "@reportErrorDescription": {}, + "directChats": "", + "@directChats": { + "type": "text", + "placeholders": {} + }, + "setPermissionsLevel": "", + "@setPermissionsLevel": { + "type": "text", + "placeholders": {} + }, + "inviteContactToGroup": "", + "@inviteContactToGroup": { + "type": "text", + "placeholders": { + "groupName": {} + } + }, + "addAccount": "", + "@addAccount": {}, + "close": "", + "@close": { + "type": "text", + "placeholders": {} + }, + "configureChat": "", + "@configureChat": { + "type": "text", + "placeholders": {} + }, + "seenByUserAndUser": "", + "@seenByUserAndUser": { + "type": "text", + "placeholders": { + "username": {}, + "username2": {} + } + }, + "chatHasBeenAddedToThisSpace": "", + "@chatHasBeenAddedToThisSpace": {}, + "reply": "", + "@reply": { + "type": "text", + "placeholders": {} + }, + "currentlyActive": "", + "@currentlyActive": { + "type": "text", + "placeholders": {} + }, + "removeYourAvatar": "", + "@removeYourAvatar": { + "type": "text", + "placeholders": {} + }, + "unsupportedAndroidVersion": "", + "@unsupportedAndroidVersion": {}, + "enterASpacepName": "", + "@enterASpacepName": {}, + "device": "", + "@device": { + "type": "text", + "placeholders": {} + }, + "blockDevice": "", + "@blockDevice": { + "type": "text", + "placeholders": {} + }, + "commandHint_html": "", + "@commandHint_html": { + "type": "text", + "description": "Usage hint for the command /html" + }, + "widgetJitsi": "", + "@widgetJitsi": {}, + "youAreNoLongerParticipatingInThisChat": "", + "@youAreNoLongerParticipatingInThisChat": { + "type": "text", + "placeholders": {} + }, + "encryption": "", + "@encryption": { + "type": "text", + "placeholders": {} + }, + "messageType": "", + "@messageType": {}, + "noEmailWarning": "", + "@noEmailWarning": {}, + "indexedDbErrorLong": "", + "@indexedDbErrorLong": {}, + "oneClientLoggedOut": "", + "@oneClientLoggedOut": {}, + "toggleMuted": "", + "@toggleMuted": { + "type": "text", + "placeholders": {} + }, + "unsupportedAndroidVersionLong": "", + "@unsupportedAndroidVersionLong": {}, + "kicked": "", + "@kicked": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "title": "", + "@title": { + "description": "Title for the application", + "type": "text", + "placeholders": {} + }, + "changeTheNameOfTheGroup": "", + "@changeTheNameOfTheGroup": { + "type": "text", + "placeholders": {} + }, + "changedTheChatAvatar": "", + "@changedTheChatAvatar": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "verifySuccess": "", + "@verifySuccess": { + "type": "text", + "placeholders": {} + }, + "sendFile": "", + "@sendFile": { + "type": "text", + "placeholders": {} + }, + "newVerificationRequest": "", + "@newVerificationRequest": { + "type": "text", + "placeholders": {} + }, + "startFirstChat": "", + "@startFirstChat": {}, + "callingAccount": "", + "@callingAccount": {}, + "requestPermission": "", + "@requestPermission": { + "type": "text", + "placeholders": {} + }, + "sentAPicture": "", + "@sentAPicture": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "invited": "", + "@invited": { + "type": "text", + "placeholders": {} + }, + "changedTheDisplaynameTo": "", + "@changedTheDisplaynameTo": { + "type": "text", + "placeholders": { + "username": {}, + "displayname": {} + } + }, + "setColorTheme": "", + "@setColorTheme": {}, + "nextAccount": "", + "@nextAccount": {}, + "commandHint_create": "", + "@commandHint_create": { + "type": "text", + "description": "Usage hint for the command /create" + }, + "youAreInvitedToThisChat": "", + "@youAreInvitedToThisChat": { + "type": "text", + "placeholders": {} + }, + "singlesignon": "", + "@singlesignon": { + "type": "text", + "placeholders": {} + }, + "warning": "", + "@warning": { + "type": "text", + "placeholders": {} + }, + "password": "", + "@password": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterAMatrixIdentifier": "", + "@pleaseEnterAMatrixIdentifier": { + "type": "text", + "placeholders": {} + }, + "allSpaces": "", + "@allSpaces": {}, + "supposedMxid": "", + "@supposedMxid": { + "type": "text", + "placeholders": { + "mxid": {} + } + }, + "editDisplayname": "", + "@editDisplayname": { + "type": "text", + "placeholders": {} + }, + "user": "", + "@user": {}, + "roomVersion": "", + "@roomVersion": { + "type": "text", + "placeholders": {} + }, + "sentAFile": "", + "@sentAFile": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "videoCall": "", + "@videoCall": { + "type": "text", + "placeholders": {} + }, + "youAcceptedTheInvitation": "", + "@youAcceptedTheInvitation": {}, + "banFromChat": "", + "@banFromChat": { + "type": "text", + "placeholders": {} + }, + "noMatrixServer": "", + "@noMatrixServer": { + "type": "text", + "placeholders": { + "server1": {}, + "server2": {} + } + }, + "userAndOthersAreTyping": "", + "@userAndOthersAreTyping": { + "type": "text", + "placeholders": { + "username": {}, + "count": {} + } + }, + "youInvitedBy": "", + "@youInvitedBy": { + "placeholders": { + "user": {} + } + }, + "userIsTyping": "", + "@userIsTyping": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "openAppToReadMessages": "", + "@openAppToReadMessages": { + "type": "text", + "placeholders": {} + }, + "sentAVideo": "", + "@sentAVideo": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "banUserDescription": "", + "@banUserDescription": {}, + "inviteContact": "", + "@inviteContact": { + "type": "text", + "placeholders": {} + }, + "requests": "", + "@requests": {}, + "askSSSSSign": "", + "@askSSSSSign": { + "type": "text", + "placeholders": {} + }, + "widgetEtherpad": "", + "@widgetEtherpad": {}, + "waitingPartnerAcceptRequest": "", + "@waitingPartnerAcceptRequest": { + "type": "text", + "placeholders": {} + }, + "remove": "", + "@remove": { + "type": "text", + "placeholders": {} + }, + "writeAMessage": "", + "@writeAMessage": { + "type": "text", + "placeholders": {} + }, + "changeTheme": "", + "@changeTheme": { + "type": "text", + "placeholders": {} + }, + "stories": "", + "@stories": {}, + "id": "", + "@id": { + "type": "text", + "placeholders": {} + }, + "addToStory": "", + "@addToStory": {}, + "removeDevicesDescription": "", + "@removeDevicesDescription": {}, + "changedTheChatDescriptionTo": "", + "@changedTheChatDescriptionTo": { + "type": "text", + "placeholders": { + "username": {}, + "description": {} + } + }, + "countParticipants": "", + "@countParticipants": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "separateChatTypes": "", + "@separateChatTypes": { + "type": "text", + "placeholders": {} + }, + "tryAgain": "", + "@tryAgain": {}, + "areGuestsAllowedToJoin": "", + "@areGuestsAllowedToJoin": { + "type": "text", + "placeholders": {} + }, + "blocked": "", + "@blocked": { + "type": "text", + "placeholders": {} + }, + "youKickedAndBanned": "", + "@youKickedAndBanned": { + "placeholders": { + "user": {} + } + }, + "dateWithoutYear": "", + "@dateWithoutYear": { + "type": "text", + "placeholders": { + "month": {}, + "day": {} + } + }, + "showDirectChatsInSpaces": "", + "@showDirectChatsInSpaces": { + "type": "text", + "placeholders": {} + }, + "removeDevice": "", + "@removeDevice": { + "type": "text", + "placeholders": {} + }, + "youCannotInviteYourself": "", + "@youCannotInviteYourself": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterValidEmail": "", + "@pleaseEnterValidEmail": {}, + "unbanUserDescription": "", + "@unbanUserDescription": {}, + "todoLists": "", + "@todoLists": {}, + "userAndUserAreTyping": "", + "@userAndUserAreTyping": { + "type": "text", + "placeholders": { + "username": {}, + "username2": {} + } + }, + "pleaseClickOnLink": "", + "@pleaseClickOnLink": { + "type": "text", + "placeholders": {} + }, + "saveFile": "", + "@saveFile": { + "type": "text", + "placeholders": {} + }, + "sendOnEnter": "", + "@sendOnEnter": {}, + "seenByUserAndCountOthers": "", + "@seenByUserAndCountOthers": { + "type": "text", + "placeholders": { + "username": {}, + "count": {} + } + }, + "pickImage": "", + "@pickImage": { + "type": "text", + "placeholders": {} + }, + "answeredTheCall": "", + "@answeredTheCall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "youRejectedTheInvitation": "", + "@youRejectedTheInvitation": {}, + "otherCallingPermissions": "", + "@otherCallingPermissions": {}, + "messagesStyle": "", + "@messagesStyle": {}, + "couldNotDecryptMessage": "", + "@couldNotDecryptMessage": { + "type": "text", + "placeholders": { + "error": {} + } + }, + "invitedUsersOnly": "", + "@invitedUsersOnly": { + "type": "text", + "placeholders": {} + }, + "link": "", + "@link": {}, + "widgetUrlError": "", + "@widgetUrlError": {}, + "emailOrUsername": "", + "@emailOrUsername": {}, + "newSpaceDescription": "", + "@newSpaceDescription": {}, + "chatDescription": "", + "@chatDescription": {}, + "callingAccountDetails": "", + "@callingAccountDetails": {}, + "next": "", + "@next": { + "type": "text", + "placeholders": {} + }, + "pleaseFollowInstructionsOnWeb": "", + "@pleaseFollowInstructionsOnWeb": { + "type": "text", + "placeholders": {} + }, + "changedTheGuestAccessRules": "", + "@changedTheGuestAccessRules": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "pleaseChooseAtLeastChars": "", + "@pleaseChooseAtLeastChars": { + "type": "text", + "placeholders": { + "min": {} + } + }, + "dateWithYear": "", + "@dateWithYear": { + "type": "text", + "placeholders": { + "year": {}, + "month": {}, + "day": {} + } + }, + "editRoomAliases": "", + "@editRoomAliases": { + "type": "text", + "placeholders": {} + }, + "enterSpace": "", + "@enterSpace": {}, + "encryptThisChat": "", + "@encryptThisChat": {}, + "fileName": "", + "@fileName": { + "type": "text", + "placeholders": {} + }, + "unavailable": "", + "@unavailable": { + "type": "text", + "placeholders": {} + }, + "previousAccount": "", + "@previousAccount": {}, + "publicRooms": "", + "@publicRooms": { + "type": "text", + "placeholders": {} + }, + "fromTheInvitation": "", + "@fromTheInvitation": { + "type": "text", + "placeholders": {} + }, + "sendMessages": "", + "@sendMessages": { + "type": "text", + "placeholders": {} + }, + "incorrectPassphraseOrKey": "", + "@incorrectPassphraseOrKey": { + "type": "text", + "placeholders": {} + }, + "emoteWarnNeedToPick": "", + "@emoteWarnNeedToPick": { + "type": "text", + "placeholders": {} + }, + "reopenChat": "", + "@reopenChat": {}, + "pleaseEnterRecoveryKey": "", + "@pleaseEnterRecoveryKey": {}, + "create": "", + "@create": { + "type": "text", + "placeholders": {} + }, + "toggleFavorite": "", + "@toggleFavorite": { + "type": "text", + "placeholders": {} + }, + "no": "", + "@no": { + "type": "text", + "placeholders": {} + }, + "alias": "", + "@alias": { + "type": "text", + "placeholders": {} + }, + "widgetNameError": "", + "@widgetNameError": {}, + "inoffensive": "", + "@inoffensive": { + "type": "text", + "placeholders": {} + }, + "unpin": "", + "@unpin": { + "type": "text", + "placeholders": {} + }, + "addToBundle": "", + "@addToBundle": {}, + "reportMessage": "", + "@reportMessage": { + "type": "text", + "placeholders": {} + }, + "spaceIsPublic": "", + "@spaceIsPublic": { + "type": "text", + "placeholders": {} + }, + "addWidget": "", + "@addWidget": {}, + "all": "", + "@all": { + "type": "text", + "placeholders": {} + }, + "removeAllOtherDevices": "", + "@removeAllOtherDevices": { + "type": "text", + "placeholders": {} + }, + "unblockDevice": "", + "@unblockDevice": { + "type": "text", + "placeholders": {} + }, + "countFiles": "", + "@countFiles": { + "placeholders": { + "count": {} + } + }, + "noKeyForThisMessage": "", + "@noKeyForThisMessage": {}, + "enableEncryptionWarning": "", + "@enableEncryptionWarning": { + "type": "text", + "placeholders": {} + }, + "inviteText": "", + "@inviteText": { + "type": "text", + "placeholders": { + "username": {}, + "link": {} + } + }, + "shareLocation": "", + "@shareLocation": { + "type": "text", + "placeholders": {} + }, + "reason": "", + "@reason": { + "type": "text", + "placeholders": {} + }, + "commandHint_markasgroup": "", + "@commandHint_markasgroup": {}, + "editTodo": "", + "@editTodo": {}, + "errorObtainingLocation": "", + "@errorObtainingLocation": { + "type": "text", + "placeholders": { + "error": {} + } + }, + "hydrateTor": "", + "@hydrateTor": {}, + "pushNotificationsNotAvailable": "", + "@pushNotificationsNotAvailable": {}, + "passwordRecovery": "", + "@passwordRecovery": { + "type": "text", + "placeholders": {} + }, + "storeInAppleKeyChain": "", + "@storeInAppleKeyChain": {}, + "replaceRoomWithNewerVersion": "", + "@replaceRoomWithNewerVersion": { + "type": "text", + "placeholders": {} + }, + "hydrate": "", + "@hydrate": {}, + "invalidServerName": "", + "@invalidServerName": {}, + "chatPermissions": "", + "@chatPermissions": {}, + "voiceMessage": "", + "@voiceMessage": { + "type": "text", + "placeholders": {} + }, + "badServerLoginTypesException": "", + "@badServerLoginTypesException": { + "type": "text", + "placeholders": { + "serverVersions": {}, + "supportedVersions": {} + } + }, + "wipeChatBackup": "", + "@wipeChatBackup": { + "type": "text", + "placeholders": {} + }, + "cantOpenUri": "", + "@cantOpenUri": { + "type": "text", + "placeholders": { + "uri": {} + } + }, + "sender": "", + "@sender": {}, + "storeInAndroidKeystore": "", + "@storeInAndroidKeystore": {}, + "optionalGroupName": "", + "@optionalGroupName": { + "type": "text", + "placeholders": {} + }, + "hideRedactedEvents": "", + "@hideRedactedEvents": { + "type": "text", + "placeholders": {} + }, + "online": "", + "@online": { + "type": "text", + "placeholders": {} + }, + "signInWithPassword": "", + "@signInWithPassword": {}, + "pleaseAddATitle": "", + "@pleaseAddATitle": {}, + "updateNow": "", + "@updateNow": {}, + "ignoredUsers": "", + "@ignoredUsers": { + "type": "text", + "placeholders": {} + }, + "lastActiveAgo": "", + "@lastActiveAgo": { + "type": "text", + "placeholders": { + "localizedTimeShort": {} + } + }, + "changedTheGuestAccessRulesTo": "", + "@changedTheGuestAccessRulesTo": { + "type": "text", + "placeholders": { + "username": {}, + "rules": {} + } + }, + "weSentYouAnEmail": "", + "@weSentYouAnEmail": { + "type": "text", + "placeholders": {} + }, + "offensive": "", + "@offensive": { + "type": "text", + "placeholders": {} + }, + "needPantalaimonWarning": "", + "@needPantalaimonWarning": { + "type": "text", + "placeholders": {} + }, + "makeAdminDescription": "", + "@makeAdminDescription": {}, + "edit": "", + "@edit": { + "type": "text", + "placeholders": {} + }, + "loadMore": "", + "@loadMore": { + "type": "text", + "placeholders": {} + }, + "noEmotesFound": "", + "@noEmotesFound": { + "type": "text", + "placeholders": {} + }, + "synchronizingPleaseWait": "", + "@synchronizingPleaseWait": { + "type": "text", + "placeholders": {} + }, + "transferFromAnotherDevice": "", + "@transferFromAnotherDevice": { + "type": "text", + "placeholders": {} + }, + "passwordHasBeenChanged": "", + "@passwordHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "pushRules": "", + "@pushRules": { + "type": "text", + "placeholders": {} + }, + "goToTheNewRoom": "", + "@goToTheNewRoom": { + "type": "text", + "placeholders": {} + }, + "commandHint_clearcache": "", + "@commandHint_clearcache": { + "type": "text", + "description": "Usage hint for the command /clearcache" + }, + "loadingPleaseWait": "", + "@loadingPleaseWait": { + "type": "text", + "placeholders": {} + }, + "copy": "", + "@copy": { + "type": "text", + "placeholders": {} + }, + "saveKeyManuallyDescription": "", + "@saveKeyManuallyDescription": {}, + "none": "", + "@none": { + "type": "text", + "placeholders": {} + }, + "editBundlesForAccount": "", + "@editBundlesForAccount": {}, + "renderRichContent": "", + "@renderRichContent": { + "type": "text", + "placeholders": {} + }, + "enableEncryption": "", + "@enableEncryption": { + "type": "text", + "placeholders": {} + }, + "whyIsThisMessageEncrypted": "", + "@whyIsThisMessageEncrypted": {}, + "unreadChats": "", + "@unreadChats": { + "type": "text", + "placeholders": { + "unreadCount": {} + } + }, + "rejectedTheInvitation": "", + "@rejectedTheInvitation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "setChatDescription": "", + "@setChatDescription": {}, + "userLeftTheChat": "", + "@userLeftTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "spaceName": "", + "@spaceName": { + "type": "text", + "placeholders": {} + }, + "importFromZipFile": "", + "@importFromZipFile": {}, + "discover": "", + "@discover": { + "type": "text", + "placeholders": {} + }, + "toggleUnread": "", + "@toggleUnread": { + "type": "text", + "placeholders": {} + }, + "or": "", + "@or": { + "type": "text", + "placeholders": {} + }, + "dehydrateWarning": "", + "@dehydrateWarning": {}, + "sendOriginal": "", + "@sendOriginal": { + "type": "text", + "placeholders": {} + }, + "noOtherDevicesFound": "", + "@noOtherDevicesFound": {}, + "whoIsAllowedToJoinThisGroup": "", + "@whoIsAllowedToJoinThisGroup": { + "type": "text", + "placeholders": {} + }, + "emptyChat": "", + "@emptyChat": { + "type": "text", + "placeholders": {} + }, + "seenByUser": "", + "@seenByUser": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "storeSecurlyOnThisDevice": "", + "@storeSecurlyOnThisDevice": {}, + "yourChatBackupHasBeenSetUp": "", + "@yourChatBackupHasBeenSetUp": {}, + "addDescription": "", + "@addDescription": {}, + "chatBackup": "", + "@chatBackup": { + "type": "text", + "placeholders": {} + }, + "redactedBy": "", + "@redactedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "submit": "", + "@submit": { + "type": "text", + "placeholders": {} + }, + "videoCallsBetaWarning": "", + "@videoCallsBetaWarning": {}, + "unmuteChat": "", + "@unmuteChat": { + "type": "text", + "placeholders": {} + }, + "createdTheChat": "", + "@createdTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "redactedAnEvent": "", + "@redactedAnEvent": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "autoplayImages": "", + "@autoplayImages": { + "type": "text", + "placeholder": {} + }, + "storyPrivacyWarning": "", + "@storyPrivacyWarning": {}, + "compareEmojiMatch": "", + "@compareEmojiMatch": { + "type": "text", + "placeholders": {} + }, + "matrixWidgets": "", + "@matrixWidgets": {}, + "participant": "", + "@participant": { + "type": "text", + "placeholders": {} + }, + "logInTo": "", + "@logInTo": { + "type": "text", + "placeholders": { + "homeserver": {} + } + }, + "yes": "", + "@yes": { + "type": "text", + "placeholders": {} + }, + "containsDisplayName": "", + "@containsDisplayName": { + "type": "text", + "placeholders": {} + }, + "signInWith": "", + "@signInWith": { + "type": "text", + "placeholders": { + "provider": {} + } + }, + "username": "", + "@username": { + "type": "text", + "placeholders": {} + }, + "changedTheRoomAliases": "", + "@changedTheRoomAliases": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "updateAvailable": "", + "@updateAvailable": {}, + "fileIsTooBigForServer": "", + "@fileIsTooBigForServer": {}, + "homeserver": "", + "@homeserver": {}, + "help": "", + "@help": { + "type": "text", + "placeholders": {} + }, + "noTodosYet": "", + "@noTodosYet": {}, + "chatDetails": "", + "@chatDetails": { + "type": "text", + "placeholders": {} + }, + "people": "", + "@people": { + "type": "text", + "placeholders": {} + }, + "changedTheHistoryVisibilityTo": "", + "@changedTheHistoryVisibilityTo": { + "type": "text", + "placeholders": { + "username": {}, + "rules": {} + } + }, + "leftTheChat": "", + "@leftTheChat": { + "type": "text", + "placeholders": {} + }, + "verified": "", + "@verified": { + "type": "text", + "placeholders": {} + }, + "repeatPassword": "", + "@repeatPassword": {}, + "setStatus": "", + "@setStatus": { + "type": "text", + "placeholders": {} + }, + "groupWith": "", + "@groupWith": { + "type": "text", + "placeholders": { + "displayname": {} + } + }, + "callingPermissions": "", + "@callingPermissions": {}, + "delete": "", + "@delete": { + "type": "text", + "placeholders": {} + }, + "newMessageInFluffyChat": "", + "@newMessageInFluffyChat": { + "type": "text", + "placeholders": {} + }, + "readUpToHere": "", + "@readUpToHere": {}, + "start": "", + "@start": {}, + "bubbleSize": "", + "@bubbleSize": { + "type": "text", + "placeholders": {} + }, + "downloadFile": "", + "@downloadFile": { + "type": "text", + "placeholders": {} + }, + "deviceId": "", + "@deviceId": { + "type": "text", + "placeholders": {} + }, + "register": "", + "@register": { + "type": "text", + "placeholders": {} + }, + "unlockOldMessages": "", + "@unlockOldMessages": {}, + "identity": "", + "@identity": { + "type": "text", + "placeholders": {} + }, + "numChats": "", + "@numChats": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "changedTheJoinRulesTo": "", + "@changedTheJoinRulesTo": { + "type": "text", + "placeholders": { + "username": {}, + "joinRules": {} + } + }, + "ignore": "", + "@ignore": { + "type": "text", + "placeholders": {} + }, + "whatIsGoingOn": "", + "@whatIsGoingOn": {}, + "recording": "", + "@recording": { + "type": "text", + "placeholders": {} + }, + "changedTheChatPermissions": "", + "@changedTheChatPermissions": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changeWallpaper": "", + "@changeWallpaper": { + "type": "text", + "placeholders": {} + }, + "moderator": "", + "@moderator": { + "type": "text", + "placeholders": {} + }, + "optionalRedactReason": "", + "@optionalRedactReason": {}, + "acceptedTheInvitation": "", + "@acceptedTheInvitation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "waitingPartnerEmoji": "", + "@waitingPartnerEmoji": { + "type": "text", + "placeholders": {} + }, + "channelCorruptedDecryptError": "", + "@channelCorruptedDecryptError": { + "type": "text", + "placeholders": {} + }, + "tryToSendAgain": "", + "@tryToSendAgain": { + "type": "text", + "placeholders": {} + }, + "guestsCanJoin": "", + "@guestsCanJoin": { + "type": "text", + "placeholders": {} + }, + "ok": "", + "@ok": { + "type": "text", + "placeholders": {} + }, + "copyToClipboard": "", + "@copyToClipboard": { + "type": "text", + "placeholders": {} + }, + "dehydrate": "", + "@dehydrate": {}, + "locationPermissionDeniedNotice": "", + "@locationPermissionDeniedNotice": { + "type": "text", + "placeholders": {} + }, + "send": "", + "@send": { + "type": "text", + "placeholders": {} + }, + "hasWithdrawnTheInvitationFor": "", + "@hasWithdrawnTheInvitationFor": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "visibleForAllParticipants": "", + "@visibleForAllParticipants": { + "type": "text", + "placeholders": {} + }, + "noRoomsFound": "", + "@noRoomsFound": { + "type": "text", + "placeholders": {} + }, + "banned": "", + "@banned": { + "type": "text", + "placeholders": {} + }, + "sendAsText": "", + "@sendAsText": { + "type": "text" + }, + "inviteForMe": "", + "@inviteForMe": { + "type": "text", + "placeholders": {} + }, + "archiveRoomDescription": "", + "@archiveRoomDescription": {}, + "exportEmotePack": "", + "@exportEmotePack": {}, + "changedTheChatNameTo": "", + "@changedTheChatNameTo": { + "type": "text", + "placeholders": { + "username": {}, + "chatname": {} + } + }, + "sendSticker": "", + "@sendSticker": { + "type": "text", + "placeholders": {} + }, + "account": "", + "@account": { + "type": "text", + "placeholders": {} + }, + "switchToAccount": "", + "@switchToAccount": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "commandInvalid": "", + "@commandInvalid": { + "type": "text" + }, + "setAsCanonicalAlias": "", + "@setAsCanonicalAlias": { + "type": "text", + "placeholders": {} + }, + "whyDoYouWantToReportThis": "", + "@whyDoYouWantToReportThis": { + "type": "text", + "placeholders": {} + }, + "locationDisabledNotice": "", + "@locationDisabledNotice": { + "type": "text", + "placeholders": {} + }, + "letsStart": "", + "@letsStart": {}, + "placeCall": "", + "@placeCall": {}, + "removedBy": "", + "@removedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheRoomInvitationLink": "", + "@changedTheRoomInvitationLink": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "newChat": "", + "@newChat": { + "type": "text", + "placeholders": {} + }, + "notifications": "", + "@notifications": { + "type": "text", + "placeholders": {} + }, + "commandHint_plain": "", + "@commandHint_plain": { + "type": "text", + "description": "Usage hint for the command /plain" + }, + "emoteSettings": "", + "@emoteSettings": { + "type": "text", + "placeholders": {} + }, + "experimentalVideoCalls": "", + "@experimentalVideoCalls": {}, + "savedEmotePack": "", + "@savedEmotePack": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "openCamera": "", + "@openCamera": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterRecoveryKeyDescription": "", + "@pleaseEnterRecoveryKeyDescription": {}, + "guestsAreForbidden": "", + "@guestsAreForbidden": { + "type": "text", + "placeholders": {} + }, + "mention": "", + "@mention": { + "type": "text", + "placeholders": {} + }, + "openInMaps": "", + "@openInMaps": { + "type": "text", + "placeholders": {} + }, + "withTheseAddressesRecoveryDescription": "", + "@withTheseAddressesRecoveryDescription": { + "type": "text", + "placeholders": {} + }, + "inviteContactToGroupQuestion": "", + "@inviteContactToGroupQuestion": {}, + "emoteExists": "", + "@emoteExists": { + "type": "text", + "placeholders": {} + }, + "redactedByBecause": "", + "@redactedByBecause": { + "type": "text", + "placeholders": { + "username": {}, + "reason": {} + } + }, + "isTyping": "", + "@isTyping": { + "type": "text", + "placeholders": {} + }, + "youHaveWithdrawnTheInvitationFor": "", + "@youHaveWithdrawnTheInvitationFor": { + "placeholders": { + "user": {} + } + }, + "chat": "", + "@chat": { + "type": "text", + "placeholders": {} + }, + "group": "", + "@group": { + "type": "text", + "placeholders": {} + }, + "leave": "", + "@leave": { + "type": "text", + "placeholders": {} + }, + "skip": "", + "@skip": { + "type": "text", + "placeholders": {} + }, + "appearOnTopDetails": "", + "@appearOnTopDetails": {}, + "roomHasBeenUpgraded": "", + "@roomHasBeenUpgraded": { + "type": "text", + "placeholders": {} + }, + "enterRoom": "", + "@enterRoom": {}, + "enableEmotesGlobally": "", + "@enableEmotesGlobally": { + "type": "text", + "placeholders": {} + }, + "areYouSure": "", + "@areYouSure": { + "type": "text", + "placeholders": {} + }, + "ignoreListDescription": "", + "@ignoreListDescription": { + "type": "text", + "placeholders": {} + }, + "pleaseChooseAPasscode": "", + "@pleaseChooseAPasscode": { + "type": "text", + "placeholders": {} + }, + "noPasswordRecoveryDescription": "", + "@noPasswordRecoveryDescription": { + "type": "text", + "placeholders": {} + }, + "changedTheProfileAvatar": "", + "@changedTheProfileAvatar": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "allChats": "", + "@allChats": { + "type": "text", + "placeholders": {} + }, + "reportUser": "", + "@reportUser": {}, + "passwordsDoNotMatch": "", + "@passwordsDoNotMatch": {}, + "sharedTheLocation": "", + "@sharedTheLocation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "commandHint_send": "", + "@commandHint_send": { + "type": "text", + "description": "Usage hint for the command /send" + }, + "onlineKeyBackupEnabled": "", + "@onlineKeyBackupEnabled": { + "type": "text", + "placeholders": {} + }, + "unbannedUser": "", + "@unbannedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "confirmEventUnpin": "", + "@confirmEventUnpin": {}, + "badServerVersionsException": "", + "@badServerVersionsException": { + "type": "text", + "placeholders": { + "serverVersions": {}, + "supportedVersions": {} + } + }, + "youInvitedUser": "", + "@youInvitedUser": { + "placeholders": { + "user": {} + } + }, + "kickedAndBanned": "", + "@kickedAndBanned": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "noConnectionToTheServer": "", + "@noConnectionToTheServer": { + "type": "text", + "placeholders": {} + }, + "fileHasBeenSavedAt": "", + "@fileHasBeenSavedAt": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "license": "", + "@license": { + "type": "text", + "placeholders": {} + }, + "addToSpace": "", + "@addToSpace": {}, + "unbanFromChat": "", + "@unbanFromChat": { + "type": "text", + "placeholders": {} + }, + "importZipFile": "", + "@importZipFile": {}, + "anyoneCanKnock": "", + "@anyoneCanKnock": {}, + "commandMissing": "", + "@commandMissing": { + "type": "text", + "placeholders": { + "command": {} + }, + "description": "State that {command} is not a valid /command." + }, + "redactMessageDescription": "", + "@redactMessageDescription": {}, + "rejoin": "", + "@rejoin": { + "type": "text", + "placeholders": {} + }, + "recoveryKey": "", + "@recoveryKey": {}, + "redactMessage": "", + "@redactMessage": { + "type": "text", + "placeholders": {} + }, + "forward": "", + "@forward": { + "type": "text", + "placeholders": {} + }, + "commandHint_discardsession": "", + "@commandHint_discardsession": { + "type": "text", + "description": "Usage hint for the command /discardsession" + }, + "invalidInput": "", + "@invalidInput": {}, + "about": "", + "@about": { + "type": "text", + "placeholders": {} + }, + "chooseAStrongPassword": "", + "@chooseAStrongPassword": { + "type": "text", + "placeholders": {} + }, + "hideUnknownEvents": "", + "@hideUnknownEvents": { + "type": "text", + "placeholders": {} + }, + "todosUnencrypted": "", + "@todosUnencrypted": {}, + "dehydrateTorLong": "", + "@dehydrateTorLong": {}, + "yourPublicKey": "", + "@yourPublicKey": { + "type": "text", + "placeholders": {} + }, + "tooManyRequestsWarning": "", + "@tooManyRequestsWarning": { + "type": "text", + "placeholders": {} + }, + "invitedUser": "", + "@invitedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "kickFromChat": "", + "@kickFromChat": { + "type": "text", + "placeholders": {} + }, + "commandHint_myroomnick": "", + "@commandHint_myroomnick": { + "type": "text", + "description": "Usage hint for the command /myroomnick" + }, + "offline": "", + "@offline": { + "type": "text", + "placeholders": {} + }, + "replyHasBeenSent": "", + "@replyHasBeenSent": {}, + "noPermission": "", + "@noPermission": { + "type": "text", + "placeholders": {} + }, + "doNotShowAgain": "", + "@doNotShowAgain": {}, + "activatedEndToEndEncryption": "", + "@activatedEndToEndEncryption": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "report": "", + "@report": {}, + "status": "", + "@status": { + "type": "text", + "placeholders": {} + }, + "deny": "", + "@deny": { + "type": "text", + "placeholders": {} + }, + "compareNumbersMatch": "", + "@compareNumbersMatch": { + "type": "text", + "placeholders": {} + }, + "groupIsPublic": "", + "@groupIsPublic": { + "type": "text", + "placeholders": {} + }, + "verifyStart": "", + "@verifyStart": { + "type": "text", + "placeholders": {} + }, + "yourStory": "", + "@yourStory": {}, + "memberChanges": "", + "@memberChanges": { + "type": "text", + "placeholders": {} + }, + "joinRoom": "", + "@joinRoom": { + "type": "text", + "placeholders": {} + }, + "ignoreUsername": "", + "@ignoreUsername": { + "type": "text", + "placeholders": {} + }, + "unverified": "", + "@unverified": {}, + "fluffychat": "", + "@fluffychat": { + "type": "text", + "placeholders": {} + }, + "howOffensiveIsThisContent": "", + "@howOffensiveIsThisContent": { + "type": "text", + "placeholders": {} + }, + "serverRequiresEmail": "", + "@serverRequiresEmail": {}, + "hideUnimportantStateEvents": "", + "@hideUnimportantStateEvents": {}, + "screenSharingTitle": "", + "@screenSharingTitle": {}, + "widgetCustom": "", + "@widgetCustom": {}, + "sentCallInformations": "", + "@sentCallInformations": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "addToSpaceDescription": "", + "@addToSpaceDescription": {}, + "googlyEyesContent": "", + "@googlyEyesContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "whoCanSeeMyStoriesDesc": "", + "@whoCanSeeMyStoriesDesc": {}, + "youBannedUser": "", + "@youBannedUser": { + "placeholders": { + "user": {} + } + }, + "theyDontMatch": "", + "@theyDontMatch": { + "type": "text", + "placeholders": {} + }, + "unsubscribeStories": "", + "@unsubscribeStories": {}, + "youHaveBeenBannedFromThisChat": "", + "@youHaveBeenBannedFromThisChat": { + "type": "text", + "placeholders": {} + }, + "displaynameHasBeenChanged": "", + "@displaynameHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "loginWithOneClick": "", + "@loginWithOneClick": {}, + "addChatDescription": "", + "@addChatDescription": {}, + "sentAnAudio": "", + "@sentAnAudio": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "editRoomAvatar": "", + "@editRoomAvatar": { + "type": "text", + "placeholders": {} + }, + "encrypted": "", + "@encrypted": { + "type": "text", + "placeholders": {} + }, + "commandHint_leave": "", + "@commandHint_leave": { + "type": "text", + "description": "Usage hint for the command /leave" + }, + "commandHint_myroomavatar": "", + "@commandHint_myroomavatar": { + "type": "text", + "description": "Usage hint for the command /myroomavatar" + }, + "cancel": "", + "@cancel": { + "type": "text", + "placeholders": {} + }, + "hasKnocked": "", + "@hasKnocked": { + "placeholders": { + "user": {} + } + }, + "publish": "", + "@publish": {}, + "openLinkInBrowser": "", + "@openLinkInBrowser": {}, + "clearArchive": "", + "@clearArchive": {}, + "appLock": "", + "@appLock": { + "type": "text", + "placeholders": {} + }, + "commandHint_react": "", + "@commandHint_react": { + "type": "text", + "description": "Usage hint for the command /react" + }, + "changedTheHistoryVisibility": "", + "@changedTheHistoryVisibility": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "commandHint_me": "", + "@commandHint_me": { + "type": "text", + "description": "Usage hint for the command /me" + }, + "pleaseEnterYourUsername": "", + "@pleaseEnterYourUsername": { + "type": "text", + "placeholders": {} + }, + "messageInfo": "", + "@messageInfo": {}, + "disableEncryptionWarning": "", + "@disableEncryptionWarning": {}, + "directChat": "", + "@directChat": {}, + "noOneCanJoin": "", + "@noOneCanJoin": {}, + "encryptionNotEnabled": "", + "@encryptionNotEnabled": { + "type": "text", + "placeholders": {} + }, + "wrongPinEntered": "", + "@wrongPinEntered": { + "type": "text", + "placeholders": { + "seconds": {} + } + }, + "sendTypingNotifications": "", + "@sendTypingNotifications": {}, + "lightTheme": "", + "@lightTheme": { + "type": "text", + "placeholders": {} + }, + "inviteGroupChat": "", + "@inviteGroupChat": {}, + "appearOnTop": "", + "@appearOnTop": {}, + "invitePrivateChat": "", + "@invitePrivateChat": {}, + "verifyTitle": "", + "@verifyTitle": { + "type": "text", + "placeholders": {} + }, + "foregroundServiceRunning": "", + "@foregroundServiceRunning": {}, + "enterAnEmailAddress": "", + "@enterAnEmailAddress": { + "type": "text", + "placeholders": {} + }, + "voiceCall": "", + "@voiceCall": {}, + "commandHint_kick": "", + "@commandHint_kick": { + "type": "text", + "description": "Usage hint for the command /kick" + }, + "copiedToClipboard": "", + "@copiedToClipboard": { + "type": "text", + "placeholders": {} + }, + "createNewSpace": "", + "@createNewSpace": { + "type": "text", + "placeholders": {} + }, + "commandHint_unban": "", + "@commandHint_unban": { + "type": "text", + "description": "Usage hint for the command /unban" + }, + "unknownEncryptionAlgorithm": "", + "@unknownEncryptionAlgorithm": { + "type": "text", + "placeholders": {} + }, + "commandHint_ban": "", + "@commandHint_ban": { + "type": "text", + "description": "Usage hint for the command /ban" + }, + "importEmojis": "", + "@importEmojis": {}, + "confirm": "", + "@confirm": { + "type": "text", + "placeholders": {} + }, + "wasDirectChatDisplayName": "", + "@wasDirectChatDisplayName": { + "type": "text", + "placeholders": { + "oldDisplayName": {} + } + }, + "noChatDescriptionYet": "", + "@noChatDescriptionYet": {}, + "defaultPermissionLevel": "", + "@defaultPermissionLevel": { + "type": "text", + "placeholders": {} + }, + "newTodo": "", + "@newTodo": {}, + "removeFromBundle": "", + "@removeFromBundle": {}, + "numUsersTyping": "", + "@numUsersTyping": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "fontSize": "", + "@fontSize": { + "type": "text", + "placeholders": {} + }, + "whoCanPerformWhichAction": "", + "@whoCanPerformWhichAction": { + "type": "text", + "placeholders": {} + }, + "confirmMatrixId": "", + "@confirmMatrixId": {}, + "learnMore": "", + "@learnMore": {}, + "iHaveClickedOnLink": "", + "@iHaveClickedOnLink": { + "type": "text", + "placeholders": {} + }, + "you": "", + "@you": { + "type": "text", + "placeholders": {} + }, + "notAnImage": "", + "@notAnImage": {}, + "users": "", + "@users": {}, + "openGallery": "", + "@openGallery": {}, + "chatDescriptionHasBeenChanged": "", + "@chatDescriptionHasBeenChanged": {}, + "search": "", + "@search": { + "type": "text", + "placeholders": {} + }, + "newGroup": "", + "@newGroup": {}, + "bundleName": "", + "@bundleName": {}, + "dehydrateTor": "", + "@dehydrateTor": {}, + "todoListChangedError": "", + "@todoListChangedError": {}, + "removeFromSpace": "", + "@removeFromSpace": {}, + "enterInviteLinkOrMatrixId": "", + "@enterInviteLinkOrMatrixId": {}, + "dateAndTimeOfDay": "", + "@dateAndTimeOfDay": { + "type": "text", + "placeholders": { + "date": {}, + "timeOfDay": {} + } + }, + "commandHint_op": "", + "@commandHint_op": { + "type": "text", + "description": "Usage hint for the command /op" + }, + "commandHint_join": "", + "@commandHint_join": { + "type": "text", + "description": "Usage hint for the command /join" + }, + "sourceCode": "", + "@sourceCode": { + "type": "text", + "placeholders": {} + }, + "enterAGroupName": "", + "@enterAGroupName": { + "type": "text", + "placeholders": {} + }, + "roomUpgradeDescription": "", + "@roomUpgradeDescription": {}, + "commandHint_invite": "", + "@commandHint_invite": { + "type": "text", + "description": "Usage hint for the command /invite" + }, + "userSentUnknownEvent": "", + "@userSentUnknownEvent": { + "type": "text", + "placeholders": { + "username": {}, + "type": {} + } + }, + "scanQrCode": "", + "@scanQrCode": {}, + "logout": "", + "@logout": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterANumber": "", + "@pleaseEnterANumber": {}, + "contactHasBeenInvitedToTheGroup": "", + "@contactHasBeenInvitedToTheGroup": { + "type": "text", + "placeholders": {} + }, + "youKicked": "", + "@youKicked": { + "placeholders": { + "user": {} + } + }, + "areYouSureYouWantToLogout": "", + "@areYouSureYouWantToLogout": { + "type": "text", + "placeholders": {} + }, + "changedTheJoinRules": "", + "@changedTheJoinRules": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "profileNotFound": "", + "@profileNotFound": {}, + "jump": "", + "@jump": {}, + "groups": "", + "@groups": { + "type": "text", + "placeholders": {} + }, + "reactedWith": "", + "@reactedWith": { + "type": "text", + "placeholders": { + "sender": {}, + "reaction": {} + } + }, + "bannedUser": "", + "@bannedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "iUnderstand": "", + "@iUnderstand": {}, + "sorryThatsNotPossible": "", + "@sorryThatsNotPossible": {}, + "storyFrom": "", + "@storyFrom": { + "type": "text", + "placeholders": { + "date": {}, + "body": {} + } + }, + "videoWithSize": "", + "@videoWithSize": { + "type": "text", + "placeholders": { + "size": {} + } + }, + "oopsSomethingWentWrong": "", + "@oopsSomethingWentWrong": { + "type": "text", + "placeholders": {} + }, + "loadCountMoreParticipants": "", + "@loadCountMoreParticipants": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "shareInviteLink": "", + "@shareInviteLink": {}, + "commandHint_markasdm": "", + "@commandHint_markasdm": {}, + "recoveryKeyLost": "", + "@recoveryKeyLost": {}, + "cuddleContent": "", + "@cuddleContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "askVerificationRequest": "", + "@askVerificationRequest": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "containsUserName": "", + "@containsUserName": { + "type": "text", + "placeholders": {} + }, + "messages": "", + "@messages": { + "type": "text", + "placeholders": {} + }, + "login": "", + "@login": { + "type": "text", + "placeholders": {} + }, + "deviceKeys": "", + "@deviceKeys": {}, + "waitingPartnerNumbers": "", + "@waitingPartnerNumbers": { + "type": "text", + "placeholders": {} + }, + "noGoogleServicesWarning": "", + "@noGoogleServicesWarning": { + "type": "text", + "placeholders": {} + }, + "everythingReady": "", + "@everythingReady": { + "type": "text", + "placeholders": {} + }, + "addEmail": "", + "@addEmail": { + "type": "text", + "placeholders": {} + }, + "emoteKeyboardNoRecents": "", + "@emoteKeyboardNoRecents": { + "type": "text", + "placeholders": {} + }, + "setCustomEmotes": "", + "@setCustomEmotes": { + "type": "text", + "placeholders": {} + }, + "startedACall": "", + "@startedACall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "emoteInvalid": "", + "@emoteInvalid": { + "type": "text", + "placeholders": {} + }, + "systemTheme": "", + "@systemTheme": { + "type": "text", + "placeholders": {} + }, + "messageWillBeRemovedWarning": "", + "@messageWillBeRemovedWarning": { + "type": "text", + "placeholders": {} + }, + "endToEndEncryption": "", + "@endToEndEncryption": {}, + "notificationsEnabledForThisAccount": "", + "@notificationsEnabledForThisAccount": { + "type": "text", + "placeholders": {} + }, + "deleteMessage": "", + "@deleteMessage": { + "type": "text", + "placeholders": {} + }, + "visibilityOfTheChatHistory": "", + "@visibilityOfTheChatHistory": { + "type": "text", + "placeholders": {} + }, + "settings": "", + "@settings": { + "type": "text", + "placeholders": {} + }, + "setTheme": "", + "@setTheme": {}, + "changeTheHomeserver": "", + "@changeTheHomeserver": { + "type": "text", + "placeholders": {} + }, + "youJoinedTheChat": "", + "@youJoinedTheChat": {}, + "wallpaper": "", + "@wallpaper": { + "type": "text", + "placeholders": {} + }, + "openVideoCamera": "", + "@openVideoCamera": { + "type": "text", + "placeholders": {} + }, + "play": "", + "@play": { + "type": "text", + "placeholders": { + "fileName": {} + } + }, + "chatBackupDescription": "", + "@chatBackupDescription": { + "type": "text", + "placeholders": {} + }, + "changeDeviceName": "", + "@changeDeviceName": { + "type": "text", + "placeholders": {} + }, + "lastSeenLongTimeAgo": "", + "@lastSeenLongTimeAgo": { + "type": "text", + "placeholders": {} + }, + "passwordForgotten": "", + "@passwordForgotten": { + "type": "text", + "placeholders": {} + }, + "statusExampleMessage": "", + "@statusExampleMessage": { + "type": "text", + "placeholders": {} + }, + "thisUserHasNotPostedAnythingYet": "", + "@thisUserHasNotPostedAnythingYet": {}, + "security": "", + "@security": { + "type": "text", + "placeholders": {} + }, + "markAsRead": "", + "@markAsRead": {}, + "sendAudio": "", + "@sendAudio": { + "type": "text", + "placeholders": {} + }, + "widgetName": "", + "@widgetName": {}, + "sentASticker": "", + "@sentASticker": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "errorAddingWidget": "", + "@errorAddingWidget": {}, + "commandHint_dm": "", + "@commandHint_dm": { + "type": "text", + "description": "Usage hint for the command /dm" + }, + "commandHint_hug": "", + "@commandHint_hug": {}, + "replace": "", + "@replace": {}, + "reject": "", + "@reject": { + "type": "text", + "placeholders": {} + }, + "extremeOffensive": "", + "@extremeOffensive": { + "type": "text", + "placeholders": {} + }, + "editBlockedServers": "", + "@editBlockedServers": { + "type": "text", + "placeholders": {} + }, + "oopsPushError": "", + "@oopsPushError": { + "type": "text", + "placeholders": {} + }, + "youUnbannedUser": "", + "@youUnbannedUser": { + "placeholders": { + "user": {} + } + }, + "deactivateAccountWarning": "", + "@deactivateAccountWarning": { + "type": "text", + "placeholders": {} + }, + "archive": "", + "@archive": { + "type": "text", + "placeholders": {} + }, + "joinedTheChat": "", + "@joinedTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "visibleForEveryone": "", + "@visibleForEveryone": { + "type": "text", + "placeholders": {} + }, + "pleaseEnter4Digits": "", + "@pleaseEnter4Digits": { + "type": "text", + "placeholders": {} + }, + "newSpace": "", + "@newSpace": {}, + "changePassword": "", + "@changePassword": { + "type": "text", + "placeholders": {} + }, + "devices": "", + "@devices": { + "type": "text", + "placeholders": {} + }, + "accept": "", + "@accept": { + "type": "text", + "placeholders": {} + }, + "unknownEvent": "", + "@unknownEvent": { + "type": "text", + "placeholders": { + "type": {} + } + }, + "emojis": "", + "@emojis": {}, + "signUp": "", + "@signUp": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourPin": "", + "@pleaseEnterYourPin": { + "type": "text", + "placeholders": {} + }, + "pleaseChoose": "", + "@pleaseChoose": { + "type": "text", + "placeholders": {} + }, + "share": "", + "@share": { + "type": "text", + "placeholders": {} + }, + "commandHint_googly": "", + "@commandHint_googly": {}, + "pleaseTryAgainLaterOrChooseDifferentServer": "", + "@pleaseTryAgainLaterOrChooseDifferentServer": {}, + "createGroup": "", + "@createGroup": {}, + "privacy": "", + "@privacy": { + "type": "text", + "placeholders": {} + }, + "changeYourAvatar": "", + "@changeYourAvatar": { + "type": "text", + "placeholders": {} + }, + "sendImage": "", + "@sendImage": { + "type": "text", + "placeholders": {} + }, + "hydrateTorLong": "", + "@hydrateTorLong": {}, + "time": "", + "@time": {}, + "enterYourHomeserver": "", + "@enterYourHomeserver": { + "type": "text", + "placeholders": {} + }, + "botMessages": "", + "@botMessages": { + "type": "text", + "placeholders": {} + }, + "contentHasBeenReported": "", + "@contentHasBeenReported": { + "type": "text", + "placeholders": {} + }, + "custom": "", + "@custom": {}, + "noBackupWarning": "", + "@noBackupWarning": {}, + "fromJoining": "", + "@fromJoining": { + "type": "text", + "placeholders": {} + }, + "verify": "", + "@verify": { + "type": "text", + "placeholders": {} + }, + "sendVideo": "", + "@sendVideo": { + "type": "text", + "placeholders": {} + }, + "editWidgets": "", + "@editWidgets": {}, + "storeInSecureStorageDescription": "", + "@storeInSecureStorageDescription": {}, + "openChat": "", + "@openChat": {}, + "kickUserDescription": "", + "@kickUserDescription": {}, + "sendAMessage": "", + "@sendAMessage": { + "type": "text", + "placeholders": {} + }, + "pin": "", + "@pin": { + "type": "text", + "placeholders": {} + }, + "importNow": "", + "@importNow": {}, + "deleteAccount": "", + "@deleteAccount": { + "type": "text", + "placeholders": {} + }, + "setInvitationLink": "", + "@setInvitationLink": { + "type": "text", + "placeholders": {} + }, + "pinMessage": "", + "@pinMessage": {}, + "screenSharingDetail": "", + "@screenSharingDetail": {}, + "muteChat": "", + "@muteChat": { + "type": "text", + "placeholders": {} + }, + "invite": "", + "@invite": {}, + "enableMultiAccounts": "", + "@enableMultiAccounts": {}, + "chooseAUsername": "", + "@chooseAUsername": { + "type": "text", + "placeholders": {} + }, + "anyoneCanJoin": "", + "@anyoneCanJoin": { + "type": "text", + "placeholders": {} + }, + "emotePacks": "", + "@emotePacks": { + "type": "text", + "placeholders": {} + }, + "makeSureTheIdentifierIsValid": "", + "@makeSureTheIdentifierIsValid": { + "type": "text", + "placeholders": {} + }, + "continueWith": "", + "@continueWith": {}, + "indexedDbErrorTitle": "", + "@indexedDbErrorTitle": {}, + "pleaseChooseAUsername": "", + "@pleaseChooseAUsername": { + "type": "text", + "placeholders": {} + }, + "endedTheCall": "", + "@endedTheCall": { + "type": "text", + "placeholders": { + "senderName": {} + } + } +} diff --git a/assets/l10n/intl_nb.arb b/assets/l10n/intl_nb.arb index da9120355..3d2f185e5 100644 --- a/assets/l10n/intl_nb.arb +++ b/assets/l10n/intl_nb.arb @@ -1,1783 +1,2651 @@ { - "@@last_modified": "2021-08-14 12:41:09.967351", - "about": "Om", - "@about": { - "type": "text", - "placeholders": {} - }, - "accept": "Godta", - "@accept": { - "type": "text", - "placeholders": {} - }, - "acceptedTheInvitation": "{username} godtok invitasjonen", - "@acceptedTheInvitation": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "account": "Konto", - "@account": { - "type": "text", - "placeholders": {} - }, - "activatedEndToEndEncryption": "{username} skrudde på ende-til-ende -kryptering", - "@activatedEndToEndEncryption": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "addGroupDescription": "Legg til gruppebeskrivelse", - "@addGroupDescription": { - "type": "text", - "placeholders": {} - }, - "admin": "Administrator", - "@admin": { - "type": "text", - "placeholders": {} - }, - "alias": "alias", - "@alias": { - "type": "text", - "placeholders": {} - }, - "all": "Alle", - "@all": { - "type": "text", - "placeholders": {} - }, - "answeredTheCall": "{senderName} besvarte anropet", - "@answeredTheCall": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "anyoneCanJoin": "Hvem som helst kan delta", - "@anyoneCanJoin": { - "type": "text", - "placeholders": {} - }, - "appLock": "Programlås", - "@appLock": { - "type": "text", - "placeholders": {} - }, - "archive": "Arkiv", - "@archive": { - "type": "text", - "placeholders": {} - }, - "areGuestsAllowedToJoin": "Skal gjester tillates å ta del", - "@areGuestsAllowedToJoin": { - "type": "text", - "placeholders": {} - }, - "areYouSure": "Er du sikker?", - "@areYouSure": { - "type": "text", - "placeholders": {} - }, - "areYouSureYouWantToLogout": "Er du sikker på at du vil logge ut?", - "@areYouSureYouWantToLogout": { - "type": "text", - "placeholders": {} - }, - "askSSSSSign": "For å kunne signere den andre personen, skriv inn ditt sikre lagerpassord eller gjenopprettingsnøkkel.", - "@askSSSSSign": { - "type": "text", - "placeholders": {} - }, - "askVerificationRequest": "Godta denne bekreftelsesforespørselen fra {username}?", - "@askVerificationRequest": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "banFromChat": "Bannlys fra sludring", - "@banFromChat": { - "type": "text", - "placeholders": {} - }, - "banned": "Bannlyst", - "@banned": { - "type": "text", - "placeholders": {} - }, - "bannedUser": "{username} bannlyste {targetName}", - "@bannedUser": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "blockDevice": "Blokker enhet", - "@blockDevice": { - "type": "text", - "placeholders": {} - }, - "botMessages": "Bot-meldinger", - "@botMessages": { - "type": "text", - "placeholders": {} - }, - "cancel": "Avbryt", - "@cancel": { - "type": "text", - "placeholders": {} - }, - "changeDeviceName": "Endre enhetsnavn", - "@changeDeviceName": { - "type": "text", - "placeholders": {} - }, - "changedTheChatAvatar": "{username} endret sludreavatar", - "@changedTheChatAvatar": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheChatDescriptionTo": "{username} endret sludrebeskrivelse til: «{description}»", - "@changedTheChatDescriptionTo": { - "type": "text", - "placeholders": { - "username": {}, - "description": {} - } - }, - "changedTheChatNameTo": "{username} endret sludringsnavn til: «{chatname}»", - "@changedTheChatNameTo": { - "type": "text", - "placeholders": { - "username": {}, - "chatname": {} - } - }, - "changedTheChatPermissions": "{username} endret sludretilgangene", - "@changedTheChatPermissions": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheDisplaynameTo": "{username} endret visningsnavn til: {displayname}", - "@changedTheDisplaynameTo": { - "type": "text", - "placeholders": { - "username": {}, - "displayname": {} - } - }, - "changedTheGuestAccessRules": "{username} endret gjestetilgangsreglene", - "@changedTheGuestAccessRules": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheGuestAccessRulesTo": "{username} endret gjestetilgangsregler til: {rules}", - "@changedTheGuestAccessRulesTo": { - "type": "text", - "placeholders": { - "username": {}, - "rules": {} - } - }, - "changedTheHistoryVisibility": "{username} endret historikksynlighet", - "@changedTheHistoryVisibility": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheHistoryVisibilityTo": "{username} endret historikksynlighet til: {rules}", - "@changedTheHistoryVisibilityTo": { - "type": "text", - "placeholders": { - "username": {}, - "rules": {} - } - }, - "changedTheJoinRules": "{username} endret tilgangsreglene", - "@changedTheJoinRules": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheJoinRulesTo": "{username} endret tilgangsreglene til: {joinRules}", - "@changedTheJoinRulesTo": { - "type": "text", - "placeholders": { - "username": {}, - "joinRules": {} - } - }, - "changedTheProfileAvatar": "{username} endret avataren sin", - "@changedTheProfileAvatar": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheRoomAliases": "{username} endret rom-aliasene", - "@changedTheRoomAliases": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheRoomInvitationLink": "{username} endret invitasjonslenken", - "@changedTheRoomInvitationLink": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changePassword": "Endre passord", - "@changePassword": { - "type": "text", - "placeholders": {} - }, - "changeTheHomeserver": "Endre hjemmetjener", - "@changeTheHomeserver": { - "type": "text", - "placeholders": {} - }, - "changeTheme": "Endre din stil", - "@changeTheme": { - "type": "text", - "placeholders": {} - }, - "changeTheNameOfTheGroup": "Endre gruppens navn", - "@changeTheNameOfTheGroup": { - "type": "text", - "placeholders": {} - }, - "changeWallpaper": "Endre bakgrunnsbilde", - "@changeWallpaper": { - "type": "text", - "placeholders": {} - }, - "channelCorruptedDecryptError": "Krypteringen er skadet", - "@channelCorruptedDecryptError": { - "type": "text", - "placeholders": {} - }, - "chat": "Sludring", - "@chat": { - "type": "text", - "placeholders": {} - }, - "chatBackup": "Sludringssikkerhetskopi", - "@chatBackup": { - "type": "text", - "placeholders": {} - }, - "chatBackupDescription": "Din sludringssikkerhetskopi er sikret med en sikkerhetsnøkkel. Ikke mist den.", - "@chatBackupDescription": { - "type": "text", - "placeholders": {} - }, - "chatDetails": "Sludringsdetaljer", - "@chatDetails": { - "type": "text", - "placeholders": {} - }, - "chooseAStrongPassword": "Velg et sterkt passord", - "@chooseAStrongPassword": { - "type": "text", - "placeholders": {} - }, - "chooseAUsername": "Velg et brukernavn", - "@chooseAUsername": { - "type": "text", - "placeholders": {} - }, - "close": "Lukk", - "@close": { - "type": "text", - "placeholders": {} - }, - "compareEmojiMatch": "Sammenlign og forsikre at følgende smilefjes samsvarer med de på den andre enheten:", - "@compareEmojiMatch": { - "type": "text", - "placeholders": {} - }, - "compareNumbersMatch": "Sammenlign og forsikre at følgende tall samsvarer med de på den andre enheten:", - "@compareNumbersMatch": { - "type": "text", - "placeholders": {} - }, - "configureChat": "Sett opp sludring", - "@configureChat": { - "type": "text", - "placeholders": {} - }, - "confirm": "Bekreft", - "@confirm": { - "type": "text", - "placeholders": {} - }, - "connect": "Koble til", - "@connect": { - "type": "text", - "placeholders": {} - }, - "contactHasBeenInvitedToTheGroup": "Kontakt invitert til gruppen", - "@contactHasBeenInvitedToTheGroup": { - "type": "text", - "placeholders": {} - }, - "containsDisplayName": "Inneholder visningsnavn", - "@containsDisplayName": { - "type": "text", - "placeholders": {} - }, - "containsUserName": "Inneholder brukernavn", - "@containsUserName": { - "type": "text", - "placeholders": {} - }, - "contentHasBeenReported": "Innholdet har blitt rapportert til tjeneradministratorene", - "@contentHasBeenReported": { - "type": "text", - "placeholders": {} - }, - "copiedToClipboard": "Kopiert til utklippstavle", - "@copiedToClipboard": { - "type": "text", - "placeholders": {} - }, - "copy": "Kopier", - "@copy": { - "type": "text", - "placeholders": {} - }, - "copyToClipboard": "Kopier til utklippstavle", - "@copyToClipboard": { - "type": "text", - "placeholders": {} - }, - "couldNotDecryptMessage": "Kunne ikke dekryptere melding: {error}", - "@couldNotDecryptMessage": { - "type": "text", - "placeholders": { - "error": {} - } - }, - "countParticipants": "{count} deltagere", - "@countParticipants": { - "type": "text", - "placeholders": { - "count": {} - } - }, - "create": "Opprett", - "@create": { - "type": "text", - "placeholders": {} - }, - "createdTheChat": "{username} opprettet sludringen", - "@createdTheChat": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "createNewGroup": "Opprett ny gruppe", - "@createNewGroup": { - "type": "text", - "placeholders": {} - }, - "currentlyActive": "Aktiv nå", - "@currentlyActive": { - "type": "text", - "placeholders": {} - }, - "darkTheme": "Mørk", - "@darkTheme": { - "type": "text", - "placeholders": {} - }, - "dateAndTimeOfDay": "{timeOfDay}, {date}", - "@dateAndTimeOfDay": { - "type": "text", - "placeholders": { - "date": {}, - "timeOfDay": {} - } - }, - "dateWithoutYear": "{day} {month}", - "@dateWithoutYear": { - "type": "text", - "placeholders": { - "month": {}, - "day": {} - } - }, - "dateWithYear": "{day} {month} {year}", - "@dateWithYear": { - "type": "text", - "placeholders": { - "year": {}, - "month": {}, - "day": {} - } - }, - "deactivateAccountWarning": "Dette vil skru av din brukerkonto for godt, og kan ikke angres! Er du sikker?", - "@deactivateAccountWarning": { - "type": "text", - "placeholders": {} - }, - "defaultPermissionLevel": "Forvalgt tilgangsnivå", - "@defaultPermissionLevel": { - "type": "text", - "placeholders": {} - }, - "delete": "Slett", - "@delete": { - "type": "text", - "placeholders": {} - }, - "deleteAccount": "Slett konto", - "@deleteAccount": { - "type": "text", - "placeholders": {} - }, - "deleteMessage": "Slett melding", - "@deleteMessage": { - "type": "text", - "placeholders": {} - }, - "deny": "Nekt", - "@deny": { - "type": "text", - "placeholders": {} - }, - "device": "Enhet", - "@device": { - "type": "text", - "placeholders": {} - }, - "deviceId": "Enhets-ID", - "@deviceId": { - "type": "text", - "placeholders": {} - }, - "devices": "Enheter", - "@devices": { - "type": "text", - "placeholders": {} - }, - "directChats": "Direktesludringer", - "@directChats": { - "type": "text", - "placeholders": {} - }, - "displaynameHasBeenChanged": "Visningsnavn endret", - "@displaynameHasBeenChanged": { - "type": "text", - "placeholders": {} - }, - "downloadFile": "Last ned fil", - "@downloadFile": { - "type": "text", - "placeholders": {} - }, - "edit": "Rediger", - "@edit": { - "type": "text", - "placeholders": {} - }, - "editBlockedServers": "Rediger blokkerte tjenere", - "@editBlockedServers": { - "type": "text", - "placeholders": {} - }, - "editChatPermissions": "Rediger sludringstilganger", - "@editChatPermissions": { - "type": "text", - "placeholders": {} - }, - "editDisplayname": "Rediger visningsnavn", - "@editDisplayname": { - "type": "text", - "placeholders": {} - }, - "editRoomAvatar": "Rediger romavatar", - "@editRoomAvatar": { - "type": "text", - "placeholders": {} - }, - "emoteExists": "Smilefjeset finnes allerede!", - "@emoteExists": { - "type": "text", - "placeholders": {} - }, - "emoteInvalid": "Ugyldig smilefjes-kode!", - "@emoteInvalid": { - "type": "text", - "placeholders": {} - }, - "emotePacks": "Smilefjespakker for rommet", - "@emotePacks": { - "type": "text", - "placeholders": {} - }, - "emoteSettings": "Smilefjes-innstillinger", - "@emoteSettings": { - "type": "text", - "placeholders": {} - }, - "emoteShortcode": "Smilefjes-kode", - "@emoteShortcode": { - "type": "text", - "placeholders": {} - }, - "emoteWarnNeedToPick": "Du må velge en smilefjes-kode og et bilde!", - "@emoteWarnNeedToPick": { - "type": "text", - "placeholders": {} - }, - "emptyChat": "Tom sludring", - "@emptyChat": { - "type": "text", - "placeholders": {} - }, - "enableEmotesGlobally": "Skru på smilefjespakke for hele programmet", - "@enableEmotesGlobally": { - "type": "text", - "placeholders": {} - }, - "enableEncryption": "Skru på kryptering", - "@enableEncryption": { - "type": "text", - "placeholders": {} - }, - "enableEncryptionWarning": "Du vil ikke kunne skru av kryptering lenger. Er du sikker?", - "@enableEncryptionWarning": { - "type": "text", - "placeholders": {} - }, - "encrypted": "Kryptert", - "@encrypted": { - "type": "text", - "placeholders": {} - }, - "encryption": "Kryptering", - "@encryption": { - "type": "text", - "placeholders": {} - }, - "encryptionNotEnabled": "Kryptering er ikke påskrudd", - "@encryptionNotEnabled": { - "type": "text", - "placeholders": {} - }, - "endedTheCall": "{senderName} avsluttet samtalen", - "@endedTheCall": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "enterAGroupName": "Skriv inn et gruppenavn", - "@enterAGroupName": { - "type": "text", - "placeholders": {} - }, - "enterAnEmailAddress": "Skriv inn en e-postadresse", - "@enterAnEmailAddress": { - "type": "text", - "placeholders": {} - }, - "enterYourHomeserver": "Skriv inn din hjemmetjener", - "@enterYourHomeserver": { - "type": "text", - "placeholders": {} - }, - "everythingReady": "Alt er klart!", - "@everythingReady": { - "type": "text", - "placeholders": {} - }, - "extremeOffensive": "Veldig", - "@extremeOffensive": { - "type": "text", - "placeholders": {} - }, - "fileName": "Filnavn", - "@fileName": { - "type": "text", - "placeholders": {} - }, - "fluffychat": "FluffyChat", - "@fluffychat": { - "type": "text", - "placeholders": {} - }, - "fontSize": "Skriftstørrelse", - "@fontSize": { - "type": "text", - "placeholders": {} - }, - "forward": "Videre", - "@forward": { - "type": "text", - "placeholders": {} - }, - "fromJoining": "Fra å ta del", - "@fromJoining": { - "type": "text", - "placeholders": {} - }, - "fromTheInvitation": "Fra invitasjonen", - "@fromTheInvitation": { - "type": "text", - "placeholders": {} - }, - "group": "Gruppe", - "@group": { - "type": "text", - "placeholders": {} - }, - "groupDescription": "Gruppebeskrivelse", - "@groupDescription": { - "type": "text", - "placeholders": {} - }, - "groupDescriptionHasBeenChanged": "Gruppebeskrivelse endret", - "@groupDescriptionHasBeenChanged": { - "type": "text", - "placeholders": {} - }, - "groupIsPublic": "Gruppen er offentlig", - "@groupIsPublic": { - "type": "text", - "placeholders": {} - }, - "groups": "Grupper", - "@groups": { - "type": "text", - "placeholders": {} - }, - "groupWith": "Gruppe med {displayname}", - "@groupWith": { - "type": "text", - "placeholders": { - "displayname": {} - } - }, - "guestsAreForbidden": "Gjester forbudt", - "@guestsAreForbidden": { - "type": "text", - "placeholders": {} - }, - "guestsCanJoin": "Gjester kan ta del", - "@guestsCanJoin": { - "type": "text", - "placeholders": {} - }, - "hasWithdrawnTheInvitationFor": "{username} har trukket tilbake invitasjonen til {targetName}", - "@hasWithdrawnTheInvitationFor": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "help": "Hjelp", - "@help": { - "type": "text", - "placeholders": {} - }, - "hideRedactedEvents": "Skjul tilbaketrukne hendelser", - "@hideRedactedEvents": { - "type": "text", - "placeholders": {} - }, - "hideUnknownEvents": "Skjul ukjente hendelser", - "@hideUnknownEvents": { - "type": "text", - "placeholders": {} - }, - "howOffensiveIsThisContent": "Hvor støtende er innholdet?", - "@howOffensiveIsThisContent": { - "type": "text", - "placeholders": {} - }, - "id": "ID", - "@id": { - "type": "text", - "placeholders": {} - }, - "identity": "Identitet", - "@identity": { - "type": "text", - "placeholders": {} - }, - "ignore": "Ignorer", - "@ignore": { - "type": "text", - "placeholders": {} - }, - "ignoredUsers": "Ignorerte brukere", - "@ignoredUsers": { - "type": "text", - "placeholders": {} - }, - "ignoreListDescription": "Du kan ignorere brukere som forstyrrer deg. Du vil ikke lenger kunne motta meldinger eller rominvitasjoner fra brukere på din personlige ignoreringsliste.", - "@ignoreListDescription": { - "type": "text", - "placeholders": {} - }, - "ignoreUsername": "Ignorer brukernavn", - "@ignoreUsername": { - "type": "text", - "placeholders": {} - }, - "iHaveClickedOnLink": "Jeg har klikket på lenken", - "@iHaveClickedOnLink": { - "type": "text", - "placeholders": {} - }, - "incorrectPassphraseOrKey": "Feilaktig passord eller gjenopprettingsnøkkel", - "@incorrectPassphraseOrKey": { - "type": "text", - "placeholders": {} - }, - "inoffensive": "Harmløst", - "@inoffensive": { - "type": "text", - "placeholders": {} - }, - "inviteContact": "Inviter kontakt", - "@inviteContact": { - "type": "text", - "placeholders": {} - }, - "inviteContactToGroup": "Inviter kontakt til {groupName}", - "@inviteContactToGroup": { - "type": "text", - "placeholders": { - "groupName": {} - } - }, - "invited": "Invitert", - "@invited": { - "type": "text", - "placeholders": {} - }, - "invitedUser": "{username} inviterte {targetName}", - "@invitedUser": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "invitedUsersOnly": "Kun inviterte brukere", - "@invitedUsersOnly": { - "type": "text", - "placeholders": {} - }, - "inviteForMe": "Invitasjon for meg", - "@inviteForMe": { - "type": "text", - "placeholders": {} - }, - "inviteText": "{username} har invitert deg til FluffyChat. \n1. Installer FluffyChat: https://fluffychat.im \n2. Registrer deg eller logg inn \n3. Åpne invitasjonslenken: {link}", - "@inviteText": { - "type": "text", - "placeholders": { - "username": {}, - "link": {} - } - }, - "isTyping": "skriver…", - "@isTyping": { - "type": "text", - "placeholders": {} - }, - "joinedTheChat": "{username}ble med i samtalen", - "@joinedTheChat": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "joinRoom": "Ta del i rom", - "@joinRoom": { - "type": "text", - "placeholders": {} - }, - "kicked": "{username} kastet ut {targetName}", - "@kicked": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "kickedAndBanned": "{username} kastet ut og bannlyste {targetName}", - "@kickedAndBanned": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "kickFromChat": "Kast ut av sludringen", - "@kickFromChat": { - "type": "text", - "placeholders": {} - }, - "lastActiveAgo": "Sist aktiv: {localizedTimeShort}", - "@lastActiveAgo": { - "type": "text", - "placeholders": { - "localizedTimeShort": {} - } - }, - "lastSeenLongTimeAgo": "Sett for lenge siden", - "@lastSeenLongTimeAgo": { - "type": "text", - "placeholders": {} - }, - "leave": "Forlat", - "@leave": { - "type": "text", - "placeholders": {} - }, - "leftTheChat": "Forlat sludringen", - "@leftTheChat": { - "type": "text", - "placeholders": {} - }, - "license": "Lisens", - "@license": { - "type": "text", - "placeholders": {} - }, - "lightTheme": "Lys", - "@lightTheme": { - "type": "text", - "placeholders": {} - }, - "loadCountMoreParticipants": "Last inn {count} deltagere til", - "@loadCountMoreParticipants": { - "type": "text", - "placeholders": { - "count": {} - } - }, - "loadingPleaseWait": "Laster inn… Vent.", - "@loadingPleaseWait": { - "type": "text", - "placeholders": {} - }, - "loadMore": "Last inn mer…", - "@loadMore": { - "type": "text", - "placeholders": {} - }, - "login": "Logg inn", - "@login": { - "type": "text", - "placeholders": {} - }, - "logInTo": "Logg inn på {homeserver}", - "@logInTo": { - "type": "text", - "placeholders": { - "homeserver": {} - } - }, - "logout": "Logg ut", - "@logout": { - "type": "text", - "placeholders": {} - }, - "makeSureTheIdentifierIsValid": "Forsikre deg om at identifikatoren er gyldig", - "@makeSureTheIdentifierIsValid": { - "type": "text", - "placeholders": {} - }, - "memberChanges": "Medlemsendringer", - "@memberChanges": { - "type": "text", - "placeholders": {} - }, - "mention": "Nevn", - "@mention": { - "type": "text", - "placeholders": {} - }, - "messages": "Meldinger", - "@messages": { - "type": "text", - "placeholders": {} - }, - "messageWillBeRemovedWarning": "Meldingen vil bli fjernet for alle deltagere", - "@messageWillBeRemovedWarning": { - "type": "text", - "placeholders": {} - }, - "moderator": "Moderator", - "@moderator": { - "type": "text", - "placeholders": {} - }, - "muteChat": "Forstum sludring", - "@muteChat": { - "type": "text", - "placeholders": {} - }, - "needPantalaimonWarning": "Merk at du trenger Pantalaimon for å bruke ende-til-ende -kryptering inntil videre.", - "@needPantalaimonWarning": { - "type": "text", - "placeholders": {} - }, - "newChat": "Ny sludring", - "@newChat": { - "type": "text", - "placeholders": {} - }, - "newMessageInFluffyChat": "Ny melding i FluffyChat", - "@newMessageInFluffyChat": { - "type": "text", - "placeholders": {} - }, - "newVerificationRequest": "Ny bekreftelsesforespørsel!", - "@newVerificationRequest": { - "type": "text", - "placeholders": {} - }, - "next": "Neste", - "@next": { - "type": "text", - "placeholders": {} - }, - "no": "Nei", - "@no": { - "type": "text", - "placeholders": {} - }, - "noEmotesFound": "Fant ingen smilefjes. 😕", - "@noEmotesFound": { - "type": "text", - "placeholders": {} - }, - "noGoogleServicesWarning": "Bruk https://microg.org/ for å få Google-tjenester (uten at det går ut over personvernet) for å få push-merknader i FluffyChat:", - "@noGoogleServicesWarning": { - "type": "text", - "placeholders": {} - }, - "none": "Ingen", - "@none": { - "type": "text", - "placeholders": {} - }, - "noPasswordRecoveryDescription": "Du har ikke lagt til en måte å gjenopprette passordet ditt på.", - "@noPasswordRecoveryDescription": { - "type": "text", - "placeholders": {} - }, - "noPermission": "Ingen tilgang", - "@noPermission": { - "type": "text", - "placeholders": {} - }, - "noRoomsFound": "Fant ingen rom …", - "@noRoomsFound": { - "type": "text", - "placeholders": {} - }, - "notifications": "Merknader", - "@notifications": { - "type": "text", - "placeholders": {} - }, - "notificationsEnabledForThisAccount": "Merknader påslått for denne kontoen", - "@notificationsEnabledForThisAccount": { - "type": "text", - "placeholders": {} - }, - "numUsersTyping": "{count} brukere skriver …", - "@numUsersTyping": { - "type": "text", - "placeholders": { - "count": {} - } - }, - "offensive": "Støtende", - "@offensive": { - "type": "text", - "placeholders": {} - }, - "offline": "Frakoblet", - "@offline": { - "type": "text", - "placeholders": {} - }, - "ok": "OK", - "@ok": { - "type": "text", - "placeholders": {} - }, - "online": "Pålogget", - "@online": { - "type": "text", - "placeholders": {} - }, - "onlineKeyBackupEnabled": "Nettbasert sikkerhetskopiering av nøkler på", - "@onlineKeyBackupEnabled": { - "type": "text", - "placeholders": {} - }, - "oopsSomethingWentWrong": "Oida, noe gikk galt …", - "@oopsSomethingWentWrong": { - "type": "text", - "placeholders": {} - }, - "openAppToReadMessages": "Åpne programmet for å lese meldinger", - "@openAppToReadMessages": { - "type": "text", - "placeholders": {} - }, - "openCamera": "Åpne kamera", - "@openCamera": { - "type": "text", - "placeholders": {} - }, - "optionalGroupName": "Gruppenavn (valgfritt)", - "@optionalGroupName": { - "type": "text", - "placeholders": {} - }, - "participant": "Deltager", - "@participant": { - "type": "text", - "placeholders": {} - }, - "passphraseOrKey": "Passord eller gjenopprettingsnøkkel", - "@passphraseOrKey": { - "type": "text", - "placeholders": {} - }, - "password": "Passord", - "@password": { - "type": "text", - "placeholders": {} - }, - "passwordForgotten": "Passord glemt", - "@passwordForgotten": { - "type": "text", - "placeholders": {} - }, - "passwordHasBeenChanged": "Passord endret", - "@passwordHasBeenChanged": { - "type": "text", - "placeholders": {} - }, - "passwordRecovery": "Passordgjenoppretting", - "@passwordRecovery": { - "type": "text", - "placeholders": {} - }, - "pickImage": "Velg bilde", - "@pickImage": { - "type": "text", - "placeholders": {} - }, - "pin": "Fest", - "@pin": { - "type": "text", - "placeholders": {} - }, - "play": "Spill av {fileName}", - "@play": { - "type": "text", - "placeholders": { - "fileName": {} - } - }, - "pleaseChooseAUsername": "Velg et brukernavn", - "@pleaseChooseAUsername": { - "type": "text", - "placeholders": {} - }, - "pleaseClickOnLink": "Klikk på lenken i e-posten og fortsett.", - "@pleaseClickOnLink": { - "type": "text", - "placeholders": {} - }, - "pleaseEnterAMatrixIdentifier": "Skriv inn en Matrix-ID.", - "@pleaseEnterAMatrixIdentifier": { - "type": "text", - "placeholders": {} - }, - "pleaseEnterYourPassword": "Skriv inn passordet ditt", - "@pleaseEnterYourPassword": { - "type": "text", - "placeholders": {} - }, - "pleaseEnterYourUsername": "Skriv inn brukernavnet ditt", - "@pleaseEnterYourUsername": { - "type": "text", - "placeholders": {} - }, - "pleaseFollowInstructionsOnWeb": "Følg instruksen på nettsiden og trykk på «Neste».", - "@pleaseFollowInstructionsOnWeb": { - "type": "text", - "placeholders": {} - }, - "privacy": "Personvern", - "@privacy": { - "type": "text", - "placeholders": {} - }, - "publicRooms": "Offentlige rom", - "@publicRooms": { - "type": "text", - "placeholders": {} - }, - "pushRules": "Dyttingsregler", - "@pushRules": { - "type": "text", - "placeholders": {} - }, - "reason": "Grunn", - "@reason": { - "type": "text", - "placeholders": {} - }, - "recording": "Opptak", - "@recording": { - "type": "text", - "placeholders": {} - }, - "redactedAnEvent": "{username} har trukket tilbake en hendelse", - "@redactedAnEvent": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "reject": "Avslå", - "@reject": { - "type": "text", - "placeholders": {} - }, - "rejectedTheInvitation": "{username} avslo invitasjonen", - "@rejectedTheInvitation": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "rejoin": "Ta del igjen", - "@rejoin": { - "type": "text", - "placeholders": {} - }, - "remove": "Fjern", - "@remove": { - "type": "text", - "placeholders": {} - }, - "removeAllOtherDevices": "Fjern alle andre enheter", - "@removeAllOtherDevices": { - "type": "text", - "placeholders": {} - }, - "removedBy": "Fjernet av {username}", - "@removedBy": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "removeDevice": "Fjern enhet", - "@removeDevice": { - "type": "text", - "placeholders": {} - }, - "unbanFromChat": "Opphev bannlysning", - "@unbanFromChat": { - "type": "text", - "placeholders": {} - }, - "renderRichContent": "Tegn rikt meldingsinnhold", - "@renderRichContent": { - "type": "text", - "placeholders": {} - }, - "replaceRoomWithNewerVersion": "Erstatt rom med nyere versjon", - "@replaceRoomWithNewerVersion": { - "type": "text", - "placeholders": {} - }, - "reply": "Svar", - "@reply": { - "type": "text", - "placeholders": {} - }, - "reportMessage": "Rapporter melding", - "@reportMessage": { - "type": "text", - "placeholders": {} - }, - "requestPermission": "Forespør tilgang", - "@requestPermission": { - "type": "text", - "placeholders": {} - }, - "roomHasBeenUpgraded": "Rommet har blitt oppgradert", - "@roomHasBeenUpgraded": { - "type": "text", - "placeholders": {} - }, - "search": "Søk", - "@search": { - "type": "text", - "placeholders": {} - }, - "security": "Sikkerhet", - "@security": { - "type": "text", - "placeholders": {} - }, - "seenByUser": "Sett av {username}", - "@seenByUser": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "seenByUserAndCountOthers": "{count, plural, other{Sett av {username} og {count} andre}}", - "@seenByUserAndCountOthers": { - "type": "text", - "placeholders": { - "username": {}, - "count": {} - } - }, - "seenByUserAndUser": "Sett av {username} og {username2}", - "@seenByUserAndUser": { - "type": "text", - "placeholders": { - "username": {}, - "username2": {} - } - }, - "send": "Send", - "@send": { - "type": "text", - "placeholders": {} - }, - "sendAMessage": "Send en melding", - "@sendAMessage": { - "type": "text", - "placeholders": {} - }, - "sendAudio": "Send lyd", - "@sendAudio": { - "type": "text", - "placeholders": {} - }, - "sendFile": "Send fil", - "@sendFile": { - "type": "text", - "placeholders": {} - }, - "sendImage": "Send bilde", - "@sendImage": { - "type": "text", - "placeholders": {} - }, - "sendMessages": "Send meldinger", - "@sendMessages": { - "type": "text", - "placeholders": {} - }, - "sendOriginal": "Send original", - "@sendOriginal": { - "type": "text", - "placeholders": {} - }, - "sendVideo": "Send video", - "@sendVideo": { - "type": "text", - "placeholders": {} - }, - "sentAFile": "{username} sendte en fil", - "@sentAFile": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sentAnAudio": "{username} sendte lyd", - "@sentAnAudio": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sentAPicture": "{username} sendte et bilde", - "@sentAPicture": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sentASticker": "{username} sendte et klistremerke", - "@sentASticker": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sentAVideo": "{username} sendte en video", - "@sentAVideo": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sentCallInformations": "{senderName} sendte anropsinfo", - "@sentCallInformations": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "setCustomEmotes": "Sett tilpassede smilefjes", - "@setCustomEmotes": { - "type": "text", - "placeholders": {} - }, - "setGroupDescription": "Sett gruppebeskrivelse", - "@setGroupDescription": { - "type": "text", - "placeholders": {} - }, - "setInvitationLink": "Sett invitasjonslenke", - "@setInvitationLink": { - "type": "text", - "placeholders": {} - }, - "setPermissionsLevel": "Sett tilgangsnivå", - "@setPermissionsLevel": { - "type": "text", - "placeholders": {} - }, - "setStatus": "Angi status", - "@setStatus": { - "type": "text", - "placeholders": {} - }, - "settings": "Innstilinger", - "@settings": { - "type": "text", - "placeholders": {} - }, - "share": "Del", - "@share": { - "type": "text", - "placeholders": {} - }, - "sharedTheLocation": "{username} delte posisjonen", - "@sharedTheLocation": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "signUp": "Registrer deg", - "@signUp": { - "type": "text", - "placeholders": {} - }, - "skip": "Hopp over", - "@skip": { - "type": "text", - "placeholders": {} - }, - "sourceCode": "Kildekode", - "@sourceCode": { - "type": "text", - "placeholders": {} - }, - "startedACall": "{senderName} startet en samtale", - "@startedACall": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "status": "Status", - "@status": { - "type": "text", - "placeholders": {} - }, - "statusExampleMessage": "Hvordan har du det i dag?", - "@statusExampleMessage": { - "type": "text", - "placeholders": {} - }, - "submit": "Send inn", - "@submit": { - "type": "text", - "placeholders": {} - }, - "systemTheme": "System", - "@systemTheme": { - "type": "text", - "placeholders": {} - }, - "theyDontMatch": "Samsvarer ikke", - "@theyDontMatch": { - "type": "text", - "placeholders": {} - }, - "theyMatch": "Samsvarer", - "@theyMatch": { - "type": "text", - "placeholders": {} - }, - "title": "FluffyChat", - "@title": { - "description": "Title for the application", - "type": "text", - "placeholders": {} - }, - "tooManyRequestsWarning": "For mange forespørsler. Prøv igjen senere!", - "@tooManyRequestsWarning": { - "type": "text", - "placeholders": {} - }, - "transferFromAnotherDevice": "Overfør fra en annen enhet", - "@transferFromAnotherDevice": { - "type": "text", - "placeholders": {} - }, - "tryToSendAgain": "Prøv å sende igjen", - "@tryToSendAgain": { - "type": "text", - "placeholders": {} - }, - "unavailable": "Utilgjengelig", - "@unavailable": { - "type": "text", - "placeholders": {} - }, - "unbannedUser": "{username} opphevet bannlysning av {targetName}", - "@unbannedUser": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "unblockDevice": "Opphev blokkering av enhet", - "@unblockDevice": { - "type": "text", - "placeholders": {} - }, - "unknownDevice": "Ukjent enhet", - "@unknownDevice": { - "type": "text", - "placeholders": {} - }, - "unknownEncryptionAlgorithm": "Ukjent krypteringsalgoritme", - "@unknownEncryptionAlgorithm": { - "type": "text", - "placeholders": {} - }, - "unknownEvent": "Ukjent hendelse «{type}»", - "@unknownEvent": { - "type": "text", - "placeholders": { - "type": {} - } - }, - "unmuteChat": "Opphev forstumming av sludring", - "@unmuteChat": { - "type": "text", - "placeholders": {} - }, - "unpin": "Løsne", - "@unpin": { - "type": "text", - "placeholders": {} - }, - "unreadChats": "{unreadCount, plural, other{{unreadCount} uleste sludringer}}", - "@unreadChats": { - "type": "text", - "placeholders": { - "unreadCount": {} - } - }, - "userAndOthersAreTyping": "{username} og {count} andre skriver…", - "@userAndOthersAreTyping": { - "type": "text", - "placeholders": { - "username": {}, - "count": {} - } - }, - "userAndUserAreTyping": "{username} og {username2} skriver…", - "@userAndUserAreTyping": { - "type": "text", - "placeholders": { - "username": {}, - "username2": {} - } - }, - "userIsTyping": "{username} skriver…", - "@userIsTyping": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "userLeftTheChat": "{username} har forlatt sludringen", - "@userLeftTheChat": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "username": "Brukernavn", - "@username": { - "type": "text", - "placeholders": {} - }, - "userSentUnknownEvent": "{username} sendte en {type}-hendelse", - "@userSentUnknownEvent": { - "type": "text", - "placeholders": { - "username": {}, - "type": {} - } - }, - "verify": "Bekreft", - "@verify": { - "type": "text", - "placeholders": {} - }, - "verifyStart": "Start bekreftelse", - "@verifyStart": { - "type": "text", - "placeholders": {} - }, - "verifySuccess": "Du har bekreftet!", - "@verifySuccess": { - "type": "text", - "placeholders": {} - }, - "verifyTitle": "Bekrefter annen konto", - "@verifyTitle": { - "type": "text", - "placeholders": {} - }, - "videoCall": "Videosamtale", - "@videoCall": { - "type": "text", - "placeholders": {} - }, - "visibilityOfTheChatHistory": "Sludrehistorikkens synlighet", - "@visibilityOfTheChatHistory": { - "type": "text", - "placeholders": {} - }, - "visibleForAllParticipants": "Synlig for alle deltagere", - "@visibleForAllParticipants": { - "type": "text", - "placeholders": {} - }, - "visibleForEveryone": "Synlig for alle", - "@visibleForEveryone": { - "type": "text", - "placeholders": {} - }, - "voiceMessage": "Lydmelding", - "@voiceMessage": { - "type": "text", - "placeholders": {} - }, - "waitingPartnerNumbers": "Venter på at samtalepartner skal godta tallene …", - "@waitingPartnerNumbers": { - "type": "text", - "placeholders": {} - }, - "wallpaper": "Bakgrunnsbilde", - "@wallpaper": { - "type": "text", - "placeholders": {} - }, - "warning": "Advarsel!", - "@warning": { - "type": "text", - "placeholders": {} - }, - "weSentYouAnEmail": "Du har fått en e-post", - "@weSentYouAnEmail": { - "type": "text", - "placeholders": {} - }, - "whoCanPerformWhichAction": "Hvem kan utføre hvilken handling", - "@whoCanPerformWhichAction": { - "type": "text", - "placeholders": {} - }, - "whoIsAllowedToJoinThisGroup": "Hvem tillates å ta del i denne gruppen", - "@whoIsAllowedToJoinThisGroup": { - "type": "text", - "placeholders": {} - }, - "whyDoYouWantToReportThis": "Hvorfor ønsker du å rapportere dette?", - "@whyDoYouWantToReportThis": { - "type": "text", - "placeholders": {} - }, - "withTheseAddressesRecoveryDescription": "Med disse adressene kan du gjenopprette passordet ditt hvis du trenger det.", - "@withTheseAddressesRecoveryDescription": { - "type": "text", - "placeholders": {} - }, - "writeAMessage": "Skriv en melding …", - "@writeAMessage": { - "type": "text", - "placeholders": {} - }, - "yes": "Ja", - "@yes": { - "type": "text", - "placeholders": {} - }, - "you": "Deg", - "@you": { - "type": "text", - "placeholders": {} - }, - "youAreInvitedToThisChat": "Du er invitert til denne sludringen", - "@youAreInvitedToThisChat": { - "type": "text", - "placeholders": {} - }, - "youAreNoLongerParticipatingInThisChat": "Du deltar ikke lenger i denne sludringen", - "@youAreNoLongerParticipatingInThisChat": { - "type": "text", - "placeholders": {} - }, - "youCannotInviteYourself": "Du kan ikke invitere deg selv", - "@youCannotInviteYourself": { - "type": "text", - "placeholders": {} - }, - "youHaveBeenBannedFromThisChat": "Du har blitt bannlyst fra denne sludringen", - "@youHaveBeenBannedFromThisChat": { - "type": "text", - "placeholders": {} - }, - "yourPublicKey": "Din offentlige nøkkel", - "@yourPublicKey": { - "type": "text", - "placeholders": {} - }, - "toggleUnread": "Marker som lest/ulest", - "@toggleUnread": { - "type": "text", - "placeholders": {} - }, - "toggleMuted": "Veksle forstumming", - "@toggleMuted": { - "type": "text", - "placeholders": {} - }, - "toggleFavorite": "Veksle favorittmerking", - "@toggleFavorite": { - "type": "text", - "placeholders": {} - }, - "noConnectionToTheServer": "Ingen tilkobling til tjeneren", - "@noConnectionToTheServer": { - "type": "text", - "placeholders": {} - }, - "pleaseEnterValidEmail": "Skriv inn en gyldig e-postadresse.", - "@pleaseEnterValidEmail": {}, - "addEmail": "Legg til e-post", - "@addEmail": { - "type": "text", - "placeholders": {} - }, - "pleaseChooseAtLeastChars": "Vennligst velg minst {min} tegn.", - "@pleaseChooseAtLeastChars": { - "type": "text", - "placeholders": { - "min": {} - } - }, - "repeatPassword": "Gjenta passord", - "@repeatPassword": {}, - "passwordsDoNotMatch": "Passordet samsvarer ikke!", - "@passwordsDoNotMatch": {}, - "addToSpace": "Legg til space", - "@addToSpace": {}, - "allChats": "Alle samtaler", - "@allChats": { - "type": "text", - "placeholders": {} - }, - "autoplayImages": "Automatisk spill av animerte stickers og emojis", - "@autoplayImages": { - "type": "text", - "placeholder": {} - }, - "badServerLoginTypesException": "Denne hjemme serveren støtter følgende innloggings-typer:\n{serverVersions}\nMen denne applikasjonen støtter kun:\n{supportedVersions}", - "@badServerLoginTypesException": { - "type": "text", - "placeholders": { - "serverVersions": {}, - "supportedVersions": {} - } - }, - "sendOnEnter": "Trykk på enter for å sende", - "@sendOnEnter": {}, - "badServerVersionsException": "Denne hjemme serveren støtter følgene Spec-versjoner:\n{serverVersions}\nMen denne applikasjonen støtter kun {supportedVersions}", - "@badServerVersionsException": { - "type": "text", - "placeholders": { - "serverVersions": {}, - "supportedVersions": {} - } - }, - "blocked": "Blokkert", - "@blocked": { - "type": "text", - "placeholders": {} - }, - "cantOpenUri": "Kan ikke åpne URI {uri}", - "@cantOpenUri": { - "type": "text", - "placeholders": { - "uri": {} - } - }, - "changeYourAvatar": "Bytt profilbilde", - "@changeYourAvatar": { - "type": "text", - "placeholders": {} + "@@last_modified": "2021-08-14 12:41:09.967351", + "about": "Om", + "@about": { + "type": "text", + "placeholders": {} + }, + "accept": "Godta", + "@accept": { + "type": "text", + "placeholders": {} + }, + "acceptedTheInvitation": "{username} godtok invitasjonen", + "@acceptedTheInvitation": { + "type": "text", + "placeholders": { + "username": {} } -} \ No newline at end of file + }, + "account": "Konto", + "@account": { + "type": "text", + "placeholders": {} + }, + "activatedEndToEndEncryption": "{username} skrudde på ende-til-ende -kryptering", + "@activatedEndToEndEncryption": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "addGroupDescription": "Legg til gruppebeskrivelse", + "@addGroupDescription": { + "type": "text", + "placeholders": {} + }, + "admin": "Administrator", + "@admin": { + "type": "text", + "placeholders": {} + }, + "alias": "alias", + "@alias": { + "type": "text", + "placeholders": {} + }, + "all": "Alle", + "@all": { + "type": "text", + "placeholders": {} + }, + "answeredTheCall": "{senderName} besvarte anropet", + "@answeredTheCall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "anyoneCanJoin": "Hvem som helst kan delta", + "@anyoneCanJoin": { + "type": "text", + "placeholders": {} + }, + "appLock": "Programlås", + "@appLock": { + "type": "text", + "placeholders": {} + }, + "archive": "Arkiv", + "@archive": { + "type": "text", + "placeholders": {} + }, + "areGuestsAllowedToJoin": "Skal gjester tillates å ta del", + "@areGuestsAllowedToJoin": { + "type": "text", + "placeholders": {} + }, + "areYouSure": "Er du sikker?", + "@areYouSure": { + "type": "text", + "placeholders": {} + }, + "areYouSureYouWantToLogout": "Er du sikker på at du vil logge ut?", + "@areYouSureYouWantToLogout": { + "type": "text", + "placeholders": {} + }, + "askSSSSSign": "For å kunne signere den andre personen, skriv inn ditt sikre lagerpassord eller gjenopprettingsnøkkel.", + "@askSSSSSign": { + "type": "text", + "placeholders": {} + }, + "askVerificationRequest": "Godta denne bekreftelsesforespørselen fra {username}?", + "@askVerificationRequest": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "banFromChat": "Bannlys fra sludring", + "@banFromChat": { + "type": "text", + "placeholders": {} + }, + "banned": "Bannlyst", + "@banned": { + "type": "text", + "placeholders": {} + }, + "bannedUser": "{username} bannlyste {targetName}", + "@bannedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "blockDevice": "Blokker enhet", + "@blockDevice": { + "type": "text", + "placeholders": {} + }, + "botMessages": "Bot-meldinger", + "@botMessages": { + "type": "text", + "placeholders": {} + }, + "cancel": "Avbryt", + "@cancel": { + "type": "text", + "placeholders": {} + }, + "changeDeviceName": "Endre enhetsnavn", + "@changeDeviceName": { + "type": "text", + "placeholders": {} + }, + "changedTheChatAvatar": "{username} endret sludreavatar", + "@changedTheChatAvatar": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheChatDescriptionTo": "{username} endret sludrebeskrivelse til: «{description}»", + "@changedTheChatDescriptionTo": { + "type": "text", + "placeholders": { + "username": {}, + "description": {} + } + }, + "changedTheChatNameTo": "{username} endret sludringsnavn til: «{chatname}»", + "@changedTheChatNameTo": { + "type": "text", + "placeholders": { + "username": {}, + "chatname": {} + } + }, + "changedTheChatPermissions": "{username} endret sludretilgangene", + "@changedTheChatPermissions": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheDisplaynameTo": "{username} endret visningsnavn til: {displayname}", + "@changedTheDisplaynameTo": { + "type": "text", + "placeholders": { + "username": {}, + "displayname": {} + } + }, + "changedTheGuestAccessRules": "{username} endret gjestetilgangsreglene", + "@changedTheGuestAccessRules": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheGuestAccessRulesTo": "{username} endret gjestetilgangsregler til: {rules}", + "@changedTheGuestAccessRulesTo": { + "type": "text", + "placeholders": { + "username": {}, + "rules": {} + } + }, + "changedTheHistoryVisibility": "{username} endret historikksynlighet", + "@changedTheHistoryVisibility": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheHistoryVisibilityTo": "{username} endret historikksynlighet til: {rules}", + "@changedTheHistoryVisibilityTo": { + "type": "text", + "placeholders": { + "username": {}, + "rules": {} + } + }, + "changedTheJoinRules": "{username} endret tilgangsreglene", + "@changedTheJoinRules": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheJoinRulesTo": "{username} endret tilgangsreglene til: {joinRules}", + "@changedTheJoinRulesTo": { + "type": "text", + "placeholders": { + "username": {}, + "joinRules": {} + } + }, + "changedTheProfileAvatar": "{username} endret avataren sin", + "@changedTheProfileAvatar": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheRoomAliases": "{username} endret rom-aliasene", + "@changedTheRoomAliases": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheRoomInvitationLink": "{username} endret invitasjonslenken", + "@changedTheRoomInvitationLink": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changePassword": "Endre passord", + "@changePassword": { + "type": "text", + "placeholders": {} + }, + "changeTheHomeserver": "Endre hjemmetjener", + "@changeTheHomeserver": { + "type": "text", + "placeholders": {} + }, + "changeTheme": "Endre din stil", + "@changeTheme": { + "type": "text", + "placeholders": {} + }, + "changeTheNameOfTheGroup": "Endre gruppens navn", + "@changeTheNameOfTheGroup": { + "type": "text", + "placeholders": {} + }, + "changeWallpaper": "Endre bakgrunnsbilde", + "@changeWallpaper": { + "type": "text", + "placeholders": {} + }, + "channelCorruptedDecryptError": "Krypteringen er skadet", + "@channelCorruptedDecryptError": { + "type": "text", + "placeholders": {} + }, + "chat": "Sludring", + "@chat": { + "type": "text", + "placeholders": {} + }, + "chatBackup": "Sludringssikkerhetskopi", + "@chatBackup": { + "type": "text", + "placeholders": {} + }, + "chatBackupDescription": "Din sludringssikkerhetskopi er sikret med en sikkerhetsnøkkel. Ikke mist den.", + "@chatBackupDescription": { + "type": "text", + "placeholders": {} + }, + "chatDetails": "Sludringsdetaljer", + "@chatDetails": { + "type": "text", + "placeholders": {} + }, + "chooseAStrongPassword": "Velg et sterkt passord", + "@chooseAStrongPassword": { + "type": "text", + "placeholders": {} + }, + "chooseAUsername": "Velg et brukernavn", + "@chooseAUsername": { + "type": "text", + "placeholders": {} + }, + "close": "Lukk", + "@close": { + "type": "text", + "placeholders": {} + }, + "compareEmojiMatch": "Sammenlign og forsikre at følgende smilefjes samsvarer med de på den andre enheten:", + "@compareEmojiMatch": { + "type": "text", + "placeholders": {} + }, + "compareNumbersMatch": "Sammenlign og forsikre at følgende tall samsvarer med de på den andre enheten:", + "@compareNumbersMatch": { + "type": "text", + "placeholders": {} + }, + "configureChat": "Sett opp sludring", + "@configureChat": { + "type": "text", + "placeholders": {} + }, + "confirm": "Bekreft", + "@confirm": { + "type": "text", + "placeholders": {} + }, + "connect": "Koble til", + "@connect": { + "type": "text", + "placeholders": {} + }, + "contactHasBeenInvitedToTheGroup": "Kontakt invitert til gruppen", + "@contactHasBeenInvitedToTheGroup": { + "type": "text", + "placeholders": {} + }, + "containsDisplayName": "Inneholder visningsnavn", + "@containsDisplayName": { + "type": "text", + "placeholders": {} + }, + "containsUserName": "Inneholder brukernavn", + "@containsUserName": { + "type": "text", + "placeholders": {} + }, + "contentHasBeenReported": "Innholdet har blitt rapportert til tjeneradministratorene", + "@contentHasBeenReported": { + "type": "text", + "placeholders": {} + }, + "copiedToClipboard": "Kopiert til utklippstavle", + "@copiedToClipboard": { + "type": "text", + "placeholders": {} + }, + "copy": "Kopier", + "@copy": { + "type": "text", + "placeholders": {} + }, + "copyToClipboard": "Kopier til utklippstavle", + "@copyToClipboard": { + "type": "text", + "placeholders": {} + }, + "couldNotDecryptMessage": "Kunne ikke dekryptere melding: {error}", + "@couldNotDecryptMessage": { + "type": "text", + "placeholders": { + "error": {} + } + }, + "countParticipants": "{count} deltagere", + "@countParticipants": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "create": "Opprett", + "@create": { + "type": "text", + "placeholders": {} + }, + "createdTheChat": "{username} opprettet sludringen", + "@createdTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "createNewGroup": "Opprett ny gruppe", + "@createNewGroup": { + "type": "text", + "placeholders": {} + }, + "currentlyActive": "Aktiv nå", + "@currentlyActive": { + "type": "text", + "placeholders": {} + }, + "darkTheme": "Mørk", + "@darkTheme": { + "type": "text", + "placeholders": {} + }, + "dateAndTimeOfDay": "{timeOfDay}, {date}", + "@dateAndTimeOfDay": { + "type": "text", + "placeholders": { + "date": {}, + "timeOfDay": {} + } + }, + "dateWithoutYear": "{day} {month}", + "@dateWithoutYear": { + "type": "text", + "placeholders": { + "month": {}, + "day": {} + } + }, + "dateWithYear": "{day} {month} {year}", + "@dateWithYear": { + "type": "text", + "placeholders": { + "year": {}, + "month": {}, + "day": {} + } + }, + "deactivateAccountWarning": "Dette vil skru av din brukerkonto for godt, og kan ikke angres! Er du sikker?", + "@deactivateAccountWarning": { + "type": "text", + "placeholders": {} + }, + "defaultPermissionLevel": "Forvalgt tilgangsnivå", + "@defaultPermissionLevel": { + "type": "text", + "placeholders": {} + }, + "delete": "Slett", + "@delete": { + "type": "text", + "placeholders": {} + }, + "deleteAccount": "Slett konto", + "@deleteAccount": { + "type": "text", + "placeholders": {} + }, + "deleteMessage": "Slett melding", + "@deleteMessage": { + "type": "text", + "placeholders": {} + }, + "deny": "Nekt", + "@deny": { + "type": "text", + "placeholders": {} + }, + "device": "Enhet", + "@device": { + "type": "text", + "placeholders": {} + }, + "deviceId": "Enhets-ID", + "@deviceId": { + "type": "text", + "placeholders": {} + }, + "devices": "Enheter", + "@devices": { + "type": "text", + "placeholders": {} + }, + "directChats": "Direktesludringer", + "@directChats": { + "type": "text", + "placeholders": {} + }, + "displaynameHasBeenChanged": "Visningsnavn endret", + "@displaynameHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "downloadFile": "Last ned fil", + "@downloadFile": { + "type": "text", + "placeholders": {} + }, + "edit": "Rediger", + "@edit": { + "type": "text", + "placeholders": {} + }, + "editBlockedServers": "Rediger blokkerte tjenere", + "@editBlockedServers": { + "type": "text", + "placeholders": {} + }, + "editChatPermissions": "Rediger sludringstilganger", + "@editChatPermissions": { + "type": "text", + "placeholders": {} + }, + "editDisplayname": "Rediger visningsnavn", + "@editDisplayname": { + "type": "text", + "placeholders": {} + }, + "editRoomAvatar": "Rediger romavatar", + "@editRoomAvatar": { + "type": "text", + "placeholders": {} + }, + "emoteExists": "Smilefjeset finnes allerede!", + "@emoteExists": { + "type": "text", + "placeholders": {} + }, + "emoteInvalid": "Ugyldig smilefjes-kode!", + "@emoteInvalid": { + "type": "text", + "placeholders": {} + }, + "emotePacks": "Smilefjespakker for rommet", + "@emotePacks": { + "type": "text", + "placeholders": {} + }, + "emoteSettings": "Smilefjes-innstillinger", + "@emoteSettings": { + "type": "text", + "placeholders": {} + }, + "emoteShortcode": "Smilefjes-kode", + "@emoteShortcode": { + "type": "text", + "placeholders": {} + }, + "emoteWarnNeedToPick": "Du må velge en smilefjes-kode og et bilde!", + "@emoteWarnNeedToPick": { + "type": "text", + "placeholders": {} + }, + "emptyChat": "Tom sludring", + "@emptyChat": { + "type": "text", + "placeholders": {} + }, + "enableEmotesGlobally": "Skru på smilefjespakke for hele programmet", + "@enableEmotesGlobally": { + "type": "text", + "placeholders": {} + }, + "enableEncryption": "Skru på kryptering", + "@enableEncryption": { + "type": "text", + "placeholders": {} + }, + "enableEncryptionWarning": "Du vil ikke kunne skru av kryptering lenger. Er du sikker?", + "@enableEncryptionWarning": { + "type": "text", + "placeholders": {} + }, + "encrypted": "Kryptert", + "@encrypted": { + "type": "text", + "placeholders": {} + }, + "encryption": "Kryptering", + "@encryption": { + "type": "text", + "placeholders": {} + }, + "encryptionNotEnabled": "Kryptering er ikke påskrudd", + "@encryptionNotEnabled": { + "type": "text", + "placeholders": {} + }, + "endedTheCall": "{senderName} avsluttet samtalen", + "@endedTheCall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "enterAGroupName": "Skriv inn et gruppenavn", + "@enterAGroupName": { + "type": "text", + "placeholders": {} + }, + "enterAnEmailAddress": "Skriv inn en e-postadresse", + "@enterAnEmailAddress": { + "type": "text", + "placeholders": {} + }, + "enterYourHomeserver": "Skriv inn din hjemmetjener", + "@enterYourHomeserver": { + "type": "text", + "placeholders": {} + }, + "everythingReady": "Alt er klart!", + "@everythingReady": { + "type": "text", + "placeholders": {} + }, + "extremeOffensive": "Veldig", + "@extremeOffensive": { + "type": "text", + "placeholders": {} + }, + "fileName": "Filnavn", + "@fileName": { + "type": "text", + "placeholders": {} + }, + "fluffychat": "FluffyChat", + "@fluffychat": { + "type": "text", + "placeholders": {} + }, + "fontSize": "Skriftstørrelse", + "@fontSize": { + "type": "text", + "placeholders": {} + }, + "forward": "Videre", + "@forward": { + "type": "text", + "placeholders": {} + }, + "fromJoining": "Fra å ta del", + "@fromJoining": { + "type": "text", + "placeholders": {} + }, + "fromTheInvitation": "Fra invitasjonen", + "@fromTheInvitation": { + "type": "text", + "placeholders": {} + }, + "group": "Gruppe", + "@group": { + "type": "text", + "placeholders": {} + }, + "groupDescription": "Gruppebeskrivelse", + "@groupDescription": { + "type": "text", + "placeholders": {} + }, + "groupDescriptionHasBeenChanged": "Gruppebeskrivelse endret", + "@groupDescriptionHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "groupIsPublic": "Gruppen er offentlig", + "@groupIsPublic": { + "type": "text", + "placeholders": {} + }, + "groups": "Grupper", + "@groups": { + "type": "text", + "placeholders": {} + }, + "groupWith": "Gruppe med {displayname}", + "@groupWith": { + "type": "text", + "placeholders": { + "displayname": {} + } + }, + "guestsAreForbidden": "Gjester forbudt", + "@guestsAreForbidden": { + "type": "text", + "placeholders": {} + }, + "guestsCanJoin": "Gjester kan ta del", + "@guestsCanJoin": { + "type": "text", + "placeholders": {} + }, + "hasWithdrawnTheInvitationFor": "{username} har trukket tilbake invitasjonen til {targetName}", + "@hasWithdrawnTheInvitationFor": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "help": "Hjelp", + "@help": { + "type": "text", + "placeholders": {} + }, + "hideRedactedEvents": "Skjul tilbaketrukne hendelser", + "@hideRedactedEvents": { + "type": "text", + "placeholders": {} + }, + "hideUnknownEvents": "Skjul ukjente hendelser", + "@hideUnknownEvents": { + "type": "text", + "placeholders": {} + }, + "howOffensiveIsThisContent": "Hvor støtende er innholdet?", + "@howOffensiveIsThisContent": { + "type": "text", + "placeholders": {} + }, + "id": "ID", + "@id": { + "type": "text", + "placeholders": {} + }, + "identity": "Identitet", + "@identity": { + "type": "text", + "placeholders": {} + }, + "ignore": "Ignorer", + "@ignore": { + "type": "text", + "placeholders": {} + }, + "ignoredUsers": "Ignorerte brukere", + "@ignoredUsers": { + "type": "text", + "placeholders": {} + }, + "ignoreListDescription": "Du kan ignorere brukere som forstyrrer deg. Du vil ikke lenger kunne motta meldinger eller rominvitasjoner fra brukere på din personlige ignoreringsliste.", + "@ignoreListDescription": { + "type": "text", + "placeholders": {} + }, + "ignoreUsername": "Ignorer brukernavn", + "@ignoreUsername": { + "type": "text", + "placeholders": {} + }, + "iHaveClickedOnLink": "Jeg har klikket på lenken", + "@iHaveClickedOnLink": { + "type": "text", + "placeholders": {} + }, + "incorrectPassphraseOrKey": "Feilaktig passord eller gjenopprettingsnøkkel", + "@incorrectPassphraseOrKey": { + "type": "text", + "placeholders": {} + }, + "inoffensive": "Harmløst", + "@inoffensive": { + "type": "text", + "placeholders": {} + }, + "inviteContact": "Inviter kontakt", + "@inviteContact": { + "type": "text", + "placeholders": {} + }, + "inviteContactToGroup": "Inviter kontakt til {groupName}", + "@inviteContactToGroup": { + "type": "text", + "placeholders": { + "groupName": {} + } + }, + "invited": "Invitert", + "@invited": { + "type": "text", + "placeholders": {} + }, + "invitedUser": "{username} inviterte {targetName}", + "@invitedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "invitedUsersOnly": "Kun inviterte brukere", + "@invitedUsersOnly": { + "type": "text", + "placeholders": {} + }, + "inviteForMe": "Invitasjon for meg", + "@inviteForMe": { + "type": "text", + "placeholders": {} + }, + "inviteText": "{username} har invitert deg til FluffyChat. \n1. Installer FluffyChat: https://fluffychat.im \n2. Registrer deg eller logg inn \n3. Åpne invitasjonslenken: {link}", + "@inviteText": { + "type": "text", + "placeholders": { + "username": {}, + "link": {} + } + }, + "isTyping": "skriver…", + "@isTyping": { + "type": "text", + "placeholders": {} + }, + "joinedTheChat": "{username}ble med i samtalen", + "@joinedTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "joinRoom": "Ta del i rom", + "@joinRoom": { + "type": "text", + "placeholders": {} + }, + "kicked": "{username} kastet ut {targetName}", + "@kicked": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "kickedAndBanned": "{username} kastet ut og bannlyste {targetName}", + "@kickedAndBanned": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "kickFromChat": "Kast ut av sludringen", + "@kickFromChat": { + "type": "text", + "placeholders": {} + }, + "lastActiveAgo": "Sist aktiv: {localizedTimeShort}", + "@lastActiveAgo": { + "type": "text", + "placeholders": { + "localizedTimeShort": {} + } + }, + "lastSeenLongTimeAgo": "Sett for lenge siden", + "@lastSeenLongTimeAgo": { + "type": "text", + "placeholders": {} + }, + "leave": "Forlat", + "@leave": { + "type": "text", + "placeholders": {} + }, + "leftTheChat": "Forlat sludringen", + "@leftTheChat": { + "type": "text", + "placeholders": {} + }, + "license": "Lisens", + "@license": { + "type": "text", + "placeholders": {} + }, + "lightTheme": "Lys", + "@lightTheme": { + "type": "text", + "placeholders": {} + }, + "loadCountMoreParticipants": "Last inn {count} deltagere til", + "@loadCountMoreParticipants": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "loadingPleaseWait": "Laster inn… Vent.", + "@loadingPleaseWait": { + "type": "text", + "placeholders": {} + }, + "loadMore": "Last inn mer…", + "@loadMore": { + "type": "text", + "placeholders": {} + }, + "login": "Logg inn", + "@login": { + "type": "text", + "placeholders": {} + }, + "logInTo": "Logg inn på {homeserver}", + "@logInTo": { + "type": "text", + "placeholders": { + "homeserver": {} + } + }, + "logout": "Logg ut", + "@logout": { + "type": "text", + "placeholders": {} + }, + "makeSureTheIdentifierIsValid": "Forsikre deg om at identifikatoren er gyldig", + "@makeSureTheIdentifierIsValid": { + "type": "text", + "placeholders": {} + }, + "memberChanges": "Medlemsendringer", + "@memberChanges": { + "type": "text", + "placeholders": {} + }, + "mention": "Nevn", + "@mention": { + "type": "text", + "placeholders": {} + }, + "messages": "Meldinger", + "@messages": { + "type": "text", + "placeholders": {} + }, + "messageWillBeRemovedWarning": "Meldingen vil bli fjernet for alle deltagere", + "@messageWillBeRemovedWarning": { + "type": "text", + "placeholders": {} + }, + "moderator": "Moderator", + "@moderator": { + "type": "text", + "placeholders": {} + }, + "muteChat": "Forstum sludring", + "@muteChat": { + "type": "text", + "placeholders": {} + }, + "needPantalaimonWarning": "Merk at du trenger Pantalaimon for å bruke ende-til-ende -kryptering inntil videre.", + "@needPantalaimonWarning": { + "type": "text", + "placeholders": {} + }, + "newChat": "Ny sludring", + "@newChat": { + "type": "text", + "placeholders": {} + }, + "newMessageInFluffyChat": "Ny melding i FluffyChat", + "@newMessageInFluffyChat": { + "type": "text", + "placeholders": {} + }, + "newVerificationRequest": "Ny bekreftelsesforespørsel!", + "@newVerificationRequest": { + "type": "text", + "placeholders": {} + }, + "next": "Neste", + "@next": { + "type": "text", + "placeholders": {} + }, + "no": "Nei", + "@no": { + "type": "text", + "placeholders": {} + }, + "noEmotesFound": "Fant ingen smilefjes. 😕", + "@noEmotesFound": { + "type": "text", + "placeholders": {} + }, + "noGoogleServicesWarning": "Bruk https://microg.org/ for å få Google-tjenester (uten at det går ut over personvernet) for å få push-merknader i FluffyChat:", + "@noGoogleServicesWarning": { + "type": "text", + "placeholders": {} + }, + "none": "Ingen", + "@none": { + "type": "text", + "placeholders": {} + }, + "noPasswordRecoveryDescription": "Du har ikke lagt til en måte å gjenopprette passordet ditt på.", + "@noPasswordRecoveryDescription": { + "type": "text", + "placeholders": {} + }, + "noPermission": "Ingen tilgang", + "@noPermission": { + "type": "text", + "placeholders": {} + }, + "noRoomsFound": "Fant ingen rom …", + "@noRoomsFound": { + "type": "text", + "placeholders": {} + }, + "notifications": "Merknader", + "@notifications": { + "type": "text", + "placeholders": {} + }, + "notificationsEnabledForThisAccount": "Merknader påslått for denne kontoen", + "@notificationsEnabledForThisAccount": { + "type": "text", + "placeholders": {} + }, + "numUsersTyping": "{count} brukere skriver …", + "@numUsersTyping": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "offensive": "Støtende", + "@offensive": { + "type": "text", + "placeholders": {} + }, + "offline": "Frakoblet", + "@offline": { + "type": "text", + "placeholders": {} + }, + "ok": "OK", + "@ok": { + "type": "text", + "placeholders": {} + }, + "online": "Pålogget", + "@online": { + "type": "text", + "placeholders": {} + }, + "onlineKeyBackupEnabled": "Nettbasert sikkerhetskopiering av nøkler på", + "@onlineKeyBackupEnabled": { + "type": "text", + "placeholders": {} + }, + "oopsSomethingWentWrong": "Oida, noe gikk galt …", + "@oopsSomethingWentWrong": { + "type": "text", + "placeholders": {} + }, + "openAppToReadMessages": "Åpne programmet for å lese meldinger", + "@openAppToReadMessages": { + "type": "text", + "placeholders": {} + }, + "openCamera": "Åpne kamera", + "@openCamera": { + "type": "text", + "placeholders": {} + }, + "optionalGroupName": "Gruppenavn (valgfritt)", + "@optionalGroupName": { + "type": "text", + "placeholders": {} + }, + "participant": "Deltager", + "@participant": { + "type": "text", + "placeholders": {} + }, + "passphraseOrKey": "Passord eller gjenopprettingsnøkkel", + "@passphraseOrKey": { + "type": "text", + "placeholders": {} + }, + "password": "Passord", + "@password": { + "type": "text", + "placeholders": {} + }, + "passwordForgotten": "Passord glemt", + "@passwordForgotten": { + "type": "text", + "placeholders": {} + }, + "passwordHasBeenChanged": "Passord endret", + "@passwordHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "passwordRecovery": "Passordgjenoppretting", + "@passwordRecovery": { + "type": "text", + "placeholders": {} + }, + "pickImage": "Velg bilde", + "@pickImage": { + "type": "text", + "placeholders": {} + }, + "pin": "Fest", + "@pin": { + "type": "text", + "placeholders": {} + }, + "play": "Spill av {fileName}", + "@play": { + "type": "text", + "placeholders": { + "fileName": {} + } + }, + "pleaseChooseAUsername": "Velg et brukernavn", + "@pleaseChooseAUsername": { + "type": "text", + "placeholders": {} + }, + "pleaseClickOnLink": "Klikk på lenken i e-posten og fortsett.", + "@pleaseClickOnLink": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterAMatrixIdentifier": "Skriv inn en Matrix-ID.", + "@pleaseEnterAMatrixIdentifier": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourPassword": "Skriv inn passordet ditt", + "@pleaseEnterYourPassword": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourUsername": "Skriv inn brukernavnet ditt", + "@pleaseEnterYourUsername": { + "type": "text", + "placeholders": {} + }, + "pleaseFollowInstructionsOnWeb": "Følg instruksen på nettsiden og trykk på «Neste».", + "@pleaseFollowInstructionsOnWeb": { + "type": "text", + "placeholders": {} + }, + "privacy": "Personvern", + "@privacy": { + "type": "text", + "placeholders": {} + }, + "publicRooms": "Offentlige rom", + "@publicRooms": { + "type": "text", + "placeholders": {} + }, + "pushRules": "Dyttingsregler", + "@pushRules": { + "type": "text", + "placeholders": {} + }, + "reason": "Grunn", + "@reason": { + "type": "text", + "placeholders": {} + }, + "recording": "Opptak", + "@recording": { + "type": "text", + "placeholders": {} + }, + "redactedAnEvent": "{username} har trukket tilbake en hendelse", + "@redactedAnEvent": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "reject": "Avslå", + "@reject": { + "type": "text", + "placeholders": {} + }, + "rejectedTheInvitation": "{username} avslo invitasjonen", + "@rejectedTheInvitation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "rejoin": "Ta del igjen", + "@rejoin": { + "type": "text", + "placeholders": {} + }, + "remove": "Fjern", + "@remove": { + "type": "text", + "placeholders": {} + }, + "removeAllOtherDevices": "Fjern alle andre enheter", + "@removeAllOtherDevices": { + "type": "text", + "placeholders": {} + }, + "removedBy": "Fjernet av {username}", + "@removedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "removeDevice": "Fjern enhet", + "@removeDevice": { + "type": "text", + "placeholders": {} + }, + "unbanFromChat": "Opphev bannlysning", + "@unbanFromChat": { + "type": "text", + "placeholders": {} + }, + "renderRichContent": "Tegn rikt meldingsinnhold", + "@renderRichContent": { + "type": "text", + "placeholders": {} + }, + "replaceRoomWithNewerVersion": "Erstatt rom med nyere versjon", + "@replaceRoomWithNewerVersion": { + "type": "text", + "placeholders": {} + }, + "reply": "Svar", + "@reply": { + "type": "text", + "placeholders": {} + }, + "reportMessage": "Rapporter melding", + "@reportMessage": { + "type": "text", + "placeholders": {} + }, + "requestPermission": "Forespør tilgang", + "@requestPermission": { + "type": "text", + "placeholders": {} + }, + "roomHasBeenUpgraded": "Rommet har blitt oppgradert", + "@roomHasBeenUpgraded": { + "type": "text", + "placeholders": {} + }, + "search": "Søk", + "@search": { + "type": "text", + "placeholders": {} + }, + "security": "Sikkerhet", + "@security": { + "type": "text", + "placeholders": {} + }, + "seenByUser": "Sett av {username}", + "@seenByUser": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "seenByUserAndCountOthers": "{count, plural, other{Sett av {username} og {count} andre}}", + "@seenByUserAndCountOthers": { + "type": "text", + "placeholders": { + "username": {}, + "count": {} + } + }, + "seenByUserAndUser": "Sett av {username} og {username2}", + "@seenByUserAndUser": { + "type": "text", + "placeholders": { + "username": {}, + "username2": {} + } + }, + "send": "Send", + "@send": { + "type": "text", + "placeholders": {} + }, + "sendAMessage": "Send en melding", + "@sendAMessage": { + "type": "text", + "placeholders": {} + }, + "sendAudio": "Send lyd", + "@sendAudio": { + "type": "text", + "placeholders": {} + }, + "sendFile": "Send fil", + "@sendFile": { + "type": "text", + "placeholders": {} + }, + "sendImage": "Send bilde", + "@sendImage": { + "type": "text", + "placeholders": {} + }, + "sendMessages": "Send meldinger", + "@sendMessages": { + "type": "text", + "placeholders": {} + }, + "sendOriginal": "Send original", + "@sendOriginal": { + "type": "text", + "placeholders": {} + }, + "sendVideo": "Send video", + "@sendVideo": { + "type": "text", + "placeholders": {} + }, + "sentAFile": "{username} sendte en fil", + "@sentAFile": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sentAnAudio": "{username} sendte lyd", + "@sentAnAudio": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sentAPicture": "{username} sendte et bilde", + "@sentAPicture": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sentASticker": "{username} sendte et klistremerke", + "@sentASticker": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sentAVideo": "{username} sendte en video", + "@sentAVideo": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sentCallInformations": "{senderName} sendte anropsinfo", + "@sentCallInformations": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "setCustomEmotes": "Sett tilpassede smilefjes", + "@setCustomEmotes": { + "type": "text", + "placeholders": {} + }, + "setGroupDescription": "Sett gruppebeskrivelse", + "@setGroupDescription": { + "type": "text", + "placeholders": {} + }, + "setInvitationLink": "Sett invitasjonslenke", + "@setInvitationLink": { + "type": "text", + "placeholders": {} + }, + "setPermissionsLevel": "Sett tilgangsnivå", + "@setPermissionsLevel": { + "type": "text", + "placeholders": {} + }, + "setStatus": "Angi status", + "@setStatus": { + "type": "text", + "placeholders": {} + }, + "settings": "Innstilinger", + "@settings": { + "type": "text", + "placeholders": {} + }, + "share": "Del", + "@share": { + "type": "text", + "placeholders": {} + }, + "sharedTheLocation": "{username} delte posisjonen", + "@sharedTheLocation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "signUp": "Registrer deg", + "@signUp": { + "type": "text", + "placeholders": {} + }, + "skip": "Hopp over", + "@skip": { + "type": "text", + "placeholders": {} + }, + "sourceCode": "Kildekode", + "@sourceCode": { + "type": "text", + "placeholders": {} + }, + "startedACall": "{senderName} startet en samtale", + "@startedACall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "status": "Status", + "@status": { + "type": "text", + "placeholders": {} + }, + "statusExampleMessage": "Hvordan har du det i dag?", + "@statusExampleMessage": { + "type": "text", + "placeholders": {} + }, + "submit": "Send inn", + "@submit": { + "type": "text", + "placeholders": {} + }, + "systemTheme": "System", + "@systemTheme": { + "type": "text", + "placeholders": {} + }, + "theyDontMatch": "Samsvarer ikke", + "@theyDontMatch": { + "type": "text", + "placeholders": {} + }, + "theyMatch": "Samsvarer", + "@theyMatch": { + "type": "text", + "placeholders": {} + }, + "title": "FluffyChat", + "@title": { + "description": "Title for the application", + "type": "text", + "placeholders": {} + }, + "tooManyRequestsWarning": "For mange forespørsler. Prøv igjen senere!", + "@tooManyRequestsWarning": { + "type": "text", + "placeholders": {} + }, + "transferFromAnotherDevice": "Overfør fra en annen enhet", + "@transferFromAnotherDevice": { + "type": "text", + "placeholders": {} + }, + "tryToSendAgain": "Prøv å sende igjen", + "@tryToSendAgain": { + "type": "text", + "placeholders": {} + }, + "unavailable": "Utilgjengelig", + "@unavailable": { + "type": "text", + "placeholders": {} + }, + "unbannedUser": "{username} opphevet bannlysning av {targetName}", + "@unbannedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "unblockDevice": "Opphev blokkering av enhet", + "@unblockDevice": { + "type": "text", + "placeholders": {} + }, + "unknownDevice": "Ukjent enhet", + "@unknownDevice": { + "type": "text", + "placeholders": {} + }, + "unknownEncryptionAlgorithm": "Ukjent krypteringsalgoritme", + "@unknownEncryptionAlgorithm": { + "type": "text", + "placeholders": {} + }, + "unknownEvent": "Ukjent hendelse «{type}»", + "@unknownEvent": { + "type": "text", + "placeholders": { + "type": {} + } + }, + "unmuteChat": "Opphev forstumming av sludring", + "@unmuteChat": { + "type": "text", + "placeholders": {} + }, + "unpin": "Løsne", + "@unpin": { + "type": "text", + "placeholders": {} + }, + "unreadChats": "{unreadCount, plural, other{{unreadCount} uleste sludringer}}", + "@unreadChats": { + "type": "text", + "placeholders": { + "unreadCount": {} + } + }, + "userAndOthersAreTyping": "{username} og {count} andre skriver…", + "@userAndOthersAreTyping": { + "type": "text", + "placeholders": { + "username": {}, + "count": {} + } + }, + "userAndUserAreTyping": "{username} og {username2} skriver…", + "@userAndUserAreTyping": { + "type": "text", + "placeholders": { + "username": {}, + "username2": {} + } + }, + "userIsTyping": "{username} skriver…", + "@userIsTyping": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "userLeftTheChat": "{username} har forlatt sludringen", + "@userLeftTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "username": "Brukernavn", + "@username": { + "type": "text", + "placeholders": {} + }, + "userSentUnknownEvent": "{username} sendte en {type}-hendelse", + "@userSentUnknownEvent": { + "type": "text", + "placeholders": { + "username": {}, + "type": {} + } + }, + "verify": "Bekreft", + "@verify": { + "type": "text", + "placeholders": {} + }, + "verifyStart": "Start bekreftelse", + "@verifyStart": { + "type": "text", + "placeholders": {} + }, + "verifySuccess": "Du har bekreftet!", + "@verifySuccess": { + "type": "text", + "placeholders": {} + }, + "verifyTitle": "Bekrefter annen konto", + "@verifyTitle": { + "type": "text", + "placeholders": {} + }, + "videoCall": "Videosamtale", + "@videoCall": { + "type": "text", + "placeholders": {} + }, + "visibilityOfTheChatHistory": "Sludrehistorikkens synlighet", + "@visibilityOfTheChatHistory": { + "type": "text", + "placeholders": {} + }, + "visibleForAllParticipants": "Synlig for alle deltagere", + "@visibleForAllParticipants": { + "type": "text", + "placeholders": {} + }, + "visibleForEveryone": "Synlig for alle", + "@visibleForEveryone": { + "type": "text", + "placeholders": {} + }, + "voiceMessage": "Lydmelding", + "@voiceMessage": { + "type": "text", + "placeholders": {} + }, + "waitingPartnerNumbers": "Venter på at samtalepartner skal godta tallene …", + "@waitingPartnerNumbers": { + "type": "text", + "placeholders": {} + }, + "wallpaper": "Bakgrunnsbilde", + "@wallpaper": { + "type": "text", + "placeholders": {} + }, + "warning": "Advarsel!", + "@warning": { + "type": "text", + "placeholders": {} + }, + "weSentYouAnEmail": "Du har fått en e-post", + "@weSentYouAnEmail": { + "type": "text", + "placeholders": {} + }, + "whoCanPerformWhichAction": "Hvem kan utføre hvilken handling", + "@whoCanPerformWhichAction": { + "type": "text", + "placeholders": {} + }, + "whoIsAllowedToJoinThisGroup": "Hvem tillates å ta del i denne gruppen", + "@whoIsAllowedToJoinThisGroup": { + "type": "text", + "placeholders": {} + }, + "whyDoYouWantToReportThis": "Hvorfor ønsker du å rapportere dette?", + "@whyDoYouWantToReportThis": { + "type": "text", + "placeholders": {} + }, + "withTheseAddressesRecoveryDescription": "Med disse adressene kan du gjenopprette passordet ditt hvis du trenger det.", + "@withTheseAddressesRecoveryDescription": { + "type": "text", + "placeholders": {} + }, + "writeAMessage": "Skriv en melding …", + "@writeAMessage": { + "type": "text", + "placeholders": {} + }, + "yes": "Ja", + "@yes": { + "type": "text", + "placeholders": {} + }, + "you": "Deg", + "@you": { + "type": "text", + "placeholders": {} + }, + "youAreInvitedToThisChat": "Du er invitert til denne sludringen", + "@youAreInvitedToThisChat": { + "type": "text", + "placeholders": {} + }, + "youAreNoLongerParticipatingInThisChat": "Du deltar ikke lenger i denne sludringen", + "@youAreNoLongerParticipatingInThisChat": { + "type": "text", + "placeholders": {} + }, + "youCannotInviteYourself": "Du kan ikke invitere deg selv", + "@youCannotInviteYourself": { + "type": "text", + "placeholders": {} + }, + "youHaveBeenBannedFromThisChat": "Du har blitt bannlyst fra denne sludringen", + "@youHaveBeenBannedFromThisChat": { + "type": "text", + "placeholders": {} + }, + "yourPublicKey": "Din offentlige nøkkel", + "@yourPublicKey": { + "type": "text", + "placeholders": {} + }, + "toggleUnread": "Marker som lest/ulest", + "@toggleUnread": { + "type": "text", + "placeholders": {} + }, + "toggleMuted": "Veksle forstumming", + "@toggleMuted": { + "type": "text", + "placeholders": {} + }, + "toggleFavorite": "Veksle favorittmerking", + "@toggleFavorite": { + "type": "text", + "placeholders": {} + }, + "noConnectionToTheServer": "Ingen tilkobling til tjeneren", + "@noConnectionToTheServer": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterValidEmail": "Skriv inn en gyldig e-postadresse.", + "@pleaseEnterValidEmail": {}, + "addEmail": "Legg til e-post", + "@addEmail": { + "type": "text", + "placeholders": {} + }, + "pleaseChooseAtLeastChars": "Vennligst velg minst {min} tegn.", + "@pleaseChooseAtLeastChars": { + "type": "text", + "placeholders": { + "min": {} + } + }, + "repeatPassword": "Gjenta passord", + "@repeatPassword": {}, + "passwordsDoNotMatch": "Passordet samsvarer ikke!", + "@passwordsDoNotMatch": {}, + "addToSpace": "Legg til space", + "@addToSpace": {}, + "allChats": "Alle samtaler", + "@allChats": { + "type": "text", + "placeholders": {} + }, + "autoplayImages": "Automatisk spill av animerte stickers og emojis", + "@autoplayImages": { + "type": "text", + "placeholder": {} + }, + "badServerLoginTypesException": "Denne hjemme serveren støtter følgende innloggings-typer:\n{serverVersions}\nMen denne applikasjonen støtter kun:\n{supportedVersions}", + "@badServerLoginTypesException": { + "type": "text", + "placeholders": { + "serverVersions": {}, + "supportedVersions": {} + } + }, + "sendOnEnter": "Trykk på enter for å sende", + "@sendOnEnter": {}, + "badServerVersionsException": "Denne hjemme serveren støtter følgene Spec-versjoner:\n{serverVersions}\nMen denne applikasjonen støtter kun {supportedVersions}", + "@badServerVersionsException": { + "type": "text", + "placeholders": { + "serverVersions": {}, + "supportedVersions": {} + } + }, + "blocked": "Blokkert", + "@blocked": { + "type": "text", + "placeholders": {} + }, + "cantOpenUri": "Kan ikke åpne URI {uri}", + "@cantOpenUri": { + "type": "text", + "placeholders": { + "uri": {} + } + }, + "changeYourAvatar": "Bytt profilbilde", + "@changeYourAvatar": { + "type": "text", + "placeholders": {} + }, + "showPassword": "", + "@showPassword": { + "type": "text", + "placeholders": {} + }, + "hugContent": "", + "@hugContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "jumpToLastReadMessage": "", + "@jumpToLastReadMessage": {}, + "allRooms": "", + "@allRooms": { + "type": "text", + "placeholders": {} + }, + "obtainingLocation": "", + "@obtainingLocation": { + "type": "text", + "placeholders": {} + }, + "whoCanSeeMyStories": "", + "@whoCanSeeMyStories": {}, + "commandHint_cuddle": "", + "@commandHint_cuddle": {}, + "chats": "", + "@chats": { + "type": "text", + "placeholders": {} + }, + "widgetVideo": "", + "@widgetVideo": {}, + "dismiss": "", + "@dismiss": {}, + "noEncryptionForPublicRooms": "", + "@noEncryptionForPublicRooms": { + "type": "text", + "placeholders": {} + }, + "reportErrorDescription": "", + "@reportErrorDescription": {}, + "addAccount": "", + "@addAccount": {}, + "chatHasBeenAddedToThisSpace": "", + "@chatHasBeenAddedToThisSpace": {}, + "removeYourAvatar": "", + "@removeYourAvatar": { + "type": "text", + "placeholders": {} + }, + "unsupportedAndroidVersion": "", + "@unsupportedAndroidVersion": {}, + "enterASpacepName": "", + "@enterASpacepName": {}, + "commandHint_html": "", + "@commandHint_html": { + "type": "text", + "description": "Usage hint for the command /html" + }, + "widgetJitsi": "", + "@widgetJitsi": {}, + "messageType": "", + "@messageType": {}, + "noEmailWarning": "", + "@noEmailWarning": {}, + "indexedDbErrorLong": "", + "@indexedDbErrorLong": {}, + "oneClientLoggedOut": "", + "@oneClientLoggedOut": {}, + "startFirstChat": "", + "@startFirstChat": {}, + "callingAccount": "", + "@callingAccount": {}, + "setColorTheme": "", + "@setColorTheme": {}, + "nextAccount": "", + "@nextAccount": {}, + "commandHint_create": "", + "@commandHint_create": { + "type": "text", + "description": "Usage hint for the command /create" + }, + "singlesignon": "", + "@singlesignon": { + "type": "text", + "placeholders": {} + }, + "allSpaces": "", + "@allSpaces": {}, + "supposedMxid": "", + "@supposedMxid": { + "type": "text", + "placeholders": { + "mxid": {} + } + }, + "user": "", + "@user": {}, + "roomVersion": "", + "@roomVersion": { + "type": "text", + "placeholders": {} + }, + "youAcceptedTheInvitation": "", + "@youAcceptedTheInvitation": {}, + "noMatrixServer": "", + "@noMatrixServer": { + "type": "text", + "placeholders": { + "server1": {}, + "server2": {} + } + }, + "youInvitedBy": "", + "@youInvitedBy": { + "placeholders": { + "user": {} + } + }, + "banUserDescription": "", + "@banUserDescription": {}, + "requests": "", + "@requests": {}, + "widgetEtherpad": "", + "@widgetEtherpad": {}, + "stories": "", + "@stories": {}, + "addToStory": "", + "@addToStory": {}, + "removeDevicesDescription": "", + "@removeDevicesDescription": {}, + "separateChatTypes": "", + "@separateChatTypes": { + "type": "text", + "placeholders": {} + }, + "tryAgain": "", + "@tryAgain": {}, + "youKickedAndBanned": "", + "@youKickedAndBanned": { + "placeholders": { + "user": {} + } + }, + "showDirectChatsInSpaces": "", + "@showDirectChatsInSpaces": { + "type": "text", + "placeholders": {} + }, + "unbanUserDescription": "", + "@unbanUserDescription": {}, + "todoLists": "", + "@todoLists": {}, + "saveFile": "", + "@saveFile": { + "type": "text", + "placeholders": {} + }, + "youRejectedTheInvitation": "", + "@youRejectedTheInvitation": {}, + "otherCallingPermissions": "", + "@otherCallingPermissions": {}, + "messagesStyle": "", + "@messagesStyle": {}, + "link": "", + "@link": {}, + "widgetUrlError": "", + "@widgetUrlError": {}, + "emailOrUsername": "", + "@emailOrUsername": {}, + "newSpaceDescription": "", + "@newSpaceDescription": {}, + "chatDescription": "", + "@chatDescription": {}, + "callingAccountDetails": "", + "@callingAccountDetails": {}, + "editRoomAliases": "", + "@editRoomAliases": { + "type": "text", + "placeholders": {} + }, + "enterSpace": "", + "@enterSpace": {}, + "encryptThisChat": "", + "@encryptThisChat": {}, + "previousAccount": "", + "@previousAccount": {}, + "reopenChat": "", + "@reopenChat": {}, + "pleaseEnterRecoveryKey": "", + "@pleaseEnterRecoveryKey": {}, + "widgetNameError": "", + "@widgetNameError": {}, + "addToBundle": "", + "@addToBundle": {}, + "spaceIsPublic": "", + "@spaceIsPublic": { + "type": "text", + "placeholders": {} + }, + "addWidget": "", + "@addWidget": {}, + "countFiles": "", + "@countFiles": { + "placeholders": { + "count": {} + } + }, + "noKeyForThisMessage": "", + "@noKeyForThisMessage": {}, + "shareLocation": "", + "@shareLocation": { + "type": "text", + "placeholders": {} + }, + "commandHint_markasgroup": "", + "@commandHint_markasgroup": {}, + "editTodo": "", + "@editTodo": {}, + "errorObtainingLocation": "", + "@errorObtainingLocation": { + "type": "text", + "placeholders": { + "error": {} + } + }, + "hydrateTor": "", + "@hydrateTor": {}, + "pushNotificationsNotAvailable": "", + "@pushNotificationsNotAvailable": {}, + "storeInAppleKeyChain": "", + "@storeInAppleKeyChain": {}, + "hydrate": "", + "@hydrate": {}, + "invalidServerName": "", + "@invalidServerName": {}, + "chatPermissions": "", + "@chatPermissions": {}, + "wipeChatBackup": "", + "@wipeChatBackup": { + "type": "text", + "placeholders": {} + }, + "sender": "", + "@sender": {}, + "storeInAndroidKeystore": "", + "@storeInAndroidKeystore": {}, + "signInWithPassword": "", + "@signInWithPassword": {}, + "pleaseAddATitle": "", + "@pleaseAddATitle": {}, + "updateNow": "", + "@updateNow": {}, + "makeAdminDescription": "", + "@makeAdminDescription": {}, + "synchronizingPleaseWait": "", + "@synchronizingPleaseWait": { + "type": "text", + "placeholders": {} + }, + "goToTheNewRoom": "", + "@goToTheNewRoom": { + "type": "text", + "placeholders": {} + }, + "commandHint_clearcache": "", + "@commandHint_clearcache": { + "type": "text", + "description": "Usage hint for the command /clearcache" + }, + "saveKeyManuallyDescription": "", + "@saveKeyManuallyDescription": {}, + "editBundlesForAccount": "", + "@editBundlesForAccount": {}, + "whyIsThisMessageEncrypted": "", + "@whyIsThisMessageEncrypted": {}, + "setChatDescription": "", + "@setChatDescription": {}, + "spaceName": "", + "@spaceName": { + "type": "text", + "placeholders": {} + }, + "importFromZipFile": "", + "@importFromZipFile": {}, + "or": "", + "@or": { + "type": "text", + "placeholders": {} + }, + "dehydrateWarning": "", + "@dehydrateWarning": {}, + "noOtherDevicesFound": "", + "@noOtherDevicesFound": {}, + "yourChatBackupHasBeenSetUp": "", + "@yourChatBackupHasBeenSetUp": {}, + "addDescription": "", + "@addDescription": {}, + "redactedBy": "", + "@redactedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "videoCallsBetaWarning": "", + "@videoCallsBetaWarning": {}, + "storyPrivacyWarning": "", + "@storyPrivacyWarning": {}, + "matrixWidgets": "", + "@matrixWidgets": {}, + "signInWith": "", + "@signInWith": { + "type": "text", + "placeholders": { + "provider": {} + } + }, + "updateAvailable": "", + "@updateAvailable": {}, + "fileIsTooBigForServer": "", + "@fileIsTooBigForServer": {}, + "homeserver": "", + "@homeserver": {}, + "noTodosYet": "", + "@noTodosYet": {}, + "people": "", + "@people": { + "type": "text", + "placeholders": {} + }, + "verified": "", + "@verified": { + "type": "text", + "placeholders": {} + }, + "callingPermissions": "", + "@callingPermissions": {}, + "readUpToHere": "", + "@readUpToHere": {}, + "start": "", + "@start": {}, + "bubbleSize": "", + "@bubbleSize": { + "type": "text", + "placeholders": {} + }, + "register": "", + "@register": { + "type": "text", + "placeholders": {} + }, + "unlockOldMessages": "", + "@unlockOldMessages": {}, + "numChats": "", + "@numChats": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "whatIsGoingOn": "", + "@whatIsGoingOn": {}, + "optionalRedactReason": "", + "@optionalRedactReason": {}, + "dehydrate": "", + "@dehydrate": {}, + "locationPermissionDeniedNotice": "", + "@locationPermissionDeniedNotice": { + "type": "text", + "placeholders": {} + }, + "sendAsText": "", + "@sendAsText": { + "type": "text" + }, + "archiveRoomDescription": "", + "@archiveRoomDescription": {}, + "exportEmotePack": "", + "@exportEmotePack": {}, + "sendSticker": "", + "@sendSticker": { + "type": "text", + "placeholders": {} + }, + "switchToAccount": "", + "@switchToAccount": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "commandInvalid": "", + "@commandInvalid": { + "type": "text" + }, + "setAsCanonicalAlias": "", + "@setAsCanonicalAlias": { + "type": "text", + "placeholders": {} + }, + "locationDisabledNotice": "", + "@locationDisabledNotice": { + "type": "text", + "placeholders": {} + }, + "letsStart": "", + "@letsStart": {}, + "commandHint_plain": "", + "@commandHint_plain": { + "type": "text", + "description": "Usage hint for the command /plain" + }, + "experimentalVideoCalls": "", + "@experimentalVideoCalls": {}, + "savedEmotePack": "", + "@savedEmotePack": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "pleaseEnterRecoveryKeyDescription": "", + "@pleaseEnterRecoveryKeyDescription": {}, + "openInMaps": "", + "@openInMaps": { + "type": "text", + "placeholders": {} + }, + "inviteContactToGroupQuestion": "", + "@inviteContactToGroupQuestion": {}, + "redactedByBecause": "", + "@redactedByBecause": { + "type": "text", + "placeholders": { + "username": {}, + "reason": {} + } + }, + "youHaveWithdrawnTheInvitationFor": "", + "@youHaveWithdrawnTheInvitationFor": { + "placeholders": { + "user": {} + } + }, + "appearOnTopDetails": "", + "@appearOnTopDetails": {}, + "enterRoom": "", + "@enterRoom": {}, + "pleaseChooseAPasscode": "", + "@pleaseChooseAPasscode": { + "type": "text", + "placeholders": {} + }, + "reportUser": "", + "@reportUser": {}, + "commandHint_send": "", + "@commandHint_send": { + "type": "text", + "description": "Usage hint for the command /send" + }, + "confirmEventUnpin": "", + "@confirmEventUnpin": {}, + "youInvitedUser": "", + "@youInvitedUser": { + "placeholders": { + "user": {} + } + }, + "fileHasBeenSavedAt": "", + "@fileHasBeenSavedAt": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "importZipFile": "", + "@importZipFile": {}, + "anyoneCanKnock": "", + "@anyoneCanKnock": {}, + "commandMissing": "", + "@commandMissing": { + "type": "text", + "placeholders": { + "command": {} + }, + "description": "State that {command} is not a valid /command." + }, + "redactMessageDescription": "", + "@redactMessageDescription": {}, + "recoveryKey": "", + "@recoveryKey": {}, + "redactMessage": "", + "@redactMessage": { + "type": "text", + "placeholders": {} + }, + "commandHint_discardsession": "", + "@commandHint_discardsession": { + "type": "text", + "description": "Usage hint for the command /discardsession" + }, + "invalidInput": "", + "@invalidInput": {}, + "todosUnencrypted": "", + "@todosUnencrypted": {}, + "dehydrateTorLong": "", + "@dehydrateTorLong": {}, + "commandHint_myroomnick": "", + "@commandHint_myroomnick": { + "type": "text", + "description": "Usage hint for the command /myroomnick" + }, + "replyHasBeenSent": "", + "@replyHasBeenSent": {}, + "doNotShowAgain": "", + "@doNotShowAgain": {}, + "report": "", + "@report": {}, + "yourStory": "", + "@yourStory": {}, + "unverified": "", + "@unverified": {}, + "serverRequiresEmail": "", + "@serverRequiresEmail": {}, + "hideUnimportantStateEvents": "", + "@hideUnimportantStateEvents": {}, + "screenSharingTitle": "", + "@screenSharingTitle": {}, + "widgetCustom": "", + "@widgetCustom": {}, + "addToSpaceDescription": "", + "@addToSpaceDescription": {}, + "googlyEyesContent": "", + "@googlyEyesContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "whoCanSeeMyStoriesDesc": "", + "@whoCanSeeMyStoriesDesc": {}, + "youBannedUser": "", + "@youBannedUser": { + "placeholders": { + "user": {} + } + }, + "unsubscribeStories": "", + "@unsubscribeStories": {}, + "loginWithOneClick": "", + "@loginWithOneClick": {}, + "addChatDescription": "", + "@addChatDescription": {}, + "commandHint_leave": "", + "@commandHint_leave": { + "type": "text", + "description": "Usage hint for the command /leave" + }, + "commandHint_myroomavatar": "", + "@commandHint_myroomavatar": { + "type": "text", + "description": "Usage hint for the command /myroomavatar" + }, + "hasKnocked": "", + "@hasKnocked": { + "placeholders": { + "user": {} + } + }, + "publish": "", + "@publish": {}, + "openLinkInBrowser": "", + "@openLinkInBrowser": {}, + "clearArchive": "", + "@clearArchive": {}, + "commandHint_react": "", + "@commandHint_react": { + "type": "text", + "description": "Usage hint for the command /react" + }, + "commandHint_me": "", + "@commandHint_me": { + "type": "text", + "description": "Usage hint for the command /me" + }, + "messageInfo": "", + "@messageInfo": {}, + "disableEncryptionWarning": "", + "@disableEncryptionWarning": {}, + "directChat": "", + "@directChat": {}, + "noOneCanJoin": "", + "@noOneCanJoin": {}, + "wrongPinEntered": "", + "@wrongPinEntered": { + "type": "text", + "placeholders": { + "seconds": {} + } + }, + "sendTypingNotifications": "", + "@sendTypingNotifications": {}, + "inviteGroupChat": "", + "@inviteGroupChat": {}, + "appearOnTop": "", + "@appearOnTop": {}, + "invitePrivateChat": "", + "@invitePrivateChat": {}, + "foregroundServiceRunning": "", + "@foregroundServiceRunning": {}, + "voiceCall": "", + "@voiceCall": {}, + "commandHint_kick": "", + "@commandHint_kick": { + "type": "text", + "description": "Usage hint for the command /kick" + }, + "createNewSpace": "", + "@createNewSpace": { + "type": "text", + "placeholders": {} + }, + "commandHint_unban": "", + "@commandHint_unban": { + "type": "text", + "description": "Usage hint for the command /unban" + }, + "commandHint_ban": "", + "@commandHint_ban": { + "type": "text", + "description": "Usage hint for the command /ban" + }, + "importEmojis": "", + "@importEmojis": {}, + "wasDirectChatDisplayName": "", + "@wasDirectChatDisplayName": { + "type": "text", + "placeholders": { + "oldDisplayName": {} + } + }, + "noChatDescriptionYet": "", + "@noChatDescriptionYet": {}, + "newTodo": "", + "@newTodo": {}, + "removeFromBundle": "", + "@removeFromBundle": {}, + "confirmMatrixId": "", + "@confirmMatrixId": {}, + "learnMore": "", + "@learnMore": {}, + "notAnImage": "", + "@notAnImage": {}, + "users": "", + "@users": {}, + "openGallery": "", + "@openGallery": {}, + "chatDescriptionHasBeenChanged": "", + "@chatDescriptionHasBeenChanged": {}, + "newGroup": "", + "@newGroup": {}, + "bundleName": "", + "@bundleName": {}, + "dehydrateTor": "", + "@dehydrateTor": {}, + "todoListChangedError": "", + "@todoListChangedError": {}, + "removeFromSpace": "", + "@removeFromSpace": {}, + "enterInviteLinkOrMatrixId": "", + "@enterInviteLinkOrMatrixId": {}, + "commandHint_op": "", + "@commandHint_op": { + "type": "text", + "description": "Usage hint for the command /op" + }, + "commandHint_join": "", + "@commandHint_join": { + "type": "text", + "description": "Usage hint for the command /join" + }, + "roomUpgradeDescription": "", + "@roomUpgradeDescription": {}, + "commandHint_invite": "", + "@commandHint_invite": { + "type": "text", + "description": "Usage hint for the command /invite" + }, + "scanQrCode": "", + "@scanQrCode": {}, + "pleaseEnterANumber": "", + "@pleaseEnterANumber": {}, + "youKicked": "", + "@youKicked": { + "placeholders": { + "user": {} + } + }, + "profileNotFound": "", + "@profileNotFound": {}, + "jump": "", + "@jump": {}, + "reactedWith": "", + "@reactedWith": { + "type": "text", + "placeholders": { + "sender": {}, + "reaction": {} + } + }, + "sorryThatsNotPossible": "", + "@sorryThatsNotPossible": {}, + "storyFrom": "", + "@storyFrom": { + "type": "text", + "placeholders": { + "date": {}, + "body": {} + } + }, + "videoWithSize": "", + "@videoWithSize": { + "type": "text", + "placeholders": { + "size": {} + } + }, + "shareInviteLink": "", + "@shareInviteLink": {}, + "commandHint_markasdm": "", + "@commandHint_markasdm": {}, + "recoveryKeyLost": "", + "@recoveryKeyLost": {}, + "cuddleContent": "", + "@cuddleContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "deviceKeys": "", + "@deviceKeys": {}, + "emoteKeyboardNoRecents": "", + "@emoteKeyboardNoRecents": { + "type": "text", + "placeholders": {} + }, + "endToEndEncryption": "", + "@endToEndEncryption": {}, + "setTheme": "", + "@setTheme": {}, + "youJoinedTheChat": "", + "@youJoinedTheChat": {}, + "openVideoCamera": "", + "@openVideoCamera": { + "type": "text", + "placeholders": {} + }, + "thisUserHasNotPostedAnythingYet": "", + "@thisUserHasNotPostedAnythingYet": {}, + "markAsRead": "", + "@markAsRead": {}, + "widgetName": "", + "@widgetName": {}, + "errorAddingWidget": "", + "@errorAddingWidget": {}, + "commandHint_dm": "", + "@commandHint_dm": { + "type": "text", + "description": "Usage hint for the command /dm" + }, + "commandHint_hug": "", + "@commandHint_hug": {}, + "replace": "", + "@replace": {}, + "oopsPushError": "", + "@oopsPushError": { + "type": "text", + "placeholders": {} + }, + "youUnbannedUser": "", + "@youUnbannedUser": { + "placeholders": { + "user": {} + } + }, + "pleaseEnter4Digits": "", + "@pleaseEnter4Digits": { + "type": "text", + "placeholders": {} + }, + "newSpace": "", + "@newSpace": {}, + "emojis": "", + "@emojis": {}, + "pleaseEnterYourPin": "", + "@pleaseEnterYourPin": { + "type": "text", + "placeholders": {} + }, + "pleaseChoose": "", + "@pleaseChoose": { + "type": "text", + "placeholders": {} + }, + "commandHint_googly": "", + "@commandHint_googly": {}, + "pleaseTryAgainLaterOrChooseDifferentServer": "", + "@pleaseTryAgainLaterOrChooseDifferentServer": {}, + "createGroup": "", + "@createGroup": {}, + "hydrateTorLong": "", + "@hydrateTorLong": {}, + "time": "", + "@time": {}, + "custom": "", + "@custom": {}, + "noBackupWarning": "", + "@noBackupWarning": {}, + "editWidgets": "", + "@editWidgets": {}, + "storeInSecureStorageDescription": "", + "@storeInSecureStorageDescription": {}, + "openChat": "", + "@openChat": {}, + "kickUserDescription": "", + "@kickUserDescription": {}, + "importNow": "", + "@importNow": {}, + "pinMessage": "", + "@pinMessage": {}, + "invite": "", + "@invite": {}, + "enableMultiAccounts": "", + "@enableMultiAccounts": {}, + "continueWith": "", + "@continueWith": {}, + "indexedDbErrorTitle": "", + "@indexedDbErrorTitle": {}, + "unsupportedAndroidVersionLong": "", + "@unsupportedAndroidVersionLong": {}, + "discover": "", + "@discover": { + "type": "text", + "placeholders": {} + }, + "storeSecurlyOnThisDevice": "", + "@storeSecurlyOnThisDevice": {}, + "iUnderstand": "", + "@iUnderstand": {}, + "screenSharingDetail": "", + "@screenSharingDetail": {}, + "waitingPartnerAcceptRequest": "", + "@waitingPartnerAcceptRequest": { + "type": "text", + "placeholders": {} + }, + "waitingPartnerEmoji": "", + "@waitingPartnerEmoji": { + "type": "text", + "placeholders": {} + }, + "placeCall": "", + "@placeCall": {} +} diff --git a/assets/l10n/intl_nl.arb b/assets/l10n/intl_nl.arb index 88d0dcd1f..6c96fcd85 100644 --- a/assets/l10n/intl_nl.arb +++ b/assets/l10n/intl_nl.arb @@ -1167,7 +1167,7 @@ "type": "text", "placeholders": {} }, - "noGoogleServicesWarning": "Het lijkt erop dat je geen Google-services op je telefoon hebt. Dat is een goede beslissing voor je privacy! Om pushmeldingen in FluffyChat te ontvangen raden we je https://microg.org/ of https://unifiedpush.org aan.", + "noGoogleServicesWarning": "Firebase Cloud Messaging lijkt niet beschikbaar op je apparaat. Om nog steeds meldingen te krijgen, adviseren we om ntfy te installeren. Met ntfy of een andere Unified Push provider kun je meldingen ontvangen op een veilige manier. Je kunt ntfy downloaden van de PlayStore of van F-Droid.", "@noGoogleServicesWarning": { "type": "text", "placeholders": {} @@ -2616,5 +2616,45 @@ "placeholders": { "seconds": {} } - } + }, + "banUserDescription": "De persoon zal worden verbannen van de chat en kan niet meer toetreden totdat de verbanning is opgeheven.", + "@banUserDescription": {}, + "removeDevicesDescription": "Je wordt op dit apparaat uitgelogd en zal niet langer in staat zijn om berichten te ontvangen.", + "@removeDevicesDescription": {}, + "unbanUserDescription": "De persoon zal weer in staat zijn om de chat te betreden als ze het proberen.", + "@unbanUserDescription": {}, + "todoLists": "(Beta) Todo's", + "@todoLists": {}, + "editTodo": "Wijzig todo", + "@editTodo": {}, + "pushNotificationsNotAvailable": "Meldingen zijn niet beschikbaar", + "@pushNotificationsNotAvailable": {}, + "pleaseAddATitle": "Voeg een titel toe", + "@pleaseAddATitle": {}, + "makeAdminDescription": "Wanneer je deze persoon beheerder maakt kun je dit niet ongedaan maken als jullie dezelfde rechten hebben.", + "@makeAdminDescription": {}, + "noTodosYet": "Er zijn nog geen todo's toegevoegd aan deze chat. Maak je eerste todo en start met samenwerken met anderen. 📝", + "@noTodosYet": {}, + "archiveRoomDescription": "De chat zal naar het archief worden verplaatst. Andere personen zullen in staat zijn te zien dat je de chat hebt verlaten.", + "@archiveRoomDescription": {}, + "todosUnencrypted": "Let op dat todo's zichtbaar zijn voor iedereen in de chat en niet zijn versleuteld.", + "@todosUnencrypted": {}, + "hasKnocked": "{user} heeft geklopt", + "@hasKnocked": { + "placeholders": { + "user": {} + } + }, + "newTodo": "Nieuwe todo", + "@newTodo": {}, + "learnMore": "Lees meer", + "@learnMore": {}, + "todoListChangedError": "Oeps... De todo's zijn aangepast terwijl je aan het bewerken was.", + "@todoListChangedError": {}, + "roomUpgradeDescription": "De chat zal dan opnieuw gemaakt worden met de nieuwe kamerversie. Alle deelnemers worden geïnformeerd dat ze moeten overstappen naar de nieuwe chat. Je kan meer lezen over kamerversies op https://spec.matrix.org/latest/rooms/", + "@roomUpgradeDescription": {}, + "pleaseEnterANumber": "Vul een getal in groter dan 0", + "@pleaseEnterANumber": {}, + "kickUserDescription": "De persoon is verwijderd uit de chat, maar is niet verbannen. In publieke chats kan de persoon op elk moment opnieuw deelnemen.", + "@kickUserDescription": {} } diff --git a/assets/l10n/intl_pl.arb b/assets/l10n/intl_pl.arb index c66066775..705d8ac47 100644 --- a/assets/l10n/intl_pl.arb +++ b/assets/l10n/intl_pl.arb @@ -844,7 +844,7 @@ "type": "text", "placeholders": {} }, - "inviteText": "{username} zaprosił/-a cię do FluffyChat. \n1. Zainstaluj FluffyChat: https://fluffychat.im \n2. Zarejestuj się lub zaloguj \n3. Otwórz link zaproszenia: {link}", + "inviteText": "{username} zaprosił/-a cię do FluffyChat. \n1. Odwiedź fluffychat.im i zainstaluj aplikację\n2. Zarejestuj się lub zaloguj \n3. Otwórz link zaproszenia:\n{link}", "@inviteText": { "type": "text", "placeholders": { @@ -1490,7 +1490,7 @@ "type": "text", "placeholders": {} }, - "wallpaper": "Tapeta", + "wallpaper": "Tapeta:", "@wallpaper": { "type": "text", "placeholders": {} @@ -1827,7 +1827,7 @@ "type": "text", "placeholders": {} }, - "redactMessage": "Przekaż wiadomość", + "redactMessage": "Utajnij wiadomość", "@redactMessage": { "type": "text", "placeholders": {} @@ -1992,7 +1992,7 @@ "@whoCanSeeMyStoriesDesc": {}, "shareYourInviteLink": "Udostępnij swój link zaproszenia", "@shareYourInviteLink": {}, - "separateChatTypes": "Oddzielenie czatów bezpośrednich i grup", + "separateChatTypes": "Oddzielenie czatów bezpośrednich i grupowych", "@separateChatTypes": { "type": "text", "placeholders": {} @@ -2202,7 +2202,7 @@ "mxid": {} } }, - "commandHint_markasdm": "Oznacz jako pokój wiadomości bezpośrednich", + "commandHint_markasdm": "Oznacz jako pokój wiadomości bezpośrednich dla podanego Matrix ID", "@commandHint_markasdm": {}, "confirmMatrixId": "Potwierdź swój identyfikator Matrix w celu usunięcia konta.", "@confirmMatrixId": {}, @@ -2483,5 +2483,172 @@ "removeFromBundle": "Usuń z tej paczki", "@removeFromBundle": {}, "openLinkInBrowser": "Otwórz link w przeglądarce", - "@openLinkInBrowser": {} + "@openLinkInBrowser": {}, + "allRooms": "Wszystkie czaty grupowe", + "@allRooms": { + "type": "text", + "placeholders": {} + }, + "reportErrorDescription": "O nie. Coś poszło nie tak. Spróbuj ponownie później. Jeśli chcesz, możesz zgłosić błąd programistom.", + "@reportErrorDescription": {}, + "setColorTheme": "Ustal styl kolorów:", + "@setColorTheme": {}, + "requests": "Żądania", + "@requests": {}, + "tryAgain": "Spróbuj ponownie", + "@tryAgain": {}, + "messagesStyle": "Wiadomości:", + "@messagesStyle": {}, + "chatDescription": "Opis czatu", + "@chatDescription": {}, + "invalidServerName": "Nieprawidłowa nazwa serwera", + "@invalidServerName": {}, + "chatPermissions": "Uprawnienia czatu", + "@chatPermissions": {}, + "signInWithPassword": "Zaloguj się z hasłem", + "@signInWithPassword": {}, + "setChatDescription": "Ustaw opis czatu", + "@setChatDescription": {}, + "importFromZipFile": "Zaimportuj z pliku .zip", + "@importFromZipFile": {}, + "discover": "Odkrywanie", + "@discover": { + "type": "text", + "placeholders": {} + }, + "redactedBy": "Utajnione przez {username}", + "@redactedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "signInWith": "Zaloguj się z {provider}", + "@signInWith": { + "type": "text", + "placeholders": { + "provider": {} + } + }, + "optionalRedactReason": "(Opcjonalnie) Powód utajnienia tej wiadomości...", + "@optionalRedactReason": {}, + "exportEmotePack": "Eksportuj pakiet Emotikon jako .zip", + "@exportEmotePack": {}, + "savedEmotePack": "Zapisano pakiet emotikon do {path}!", + "@savedEmotePack": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "inviteContactToGroupQuestion": "Czy chcesz zaprosić {contact} do czatu „{groupName}”?", + "@inviteContactToGroupQuestion": {}, + "redactedByBecause": "Utajnione przez {username} z powodu: \"{reason}\"", + "@redactedByBecause": { + "type": "text", + "placeholders": { + "username": {}, + "reason": {} + } + }, + "importZipFile": "Zaimportuj plik .zip", + "@importZipFile": {}, + "anyoneCanKnock": "Każdy może zapukać", + "@anyoneCanKnock": {}, + "redactMessageDescription": "Wiadomość zostanie utajniona u wszystkich uczestników tej rozmowy. Nie można tego cofnąć.", + "@redactMessageDescription": {}, + "invalidInput": "Nieprawidłowe dane!", + "@invalidInput": {}, + "report": "raport", + "@report": {}, + "addChatDescription": "Dodaj opis tego czatu", + "@addChatDescription": {}, + "directChat": "Rozmowa bezpośrednia", + "@directChat": {}, + "noOneCanJoin": "Nikt nie może dołączyć", + "@noOneCanJoin": {}, + "wrongPinEntered": "Wprowadzono nieprawidłowy kod PIN! Spróbuj ponownie za {seconds} sekund...", + "@wrongPinEntered": { + "type": "text", + "placeholders": { + "seconds": {} + } + }, + "sendTypingNotifications": "Wysyłaj powiadomienie o pisaniu", + "@sendTypingNotifications": {}, + "inviteGroupChat": "📨 Zaproszenie do rozmowy grupowej", + "@inviteGroupChat": {}, + "invitePrivateChat": "📨 Zaproszenie do rozmowy prywatnej", + "@invitePrivateChat": {}, + "importEmojis": "Zaimportuj Emoji", + "@importEmojis": {}, + "noChatDescriptionYet": "Nie utworzono jeszcze opisu czatu.", + "@noChatDescriptionYet": {}, + "notAnImage": "To nie jest plik obrazu.", + "@notAnImage": {}, + "chatDescriptionHasBeenChanged": "Zmieniono opis czatu", + "@chatDescriptionHasBeenChanged": {}, + "profileNotFound": "Nie można odnaleźć użytkownika na serwerze. Być może wystąpił problem z połączeniem lub użytkownik nie istnieje.", + "@profileNotFound": {}, + "shareInviteLink": "Udostępnij link zaproszenia", + "@shareInviteLink": {}, + "emoteKeyboardNoRecents": "Tutaj pojawiają się ostatnio używane emotikony...", + "@emoteKeyboardNoRecents": { + "type": "text", + "placeholders": {} + }, + "setTheme": "Ustaw wygląd:", + "@setTheme": {}, + "replace": "Zastąp", + "@replace": {}, + "pleaseTryAgainLaterOrChooseDifferentServer": "Spróbuj ponownie później lub wybierz inny serwer.", + "@pleaseTryAgainLaterOrChooseDifferentServer": {}, + "createGroup": "Utwórz grupę", + "@createGroup": {}, + "importNow": "Zaimportuj", + "@importNow": {}, + "invite": "Zaproszenie", + "@invite": {}, + "continueWith": "Kontynuuj z:", + "@continueWith": {}, + "banUserDescription": "", + "@banUserDescription": {}, + "removeDevicesDescription": "", + "@removeDevicesDescription": {}, + "unbanUserDescription": "", + "@unbanUserDescription": {}, + "todoLists": "", + "@todoLists": {}, + "editTodo": "", + "@editTodo": {}, + "pushNotificationsNotAvailable": "", + "@pushNotificationsNotAvailable": {}, + "pleaseAddATitle": "", + "@pleaseAddATitle": {}, + "makeAdminDescription": "", + "@makeAdminDescription": {}, + "noTodosYet": "", + "@noTodosYet": {}, + "archiveRoomDescription": "", + "@archiveRoomDescription": {}, + "todosUnencrypted": "", + "@todosUnencrypted": {}, + "hasKnocked": "", + "@hasKnocked": { + "placeholders": { + "user": {} + } + }, + "newTodo": "", + "@newTodo": {}, + "learnMore": "", + "@learnMore": {}, + "todoListChangedError": "", + "@todoListChangedError": {}, + "roomUpgradeDescription": "", + "@roomUpgradeDescription": {}, + "pleaseEnterANumber": "", + "@pleaseEnterANumber": {}, + "kickUserDescription": "", + "@kickUserDescription": {} } diff --git a/assets/l10n/intl_pt.arb b/assets/l10n/intl_pt.arb index 49312de13..0c90a1404 100644 --- a/assets/l10n/intl_pt.arb +++ b/assets/l10n/intl_pt.arb @@ -1,120 +1,2621 @@ { - "@@last_modified": "2021-08-14 12:41:09.940318", - "copiedToClipboard": "Copiada para a área de transferência", - "@copiedToClipboard": { - "type": "text", - "placeholders": {} - }, - "login": "Iniciar sessão", - "@login": { - "type": "text", - "placeholders": {} - }, - "about": "Sobre", - "@about": { - "type": "text", - "placeholders": {} - }, - "admin": "Admin", - "@admin": { - "type": "text", - "placeholders": {} - }, - "areYouSure": "Tens a certeza?", - "@areYouSure": { - "type": "text", - "placeholders": {} - }, - "notifications": "Notificações", - "@notifications": { - "type": "text", - "placeholders": {} - }, - "account": "Conta", - "@account": { - "type": "text", - "placeholders": {} - }, - "cancel": "Cancelar", - "@cancel": { - "type": "text", - "placeholders": {} - }, - "delete": "Eliminar", - "@delete": { - "type": "text", - "placeholders": {} - }, - "dateAndTimeOfDay": "{date}, {timeOfDay}", - "@dateAndTimeOfDay": { - "type": "text", - "placeholders": { - "date": {}, - "timeOfDay": {} - } - }, - "dateWithYear": "{day}-{month}-{year}", - "@dateWithYear": { - "type": "text", - "placeholders": { - "year": {}, - "month": {}, - "day": {} - } - }, - "help": "Ajuda", - "@help": { - "type": "text", - "placeholders": {} - }, - "messages": "Mensagens", - "@messages": { - "type": "text", - "placeholders": {} - }, - "reason": "Razão", - "@reason": { - "type": "text", - "placeholders": {} - }, - "privacy": "Privacidade", - "@privacy": { - "type": "text", - "placeholders": {} - }, - "openCamera": "Abrir câmara", - "@openCamera": { - "type": "text", - "placeholders": {} - }, - "settings": "Configurações", - "@settings": { - "type": "text", - "placeholders": {} - }, - "logout": "Terminar sessão", - "@logout": { - "type": "text", - "placeholders": {} - }, - "search": "Pesquisar", - "@search": { - "type": "text", - "placeholders": {} - }, - "users": "Utilizadores", - "@users": {}, - "close": "Fechar", - "@close": { - "type": "text", - "placeholders": {} - }, - "dateWithoutYear": "{day}-{month}", - "@dateWithoutYear": { - "type": "text", - "placeholders": { - "month": {}, - "day": {} - } + "@@last_modified": "2021-08-14 12:41:09.940318", + "copiedToClipboard": "Copiada para a área de transferência", + "@copiedToClipboard": { + "type": "text", + "placeholders": {} + }, + "login": "Iniciar sessão", + "@login": { + "type": "text", + "placeholders": {} + }, + "about": "Sobre", + "@about": { + "type": "text", + "placeholders": {} + }, + "admin": "Admin", + "@admin": { + "type": "text", + "placeholders": {} + }, + "areYouSure": "Tens a certeza?", + "@areYouSure": { + "type": "text", + "placeholders": {} + }, + "notifications": "Notificações", + "@notifications": { + "type": "text", + "placeholders": {} + }, + "account": "Conta", + "@account": { + "type": "text", + "placeholders": {} + }, + "cancel": "Cancelar", + "@cancel": { + "type": "text", + "placeholders": {} + }, + "delete": "Eliminar", + "@delete": { + "type": "text", + "placeholders": {} + }, + "dateAndTimeOfDay": "{date}, {timeOfDay}", + "@dateAndTimeOfDay": { + "type": "text", + "placeholders": { + "date": {}, + "timeOfDay": {} } -} \ No newline at end of file + }, + "dateWithYear": "{day}-{month}-{year}", + "@dateWithYear": { + "type": "text", + "placeholders": { + "year": {}, + "month": {}, + "day": {} + } + }, + "help": "Ajuda", + "@help": { + "type": "text", + "placeholders": {} + }, + "messages": "Mensagens", + "@messages": { + "type": "text", + "placeholders": {} + }, + "reason": "Razão", + "@reason": { + "type": "text", + "placeholders": {} + }, + "privacy": "Privacidade", + "@privacy": { + "type": "text", + "placeholders": {} + }, + "openCamera": "Abrir câmara", + "@openCamera": { + "type": "text", + "placeholders": {} + }, + "settings": "Configurações", + "@settings": { + "type": "text", + "placeholders": {} + }, + "logout": "Terminar sessão", + "@logout": { + "type": "text", + "placeholders": {} + }, + "search": "Pesquisar", + "@search": { + "type": "text", + "placeholders": {} + }, + "users": "Utilizadores", + "@users": {}, + "close": "Fechar", + "@close": { + "type": "text", + "placeholders": {} + }, + "dateWithoutYear": "{day}-{month}", + "@dateWithoutYear": { + "type": "text", + "placeholders": { + "month": {}, + "day": {} + } + }, + "showPassword": "", + "@showPassword": { + "type": "text", + "placeholders": {} + }, + "hugContent": "", + "@hugContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "darkTheme": "", + "@darkTheme": { + "type": "text", + "placeholders": {} + }, + "passphraseOrKey": "", + "@passphraseOrKey": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourPassword": "", + "@pleaseEnterYourPassword": { + "type": "text", + "placeholders": {} + }, + "theyMatch": "", + "@theyMatch": { + "type": "text", + "placeholders": {} + }, + "connect": "", + "@connect": { + "type": "text", + "placeholders": {} + }, + "jumpToLastReadMessage": "", + "@jumpToLastReadMessage": {}, + "allRooms": "", + "@allRooms": { + "type": "text", + "placeholders": {} + }, + "obtainingLocation": "", + "@obtainingLocation": { + "type": "text", + "placeholders": {} + }, + "whoCanSeeMyStories": "", + "@whoCanSeeMyStories": {}, + "commandHint_cuddle": "", + "@commandHint_cuddle": {}, + "chats": "", + "@chats": { + "type": "text", + "placeholders": {} + }, + "widgetVideo": "", + "@widgetVideo": {}, + "dismiss": "", + "@dismiss": {}, + "unknownDevice": "", + "@unknownDevice": { + "type": "text", + "placeholders": {} + }, + "emoteShortcode": "", + "@emoteShortcode": { + "type": "text", + "placeholders": {} + }, + "noEncryptionForPublicRooms": "", + "@noEncryptionForPublicRooms": { + "type": "text", + "placeholders": {} + }, + "reportErrorDescription": "", + "@reportErrorDescription": {}, + "directChats": "", + "@directChats": { + "type": "text", + "placeholders": {} + }, + "setPermissionsLevel": "", + "@setPermissionsLevel": { + "type": "text", + "placeholders": {} + }, + "inviteContactToGroup": "", + "@inviteContactToGroup": { + "type": "text", + "placeholders": { + "groupName": {} + } + }, + "addAccount": "", + "@addAccount": {}, + "configureChat": "", + "@configureChat": { + "type": "text", + "placeholders": {} + }, + "seenByUserAndUser": "", + "@seenByUserAndUser": { + "type": "text", + "placeholders": { + "username": {}, + "username2": {} + } + }, + "chatHasBeenAddedToThisSpace": "", + "@chatHasBeenAddedToThisSpace": {}, + "reply": "", + "@reply": { + "type": "text", + "placeholders": {} + }, + "currentlyActive": "", + "@currentlyActive": { + "type": "text", + "placeholders": {} + }, + "removeYourAvatar": "", + "@removeYourAvatar": { + "type": "text", + "placeholders": {} + }, + "unsupportedAndroidVersion": "", + "@unsupportedAndroidVersion": {}, + "enterASpacepName": "", + "@enterASpacepName": {}, + "device": "", + "@device": { + "type": "text", + "placeholders": {} + }, + "blockDevice": "", + "@blockDevice": { + "type": "text", + "placeholders": {} + }, + "commandHint_html": "", + "@commandHint_html": { + "type": "text", + "description": "Usage hint for the command /html" + }, + "widgetJitsi": "", + "@widgetJitsi": {}, + "youAreNoLongerParticipatingInThisChat": "", + "@youAreNoLongerParticipatingInThisChat": { + "type": "text", + "placeholders": {} + }, + "encryption": "", + "@encryption": { + "type": "text", + "placeholders": {} + }, + "messageType": "", + "@messageType": {}, + "noEmailWarning": "", + "@noEmailWarning": {}, + "indexedDbErrorLong": "", + "@indexedDbErrorLong": {}, + "oneClientLoggedOut": "", + "@oneClientLoggedOut": {}, + "toggleMuted": "", + "@toggleMuted": { + "type": "text", + "placeholders": {} + }, + "kicked": "", + "@kicked": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "title": "", + "@title": { + "description": "Title for the application", + "type": "text", + "placeholders": {} + }, + "changeTheNameOfTheGroup": "", + "@changeTheNameOfTheGroup": { + "type": "text", + "placeholders": {} + }, + "changedTheChatAvatar": "", + "@changedTheChatAvatar": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "verifySuccess": "", + "@verifySuccess": { + "type": "text", + "placeholders": {} + }, + "sendFile": "", + "@sendFile": { + "type": "text", + "placeholders": {} + }, + "newVerificationRequest": "", + "@newVerificationRequest": { + "type": "text", + "placeholders": {} + }, + "startFirstChat": "", + "@startFirstChat": {}, + "callingAccount": "", + "@callingAccount": {}, + "requestPermission": "", + "@requestPermission": { + "type": "text", + "placeholders": {} + }, + "sentAPicture": "", + "@sentAPicture": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "invited": "", + "@invited": { + "type": "text", + "placeholders": {} + }, + "setColorTheme": "", + "@setColorTheme": {}, + "nextAccount": "", + "@nextAccount": {}, + "commandHint_create": "", + "@commandHint_create": { + "type": "text", + "description": "Usage hint for the command /create" + }, + "youAreInvitedToThisChat": "", + "@youAreInvitedToThisChat": { + "type": "text", + "placeholders": {} + }, + "singlesignon": "", + "@singlesignon": { + "type": "text", + "placeholders": {} + }, + "warning": "", + "@warning": { + "type": "text", + "placeholders": {} + }, + "password": "", + "@password": { + "type": "text", + "placeholders": {} + }, + "allSpaces": "", + "@allSpaces": {}, + "supposedMxid": "", + "@supposedMxid": { + "type": "text", + "placeholders": { + "mxid": {} + } + }, + "editDisplayname": "", + "@editDisplayname": { + "type": "text", + "placeholders": {} + }, + "user": "", + "@user": {}, + "roomVersion": "", + "@roomVersion": { + "type": "text", + "placeholders": {} + }, + "sentAFile": "", + "@sentAFile": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "videoCall": "", + "@videoCall": { + "type": "text", + "placeholders": {} + }, + "youAcceptedTheInvitation": "", + "@youAcceptedTheInvitation": {}, + "banFromChat": "", + "@banFromChat": { + "type": "text", + "placeholders": {} + }, + "noMatrixServer": "", + "@noMatrixServer": { + "type": "text", + "placeholders": { + "server1": {}, + "server2": {} + } + }, + "userAndOthersAreTyping": "", + "@userAndOthersAreTyping": { + "type": "text", + "placeholders": { + "username": {}, + "count": {} + } + }, + "youInvitedBy": "", + "@youInvitedBy": { + "placeholders": { + "user": {} + } + }, + "userIsTyping": "", + "@userIsTyping": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "openAppToReadMessages": "", + "@openAppToReadMessages": { + "type": "text", + "placeholders": {} + }, + "sentAVideo": "", + "@sentAVideo": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "banUserDescription": "", + "@banUserDescription": {}, + "inviteContact": "", + "@inviteContact": { + "type": "text", + "placeholders": {} + }, + "requests": "", + "@requests": {}, + "askSSSSSign": "", + "@askSSSSSign": { + "type": "text", + "placeholders": {} + }, + "widgetEtherpad": "", + "@widgetEtherpad": {}, + "waitingPartnerAcceptRequest": "", + "@waitingPartnerAcceptRequest": { + "type": "text", + "placeholders": {} + }, + "remove": "", + "@remove": { + "type": "text", + "placeholders": {} + }, + "writeAMessage": "", + "@writeAMessage": { + "type": "text", + "placeholders": {} + }, + "changeTheme": "", + "@changeTheme": { + "type": "text", + "placeholders": {} + }, + "stories": "", + "@stories": {}, + "id": "", + "@id": { + "type": "text", + "placeholders": {} + }, + "addToStory": "", + "@addToStory": {}, + "removeDevicesDescription": "", + "@removeDevicesDescription": {}, + "changedTheChatDescriptionTo": "", + "@changedTheChatDescriptionTo": { + "type": "text", + "placeholders": { + "username": {}, + "description": {} + } + }, + "countParticipants": "", + "@countParticipants": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "separateChatTypes": "", + "@separateChatTypes": { + "type": "text", + "placeholders": {} + }, + "tryAgain": "", + "@tryAgain": {}, + "areGuestsAllowedToJoin": "", + "@areGuestsAllowedToJoin": { + "type": "text", + "placeholders": {} + }, + "blocked": "", + "@blocked": { + "type": "text", + "placeholders": {} + }, + "youKickedAndBanned": "", + "@youKickedAndBanned": { + "placeholders": { + "user": {} + } + }, + "showDirectChatsInSpaces": "", + "@showDirectChatsInSpaces": { + "type": "text", + "placeholders": {} + }, + "removeDevice": "", + "@removeDevice": { + "type": "text", + "placeholders": {} + }, + "youCannotInviteYourself": "", + "@youCannotInviteYourself": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterValidEmail": "", + "@pleaseEnterValidEmail": {}, + "unbanUserDescription": "", + "@unbanUserDescription": {}, + "todoLists": "", + "@todoLists": {}, + "userAndUserAreTyping": "", + "@userAndUserAreTyping": { + "type": "text", + "placeholders": { + "username": {}, + "username2": {} + } + }, + "pleaseClickOnLink": "", + "@pleaseClickOnLink": { + "type": "text", + "placeholders": {} + }, + "saveFile": "", + "@saveFile": { + "type": "text", + "placeholders": {} + }, + "sendOnEnter": "", + "@sendOnEnter": {}, + "seenByUserAndCountOthers": "", + "@seenByUserAndCountOthers": { + "type": "text", + "placeholders": { + "username": {}, + "count": {} + } + }, + "answeredTheCall": "", + "@answeredTheCall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "youRejectedTheInvitation": "", + "@youRejectedTheInvitation": {}, + "otherCallingPermissions": "", + "@otherCallingPermissions": {}, + "messagesStyle": "", + "@messagesStyle": {}, + "couldNotDecryptMessage": "", + "@couldNotDecryptMessage": { + "type": "text", + "placeholders": { + "error": {} + } + }, + "invitedUsersOnly": "", + "@invitedUsersOnly": { + "type": "text", + "placeholders": {} + }, + "link": "", + "@link": {}, + "widgetUrlError": "", + "@widgetUrlError": {}, + "emailOrUsername": "", + "@emailOrUsername": {}, + "newSpaceDescription": "", + "@newSpaceDescription": {}, + "chatDescription": "", + "@chatDescription": {}, + "callingAccountDetails": "", + "@callingAccountDetails": {}, + "next": "", + "@next": { + "type": "text", + "placeholders": {} + }, + "pleaseFollowInstructionsOnWeb": "", + "@pleaseFollowInstructionsOnWeb": { + "type": "text", + "placeholders": {} + }, + "changedTheGuestAccessRules": "", + "@changedTheGuestAccessRules": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "pleaseChooseAtLeastChars": "", + "@pleaseChooseAtLeastChars": { + "type": "text", + "placeholders": { + "min": {} + } + }, + "editRoomAliases": "", + "@editRoomAliases": { + "type": "text", + "placeholders": {} + }, + "enterSpace": "", + "@enterSpace": {}, + "encryptThisChat": "", + "@encryptThisChat": {}, + "fileName": "", + "@fileName": { + "type": "text", + "placeholders": {} + }, + "unavailable": "", + "@unavailable": { + "type": "text", + "placeholders": {} + }, + "previousAccount": "", + "@previousAccount": {}, + "publicRooms": "", + "@publicRooms": { + "type": "text", + "placeholders": {} + }, + "fromTheInvitation": "", + "@fromTheInvitation": { + "type": "text", + "placeholders": {} + }, + "sendMessages": "", + "@sendMessages": { + "type": "text", + "placeholders": {} + }, + "incorrectPassphraseOrKey": "", + "@incorrectPassphraseOrKey": { + "type": "text", + "placeholders": {} + }, + "emoteWarnNeedToPick": "", + "@emoteWarnNeedToPick": { + "type": "text", + "placeholders": {} + }, + "reopenChat": "", + "@reopenChat": {}, + "pleaseEnterRecoveryKey": "", + "@pleaseEnterRecoveryKey": {}, + "create": "", + "@create": { + "type": "text", + "placeholders": {} + }, + "toggleFavorite": "", + "@toggleFavorite": { + "type": "text", + "placeholders": {} + }, + "no": "", + "@no": { + "type": "text", + "placeholders": {} + }, + "alias": "", + "@alias": { + "type": "text", + "placeholders": {} + }, + "widgetNameError": "", + "@widgetNameError": {}, + "inoffensive": "", + "@inoffensive": { + "type": "text", + "placeholders": {} + }, + "unpin": "", + "@unpin": { + "type": "text", + "placeholders": {} + }, + "addToBundle": "", + "@addToBundle": {}, + "reportMessage": "", + "@reportMessage": { + "type": "text", + "placeholders": {} + }, + "spaceIsPublic": "", + "@spaceIsPublic": { + "type": "text", + "placeholders": {} + }, + "addWidget": "", + "@addWidget": {}, + "all": "", + "@all": { + "type": "text", + "placeholders": {} + }, + "removeAllOtherDevices": "", + "@removeAllOtherDevices": { + "type": "text", + "placeholders": {} + }, + "unblockDevice": "", + "@unblockDevice": { + "type": "text", + "placeholders": {} + }, + "countFiles": "", + "@countFiles": { + "placeholders": { + "count": {} + } + }, + "noKeyForThisMessage": "", + "@noKeyForThisMessage": {}, + "enableEncryptionWarning": "", + "@enableEncryptionWarning": { + "type": "text", + "placeholders": {} + }, + "inviteText": "", + "@inviteText": { + "type": "text", + "placeholders": { + "username": {}, + "link": {} + } + }, + "shareLocation": "", + "@shareLocation": { + "type": "text", + "placeholders": {} + }, + "commandHint_markasgroup": "", + "@commandHint_markasgroup": {}, + "editTodo": "", + "@editTodo": {}, + "errorObtainingLocation": "", + "@errorObtainingLocation": { + "type": "text", + "placeholders": { + "error": {} + } + }, + "hydrateTor": "", + "@hydrateTor": {}, + "pushNotificationsNotAvailable": "", + "@pushNotificationsNotAvailable": {}, + "passwordRecovery": "", + "@passwordRecovery": { + "type": "text", + "placeholders": {} + }, + "storeInAppleKeyChain": "", + "@storeInAppleKeyChain": {}, + "replaceRoomWithNewerVersion": "", + "@replaceRoomWithNewerVersion": { + "type": "text", + "placeholders": {} + }, + "hydrate": "", + "@hydrate": {}, + "invalidServerName": "", + "@invalidServerName": {}, + "chatPermissions": "", + "@chatPermissions": {}, + "voiceMessage": "", + "@voiceMessage": { + "type": "text", + "placeholders": {} + }, + "badServerLoginTypesException": "", + "@badServerLoginTypesException": { + "type": "text", + "placeholders": { + "serverVersions": {}, + "supportedVersions": {} + } + }, + "wipeChatBackup": "", + "@wipeChatBackup": { + "type": "text", + "placeholders": {} + }, + "cantOpenUri": "", + "@cantOpenUri": { + "type": "text", + "placeholders": { + "uri": {} + } + }, + "sender": "", + "@sender": {}, + "storeInAndroidKeystore": "", + "@storeInAndroidKeystore": {}, + "optionalGroupName": "", + "@optionalGroupName": { + "type": "text", + "placeholders": {} + }, + "hideRedactedEvents": "", + "@hideRedactedEvents": { + "type": "text", + "placeholders": {} + }, + "online": "", + "@online": { + "type": "text", + "placeholders": {} + }, + "signInWithPassword": "", + "@signInWithPassword": {}, + "pleaseAddATitle": "", + "@pleaseAddATitle": {}, + "updateNow": "", + "@updateNow": {}, + "ignoredUsers": "", + "@ignoredUsers": { + "type": "text", + "placeholders": {} + }, + "lastActiveAgo": "", + "@lastActiveAgo": { + "type": "text", + "placeholders": { + "localizedTimeShort": {} + } + }, + "changedTheGuestAccessRulesTo": "", + "@changedTheGuestAccessRulesTo": { + "type": "text", + "placeholders": { + "username": {}, + "rules": {} + } + }, + "weSentYouAnEmail": "", + "@weSentYouAnEmail": { + "type": "text", + "placeholders": {} + }, + "offensive": "", + "@offensive": { + "type": "text", + "placeholders": {} + }, + "needPantalaimonWarning": "", + "@needPantalaimonWarning": { + "type": "text", + "placeholders": {} + }, + "makeAdminDescription": "", + "@makeAdminDescription": {}, + "edit": "", + "@edit": { + "type": "text", + "placeholders": {} + }, + "loadMore": "", + "@loadMore": { + "type": "text", + "placeholders": {} + }, + "noEmotesFound": "", + "@noEmotesFound": { + "type": "text", + "placeholders": {} + }, + "synchronizingPleaseWait": "", + "@synchronizingPleaseWait": { + "type": "text", + "placeholders": {} + }, + "transferFromAnotherDevice": "", + "@transferFromAnotherDevice": { + "type": "text", + "placeholders": {} + }, + "passwordHasBeenChanged": "", + "@passwordHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "pushRules": "", + "@pushRules": { + "type": "text", + "placeholders": {} + }, + "goToTheNewRoom": "", + "@goToTheNewRoom": { + "type": "text", + "placeholders": {} + }, + "commandHint_clearcache": "", + "@commandHint_clearcache": { + "type": "text", + "description": "Usage hint for the command /clearcache" + }, + "loadingPleaseWait": "", + "@loadingPleaseWait": { + "type": "text", + "placeholders": {} + }, + "copy": "", + "@copy": { + "type": "text", + "placeholders": {} + }, + "saveKeyManuallyDescription": "", + "@saveKeyManuallyDescription": {}, + "none": "", + "@none": { + "type": "text", + "placeholders": {} + }, + "editBundlesForAccount": "", + "@editBundlesForAccount": {}, + "renderRichContent": "", + "@renderRichContent": { + "type": "text", + "placeholders": {} + }, + "enableEncryption": "", + "@enableEncryption": { + "type": "text", + "placeholders": {} + }, + "whyIsThisMessageEncrypted": "", + "@whyIsThisMessageEncrypted": {}, + "rejectedTheInvitation": "", + "@rejectedTheInvitation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "setChatDescription": "", + "@setChatDescription": {}, + "userLeftTheChat": "", + "@userLeftTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "spaceName": "", + "@spaceName": { + "type": "text", + "placeholders": {} + }, + "importFromZipFile": "", + "@importFromZipFile": {}, + "discover": "", + "@discover": { + "type": "text", + "placeholders": {} + }, + "toggleUnread": "", + "@toggleUnread": { + "type": "text", + "placeholders": {} + }, + "or": "", + "@or": { + "type": "text", + "placeholders": {} + }, + "dehydrateWarning": "", + "@dehydrateWarning": {}, + "sendOriginal": "", + "@sendOriginal": { + "type": "text", + "placeholders": {} + }, + "noOtherDevicesFound": "", + "@noOtherDevicesFound": {}, + "whoIsAllowedToJoinThisGroup": "", + "@whoIsAllowedToJoinThisGroup": { + "type": "text", + "placeholders": {} + }, + "emptyChat": "", + "@emptyChat": { + "type": "text", + "placeholders": {} + }, + "seenByUser": "", + "@seenByUser": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "yourChatBackupHasBeenSetUp": "", + "@yourChatBackupHasBeenSetUp": {}, + "addDescription": "", + "@addDescription": {}, + "chatBackup": "", + "@chatBackup": { + "type": "text", + "placeholders": {} + }, + "redactedBy": "", + "@redactedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "submit": "", + "@submit": { + "type": "text", + "placeholders": {} + }, + "videoCallsBetaWarning": "", + "@videoCallsBetaWarning": {}, + "unmuteChat": "", + "@unmuteChat": { + "type": "text", + "placeholders": {} + }, + "createdTheChat": "", + "@createdTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "redactedAnEvent": "", + "@redactedAnEvent": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "autoplayImages": "", + "@autoplayImages": { + "type": "text", + "placeholder": {} + }, + "storyPrivacyWarning": "", + "@storyPrivacyWarning": {}, + "compareEmojiMatch": "", + "@compareEmojiMatch": { + "type": "text", + "placeholders": {} + }, + "matrixWidgets": "", + "@matrixWidgets": {}, + "participant": "", + "@participant": { + "type": "text", + "placeholders": {} + }, + "logInTo": "", + "@logInTo": { + "type": "text", + "placeholders": { + "homeserver": {} + } + }, + "yes": "", + "@yes": { + "type": "text", + "placeholders": {} + }, + "containsDisplayName": "", + "@containsDisplayName": { + "type": "text", + "placeholders": {} + }, + "signInWith": "", + "@signInWith": { + "type": "text", + "placeholders": { + "provider": {} + } + }, + "username": "", + "@username": { + "type": "text", + "placeholders": {} + }, + "changedTheRoomAliases": "", + "@changedTheRoomAliases": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "updateAvailable": "", + "@updateAvailable": {}, + "fileIsTooBigForServer": "", + "@fileIsTooBigForServer": {}, + "homeserver": "", + "@homeserver": {}, + "noTodosYet": "", + "@noTodosYet": {}, + "chatDetails": "", + "@chatDetails": { + "type": "text", + "placeholders": {} + }, + "people": "", + "@people": { + "type": "text", + "placeholders": {} + }, + "changedTheHistoryVisibilityTo": "", + "@changedTheHistoryVisibilityTo": { + "type": "text", + "placeholders": { + "username": {}, + "rules": {} + } + }, + "leftTheChat": "", + "@leftTheChat": { + "type": "text", + "placeholders": {} + }, + "verified": "", + "@verified": { + "type": "text", + "placeholders": {} + }, + "repeatPassword": "", + "@repeatPassword": {}, + "setStatus": "", + "@setStatus": { + "type": "text", + "placeholders": {} + }, + "groupWith": "", + "@groupWith": { + "type": "text", + "placeholders": { + "displayname": {} + } + }, + "callingPermissions": "", + "@callingPermissions": {}, + "newMessageInFluffyChat": "", + "@newMessageInFluffyChat": { + "type": "text", + "placeholders": {} + }, + "readUpToHere": "", + "@readUpToHere": {}, + "start": "", + "@start": {}, + "bubbleSize": "", + "@bubbleSize": { + "type": "text", + "placeholders": {} + }, + "downloadFile": "", + "@downloadFile": { + "type": "text", + "placeholders": {} + }, + "deviceId": "", + "@deviceId": { + "type": "text", + "placeholders": {} + }, + "register": "", + "@register": { + "type": "text", + "placeholders": {} + }, + "unlockOldMessages": "", + "@unlockOldMessages": {}, + "identity": "", + "@identity": { + "type": "text", + "placeholders": {} + }, + "numChats": "", + "@numChats": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "changedTheJoinRulesTo": "", + "@changedTheJoinRulesTo": { + "type": "text", + "placeholders": { + "username": {}, + "joinRules": {} + } + }, + "ignore": "", + "@ignore": { + "type": "text", + "placeholders": {} + }, + "whatIsGoingOn": "", + "@whatIsGoingOn": {}, + "recording": "", + "@recording": { + "type": "text", + "placeholders": {} + }, + "changedTheChatPermissions": "", + "@changedTheChatPermissions": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changeWallpaper": "", + "@changeWallpaper": { + "type": "text", + "placeholders": {} + }, + "moderator": "", + "@moderator": { + "type": "text", + "placeholders": {} + }, + "optionalRedactReason": "", + "@optionalRedactReason": {}, + "acceptedTheInvitation": "", + "@acceptedTheInvitation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "waitingPartnerEmoji": "", + "@waitingPartnerEmoji": { + "type": "text", + "placeholders": {} + }, + "channelCorruptedDecryptError": "", + "@channelCorruptedDecryptError": { + "type": "text", + "placeholders": {} + }, + "tryToSendAgain": "", + "@tryToSendAgain": { + "type": "text", + "placeholders": {} + }, + "guestsCanJoin": "", + "@guestsCanJoin": { + "type": "text", + "placeholders": {} + }, + "copyToClipboard": "", + "@copyToClipboard": { + "type": "text", + "placeholders": {} + }, + "dehydrate": "", + "@dehydrate": {}, + "locationPermissionDeniedNotice": "", + "@locationPermissionDeniedNotice": { + "type": "text", + "placeholders": {} + }, + "send": "", + "@send": { + "type": "text", + "placeholders": {} + }, + "hasWithdrawnTheInvitationFor": "", + "@hasWithdrawnTheInvitationFor": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "visibleForAllParticipants": "", + "@visibleForAllParticipants": { + "type": "text", + "placeholders": {} + }, + "noRoomsFound": "", + "@noRoomsFound": { + "type": "text", + "placeholders": {} + }, + "banned": "", + "@banned": { + "type": "text", + "placeholders": {} + }, + "sendAsText": "", + "@sendAsText": { + "type": "text" + }, + "inviteForMe": "", + "@inviteForMe": { + "type": "text", + "placeholders": {} + }, + "archiveRoomDescription": "", + "@archiveRoomDescription": {}, + "exportEmotePack": "", + "@exportEmotePack": {}, + "changedTheChatNameTo": "", + "@changedTheChatNameTo": { + "type": "text", + "placeholders": { + "username": {}, + "chatname": {} + } + }, + "sendSticker": "", + "@sendSticker": { + "type": "text", + "placeholders": {} + }, + "switchToAccount": "", + "@switchToAccount": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "commandInvalid": "", + "@commandInvalid": { + "type": "text" + }, + "setAsCanonicalAlias": "", + "@setAsCanonicalAlias": { + "type": "text", + "placeholders": {} + }, + "whyDoYouWantToReportThis": "", + "@whyDoYouWantToReportThis": { + "type": "text", + "placeholders": {} + }, + "locationDisabledNotice": "", + "@locationDisabledNotice": { + "type": "text", + "placeholders": {} + }, + "letsStart": "", + "@letsStart": {}, + "removedBy": "", + "@removedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheRoomInvitationLink": "", + "@changedTheRoomInvitationLink": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "newChat": "", + "@newChat": { + "type": "text", + "placeholders": {} + }, + "commandHint_plain": "", + "@commandHint_plain": { + "type": "text", + "description": "Usage hint for the command /plain" + }, + "emoteSettings": "", + "@emoteSettings": { + "type": "text", + "placeholders": {} + }, + "experimentalVideoCalls": "", + "@experimentalVideoCalls": {}, + "savedEmotePack": "", + "@savedEmotePack": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "pleaseEnterRecoveryKeyDescription": "", + "@pleaseEnterRecoveryKeyDescription": {}, + "guestsAreForbidden": "", + "@guestsAreForbidden": { + "type": "text", + "placeholders": {} + }, + "mention": "", + "@mention": { + "type": "text", + "placeholders": {} + }, + "openInMaps": "", + "@openInMaps": { + "type": "text", + "placeholders": {} + }, + "inviteContactToGroupQuestion": "", + "@inviteContactToGroupQuestion": {}, + "emoteExists": "", + "@emoteExists": { + "type": "text", + "placeholders": {} + }, + "redactedByBecause": "", + "@redactedByBecause": { + "type": "text", + "placeholders": { + "username": {}, + "reason": {} + } + }, + "isTyping": "", + "@isTyping": { + "type": "text", + "placeholders": {} + }, + "youHaveWithdrawnTheInvitationFor": "", + "@youHaveWithdrawnTheInvitationFor": { + "placeholders": { + "user": {} + } + }, + "chat": "", + "@chat": { + "type": "text", + "placeholders": {} + }, + "group": "", + "@group": { + "type": "text", + "placeholders": {} + }, + "leave": "", + "@leave": { + "type": "text", + "placeholders": {} + }, + "skip": "", + "@skip": { + "type": "text", + "placeholders": {} + }, + "appearOnTopDetails": "", + "@appearOnTopDetails": {}, + "roomHasBeenUpgraded": "", + "@roomHasBeenUpgraded": { + "type": "text", + "placeholders": {} + }, + "enterRoom": "", + "@enterRoom": {}, + "enableEmotesGlobally": "", + "@enableEmotesGlobally": { + "type": "text", + "placeholders": {} + }, + "ignoreListDescription": "", + "@ignoreListDescription": { + "type": "text", + "placeholders": {} + }, + "pleaseChooseAPasscode": "", + "@pleaseChooseAPasscode": { + "type": "text", + "placeholders": {} + }, + "noPasswordRecoveryDescription": "", + "@noPasswordRecoveryDescription": { + "type": "text", + "placeholders": {} + }, + "changedTheProfileAvatar": "", + "@changedTheProfileAvatar": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "allChats": "", + "@allChats": { + "type": "text", + "placeholders": {} + }, + "reportUser": "", + "@reportUser": {}, + "commandHint_send": "", + "@commandHint_send": { + "type": "text", + "description": "Usage hint for the command /send" + }, + "onlineKeyBackupEnabled": "", + "@onlineKeyBackupEnabled": { + "type": "text", + "placeholders": {} + }, + "unbannedUser": "", + "@unbannedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "confirmEventUnpin": "", + "@confirmEventUnpin": {}, + "badServerVersionsException": "", + "@badServerVersionsException": { + "type": "text", + "placeholders": { + "serverVersions": {}, + "supportedVersions": {} + } + }, + "youInvitedUser": "", + "@youInvitedUser": { + "placeholders": { + "user": {} + } + }, + "kickedAndBanned": "", + "@kickedAndBanned": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "noConnectionToTheServer": "", + "@noConnectionToTheServer": { + "type": "text", + "placeholders": {} + }, + "fileHasBeenSavedAt": "", + "@fileHasBeenSavedAt": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "license": "", + "@license": { + "type": "text", + "placeholders": {} + }, + "addToSpace": "", + "@addToSpace": {}, + "importZipFile": "", + "@importZipFile": {}, + "anyoneCanKnock": "", + "@anyoneCanKnock": {}, + "commandMissing": "", + "@commandMissing": { + "type": "text", + "placeholders": { + "command": {} + }, + "description": "State that {command} is not a valid /command." + }, + "redactMessageDescription": "", + "@redactMessageDescription": {}, + "rejoin": "", + "@rejoin": { + "type": "text", + "placeholders": {} + }, + "recoveryKey": "", + "@recoveryKey": {}, + "redactMessage": "", + "@redactMessage": { + "type": "text", + "placeholders": {} + }, + "forward": "", + "@forward": { + "type": "text", + "placeholders": {} + }, + "commandHint_discardsession": "", + "@commandHint_discardsession": { + "type": "text", + "description": "Usage hint for the command /discardsession" + }, + "invalidInput": "", + "@invalidInput": {}, + "chooseAStrongPassword": "", + "@chooseAStrongPassword": { + "type": "text", + "placeholders": {} + }, + "hideUnknownEvents": "", + "@hideUnknownEvents": { + "type": "text", + "placeholders": {} + }, + "todosUnencrypted": "", + "@todosUnencrypted": {}, + "dehydrateTorLong": "", + "@dehydrateTorLong": {}, + "yourPublicKey": "", + "@yourPublicKey": { + "type": "text", + "placeholders": {} + }, + "tooManyRequestsWarning": "", + "@tooManyRequestsWarning": { + "type": "text", + "placeholders": {} + }, + "invitedUser": "", + "@invitedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "kickFromChat": "", + "@kickFromChat": { + "type": "text", + "placeholders": {} + }, + "commandHint_myroomnick": "", + "@commandHint_myroomnick": { + "type": "text", + "description": "Usage hint for the command /myroomnick" + }, + "offline": "", + "@offline": { + "type": "text", + "placeholders": {} + }, + "replyHasBeenSent": "", + "@replyHasBeenSent": {}, + "noPermission": "", + "@noPermission": { + "type": "text", + "placeholders": {} + }, + "doNotShowAgain": "", + "@doNotShowAgain": {}, + "activatedEndToEndEncryption": "", + "@activatedEndToEndEncryption": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "report": "", + "@report": {}, + "status": "", + "@status": { + "type": "text", + "placeholders": {} + }, + "deny": "", + "@deny": { + "type": "text", + "placeholders": {} + }, + "compareNumbersMatch": "", + "@compareNumbersMatch": { + "type": "text", + "placeholders": {} + }, + "groupIsPublic": "", + "@groupIsPublic": { + "type": "text", + "placeholders": {} + }, + "verifyStart": "", + "@verifyStart": { + "type": "text", + "placeholders": {} + }, + "yourStory": "", + "@yourStory": {}, + "memberChanges": "", + "@memberChanges": { + "type": "text", + "placeholders": {} + }, + "joinRoom": "", + "@joinRoom": { + "type": "text", + "placeholders": {} + }, + "ignoreUsername": "", + "@ignoreUsername": { + "type": "text", + "placeholders": {} + }, + "unverified": "", + "@unverified": {}, + "fluffychat": "", + "@fluffychat": { + "type": "text", + "placeholders": {} + }, + "howOffensiveIsThisContent": "", + "@howOffensiveIsThisContent": { + "type": "text", + "placeholders": {} + }, + "serverRequiresEmail": "", + "@serverRequiresEmail": {}, + "hideUnimportantStateEvents": "", + "@hideUnimportantStateEvents": {}, + "screenSharingTitle": "", + "@screenSharingTitle": {}, + "widgetCustom": "", + "@widgetCustom": {}, + "sentCallInformations": "", + "@sentCallInformations": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "addToSpaceDescription": "", + "@addToSpaceDescription": {}, + "googlyEyesContent": "", + "@googlyEyesContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "whoCanSeeMyStoriesDesc": "", + "@whoCanSeeMyStoriesDesc": {}, + "youBannedUser": "", + "@youBannedUser": { + "placeholders": { + "user": {} + } + }, + "theyDontMatch": "", + "@theyDontMatch": { + "type": "text", + "placeholders": {} + }, + "unsubscribeStories": "", + "@unsubscribeStories": {}, + "youHaveBeenBannedFromThisChat": "", + "@youHaveBeenBannedFromThisChat": { + "type": "text", + "placeholders": {} + }, + "displaynameHasBeenChanged": "", + "@displaynameHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "loginWithOneClick": "", + "@loginWithOneClick": {}, + "addChatDescription": "", + "@addChatDescription": {}, + "sentAnAudio": "", + "@sentAnAudio": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "editRoomAvatar": "", + "@editRoomAvatar": { + "type": "text", + "placeholders": {} + }, + "encrypted": "", + "@encrypted": { + "type": "text", + "placeholders": {} + }, + "commandHint_leave": "", + "@commandHint_leave": { + "type": "text", + "description": "Usage hint for the command /leave" + }, + "commandHint_myroomavatar": "", + "@commandHint_myroomavatar": { + "type": "text", + "description": "Usage hint for the command /myroomavatar" + }, + "hasKnocked": "", + "@hasKnocked": { + "placeholders": { + "user": {} + } + }, + "publish": "", + "@publish": {}, + "openLinkInBrowser": "", + "@openLinkInBrowser": {}, + "clearArchive": "", + "@clearArchive": {}, + "appLock": "", + "@appLock": { + "type": "text", + "placeholders": {} + }, + "commandHint_react": "", + "@commandHint_react": { + "type": "text", + "description": "Usage hint for the command /react" + }, + "changedTheHistoryVisibility": "", + "@changedTheHistoryVisibility": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "commandHint_me": "", + "@commandHint_me": { + "type": "text", + "description": "Usage hint for the command /me" + }, + "pleaseEnterYourUsername": "", + "@pleaseEnterYourUsername": { + "type": "text", + "placeholders": {} + }, + "messageInfo": "", + "@messageInfo": {}, + "disableEncryptionWarning": "", + "@disableEncryptionWarning": {}, + "directChat": "", + "@directChat": {}, + "noOneCanJoin": "", + "@noOneCanJoin": {}, + "encryptionNotEnabled": "", + "@encryptionNotEnabled": { + "type": "text", + "placeholders": {} + }, + "wrongPinEntered": "", + "@wrongPinEntered": { + "type": "text", + "placeholders": { + "seconds": {} + } + }, + "sendTypingNotifications": "", + "@sendTypingNotifications": {}, + "lightTheme": "", + "@lightTheme": { + "type": "text", + "placeholders": {} + }, + "inviteGroupChat": "", + "@inviteGroupChat": {}, + "appearOnTop": "", + "@appearOnTop": {}, + "invitePrivateChat": "", + "@invitePrivateChat": {}, + "verifyTitle": "", + "@verifyTitle": { + "type": "text", + "placeholders": {} + }, + "foregroundServiceRunning": "", + "@foregroundServiceRunning": {}, + "enterAnEmailAddress": "", + "@enterAnEmailAddress": { + "type": "text", + "placeholders": {} + }, + "voiceCall": "", + "@voiceCall": {}, + "commandHint_kick": "", + "@commandHint_kick": { + "type": "text", + "description": "Usage hint for the command /kick" + }, + "createNewSpace": "", + "@createNewSpace": { + "type": "text", + "placeholders": {} + }, + "commandHint_unban": "", + "@commandHint_unban": { + "type": "text", + "description": "Usage hint for the command /unban" + }, + "unknownEncryptionAlgorithm": "", + "@unknownEncryptionAlgorithm": { + "type": "text", + "placeholders": {} + }, + "commandHint_ban": "", + "@commandHint_ban": { + "type": "text", + "description": "Usage hint for the command /ban" + }, + "importEmojis": "", + "@importEmojis": {}, + "confirm": "", + "@confirm": { + "type": "text", + "placeholders": {} + }, + "wasDirectChatDisplayName": "", + "@wasDirectChatDisplayName": { + "type": "text", + "placeholders": { + "oldDisplayName": {} + } + }, + "noChatDescriptionYet": "", + "@noChatDescriptionYet": {}, + "defaultPermissionLevel": "", + "@defaultPermissionLevel": { + "type": "text", + "placeholders": {} + }, + "newTodo": "", + "@newTodo": {}, + "removeFromBundle": "", + "@removeFromBundle": {}, + "numUsersTyping": "", + "@numUsersTyping": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "fontSize": "", + "@fontSize": { + "type": "text", + "placeholders": {} + }, + "whoCanPerformWhichAction": "", + "@whoCanPerformWhichAction": { + "type": "text", + "placeholders": {} + }, + "confirmMatrixId": "", + "@confirmMatrixId": {}, + "learnMore": "", + "@learnMore": {}, + "iHaveClickedOnLink": "", + "@iHaveClickedOnLink": { + "type": "text", + "placeholders": {} + }, + "you": "", + "@you": { + "type": "text", + "placeholders": {} + }, + "notAnImage": "", + "@notAnImage": {}, + "openGallery": "", + "@openGallery": {}, + "chatDescriptionHasBeenChanged": "", + "@chatDescriptionHasBeenChanged": {}, + "newGroup": "", + "@newGroup": {}, + "bundleName": "", + "@bundleName": {}, + "dehydrateTor": "", + "@dehydrateTor": {}, + "todoListChangedError": "", + "@todoListChangedError": {}, + "removeFromSpace": "", + "@removeFromSpace": {}, + "enterInviteLinkOrMatrixId": "", + "@enterInviteLinkOrMatrixId": {}, + "commandHint_op": "", + "@commandHint_op": { + "type": "text", + "description": "Usage hint for the command /op" + }, + "commandHint_join": "", + "@commandHint_join": { + "type": "text", + "description": "Usage hint for the command /join" + }, + "sourceCode": "", + "@sourceCode": { + "type": "text", + "placeholders": {} + }, + "enterAGroupName": "", + "@enterAGroupName": { + "type": "text", + "placeholders": {} + }, + "roomUpgradeDescription": "", + "@roomUpgradeDescription": {}, + "commandHint_invite": "", + "@commandHint_invite": { + "type": "text", + "description": "Usage hint for the command /invite" + }, + "userSentUnknownEvent": "", + "@userSentUnknownEvent": { + "type": "text", + "placeholders": { + "username": {}, + "type": {} + } + }, + "scanQrCode": "", + "@scanQrCode": {}, + "pleaseEnterANumber": "", + "@pleaseEnterANumber": {}, + "contactHasBeenInvitedToTheGroup": "", + "@contactHasBeenInvitedToTheGroup": { + "type": "text", + "placeholders": {} + }, + "youKicked": "", + "@youKicked": { + "placeholders": { + "user": {} + } + }, + "areYouSureYouWantToLogout": "", + "@areYouSureYouWantToLogout": { + "type": "text", + "placeholders": {} + }, + "changedTheJoinRules": "", + "@changedTheJoinRules": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "profileNotFound": "", + "@profileNotFound": {}, + "jump": "", + "@jump": {}, + "groups": "", + "@groups": { + "type": "text", + "placeholders": {} + }, + "reactedWith": "", + "@reactedWith": { + "type": "text", + "placeholders": { + "sender": {}, + "reaction": {} + } + }, + "bannedUser": "", + "@bannedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "sorryThatsNotPossible": "", + "@sorryThatsNotPossible": {}, + "storyFrom": "", + "@storyFrom": { + "type": "text", + "placeholders": { + "date": {}, + "body": {} + } + }, + "videoWithSize": "", + "@videoWithSize": { + "type": "text", + "placeholders": { + "size": {} + } + }, + "oopsSomethingWentWrong": "", + "@oopsSomethingWentWrong": { + "type": "text", + "placeholders": {} + }, + "loadCountMoreParticipants": "", + "@loadCountMoreParticipants": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "shareInviteLink": "", + "@shareInviteLink": {}, + "commandHint_markasdm": "", + "@commandHint_markasdm": {}, + "recoveryKeyLost": "", + "@recoveryKeyLost": {}, + "cuddleContent": "", + "@cuddleContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "askVerificationRequest": "", + "@askVerificationRequest": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "containsUserName": "", + "@containsUserName": { + "type": "text", + "placeholders": {} + }, + "deviceKeys": "", + "@deviceKeys": {}, + "waitingPartnerNumbers": "", + "@waitingPartnerNumbers": { + "type": "text", + "placeholders": {} + }, + "everythingReady": "", + "@everythingReady": { + "type": "text", + "placeholders": {} + }, + "addEmail": "", + "@addEmail": { + "type": "text", + "placeholders": {} + }, + "emoteKeyboardNoRecents": "", + "@emoteKeyboardNoRecents": { + "type": "text", + "placeholders": {} + }, + "setCustomEmotes": "", + "@setCustomEmotes": { + "type": "text", + "placeholders": {} + }, + "startedACall": "", + "@startedACall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "emoteInvalid": "", + "@emoteInvalid": { + "type": "text", + "placeholders": {} + }, + "systemTheme": "", + "@systemTheme": { + "type": "text", + "placeholders": {} + }, + "messageWillBeRemovedWarning": "", + "@messageWillBeRemovedWarning": { + "type": "text", + "placeholders": {} + }, + "endToEndEncryption": "", + "@endToEndEncryption": {}, + "notificationsEnabledForThisAccount": "", + "@notificationsEnabledForThisAccount": { + "type": "text", + "placeholders": {} + }, + "deleteMessage": "", + "@deleteMessage": { + "type": "text", + "placeholders": {} + }, + "visibilityOfTheChatHistory": "", + "@visibilityOfTheChatHistory": { + "type": "text", + "placeholders": {} + }, + "setTheme": "", + "@setTheme": {}, + "changeTheHomeserver": "", + "@changeTheHomeserver": { + "type": "text", + "placeholders": {} + }, + "youJoinedTheChat": "", + "@youJoinedTheChat": {}, + "wallpaper": "", + "@wallpaper": { + "type": "text", + "placeholders": {} + }, + "openVideoCamera": "", + "@openVideoCamera": { + "type": "text", + "placeholders": {} + }, + "play": "", + "@play": { + "type": "text", + "placeholders": { + "fileName": {} + } + }, + "chatBackupDescription": "", + "@chatBackupDescription": { + "type": "text", + "placeholders": {} + }, + "changeDeviceName": "", + "@changeDeviceName": { + "type": "text", + "placeholders": {} + }, + "lastSeenLongTimeAgo": "", + "@lastSeenLongTimeAgo": { + "type": "text", + "placeholders": {} + }, + "passwordForgotten": "", + "@passwordForgotten": { + "type": "text", + "placeholders": {} + }, + "statusExampleMessage": "", + "@statusExampleMessage": { + "type": "text", + "placeholders": {} + }, + "thisUserHasNotPostedAnythingYet": "", + "@thisUserHasNotPostedAnythingYet": {}, + "security": "", + "@security": { + "type": "text", + "placeholders": {} + }, + "markAsRead": "", + "@markAsRead": {}, + "sendAudio": "", + "@sendAudio": { + "type": "text", + "placeholders": {} + }, + "widgetName": "", + "@widgetName": {}, + "sentASticker": "", + "@sentASticker": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "errorAddingWidget": "", + "@errorAddingWidget": {}, + "commandHint_dm": "", + "@commandHint_dm": { + "type": "text", + "description": "Usage hint for the command /dm" + }, + "commandHint_hug": "", + "@commandHint_hug": {}, + "replace": "", + "@replace": {}, + "reject": "", + "@reject": { + "type": "text", + "placeholders": {} + }, + "editBlockedServers": "", + "@editBlockedServers": { + "type": "text", + "placeholders": {} + }, + "oopsPushError": "", + "@oopsPushError": { + "type": "text", + "placeholders": {} + }, + "youUnbannedUser": "", + "@youUnbannedUser": { + "placeholders": { + "user": {} + } + }, + "deactivateAccountWarning": "", + "@deactivateAccountWarning": { + "type": "text", + "placeholders": {} + }, + "archive": "", + "@archive": { + "type": "text", + "placeholders": {} + }, + "joinedTheChat": "", + "@joinedTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "visibleForEveryone": "", + "@visibleForEveryone": { + "type": "text", + "placeholders": {} + }, + "pleaseEnter4Digits": "", + "@pleaseEnter4Digits": { + "type": "text", + "placeholders": {} + }, + "newSpace": "", + "@newSpace": {}, + "changePassword": "", + "@changePassword": { + "type": "text", + "placeholders": {} + }, + "devices": "", + "@devices": { + "type": "text", + "placeholders": {} + }, + "accept": "", + "@accept": { + "type": "text", + "placeholders": {} + }, + "unknownEvent": "", + "@unknownEvent": { + "type": "text", + "placeholders": { + "type": {} + } + }, + "emojis": "", + "@emojis": {}, + "signUp": "", + "@signUp": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourPin": "", + "@pleaseEnterYourPin": { + "type": "text", + "placeholders": {} + }, + "pleaseChoose": "", + "@pleaseChoose": { + "type": "text", + "placeholders": {} + }, + "share": "", + "@share": { + "type": "text", + "placeholders": {} + }, + "commandHint_googly": "", + "@commandHint_googly": {}, + "pleaseTryAgainLaterOrChooseDifferentServer": "", + "@pleaseTryAgainLaterOrChooseDifferentServer": {}, + "createGroup": "", + "@createGroup": {}, + "changeYourAvatar": "", + "@changeYourAvatar": { + "type": "text", + "placeholders": {} + }, + "sendImage": "", + "@sendImage": { + "type": "text", + "placeholders": {} + }, + "hydrateTorLong": "", + "@hydrateTorLong": {}, + "time": "", + "@time": {}, + "enterYourHomeserver": "", + "@enterYourHomeserver": { + "type": "text", + "placeholders": {} + }, + "botMessages": "", + "@botMessages": { + "type": "text", + "placeholders": {} + }, + "contentHasBeenReported": "", + "@contentHasBeenReported": { + "type": "text", + "placeholders": {} + }, + "custom": "", + "@custom": {}, + "noBackupWarning": "", + "@noBackupWarning": {}, + "fromJoining": "", + "@fromJoining": { + "type": "text", + "placeholders": {} + }, + "verify": "", + "@verify": { + "type": "text", + "placeholders": {} + }, + "sendVideo": "", + "@sendVideo": { + "type": "text", + "placeholders": {} + }, + "editWidgets": "", + "@editWidgets": {}, + "storeInSecureStorageDescription": "", + "@storeInSecureStorageDescription": {}, + "openChat": "", + "@openChat": {}, + "kickUserDescription": "", + "@kickUserDescription": {}, + "sendAMessage": "", + "@sendAMessage": { + "type": "text", + "placeholders": {} + }, + "pin": "", + "@pin": { + "type": "text", + "placeholders": {} + }, + "importNow": "", + "@importNow": {}, + "deleteAccount": "", + "@deleteAccount": { + "type": "text", + "placeholders": {} + }, + "setInvitationLink": "", + "@setInvitationLink": { + "type": "text", + "placeholders": {} + }, + "pinMessage": "", + "@pinMessage": {}, + "muteChat": "", + "@muteChat": { + "type": "text", + "placeholders": {} + }, + "invite": "", + "@invite": {}, + "enableMultiAccounts": "", + "@enableMultiAccounts": {}, + "chooseAUsername": "", + "@chooseAUsername": { + "type": "text", + "placeholders": {} + }, + "anyoneCanJoin": "", + "@anyoneCanJoin": { + "type": "text", + "placeholders": {} + }, + "emotePacks": "", + "@emotePacks": { + "type": "text", + "placeholders": {} + }, + "makeSureTheIdentifierIsValid": "", + "@makeSureTheIdentifierIsValid": { + "type": "text", + "placeholders": {} + }, + "continueWith": "", + "@continueWith": {}, + "indexedDbErrorTitle": "", + "@indexedDbErrorTitle": {}, + "pleaseChooseAUsername": "", + "@pleaseChooseAUsername": { + "type": "text", + "placeholders": {} + }, + "endedTheCall": "", + "@endedTheCall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "unsupportedAndroidVersionLong": "", + "@unsupportedAndroidVersionLong": {}, + "storeSecurlyOnThisDevice": "", + "@storeSecurlyOnThisDevice": {}, + "ok": "", + "@ok": { + "type": "text", + "placeholders": {} + }, + "passwordsDoNotMatch": "", + "@passwordsDoNotMatch": {}, + "sharedTheLocation": "", + "@sharedTheLocation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "unbanFromChat": "", + "@unbanFromChat": { + "type": "text", + "placeholders": {} + }, + "iUnderstand": "", + "@iUnderstand": {}, + "screenSharingDetail": "", + "@screenSharingDetail": {}, + "changedTheDisplaynameTo": "", + "@changedTheDisplaynameTo": { + "type": "text", + "placeholders": { + "username": {}, + "displayname": {} + } + }, + "unreadChats": "", + "@unreadChats": { + "type": "text", + "placeholders": { + "unreadCount": {} + } + }, + "pleaseEnterAMatrixIdentifier": "", + "@pleaseEnterAMatrixIdentifier": { + "type": "text", + "placeholders": {} + }, + "pickImage": "", + "@pickImage": { + "type": "text", + "placeholders": {} + }, + "withTheseAddressesRecoveryDescription": "", + "@withTheseAddressesRecoveryDescription": { + "type": "text", + "placeholders": {} + }, + "placeCall": "", + "@placeCall": {}, + "noGoogleServicesWarning": "", + "@noGoogleServicesWarning": { + "type": "text", + "placeholders": {} + }, + "extremeOffensive": "", + "@extremeOffensive": { + "type": "text", + "placeholders": {} + } +} diff --git a/assets/l10n/intl_pt_BR.arb b/assets/l10n/intl_pt_BR.arb index af0dab535..4a4ce685b 100644 --- a/assets/l10n/intl_pt_BR.arb +++ b/assets/l10n/intl_pt_BR.arb @@ -2476,5 +2476,185 @@ "exportEmotePack": "Exportar pacote de Emotes como .zip", "@exportEmotePack": {}, "replace": "Substituir", - "@replace": {} + "@replace": {}, + "jumpToLastReadMessage": "", + "@jumpToLastReadMessage": {}, + "reportErrorDescription": "", + "@reportErrorDescription": {}, + "setColorTheme": "", + "@setColorTheme": {}, + "banUserDescription": "", + "@banUserDescription": {}, + "requests": "", + "@requests": {}, + "removeDevicesDescription": "", + "@removeDevicesDescription": {}, + "tryAgain": "", + "@tryAgain": {}, + "unbanUserDescription": "", + "@unbanUserDescription": {}, + "todoLists": "", + "@todoLists": {}, + "messagesStyle": "", + "@messagesStyle": {}, + "newSpaceDescription": "", + "@newSpaceDescription": {}, + "chatDescription": "", + "@chatDescription": {}, + "encryptThisChat": "", + "@encryptThisChat": {}, + "reopenChat": "", + "@reopenChat": {}, + "editTodo": "", + "@editTodo": {}, + "pushNotificationsNotAvailable": "", + "@pushNotificationsNotAvailable": {}, + "invalidServerName": "", + "@invalidServerName": {}, + "chatPermissions": "", + "@chatPermissions": {}, + "signInWithPassword": "", + "@signInWithPassword": {}, + "pleaseAddATitle": "", + "@pleaseAddATitle": {}, + "makeAdminDescription": "", + "@makeAdminDescription": {}, + "setChatDescription": "", + "@setChatDescription": {}, + "noOtherDevicesFound": "", + "@noOtherDevicesFound": {}, + "redactedBy": "", + "@redactedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "signInWith": "", + "@signInWith": { + "type": "text", + "placeholders": { + "provider": {} + } + }, + "fileIsTooBigForServer": "", + "@fileIsTooBigForServer": {}, + "noTodosYet": "", + "@noTodosYet": {}, + "readUpToHere": "", + "@readUpToHere": {}, + "optionalRedactReason": "", + "@optionalRedactReason": {}, + "archiveRoomDescription": "", + "@archiveRoomDescription": {}, + "letsStart": "", + "@letsStart": {}, + "inviteContactToGroupQuestion": "", + "@inviteContactToGroupQuestion": {}, + "redactedByBecause": "", + "@redactedByBecause": { + "type": "text", + "placeholders": { + "username": {}, + "reason": {} + } + }, + "fileHasBeenSavedAt": "", + "@fileHasBeenSavedAt": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "anyoneCanKnock": "", + "@anyoneCanKnock": {}, + "redactMessageDescription": "", + "@redactMessageDescription": {}, + "invalidInput": "", + "@invalidInput": {}, + "todosUnencrypted": "", + "@todosUnencrypted": {}, + "report": "", + "@report": {}, + "addChatDescription": "", + "@addChatDescription": {}, + "hasKnocked": "", + "@hasKnocked": { + "placeholders": { + "user": {} + } + }, + "openLinkInBrowser": "", + "@openLinkInBrowser": {}, + "disableEncryptionWarning": "", + "@disableEncryptionWarning": {}, + "directChat": "", + "@directChat": {}, + "noOneCanJoin": "", + "@noOneCanJoin": {}, + "wrongPinEntered": "", + "@wrongPinEntered": { + "type": "text", + "placeholders": { + "seconds": {} + } + }, + "inviteGroupChat": "", + "@inviteGroupChat": {}, + "invitePrivateChat": "", + "@invitePrivateChat": {}, + "wasDirectChatDisplayName": "", + "@wasDirectChatDisplayName": { + "type": "text", + "placeholders": { + "oldDisplayName": {} + } + }, + "noChatDescriptionYet": "", + "@noChatDescriptionYet": {}, + "newTodo": "", + "@newTodo": {}, + "learnMore": "", + "@learnMore": {}, + "chatDescriptionHasBeenChanged": "", + "@chatDescriptionHasBeenChanged": {}, + "todoListChangedError": "", + "@todoListChangedError": {}, + "enterInviteLinkOrMatrixId": "", + "@enterInviteLinkOrMatrixId": {}, + "roomUpgradeDescription": "", + "@roomUpgradeDescription": {}, + "pleaseEnterANumber": "", + "@pleaseEnterANumber": {}, + "profileNotFound": "", + "@profileNotFound": {}, + "jump": "", + "@jump": {}, + "sorryThatsNotPossible": "", + "@sorryThatsNotPossible": {}, + "shareInviteLink": "", + "@shareInviteLink": {}, + "deviceKeys": "", + "@deviceKeys": {}, + "emoteKeyboardNoRecents": "", + "@emoteKeyboardNoRecents": { + "type": "text", + "placeholders": {} + }, + "endToEndEncryption": "", + "@endToEndEncryption": {}, + "setTheme": "", + "@setTheme": {}, + "pleaseTryAgainLaterOrChooseDifferentServer": "", + "@pleaseTryAgainLaterOrChooseDifferentServer": {}, + "createGroup": "", + "@createGroup": {}, + "noBackupWarning": "", + "@noBackupWarning": {}, + "kickUserDescription": "", + "@kickUserDescription": {}, + "invite": "", + "@invite": {}, + "continueWith": "", + "@continueWith": {} } diff --git a/assets/l10n/intl_pt_PT.arb b/assets/l10n/intl_pt_PT.arb index cd99918f7..8ce67b83f 100644 --- a/assets/l10n/intl_pt_PT.arb +++ b/assets/l10n/intl_pt_PT.arb @@ -1,1688 +1,2647 @@ { - "passwordsDoNotMatch": "As palavras-passe não correspondem!", - "@passwordsDoNotMatch": {}, - "pleaseEnterValidEmail": "Por favor, insere um endereço de correio eletrónico válido.", - "@pleaseEnterValidEmail": {}, - "repeatPassword": "Repete a palavra-passe", - "@repeatPassword": {}, - "pleaseChooseAtLeastChars": "Por favor, usa no mínimo {min} caracteres.", - "@pleaseChooseAtLeastChars": { - "type": "text", - "placeholders": { - "min": {} - } - }, - "about": "Acerca de", - "@about": { - "type": "text", - "placeholders": {} - }, - "accept": "Aceitar", - "@accept": { - "type": "text", - "placeholders": {} - }, - "acceptedTheInvitation": "{username} aceitou o convite", - "@acceptedTheInvitation": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "account": "Conta", - "@account": { - "type": "text", - "placeholders": {} - }, - "activatedEndToEndEncryption": "{username} ativou encriptação ponta-a-ponta", - "@activatedEndToEndEncryption": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "addEmail": "Adicionar correio eletrónico", - "@addEmail": { - "type": "text", - "placeholders": {} - }, - "addGroupDescription": "Adicionar descrição de grupo", - "@addGroupDescription": { - "type": "text", - "placeholders": {} - }, - "addToSpace": "Adicionar ao espaço", - "@addToSpace": {}, - "admin": "Admin", - "@admin": { - "type": "text", - "placeholders": {} - }, - "alias": "alcunha", - "@alias": { - "type": "text", - "placeholders": {} - }, - "all": "Todos(as)", - "@all": { - "type": "text", - "placeholders": {} - }, - "allChats": "Todas as conversas", - "@allChats": { - "type": "text", - "placeholders": {} - }, - "answeredTheCall": "{senderName} atendeu a chamada", - "@answeredTheCall": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "anyoneCanJoin": "Qualquer pessoa pode entrar", - "@anyoneCanJoin": { - "type": "text", - "placeholders": {} - }, - "archive": "Arquivo", - "@archive": { - "type": "text", - "placeholders": {} - }, - "areGuestsAllowedToJoin": "Todos os visitantes podem entrar", - "@areGuestsAllowedToJoin": { - "type": "text", - "placeholders": {} - }, - "areYouSure": "Tens a certeza?", - "@areYouSure": { - "type": "text", - "placeholders": {} - }, - "areYouSureYouWantToLogout": "Tens a certeza que queres sair?", - "@areYouSureYouWantToLogout": { - "type": "text", - "placeholders": {} - }, - "askSSSSSign": "Para poderes assinar a outra pessoa, por favor, insere a tua senha de armazenamento seguro ou a chave de recuperação.", - "@askSSSSSign": { - "type": "text", - "placeholders": {} - }, - "askVerificationRequest": "Aceitar este pedido de verificação de {username}?", - "@askVerificationRequest": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "autoplayImages": "Automaticamente reproduzir autocolantes e emotes animados", - "@autoplayImages": { - "type": "text", - "placeholder": {} - }, - "sendOnEnter": "Enviar com Enter", - "@sendOnEnter": {}, - "badServerVersionsException": "O servidor suporta as versões Spec:\n{serverVersions}\nMas esta aplicação apenas suporta {suportedVersions}", - "@badServerVersionsException": { - "type": "text", - "placeholders": { - "serverVersions": {}, - "supportedVersions": {} - } - }, - "badServerLoginTypesException": "O servidor suporta os tipos de início de sessão:\n{serverVersions}\nMas esta aplicação apenas suporta:\n{suportedVersions}", - "@badServerLoginTypesException": { - "type": "text", - "placeholders": { - "serverVersions": {}, - "supportedVersions": {} - } - }, - "banFromChat": "Banir da conversa", - "@banFromChat": { - "type": "text", - "placeholders": {} - }, - "banned": "Banido(a)", - "@banned": { - "type": "text", - "placeholders": {} - }, - "bannedUser": "{username} baniu {targetName}", - "@bannedUser": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "blockDevice": "Bloquear dispositivo", - "@blockDevice": { - "type": "text", - "placeholders": {} - }, - "blocked": "Bloqueado", - "@blocked": { - "type": "text", - "placeholders": {} - }, - "botMessages": "Mensagens de robôs", - "@botMessages": { - "type": "text", - "placeholders": {} - }, - "cancel": "Cancelar", - "@cancel": { - "type": "text", - "placeholders": {} - }, - "cantOpenUri": "Não é possível abrir o URI {uri}", - "@cantOpenUri": { - "type": "text", - "placeholders": { - "uri": {} - } - }, - "changeDeviceName": "Alterar nome do dispositivo", - "@changeDeviceName": { - "type": "text", - "placeholders": {} - }, - "changedTheChatPermissions": "{username} alterou as permissões da conversa", - "@changedTheChatPermissions": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheDisplaynameTo": "{username} alterou o seu nome para: '{displayname}'", - "@changedTheDisplaynameTo": { - "type": "text", - "placeholders": { - "username": {}, - "displayname": {} - } - }, - "changedTheGuestAccessRulesTo": "{username} alterou as regras de acesso de visitantes para: {rules}", - "@changedTheGuestAccessRulesTo": { - "type": "text", - "placeholders": { - "username": {}, - "rules": {} - } - }, - "changedTheJoinRules": "{username} alterou as regras de entrada", - "@changedTheJoinRules": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheJoinRulesTo": "{username} alterou as regras de entrada para: {joinRules}", - "@changedTheJoinRulesTo": { - "type": "text", - "placeholders": { - "username": {}, - "joinRules": {} - } - }, - "changedTheProfileAvatar": "{username} alterou o seu avatar", - "@changedTheProfileAvatar": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheRoomAliases": "{username} alterou as alcunhas da sala", - "@changedTheRoomAliases": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheRoomInvitationLink": "{username} alterou a ligação de convite", - "@changedTheRoomInvitationLink": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changePassword": "Alterar palavra-passe", - "@changePassword": { - "type": "text", - "placeholders": {} - }, - "changeTheHomeserver": "Alterar o servidor", - "@changeTheHomeserver": { - "type": "text", - "placeholders": {} - }, - "changeTheme": "Alterar o teu estilo", - "@changeTheme": { - "type": "text", - "placeholders": {} - }, - "changeTheNameOfTheGroup": "Alterar o nome do grupo", - "@changeTheNameOfTheGroup": { - "type": "text", - "placeholders": {} - }, - "changeWallpaper": "Alterar o fundo", - "@changeWallpaper": { - "type": "text", - "placeholders": {} - }, - "changeYourAvatar": "Alterar o teu avatar", - "@changeYourAvatar": { - "type": "text", - "placeholders": {} - }, - "channelCorruptedDecryptError": "A encriptação foi corrompida", - "@channelCorruptedDecryptError": { - "type": "text", - "placeholders": {} - }, - "chat": "Conversa", - "@chat": { - "type": "text", - "placeholders": {} - }, - "yourChatBackupHasBeenSetUp": "A cópia de segurança foi configurada.", - "@yourChatBackupHasBeenSetUp": {}, - "chatBackup": "Cópia de segurança de conversas", - "@chatBackup": { - "type": "text", - "placeholders": {} - }, - "chatBackupDescription": "A tuas mensagens antigas estão protegidas com uma chave de recuperação. Por favor, certifica-te que não a perdes.", - "@chatBackupDescription": { - "type": "text", - "placeholders": {} - }, - "chatDetails": "Detalhes de conversa", - "@chatDetails": { - "type": "text", - "placeholders": {} - }, - "chatHasBeenAddedToThisSpace": "A conversa foi adicionada a este espaço", - "@chatHasBeenAddedToThisSpace": {}, - "chats": "Conversas", - "@chats": { - "type": "text", - "placeholders": {} - }, - "chooseAStrongPassword": "Escolhe uma palavra-passe forte", - "@chooseAStrongPassword": { - "type": "text", - "placeholders": {} - }, - "chooseAUsername": "Escolhe um nome de utilizador", - "@chooseAUsername": { - "type": "text", - "placeholders": {} - }, - "clearArchive": "Limpar arquivo", - "@clearArchive": {}, - "close": "Fechar", - "@close": { - "type": "text", - "placeholders": {} - }, - "commandHint_ban": "Banir o utilizador dado desta sala", - "@commandHint_ban": { - "type": "text", - "description": "Usage hint for the command /ban" - }, - "commandHint_html": "Enviar texto formatado com HTML", - "@commandHint_html": { - "type": "text", - "description": "Usage hint for the command /html" - }, - "commandHint_invite": "Convidar o utilizador dado a esta sala", - "@commandHint_invite": { - "type": "text", - "description": "Usage hint for the command /invite" - }, - "commandHint_join": "Entrar na sala dada", - "@commandHint_join": { - "type": "text", - "description": "Usage hint for the command /join" - }, - "commandHint_kick": "Remover o utilizador dado desta sala", - "@commandHint_kick": { - "type": "text", - "description": "Usage hint for the command /kick" - }, - "commandHint_leave": "Sair desta sala", - "@commandHint_leave": { - "type": "text", - "description": "Usage hint for the command /leave" - }, - "commandHint_me": "Descreve-te", - "@commandHint_me": { - "type": "text", - "description": "Usage hint for the command /me" - }, - "commandHint_myroomavatar": "Definir a tua imagem para esta sala (por mxc-uri)", - "@commandHint_myroomavatar": { - "type": "text", - "description": "Usage hint for the command /myroomavatar" - }, - "commandHint_myroomnick": "Definir o teu nome para esta sala", - "@commandHint_myroomnick": { - "type": "text", - "description": "Usage hint for the command /myroomnick" - }, - "commandHint_op": "Definir o nível de poder do utilizador dado (por omissão: 50)", - "@commandHint_op": { - "type": "text", - "description": "Usage hint for the command /op" - }, - "commandHint_plain": "Enviar texto não formatado", - "@commandHint_plain": { - "type": "text", - "description": "Usage hint for the command /plain" - }, - "commandHint_react": "Enviar respostas como reações", - "@commandHint_react": { - "type": "text", - "description": "Usage hint for the command /react" - }, - "commandHint_send": "Enviar texto", - "@commandHint_send": { - "type": "text", - "description": "Usage hint for the command /send" - }, - "commandHint_unban": "Perdoar o utilizador dado", - "@commandHint_unban": { - "type": "text", - "description": "Usage hint for the command /unban" - }, - "commandInvalid": "Comando inválido", - "@commandInvalid": { - "type": "text" - }, - "commandMissing": "{command} não é um comando.", - "@commandMissing": { - "type": "text", - "placeholders": { - "command": {} - }, - "description": "State that {command} is not a valid /command." - }, - "compareEmojiMatch": "Compara e certifica-te que os emojis que se seguem correspondem aos do outro dispositivo:", - "@compareEmojiMatch": { - "type": "text", - "placeholders": {} - }, - "compareNumbersMatch": "Compara e certifica-te que os números que se seguem correspondem aos do outro dispositivo:", - "@compareNumbersMatch": { - "type": "text", - "placeholders": {} - }, - "configureChat": "Configurar conversa", - "@configureChat": { - "type": "text", - "placeholders": {} - }, - "confirm": "Confirmar", - "@confirm": { - "type": "text", - "placeholders": {} - }, - "connect": "Ligar", - "@connect": { - "type": "text", - "placeholders": {} - }, - "contactHasBeenInvitedToTheGroup": "O contacto foi convidado para o grupo", - "@contactHasBeenInvitedToTheGroup": { - "type": "text", - "placeholders": {} - }, - "containsDisplayName": "Contém nome de exibição", - "@containsDisplayName": { - "type": "text", - "placeholders": {} - }, - "containsUserName": "Contém nome de utilizador", - "@containsUserName": { - "type": "text", - "placeholders": {} - }, - "contentHasBeenReported": "O conteúdo foi denunciado aos admins do servidor", - "@contentHasBeenReported": { - "type": "text", - "placeholders": {} - }, - "copiedToClipboard": "Copiado para a área de transferência", - "@copiedToClipboard": { - "type": "text", - "placeholders": {} - }, - "copy": "Copiar", - "@copy": { - "type": "text", - "placeholders": {} - }, - "copyToClipboard": "Copiar para a área de transferência", - "@copyToClipboard": { - "type": "text", - "placeholders": {} - }, - "couldNotDecryptMessage": "Não foi possível desencriptar mensagem: {error}", - "@couldNotDecryptMessage": { - "type": "text", - "placeholders": { - "error": {} - } - }, - "countParticipants": "{count} participantes", - "@countParticipants": { - "type": "text", - "placeholders": { - "count": {} - } - }, - "create": "Criar", - "@create": { - "type": "text", - "placeholders": {} - }, - "createdTheChat": "{username} criou a conversa", - "@createdTheChat": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "createNewGroup": "Criar novo grupo", - "@createNewGroup": { - "type": "text", - "placeholders": {} - }, - "createNewSpace": "Novo espaço", - "@createNewSpace": { - "type": "text", - "placeholders": {} - }, - "currentlyActive": "Ativo(a) agora", - "@currentlyActive": { - "type": "text", - "placeholders": {} - }, - "darkTheme": "Escuro", - "@darkTheme": { - "type": "text", - "placeholders": {} - }, - "dateAndTimeOfDay": "{date} às {timeOfDay}", - "@dateAndTimeOfDay": { - "type": "text", - "placeholders": { - "date": {}, - "timeOfDay": {} - } - }, - "dateWithoutYear": "{day}-{month}", - "@dateWithoutYear": { - "type": "text", - "placeholders": { - "month": {}, - "day": {} - } - }, - "dateWithYear": "{day}-{month}-{year}", - "@dateWithYear": { - "type": "text", - "placeholders": { - "year": {}, - "month": {}, - "day": {} - } - }, - "deactivateAccountWarning": "Isto irá desativar a tua conta. Não é reversível! Tens a certeza?", - "@deactivateAccountWarning": { - "type": "text", - "placeholders": {} - }, - "defaultPermissionLevel": "Nível de permissão normal", - "@defaultPermissionLevel": { - "type": "text", - "placeholders": {} - }, - "delete": "Eliminar", - "@delete": { - "type": "text", - "placeholders": {} - }, - "deleteAccount": "Eliminar conta", - "@deleteAccount": { - "type": "text", - "placeholders": {} - }, - "deleteMessage": "Eliminar mensagem", - "@deleteMessage": { - "type": "text", - "placeholders": {} - }, - "deny": "Recusar", - "@deny": { - "type": "text", - "placeholders": {} - }, - "device": "Dispositivo", - "@device": { - "type": "text", - "placeholders": {} - }, - "deviceId": "ID de dispositivo", - "@deviceId": { - "type": "text", - "placeholders": {} - }, - "devices": "Dispositivos", - "@devices": { - "type": "text", - "placeholders": {} - }, - "directChats": "Conversas diretas", - "@directChats": { - "type": "text", - "placeholders": {} - }, - "displaynameHasBeenChanged": "Nome de exibição alterado", - "@displaynameHasBeenChanged": { - "type": "text", - "placeholders": {} - }, - "downloadFile": "Descarregar ficheiro", - "@downloadFile": { - "type": "text", - "placeholders": {} - }, - "edit": "Editar", - "@edit": { - "type": "text", - "placeholders": {} - }, - "editBlockedServers": "Editar servidores bloqueados", - "@editBlockedServers": { - "type": "text", - "placeholders": {} - }, - "editChatPermissions": "Editar permissões de conversa", - "@editChatPermissions": { - "type": "text", - "placeholders": {} - }, - "editDisplayname": "Editar nome de exibição", - "@editDisplayname": { - "type": "text", - "placeholders": {} - }, - "editRoomAliases": "Editar alcunhas da sala", - "@editRoomAliases": { - "type": "text", - "placeholders": {} - }, - "editRoomAvatar": "Editar avatar da sala", - "@editRoomAvatar": { - "type": "text", - "placeholders": {} - }, - "emoteExists": "Emote já existente!", - "@emoteExists": { - "type": "text", - "placeholders": {} - }, - "emoteInvalid": "Código de emote inválido!", - "@emoteInvalid": { - "type": "text", - "placeholders": {} - }, - "emotePacks": "Pacotes de emotes da sala", - "@emotePacks": { - "type": "text", - "placeholders": {} - }, - "emoteSettings": "Configurações de emotes", - "@emoteSettings": { - "type": "text", - "placeholders": {} - }, - "emoteShortcode": "Código do emote", - "@emoteShortcode": { - "type": "text", - "placeholders": {} - }, - "emoteWarnNeedToPick": "Precisas de escolher um código de emote e uma imagem!", - "@emoteWarnNeedToPick": { - "type": "text", - "placeholders": {} - }, - "emptyChat": "Conversa vazia", - "@emptyChat": { - "type": "text", - "placeholders": {} - }, - "enableEmotesGlobally": "Ativar pacote de emotes globalmente", - "@enableEmotesGlobally": { - "type": "text", - "placeholders": {} - }, - "enableEncryption": "Ativar encriptação", - "@enableEncryption": { - "type": "text", - "placeholders": {} - }, - "enableEncryptionWarning": "Nunca mais poderás desativar a encriptação. Tens a certeza?", - "@enableEncryptionWarning": { - "type": "text", - "placeholders": {} - }, - "encrypted": "Encriptada", - "@encrypted": { - "type": "text", - "placeholders": {} - }, - "encryption": "Encriptação", - "@encryption": { - "type": "text", - "placeholders": {} - }, - "encryptionNotEnabled": "A encriptação não está ativada", - "@encryptionNotEnabled": { - "type": "text", - "placeholders": {} - }, - "endedTheCall": "{senderName} terminou a chamada", - "@endedTheCall": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "enterAGroupName": "Insere o nome do grupo", - "@enterAGroupName": { - "type": "text", - "placeholders": {} - }, - "enterAnEmailAddress": "Insere um endereço de correio eletrónico", - "@enterAnEmailAddress": { - "type": "text", - "placeholders": {} - }, - "enterASpacepName": "Insere o nome do espaço", - "@enterASpacepName": {}, - "homeserver": "Servidor", - "@homeserver": {}, - "enterYourHomeserver": "Insere o teu servidor", - "@enterYourHomeserver": { - "type": "text", - "placeholders": {} - }, - "errorObtainingLocation": "Erro ao obter localização: {error}", - "@errorObtainingLocation": { - "type": "text", - "placeholders": { - "error": {} - } - }, - "everythingReady": "Tudo a postos!", - "@everythingReady": { - "type": "text", - "placeholders": {} - }, - "extremeOffensive": "Extremamente ofensivo", - "@extremeOffensive": { - "type": "text", - "placeholders": {} - }, - "fileName": "Nome do ficheiro", - "@fileName": { - "type": "text", - "placeholders": {} - }, - "fluffychat": "FluffyChat", - "@fluffychat": { - "type": "text", - "placeholders": {} - }, - "fontSize": "Tamanho da letra", - "@fontSize": { - "type": "text", - "placeholders": {} - }, - "forward": "Reencaminhar", - "@forward": { - "type": "text", - "placeholders": {} - }, - "goToTheNewRoom": "Ir para a nova sala", - "@goToTheNewRoom": { - "type": "text", - "placeholders": {} - }, - "group": "Grupo", - "@group": { - "type": "text", - "placeholders": {} - }, - "groupDescription": "Descrição do grupo", - "@groupDescription": { - "type": "text", - "placeholders": {} - }, - "groupDescriptionHasBeenChanged": "Descrição do grupo alterada", - "@groupDescriptionHasBeenChanged": { - "type": "text", - "placeholders": {} - }, - "groupIsPublic": "O grupo é público", - "@groupIsPublic": { - "type": "text", - "placeholders": {} - }, - "groups": "Grupos", - "@groups": { - "type": "text", - "placeholders": {} - }, - "groupWith": "Grupo com {displayname}", - "@groupWith": { - "type": "text", - "placeholders": { - "displayname": {} - } - }, - "guestsAreForbidden": "São proibidos visitantes", - "@guestsAreForbidden": { - "type": "text", - "placeholders": {} - }, - "guestsCanJoin": "Podem entrar visitantes", - "@guestsCanJoin": { - "type": "text", - "placeholders": {} - }, - "hasWithdrawnTheInvitationFor": "{username} revogou o convite para {targetName}", - "@hasWithdrawnTheInvitationFor": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "help": "Ajuda", - "@help": { - "type": "text", - "placeholders": {} - }, - "hideRedactedEvents": "Esconder eventos eliminados", - "@hideRedactedEvents": { - "type": "text", - "placeholders": {} - }, - "hideUnknownEvents": "Esconder eventos desconhecidos", - "@hideUnknownEvents": { - "type": "text", - "placeholders": {} - }, - "howOffensiveIsThisContent": "Quão ofensivo é este conteúdo?", - "@howOffensiveIsThisContent": { - "type": "text", - "placeholders": {} - }, - "id": "ID", - "@id": { - "type": "text", - "placeholders": {} - }, - "identity": "Identidade", - "@identity": { - "type": "text", - "placeholders": {} - }, - "ignore": "Ignorar", - "@ignore": { - "type": "text", - "placeholders": {} - }, - "ignoredUsers": "Utilizadores ignorados", - "@ignoredUsers": { - "type": "text", - "placeholders": {} - }, - "ignoreListDescription": "Podes ignorar utilizadores que te incomodem. Não irás poder receber quaisquer mensagens ou convites para salas de utilizadores na tua lista pessoal de ignorados.", - "@ignoreListDescription": { - "type": "text", - "placeholders": {} - }, - "ignoreUsername": "Nome do utilizador a ignorar", - "@ignoreUsername": { - "type": "text", - "placeholders": {} - }, - "iHaveClickedOnLink": "Eu cliquei na ligação", - "@iHaveClickedOnLink": { - "type": "text", - "placeholders": {} - }, - "incorrectPassphraseOrKey": "Senha ou chave de recuperação incorretos", - "@incorrectPassphraseOrKey": { - "type": "text", - "placeholders": {} - }, - "inoffensive": "Inofensivo", - "@inoffensive": { - "type": "text", - "placeholders": {} - }, - "inviteContact": "Convidar contacto", - "@inviteContact": { - "type": "text", - "placeholders": {} - }, - "inviteContactToGroup": "Convidar contacto para {groupName}", - "@inviteContactToGroup": { - "type": "text", - "placeholders": { - "groupName": {} - } - }, - "invited": "Convidado(a)", - "@invited": { - "type": "text", - "placeholders": {} - }, - "invitedUser": "{username} convidou {targetName}", - "@invitedUser": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "invitedUsersOnly": "Utilizadores(as) convidados(as) apenas", - "@invitedUsersOnly": { - "type": "text", - "placeholders": {} - }, - "inviteForMe": "Convite para mim", - "@inviteForMe": { - "type": "text", - "placeholders": {} - }, - "inviteText": "{username} convidou-te para o FluffyChat.\n1. Instala o FluffyChat: https://fluffychat.im\n2. Regista-te ou inicia sessão.\n3. Abre a ligação de convite: {link}", - "@inviteText": { - "type": "text", - "placeholders": { - "username": {}, - "link": {} - } - }, - "isTyping": "está a escrever…", - "@isTyping": { - "type": "text", - "placeholders": {} - }, - "joinedTheChat": "{username} entrou na conversa", - "@joinedTheChat": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "joinRoom": "Entrar na sala", - "@joinRoom": { - "type": "text", - "placeholders": {} - }, - "kicked": "{username} expulsou {targetName}", - "@kicked": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "kickedAndBanned": "{username} expulsou e baniu {targetName}", - "@kickedAndBanned": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "kickFromChat": "Expulsar da conversa", - "@kickFromChat": { - "type": "text", - "placeholders": {} - }, - "lastActiveAgo": "Ativo(a) pela última vez: {localizedTimeShort}", - "@lastActiveAgo": { - "type": "text", - "placeholders": { - "localizedTimeShort": {} - } - }, - "lastSeenLongTimeAgo": "Visto(a) há muito tempo", - "@lastSeenLongTimeAgo": { - "type": "text", - "placeholders": {} - }, - "leave": "Sair", - "@leave": { - "type": "text", - "placeholders": {} - }, - "leftTheChat": "Saiu da conversa", - "@leftTheChat": { - "type": "text", - "placeholders": {} - }, - "license": "Licença", - "@license": { - "type": "text", - "placeholders": {} - }, - "lightTheme": "Claro", - "@lightTheme": { - "type": "text", - "placeholders": {} - }, - "loadCountMoreParticipants": "Carregar mais {count} participantes", - "@loadCountMoreParticipants": { - "type": "text", - "placeholders": { - "count": {} - } - }, - "loadingPleaseWait": "A carregar... Por favor aguarde.", - "@loadingPleaseWait": { - "type": "text", - "placeholders": {} - }, - "loadMore": "Carregar mais…", - "@loadMore": { - "type": "text", - "placeholders": {} - }, - "locationDisabledNotice": "Os serviços de localização estão desativados. Por favor, ativa-os para poder partilhar a sua localização.", - "@locationDisabledNotice": { - "type": "text", - "placeholders": {} - }, - "locationPermissionDeniedNotice": "Permissão de localização recusada. Por favor, concede permissão para poderes partilhar a tua posição.", - "@locationPermissionDeniedNotice": { - "type": "text", - "placeholders": {} - }, - "login": "Entrar", - "@login": { - "type": "text", - "placeholders": {} - }, - "logInTo": "Entrar em {homeserver}", - "@logInTo": { - "type": "text", - "placeholders": { - "homeserver": {} - } - }, - "loginWithOneClick": "Entrar com um clique", - "@loginWithOneClick": {}, - "logout": "Sair", - "@logout": { - "type": "text", - "placeholders": {} - }, - "makeSureTheIdentifierIsValid": "Certifica-te que o identificador é válido", - "@makeSureTheIdentifierIsValid": { - "type": "text", - "placeholders": {} - }, - "memberChanges": "Alterações de membros", - "@memberChanges": { - "type": "text", - "placeholders": {} - }, - "mention": "Mencionar", - "@mention": { - "type": "text", - "placeholders": {} - }, - "messages": "Mensagens", - "@messages": { - "type": "text", - "placeholders": {} - }, - "messageWillBeRemovedWarning": "A mensagem será eliminada para todos os participantes", - "@messageWillBeRemovedWarning": { - "type": "text", - "placeholders": {} - }, - "moderator": "Moderador", - "@moderator": { - "type": "text", - "placeholders": {} - }, - "muteChat": "Silenciar conversa", - "@muteChat": { - "type": "text", - "placeholders": {} - }, - "needPantalaimonWarning": "Por favor,", - "@needPantalaimonWarning": { - "type": "text", - "placeholders": {} - }, - "newChat": "Nova conversa", - "@newChat": { - "type": "text", - "placeholders": {} - }, - "newMessageInFluffyChat": "Nova mensagem no FluffyChat", - "@newMessageInFluffyChat": { - "type": "text", - "placeholders": {} - }, - "newVerificationRequest": "Novo pedido de verificação!", - "@newVerificationRequest": { - "type": "text", - "placeholders": {} - }, - "next": "Próximo", - "@next": { - "type": "text", - "placeholders": {} - }, - "no": "Não", - "@no": { - "type": "text", - "placeholders": {} - }, - "noConnectionToTheServer": "Nenhuma ligação ao servidor", - "@noConnectionToTheServer": { - "type": "text", - "placeholders": {} - }, - "noEmotesFound": "Nenhuns emotes encontrados. 😕", - "@noEmotesFound": { - "type": "text", - "placeholders": {} - }, - "noEncryptionForPublicRooms": "Só podes ativar a encriptação quando a sala não for publicamente acessível.", - "@noEncryptionForPublicRooms": { - "type": "text", - "placeholders": {} - }, - "noGoogleServicesWarning": "Parece que não tens nenhuns serviços da Google no seu telemóvel. É uma boa decisão para a sua privacidade! Para receber notificações instantâneas no FluffyChat, recomendamos que uses https://microg.org/ ou https://unifiedpush.org/.", - "@noGoogleServicesWarning": { - "type": "text", - "placeholders": {} - }, - "noMatrixServer": "{server1} não é um servidor Matrix, usar {server2}?", - "@noMatrixServer": { - "type": "text", - "placeholders": { - "server1": {}, - "server2": {} - } - }, - "shareYourInviteLink": "Partilhar a ligação de convite", - "@shareYourInviteLink": {}, - "none": "Nenhum", - "@none": { - "type": "text", - "placeholders": {} - }, - "changedTheChatAvatar": "{username} alterou o avatar da conversa", - "@changedTheChatAvatar": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheHistoryVisibilityTo": "{username} alterou a visibilidade do histórico para: {rules}", - "@changedTheHistoryVisibilityTo": { - "type": "text", - "placeholders": { - "username": {}, - "rules": {} - } - }, - "changedTheChatDescriptionTo": "{username} alterou a descrição da conversa para: '{description}'", - "@changedTheChatDescriptionTo": { - "type": "text", - "placeholders": { - "username": {}, - "description": {} - } - }, - "changedTheChatNameTo": "{username} alterou o nome da conversa para: '{chatname}'", - "@changedTheChatNameTo": { - "type": "text", - "placeholders": { - "username": {}, - "chatname": {} - } - }, - "changedTheGuestAccessRules": "{username} alterou as regras de acesso de visitantes", - "@changedTheGuestAccessRules": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheHistoryVisibility": "{username} alterou a visibilidade do histórico", - "@changedTheHistoryVisibility": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sendAMessage": "Enviar a mensagem", - "@sendAMessage": { - "type": "text", - "placeholders": {} - }, - "sendAudio": "Enviar áudio", - "@sendAudio": { - "type": "text", - "placeholders": {} - }, - "sendAsText": "Enviar como texto", - "@sendAsText": { - "type": "text" - }, - "send": "Enviar", - "@send": { - "type": "text", - "placeholders": {} - }, - "appLock": "Bloqueio da aplicação", - "@appLock": { - "type": "text", - "placeholders": {} - }, - "noPasswordRecoveryDescription": "Ainda não adicionaste uma forma de recuperar a tua palavra-passe.", - "@noPasswordRecoveryDescription": { - "type": "text", - "placeholders": {} - }, - "noPermission": "Sem permissão", - "@noPermission": { - "type": "text", - "placeholders": {} - }, - "noRoomsFound": "Não foram encontradas nenhumas salas…", - "@noRoomsFound": { - "type": "text", - "placeholders": {} - }, - "notifications": "Notificações", - "@notifications": { - "type": "text", - "placeholders": {} - }, - "notificationsEnabledForThisAccount": "Notificações ativadas para esta conta", - "@notificationsEnabledForThisAccount": { - "type": "text", - "placeholders": {} - }, - "numUsersTyping": "Estão {count} utilizadores(as) a escrever…", - "@numUsersTyping": { - "type": "text", - "placeholders": { - "count": {} - } - }, - "obtainingLocation": "A obter localização…", - "@obtainingLocation": { - "type": "text", - "placeholders": {} - }, - "offensive": "Offensivo", - "@offensive": { - "type": "text", - "placeholders": {} - }, - "offline": "Offline", - "@offline": { - "type": "text", - "placeholders": {} - }, - "ok": "ok", - "@ok": { - "type": "text", - "placeholders": {} - }, - "online": "Online", - "@online": { - "type": "text", - "placeholders": {} - }, - "onlineKeyBackupEnabled": "A cópia de segurança online de chaves está ativada", - "@onlineKeyBackupEnabled": { - "type": "text", - "placeholders": {} - }, - "oopsPushError": "Ups! Infelizmente, ocorreu um erro ao configurar as notificações instantâneas.", - "@oopsPushError": { - "type": "text", - "placeholders": {} - }, - "oopsSomethingWentWrong": "Ups, algo correu mal…", - "@oopsSomethingWentWrong": { - "type": "text", - "placeholders": {} - }, - "openAppToReadMessages": "Abrir aplicação para ler mensagens", - "@openAppToReadMessages": { - "type": "text", - "placeholders": {} - }, - "openCamera": "Abrir câmara", - "@openCamera": { - "type": "text", - "placeholders": {} - }, - "oneClientLoggedOut": "Um dos teus clientes terminou sessão", - "@oneClientLoggedOut": {}, - "addAccount": "Adicionar conta", - "@addAccount": {}, - "editBundlesForAccount": "Editar pacotes para esta conta", - "@editBundlesForAccount": {}, - "addToBundle": "Adicionar ao pacote", - "@addToBundle": {}, - "removeFromBundle": "Remover deste pacote", - "@removeFromBundle": {}, - "bundleName": "Nome do pacote", - "@bundleName": {}, - "enableMultiAccounts": "(BETA) Ativar múltiplas contas neste dispositivo", - "@enableMultiAccounts": {}, - "openInMaps": "Abrir nos mapas", - "@openInMaps": { - "type": "text", - "placeholders": {} - }, - "link": "Ligação", - "@link": {}, - "serverRequiresEmail": "Este servidor precisa de validar o teu endereço de correio eletrónico para o registo.", - "@serverRequiresEmail": {}, - "optionalGroupName": "(Opcional) Nome do grupo", - "@optionalGroupName": { - "type": "text", - "placeholders": {} - }, - "or": "Ou", - "@or": { - "type": "text", - "placeholders": {} - }, - "participant": "Participante", - "@participant": { - "type": "text", - "placeholders": {} - }, - "passphraseOrKey": "senha ou chave de recuperação", - "@passphraseOrKey": { - "type": "text", - "placeholders": {} - }, - "password": "Palavra-passe", - "@password": { - "type": "text", - "placeholders": {} - }, - "passwordForgotten": "Palavra-passe esquecida", - "@passwordForgotten": { - "type": "text", - "placeholders": {} - }, - "passwordHasBeenChanged": "A palavra-passe foi alterada", - "@passwordHasBeenChanged": { - "type": "text", - "placeholders": {} - }, - "passwordRecovery": "Recuperação de palavra-passe", - "@passwordRecovery": { - "type": "text", - "placeholders": {} - }, - "people": "Pessoas", - "@people": { - "type": "text", - "placeholders": {} - }, - "pickImage": "Escolher uma imagem", - "@pickImage": { - "type": "text", - "placeholders": {} - }, - "pin": "Afixar", - "@pin": { - "type": "text", - "placeholders": {} - }, - "play": "Reproduzir {fileName}", - "@play": { - "type": "text", - "placeholders": { - "fileName": {} - } - }, - "pleaseChoose": "Por favor, escolhe", - "@pleaseChoose": { - "type": "text", - "placeholders": {} - }, - "pleaseChooseAPasscode": "Por favor, escolhe um código-passe", - "@pleaseChooseAPasscode": { - "type": "text", - "placeholders": {} - }, - "pleaseChooseAUsername": "Por favor, escolhe um nome de utilizador", - "@pleaseChooseAUsername": { - "type": "text", - "placeholders": {} - }, - "pleaseClickOnLink": "Por favor, clica na ligação no correio eletrónico e depois continua.", - "@pleaseClickOnLink": { - "type": "text", - "placeholders": {} - }, - "pleaseEnter4Digits": "Por favor, insere 4 dígitos ou deixa vazio para desativar o bloqueio da aplicação.", - "@pleaseEnter4Digits": { - "type": "text", - "placeholders": {} - }, - "pleaseEnterAMatrixIdentifier": "Por favor, insere um ID Matrix.", - "@pleaseEnterAMatrixIdentifier": { - "type": "text", - "placeholders": {} - }, - "pleaseEnterYourPassword": "Por favor, insere a tua palavra-passe", - "@pleaseEnterYourPassword": { - "type": "text", - "placeholders": {} - }, - "pleaseEnterYourPin": "Por favor, insere o teu código", - "@pleaseEnterYourPin": { - "type": "text", - "placeholders": {} - }, - "pleaseEnterYourUsername": "Por favor, insere o teu nome de utilizador", - "@pleaseEnterYourUsername": { - "type": "text", - "placeholders": {} - }, - "pleaseFollowInstructionsOnWeb": "Por favor, segue as instruções no website e clica em \"Seguinte\".", - "@pleaseFollowInstructionsOnWeb": { - "type": "text", - "placeholders": {} - }, - "privacy": "Privacidade", - "@privacy": { - "type": "text", - "placeholders": {} - }, - "publicRooms": "Salas públicas", - "@publicRooms": { - "type": "text", - "placeholders": {} - }, - "reason": "Razão", - "@reason": { - "type": "text", - "placeholders": {} - }, - "redactedAnEvent": "{username} eliminou um evento", - "@redactedAnEvent": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "recording": "A gravar", - "@recording": { - "type": "text", - "placeholders": {} - }, - "redactMessage": "Eliminar mensagem", - "@redactMessage": { - "type": "text", - "placeholders": {} - }, - "register": "Registar", - "@register": { - "type": "text", - "placeholders": {} - }, - "reject": "Rejeitar", - "@reject": { - "type": "text", - "placeholders": {} - }, - "rejectedTheInvitation": "{username} rejeitou o convite", - "@rejectedTheInvitation": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "rejoin": "Reentrar", - "@rejoin": { - "type": "text", - "placeholders": {} - }, - "remove": "Remover", - "@remove": { - "type": "text", - "placeholders": {} - }, - "removeAllOtherDevices": "Remover todos os outros dispositivos", - "@removeAllOtherDevices": { - "type": "text", - "placeholders": {} - }, - "removedBy": "Removido por {username}", - "@removedBy": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "removeDevice": "Remover dispositivo", - "@removeDevice": { - "type": "text", - "placeholders": {} - }, - "unbanFromChat": "Perdoar nesta conversa", - "@unbanFromChat": { - "type": "text", - "placeholders": {} - }, - "removeYourAvatar": "Remover o teu avatar", - "@removeYourAvatar": { - "type": "text", - "placeholders": {} - }, - "renderRichContent": "Exibir conteúdo de mensagem rico", - "@renderRichContent": { - "type": "text", - "placeholders": {} - }, - "replaceRoomWithNewerVersion": "Substituir sala com versão mais recente", - "@replaceRoomWithNewerVersion": { - "type": "text", - "placeholders": {} - }, - "reply": "Responder", - "@reply": { - "type": "text", - "placeholders": {} - }, - "reportMessage": "Reportar mensagem", - "@reportMessage": { - "type": "text", - "placeholders": {} - }, - "requestPermission": "Pedir permissão", - "@requestPermission": { - "type": "text", - "placeholders": {} - }, - "roomHasBeenUpgraded": "A sala foi atualizada", - "@roomHasBeenUpgraded": { - "type": "text", - "placeholders": {} - }, - "roomVersion": "Versão da sala", - "@roomVersion": { - "type": "text", - "placeholders": {} - }, - "saveFile": "Guardar ficheiro", - "@saveFile": { - "type": "text", - "placeholders": {} - }, - "search": "Procurar", - "@search": { - "type": "text", - "placeholders": {} - }, - "security": "Segurança", - "@security": { - "type": "text", - "placeholders": {} - }, - "seenByUser": "Visto por {username}", - "@seenByUser": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "seenByUserAndUser": "Visto por {username} e por {username2}", - "@seenByUserAndUser": { - "type": "text", - "placeholders": { - "username": {}, - "username2": {} - } - }, - "sendFile": "Enviar ficheiro", - "@sendFile": { - "type": "text", - "placeholders": {} - }, - "sendImage": "Enviar imagem", - "@sendImage": { - "type": "text", - "placeholders": {} - }, - "sendMessages": "Enviar mensagens", - "@sendMessages": { - "type": "text", - "placeholders": {} - }, - "sendOriginal": "Enviar original", - "@sendOriginal": { - "type": "text", - "placeholders": {} - }, - "sendSticker": "Enviar autocolante", - "@sendSticker": { - "type": "text", - "placeholders": {} - }, - "sendVideo": "Enviar vídeo", - "@sendVideo": { - "type": "text", - "placeholders": {} - }, - "sentAFile": "{username} enviar um ficheiro", - "@sentAFile": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sentAnAudio": "{username} enviar um áudio", - "@sentAnAudio": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sentAPicture": "{username} enviar uma imagem", - "@sentAPicture": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sentASticker": "{username} enviou um autocolante", - "@sentASticker": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sentAVideo": "{username} enviou um vídeo", - "@sentAVideo": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "updateAvailable": "Atualização do FluffyChat disponível", - "@updateAvailable": {}, - "updateNow": "Iniciar atualização me segundo plano", - "@updateNow": {}, - "commandHint_clearcache": "Limpar cache", - "@commandHint_clearcache": { - "type": "text", - "description": "Usage hint for the command /clearcache" - }, - "commandHint_create": "Criar uma conversa de grupo vazia\nUsa --no-encryption para desativar a encriptação", - "@commandHint_create": { - "type": "text", - "description": "Usage hint for the command /create" - }, - "commandHint_discardsession": "Descartar sessão", - "@commandHint_discardsession": { - "type": "text", - "description": "Usage hint for the command /discardsession" - }, - "commandHint_dm": "Iniciar uma conversa direta\nUsa --no-encryption para desativar a encriptação", - "@commandHint_dm": { - "type": "text", - "description": "Usage hint for the command /dm" - }, - "dehydrate": "Exportar sessão e limpar dispositivo", - "@dehydrate": {}, - "dehydrateWarning": "Esta ação não pode ser revertida. Assegura-te que guardas bem a cópia de segurança.", - "@dehydrateWarning": {}, - "hydrateTorLong": "Exportaste a tua sessão na última vez que estiveste no TOR? Importa-a rapidamente e continua a conversar.", - "@hydrateTorLong": {}, - "dehydrateTor": "Utilizadores do TOR: Exportar sessão", - "@dehydrateTor": {}, - "hydrate": "Restaurar a partir de cópia de segurança", - "@hydrate": {}, - "bubbleSize": "Tamanho da bolha", - "@bubbleSize": { - "type": "text", - "placeholders": {} - }, - "hydrateTor": "Utilizadores do TOR: Importar sessão", - "@hydrateTor": {}, - "dehydrateTorLong": "Para utilizadores do TOR, é recomendado exportar a sessão antes de fechar a janela.", - "@dehydrateTorLong": {} -} \ No newline at end of file + "passwordsDoNotMatch": "As palavras-passe não correspondem!", + "@passwordsDoNotMatch": {}, + "pleaseEnterValidEmail": "Por favor, insere um endereço de correio eletrónico válido.", + "@pleaseEnterValidEmail": {}, + "repeatPassword": "Repete a palavra-passe", + "@repeatPassword": {}, + "pleaseChooseAtLeastChars": "Por favor, usa no mínimo {min} caracteres.", + "@pleaseChooseAtLeastChars": { + "type": "text", + "placeholders": { + "min": {} + } + }, + "about": "Acerca de", + "@about": { + "type": "text", + "placeholders": {} + }, + "accept": "Aceitar", + "@accept": { + "type": "text", + "placeholders": {} + }, + "acceptedTheInvitation": "{username} aceitou o convite", + "@acceptedTheInvitation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "account": "Conta", + "@account": { + "type": "text", + "placeholders": {} + }, + "activatedEndToEndEncryption": "{username} ativou encriptação ponta-a-ponta", + "@activatedEndToEndEncryption": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "addEmail": "Adicionar correio eletrónico", + "@addEmail": { + "type": "text", + "placeholders": {} + }, + "addGroupDescription": "Adicionar descrição de grupo", + "@addGroupDescription": { + "type": "text", + "placeholders": {} + }, + "addToSpace": "Adicionar ao espaço", + "@addToSpace": {}, + "admin": "Admin", + "@admin": { + "type": "text", + "placeholders": {} + }, + "alias": "alcunha", + "@alias": { + "type": "text", + "placeholders": {} + }, + "all": "Todos(as)", + "@all": { + "type": "text", + "placeholders": {} + }, + "allChats": "Todas as conversas", + "@allChats": { + "type": "text", + "placeholders": {} + }, + "answeredTheCall": "{senderName} atendeu a chamada", + "@answeredTheCall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "anyoneCanJoin": "Qualquer pessoa pode entrar", + "@anyoneCanJoin": { + "type": "text", + "placeholders": {} + }, + "archive": "Arquivo", + "@archive": { + "type": "text", + "placeholders": {} + }, + "areGuestsAllowedToJoin": "Todos os visitantes podem entrar", + "@areGuestsAllowedToJoin": { + "type": "text", + "placeholders": {} + }, + "areYouSure": "Tens a certeza?", + "@areYouSure": { + "type": "text", + "placeholders": {} + }, + "areYouSureYouWantToLogout": "Tens a certeza que queres sair?", + "@areYouSureYouWantToLogout": { + "type": "text", + "placeholders": {} + }, + "askSSSSSign": "Para poderes assinar a outra pessoa, por favor, insere a tua senha de armazenamento seguro ou a chave de recuperação.", + "@askSSSSSign": { + "type": "text", + "placeholders": {} + }, + "askVerificationRequest": "Aceitar este pedido de verificação de {username}?", + "@askVerificationRequest": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "autoplayImages": "Automaticamente reproduzir autocolantes e emotes animados", + "@autoplayImages": { + "type": "text", + "placeholder": {} + }, + "sendOnEnter": "Enviar com Enter", + "@sendOnEnter": {}, + "badServerVersionsException": "O servidor suporta as versões Spec:\n{serverVersions}\nMas esta aplicação apenas suporta {suportedVersions}", + "@badServerVersionsException": { + "type": "text", + "placeholders": { + "serverVersions": {}, + "supportedVersions": {} + } + }, + "badServerLoginTypesException": "O servidor suporta os tipos de início de sessão:\n{serverVersions}\nMas esta aplicação apenas suporta:\n{suportedVersions}", + "@badServerLoginTypesException": { + "type": "text", + "placeholders": { + "serverVersions": {}, + "supportedVersions": {} + } + }, + "banFromChat": "Banir da conversa", + "@banFromChat": { + "type": "text", + "placeholders": {} + }, + "banned": "Banido(a)", + "@banned": { + "type": "text", + "placeholders": {} + }, + "bannedUser": "{username} baniu {targetName}", + "@bannedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "blockDevice": "Bloquear dispositivo", + "@blockDevice": { + "type": "text", + "placeholders": {} + }, + "blocked": "Bloqueado", + "@blocked": { + "type": "text", + "placeholders": {} + }, + "botMessages": "Mensagens de robôs", + "@botMessages": { + "type": "text", + "placeholders": {} + }, + "cancel": "Cancelar", + "@cancel": { + "type": "text", + "placeholders": {} + }, + "cantOpenUri": "Não é possível abrir o URI {uri}", + "@cantOpenUri": { + "type": "text", + "placeholders": { + "uri": {} + } + }, + "changeDeviceName": "Alterar nome do dispositivo", + "@changeDeviceName": { + "type": "text", + "placeholders": {} + }, + "changedTheChatPermissions": "{username} alterou as permissões da conversa", + "@changedTheChatPermissions": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheDisplaynameTo": "{username} alterou o seu nome para: '{displayname}'", + "@changedTheDisplaynameTo": { + "type": "text", + "placeholders": { + "username": {}, + "displayname": {} + } + }, + "changedTheGuestAccessRulesTo": "{username} alterou as regras de acesso de visitantes para: {rules}", + "@changedTheGuestAccessRulesTo": { + "type": "text", + "placeholders": { + "username": {}, + "rules": {} + } + }, + "changedTheJoinRules": "{username} alterou as regras de entrada", + "@changedTheJoinRules": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheJoinRulesTo": "{username} alterou as regras de entrada para: {joinRules}", + "@changedTheJoinRulesTo": { + "type": "text", + "placeholders": { + "username": {}, + "joinRules": {} + } + }, + "changedTheProfileAvatar": "{username} alterou o seu avatar", + "@changedTheProfileAvatar": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheRoomAliases": "{username} alterou as alcunhas da sala", + "@changedTheRoomAliases": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheRoomInvitationLink": "{username} alterou a ligação de convite", + "@changedTheRoomInvitationLink": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changePassword": "Alterar palavra-passe", + "@changePassword": { + "type": "text", + "placeholders": {} + }, + "changeTheHomeserver": "Alterar o servidor", + "@changeTheHomeserver": { + "type": "text", + "placeholders": {} + }, + "changeTheme": "Alterar o teu estilo", + "@changeTheme": { + "type": "text", + "placeholders": {} + }, + "changeTheNameOfTheGroup": "Alterar o nome do grupo", + "@changeTheNameOfTheGroup": { + "type": "text", + "placeholders": {} + }, + "changeWallpaper": "Alterar o fundo", + "@changeWallpaper": { + "type": "text", + "placeholders": {} + }, + "changeYourAvatar": "Alterar o teu avatar", + "@changeYourAvatar": { + "type": "text", + "placeholders": {} + }, + "channelCorruptedDecryptError": "A encriptação foi corrompida", + "@channelCorruptedDecryptError": { + "type": "text", + "placeholders": {} + }, + "chat": "Conversa", + "@chat": { + "type": "text", + "placeholders": {} + }, + "yourChatBackupHasBeenSetUp": "A cópia de segurança foi configurada.", + "@yourChatBackupHasBeenSetUp": {}, + "chatBackup": "Cópia de segurança de conversas", + "@chatBackup": { + "type": "text", + "placeholders": {} + }, + "chatBackupDescription": "A tuas mensagens antigas estão protegidas com uma chave de recuperação. Por favor, certifica-te que não a perdes.", + "@chatBackupDescription": { + "type": "text", + "placeholders": {} + }, + "chatDetails": "Detalhes de conversa", + "@chatDetails": { + "type": "text", + "placeholders": {} + }, + "chatHasBeenAddedToThisSpace": "A conversa foi adicionada a este espaço", + "@chatHasBeenAddedToThisSpace": {}, + "chats": "Conversas", + "@chats": { + "type": "text", + "placeholders": {} + }, + "chooseAStrongPassword": "Escolhe uma palavra-passe forte", + "@chooseAStrongPassword": { + "type": "text", + "placeholders": {} + }, + "chooseAUsername": "Escolhe um nome de utilizador", + "@chooseAUsername": { + "type": "text", + "placeholders": {} + }, + "clearArchive": "Limpar arquivo", + "@clearArchive": {}, + "close": "Fechar", + "@close": { + "type": "text", + "placeholders": {} + }, + "commandHint_ban": "Banir o utilizador dado desta sala", + "@commandHint_ban": { + "type": "text", + "description": "Usage hint for the command /ban" + }, + "commandHint_html": "Enviar texto formatado com HTML", + "@commandHint_html": { + "type": "text", + "description": "Usage hint for the command /html" + }, + "commandHint_invite": "Convidar o utilizador dado a esta sala", + "@commandHint_invite": { + "type": "text", + "description": "Usage hint for the command /invite" + }, + "commandHint_join": "Entrar na sala dada", + "@commandHint_join": { + "type": "text", + "description": "Usage hint for the command /join" + }, + "commandHint_kick": "Remover o utilizador dado desta sala", + "@commandHint_kick": { + "type": "text", + "description": "Usage hint for the command /kick" + }, + "commandHint_leave": "Sair desta sala", + "@commandHint_leave": { + "type": "text", + "description": "Usage hint for the command /leave" + }, + "commandHint_me": "Descreve-te", + "@commandHint_me": { + "type": "text", + "description": "Usage hint for the command /me" + }, + "commandHint_myroomavatar": "Definir a tua imagem para esta sala (por mxc-uri)", + "@commandHint_myroomavatar": { + "type": "text", + "description": "Usage hint for the command /myroomavatar" + }, + "commandHint_myroomnick": "Definir o teu nome para esta sala", + "@commandHint_myroomnick": { + "type": "text", + "description": "Usage hint for the command /myroomnick" + }, + "commandHint_op": "Definir o nível de poder do utilizador dado (por omissão: 50)", + "@commandHint_op": { + "type": "text", + "description": "Usage hint for the command /op" + }, + "commandHint_plain": "Enviar texto não formatado", + "@commandHint_plain": { + "type": "text", + "description": "Usage hint for the command /plain" + }, + "commandHint_react": "Enviar respostas como reações", + "@commandHint_react": { + "type": "text", + "description": "Usage hint for the command /react" + }, + "commandHint_send": "Enviar texto", + "@commandHint_send": { + "type": "text", + "description": "Usage hint for the command /send" + }, + "commandHint_unban": "Perdoar o utilizador dado", + "@commandHint_unban": { + "type": "text", + "description": "Usage hint for the command /unban" + }, + "commandInvalid": "Comando inválido", + "@commandInvalid": { + "type": "text" + }, + "commandMissing": "{command} não é um comando.", + "@commandMissing": { + "type": "text", + "placeholders": { + "command": {} + }, + "description": "State that {command} is not a valid /command." + }, + "compareEmojiMatch": "Compara e certifica-te que os emojis que se seguem correspondem aos do outro dispositivo:", + "@compareEmojiMatch": { + "type": "text", + "placeholders": {} + }, + "compareNumbersMatch": "Compara e certifica-te que os números que se seguem correspondem aos do outro dispositivo:", + "@compareNumbersMatch": { + "type": "text", + "placeholders": {} + }, + "configureChat": "Configurar conversa", + "@configureChat": { + "type": "text", + "placeholders": {} + }, + "confirm": "Confirmar", + "@confirm": { + "type": "text", + "placeholders": {} + }, + "connect": "Ligar", + "@connect": { + "type": "text", + "placeholders": {} + }, + "contactHasBeenInvitedToTheGroup": "O contacto foi convidado para o grupo", + "@contactHasBeenInvitedToTheGroup": { + "type": "text", + "placeholders": {} + }, + "containsDisplayName": "Contém nome de exibição", + "@containsDisplayName": { + "type": "text", + "placeholders": {} + }, + "containsUserName": "Contém nome de utilizador", + "@containsUserName": { + "type": "text", + "placeholders": {} + }, + "contentHasBeenReported": "O conteúdo foi denunciado aos admins do servidor", + "@contentHasBeenReported": { + "type": "text", + "placeholders": {} + }, + "copiedToClipboard": "Copiado para a área de transferência", + "@copiedToClipboard": { + "type": "text", + "placeholders": {} + }, + "copy": "Copiar", + "@copy": { + "type": "text", + "placeholders": {} + }, + "copyToClipboard": "Copiar para a área de transferência", + "@copyToClipboard": { + "type": "text", + "placeholders": {} + }, + "couldNotDecryptMessage": "Não foi possível desencriptar mensagem: {error}", + "@couldNotDecryptMessage": { + "type": "text", + "placeholders": { + "error": {} + } + }, + "countParticipants": "{count} participantes", + "@countParticipants": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "create": "Criar", + "@create": { + "type": "text", + "placeholders": {} + }, + "createdTheChat": "{username} criou a conversa", + "@createdTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "createNewGroup": "Criar novo grupo", + "@createNewGroup": { + "type": "text", + "placeholders": {} + }, + "createNewSpace": "Novo espaço", + "@createNewSpace": { + "type": "text", + "placeholders": {} + }, + "currentlyActive": "Ativo(a) agora", + "@currentlyActive": { + "type": "text", + "placeholders": {} + }, + "darkTheme": "Escuro", + "@darkTheme": { + "type": "text", + "placeholders": {} + }, + "dateAndTimeOfDay": "{date} às {timeOfDay}", + "@dateAndTimeOfDay": { + "type": "text", + "placeholders": { + "date": {}, + "timeOfDay": {} + } + }, + "dateWithoutYear": "{day}-{month}", + "@dateWithoutYear": { + "type": "text", + "placeholders": { + "month": {}, + "day": {} + } + }, + "dateWithYear": "{day}-{month}-{year}", + "@dateWithYear": { + "type": "text", + "placeholders": { + "year": {}, + "month": {}, + "day": {} + } + }, + "deactivateAccountWarning": "Isto irá desativar a tua conta. Não é reversível! Tens a certeza?", + "@deactivateAccountWarning": { + "type": "text", + "placeholders": {} + }, + "defaultPermissionLevel": "Nível de permissão normal", + "@defaultPermissionLevel": { + "type": "text", + "placeholders": {} + }, + "delete": "Eliminar", + "@delete": { + "type": "text", + "placeholders": {} + }, + "deleteAccount": "Eliminar conta", + "@deleteAccount": { + "type": "text", + "placeholders": {} + }, + "deleteMessage": "Eliminar mensagem", + "@deleteMessage": { + "type": "text", + "placeholders": {} + }, + "deny": "Recusar", + "@deny": { + "type": "text", + "placeholders": {} + }, + "device": "Dispositivo", + "@device": { + "type": "text", + "placeholders": {} + }, + "deviceId": "ID de dispositivo", + "@deviceId": { + "type": "text", + "placeholders": {} + }, + "devices": "Dispositivos", + "@devices": { + "type": "text", + "placeholders": {} + }, + "directChats": "Conversas diretas", + "@directChats": { + "type": "text", + "placeholders": {} + }, + "displaynameHasBeenChanged": "Nome de exibição alterado", + "@displaynameHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "downloadFile": "Descarregar ficheiro", + "@downloadFile": { + "type": "text", + "placeholders": {} + }, + "edit": "Editar", + "@edit": { + "type": "text", + "placeholders": {} + }, + "editBlockedServers": "Editar servidores bloqueados", + "@editBlockedServers": { + "type": "text", + "placeholders": {} + }, + "editChatPermissions": "Editar permissões de conversa", + "@editChatPermissions": { + "type": "text", + "placeholders": {} + }, + "editDisplayname": "Editar nome de exibição", + "@editDisplayname": { + "type": "text", + "placeholders": {} + }, + "editRoomAliases": "Editar alcunhas da sala", + "@editRoomAliases": { + "type": "text", + "placeholders": {} + }, + "editRoomAvatar": "Editar avatar da sala", + "@editRoomAvatar": { + "type": "text", + "placeholders": {} + }, + "emoteExists": "Emote já existente!", + "@emoteExists": { + "type": "text", + "placeholders": {} + }, + "emoteInvalid": "Código de emote inválido!", + "@emoteInvalid": { + "type": "text", + "placeholders": {} + }, + "emotePacks": "Pacotes de emotes da sala", + "@emotePacks": { + "type": "text", + "placeholders": {} + }, + "emoteSettings": "Configurações de emotes", + "@emoteSettings": { + "type": "text", + "placeholders": {} + }, + "emoteShortcode": "Código do emote", + "@emoteShortcode": { + "type": "text", + "placeholders": {} + }, + "emoteWarnNeedToPick": "Precisas de escolher um código de emote e uma imagem!", + "@emoteWarnNeedToPick": { + "type": "text", + "placeholders": {} + }, + "emptyChat": "Conversa vazia", + "@emptyChat": { + "type": "text", + "placeholders": {} + }, + "enableEmotesGlobally": "Ativar pacote de emotes globalmente", + "@enableEmotesGlobally": { + "type": "text", + "placeholders": {} + }, + "enableEncryption": "Ativar encriptação", + "@enableEncryption": { + "type": "text", + "placeholders": {} + }, + "enableEncryptionWarning": "Nunca mais poderás desativar a encriptação. Tens a certeza?", + "@enableEncryptionWarning": { + "type": "text", + "placeholders": {} + }, + "encrypted": "Encriptada", + "@encrypted": { + "type": "text", + "placeholders": {} + }, + "encryption": "Encriptação", + "@encryption": { + "type": "text", + "placeholders": {} + }, + "encryptionNotEnabled": "A encriptação não está ativada", + "@encryptionNotEnabled": { + "type": "text", + "placeholders": {} + }, + "endedTheCall": "{senderName} terminou a chamada", + "@endedTheCall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "enterAGroupName": "Insere o nome do grupo", + "@enterAGroupName": { + "type": "text", + "placeholders": {} + }, + "enterAnEmailAddress": "Insere um endereço de correio eletrónico", + "@enterAnEmailAddress": { + "type": "text", + "placeholders": {} + }, + "enterASpacepName": "Insere o nome do espaço", + "@enterASpacepName": {}, + "homeserver": "Servidor", + "@homeserver": {}, + "enterYourHomeserver": "Insere o teu servidor", + "@enterYourHomeserver": { + "type": "text", + "placeholders": {} + }, + "errorObtainingLocation": "Erro ao obter localização: {error}", + "@errorObtainingLocation": { + "type": "text", + "placeholders": { + "error": {} + } + }, + "everythingReady": "Tudo a postos!", + "@everythingReady": { + "type": "text", + "placeholders": {} + }, + "extremeOffensive": "Extremamente ofensivo", + "@extremeOffensive": { + "type": "text", + "placeholders": {} + }, + "fileName": "Nome do ficheiro", + "@fileName": { + "type": "text", + "placeholders": {} + }, + "fluffychat": "FluffyChat", + "@fluffychat": { + "type": "text", + "placeholders": {} + }, + "fontSize": "Tamanho da letra", + "@fontSize": { + "type": "text", + "placeholders": {} + }, + "forward": "Reencaminhar", + "@forward": { + "type": "text", + "placeholders": {} + }, + "goToTheNewRoom": "Ir para a nova sala", + "@goToTheNewRoom": { + "type": "text", + "placeholders": {} + }, + "group": "Grupo", + "@group": { + "type": "text", + "placeholders": {} + }, + "groupDescription": "Descrição do grupo", + "@groupDescription": { + "type": "text", + "placeholders": {} + }, + "groupDescriptionHasBeenChanged": "Descrição do grupo alterada", + "@groupDescriptionHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "groupIsPublic": "O grupo é público", + "@groupIsPublic": { + "type": "text", + "placeholders": {} + }, + "groups": "Grupos", + "@groups": { + "type": "text", + "placeholders": {} + }, + "groupWith": "Grupo com {displayname}", + "@groupWith": { + "type": "text", + "placeholders": { + "displayname": {} + } + }, + "guestsAreForbidden": "São proibidos visitantes", + "@guestsAreForbidden": { + "type": "text", + "placeholders": {} + }, + "guestsCanJoin": "Podem entrar visitantes", + "@guestsCanJoin": { + "type": "text", + "placeholders": {} + }, + "hasWithdrawnTheInvitationFor": "{username} revogou o convite para {targetName}", + "@hasWithdrawnTheInvitationFor": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "help": "Ajuda", + "@help": { + "type": "text", + "placeholders": {} + }, + "hideRedactedEvents": "Esconder eventos eliminados", + "@hideRedactedEvents": { + "type": "text", + "placeholders": {} + }, + "hideUnknownEvents": "Esconder eventos desconhecidos", + "@hideUnknownEvents": { + "type": "text", + "placeholders": {} + }, + "howOffensiveIsThisContent": "Quão ofensivo é este conteúdo?", + "@howOffensiveIsThisContent": { + "type": "text", + "placeholders": {} + }, + "id": "ID", + "@id": { + "type": "text", + "placeholders": {} + }, + "identity": "Identidade", + "@identity": { + "type": "text", + "placeholders": {} + }, + "ignore": "Ignorar", + "@ignore": { + "type": "text", + "placeholders": {} + }, + "ignoredUsers": "Utilizadores ignorados", + "@ignoredUsers": { + "type": "text", + "placeholders": {} + }, + "ignoreListDescription": "Podes ignorar utilizadores que te incomodem. Não irás poder receber quaisquer mensagens ou convites para salas de utilizadores na tua lista pessoal de ignorados.", + "@ignoreListDescription": { + "type": "text", + "placeholders": {} + }, + "ignoreUsername": "Nome do utilizador a ignorar", + "@ignoreUsername": { + "type": "text", + "placeholders": {} + }, + "iHaveClickedOnLink": "Eu cliquei na ligação", + "@iHaveClickedOnLink": { + "type": "text", + "placeholders": {} + }, + "incorrectPassphraseOrKey": "Senha ou chave de recuperação incorretos", + "@incorrectPassphraseOrKey": { + "type": "text", + "placeholders": {} + }, + "inoffensive": "Inofensivo", + "@inoffensive": { + "type": "text", + "placeholders": {} + }, + "inviteContact": "Convidar contacto", + "@inviteContact": { + "type": "text", + "placeholders": {} + }, + "inviteContactToGroup": "Convidar contacto para {groupName}", + "@inviteContactToGroup": { + "type": "text", + "placeholders": { + "groupName": {} + } + }, + "invited": "Convidado(a)", + "@invited": { + "type": "text", + "placeholders": {} + }, + "invitedUser": "{username} convidou {targetName}", + "@invitedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "invitedUsersOnly": "Utilizadores(as) convidados(as) apenas", + "@invitedUsersOnly": { + "type": "text", + "placeholders": {} + }, + "inviteForMe": "Convite para mim", + "@inviteForMe": { + "type": "text", + "placeholders": {} + }, + "inviteText": "{username} convidou-te para o FluffyChat.\n1. Instala o FluffyChat: https://fluffychat.im\n2. Regista-te ou inicia sessão.\n3. Abre a ligação de convite: {link}", + "@inviteText": { + "type": "text", + "placeholders": { + "username": {}, + "link": {} + } + }, + "isTyping": "está a escrever…", + "@isTyping": { + "type": "text", + "placeholders": {} + }, + "joinedTheChat": "{username} entrou na conversa", + "@joinedTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "joinRoom": "Entrar na sala", + "@joinRoom": { + "type": "text", + "placeholders": {} + }, + "kicked": "{username} expulsou {targetName}", + "@kicked": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "kickedAndBanned": "{username} expulsou e baniu {targetName}", + "@kickedAndBanned": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "kickFromChat": "Expulsar da conversa", + "@kickFromChat": { + "type": "text", + "placeholders": {} + }, + "lastActiveAgo": "Ativo(a) pela última vez: {localizedTimeShort}", + "@lastActiveAgo": { + "type": "text", + "placeholders": { + "localizedTimeShort": {} + } + }, + "lastSeenLongTimeAgo": "Visto(a) há muito tempo", + "@lastSeenLongTimeAgo": { + "type": "text", + "placeholders": {} + }, + "leave": "Sair", + "@leave": { + "type": "text", + "placeholders": {} + }, + "leftTheChat": "Saiu da conversa", + "@leftTheChat": { + "type": "text", + "placeholders": {} + }, + "license": "Licença", + "@license": { + "type": "text", + "placeholders": {} + }, + "lightTheme": "Claro", + "@lightTheme": { + "type": "text", + "placeholders": {} + }, + "loadCountMoreParticipants": "Carregar mais {count} participantes", + "@loadCountMoreParticipants": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "loadingPleaseWait": "A carregar... Por favor aguarde.", + "@loadingPleaseWait": { + "type": "text", + "placeholders": {} + }, + "loadMore": "Carregar mais…", + "@loadMore": { + "type": "text", + "placeholders": {} + }, + "locationDisabledNotice": "Os serviços de localização estão desativados. Por favor, ativa-os para poder partilhar a sua localização.", + "@locationDisabledNotice": { + "type": "text", + "placeholders": {} + }, + "locationPermissionDeniedNotice": "Permissão de localização recusada. Por favor, concede permissão para poderes partilhar a tua posição.", + "@locationPermissionDeniedNotice": { + "type": "text", + "placeholders": {} + }, + "login": "Entrar", + "@login": { + "type": "text", + "placeholders": {} + }, + "logInTo": "Entrar em {homeserver}", + "@logInTo": { + "type": "text", + "placeholders": { + "homeserver": {} + } + }, + "loginWithOneClick": "Entrar com um clique", + "@loginWithOneClick": {}, + "logout": "Sair", + "@logout": { + "type": "text", + "placeholders": {} + }, + "makeSureTheIdentifierIsValid": "Certifica-te que o identificador é válido", + "@makeSureTheIdentifierIsValid": { + "type": "text", + "placeholders": {} + }, + "memberChanges": "Alterações de membros", + "@memberChanges": { + "type": "text", + "placeholders": {} + }, + "mention": "Mencionar", + "@mention": { + "type": "text", + "placeholders": {} + }, + "messages": "Mensagens", + "@messages": { + "type": "text", + "placeholders": {} + }, + "messageWillBeRemovedWarning": "A mensagem será eliminada para todos os participantes", + "@messageWillBeRemovedWarning": { + "type": "text", + "placeholders": {} + }, + "moderator": "Moderador", + "@moderator": { + "type": "text", + "placeholders": {} + }, + "muteChat": "Silenciar conversa", + "@muteChat": { + "type": "text", + "placeholders": {} + }, + "needPantalaimonWarning": "Por favor,", + "@needPantalaimonWarning": { + "type": "text", + "placeholders": {} + }, + "newChat": "Nova conversa", + "@newChat": { + "type": "text", + "placeholders": {} + }, + "newMessageInFluffyChat": "Nova mensagem no FluffyChat", + "@newMessageInFluffyChat": { + "type": "text", + "placeholders": {} + }, + "newVerificationRequest": "Novo pedido de verificação!", + "@newVerificationRequest": { + "type": "text", + "placeholders": {} + }, + "next": "Próximo", + "@next": { + "type": "text", + "placeholders": {} + }, + "no": "Não", + "@no": { + "type": "text", + "placeholders": {} + }, + "noConnectionToTheServer": "Nenhuma ligação ao servidor", + "@noConnectionToTheServer": { + "type": "text", + "placeholders": {} + }, + "noEmotesFound": "Nenhuns emotes encontrados. 😕", + "@noEmotesFound": { + "type": "text", + "placeholders": {} + }, + "noEncryptionForPublicRooms": "Só podes ativar a encriptação quando a sala não for publicamente acessível.", + "@noEncryptionForPublicRooms": { + "type": "text", + "placeholders": {} + }, + "noGoogleServicesWarning": "Parece que não tens nenhuns serviços da Google no seu telemóvel. É uma boa decisão para a sua privacidade! Para receber notificações instantâneas no FluffyChat, recomendamos que uses https://microg.org/ ou https://unifiedpush.org/.", + "@noGoogleServicesWarning": { + "type": "text", + "placeholders": {} + }, + "noMatrixServer": "{server1} não é um servidor Matrix, usar {server2}?", + "@noMatrixServer": { + "type": "text", + "placeholders": { + "server1": {}, + "server2": {} + } + }, + "shareYourInviteLink": "Partilhar a ligação de convite", + "@shareYourInviteLink": {}, + "none": "Nenhum", + "@none": { + "type": "text", + "placeholders": {} + }, + "changedTheChatAvatar": "{username} alterou o avatar da conversa", + "@changedTheChatAvatar": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheHistoryVisibilityTo": "{username} alterou a visibilidade do histórico para: {rules}", + "@changedTheHistoryVisibilityTo": { + "type": "text", + "placeholders": { + "username": {}, + "rules": {} + } + }, + "changedTheChatDescriptionTo": "{username} alterou a descrição da conversa para: '{description}'", + "@changedTheChatDescriptionTo": { + "type": "text", + "placeholders": { + "username": {}, + "description": {} + } + }, + "changedTheChatNameTo": "{username} alterou o nome da conversa para: '{chatname}'", + "@changedTheChatNameTo": { + "type": "text", + "placeholders": { + "username": {}, + "chatname": {} + } + }, + "changedTheGuestAccessRules": "{username} alterou as regras de acesso de visitantes", + "@changedTheGuestAccessRules": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheHistoryVisibility": "{username} alterou a visibilidade do histórico", + "@changedTheHistoryVisibility": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sendAMessage": "Enviar a mensagem", + "@sendAMessage": { + "type": "text", + "placeholders": {} + }, + "sendAudio": "Enviar áudio", + "@sendAudio": { + "type": "text", + "placeholders": {} + }, + "sendAsText": "Enviar como texto", + "@sendAsText": { + "type": "text" + }, + "send": "Enviar", + "@send": { + "type": "text", + "placeholders": {} + }, + "appLock": "Bloqueio da aplicação", + "@appLock": { + "type": "text", + "placeholders": {} + }, + "noPasswordRecoveryDescription": "Ainda não adicionaste uma forma de recuperar a tua palavra-passe.", + "@noPasswordRecoveryDescription": { + "type": "text", + "placeholders": {} + }, + "noPermission": "Sem permissão", + "@noPermission": { + "type": "text", + "placeholders": {} + }, + "noRoomsFound": "Não foram encontradas nenhumas salas…", + "@noRoomsFound": { + "type": "text", + "placeholders": {} + }, + "notifications": "Notificações", + "@notifications": { + "type": "text", + "placeholders": {} + }, + "notificationsEnabledForThisAccount": "Notificações ativadas para esta conta", + "@notificationsEnabledForThisAccount": { + "type": "text", + "placeholders": {} + }, + "numUsersTyping": "Estão {count} utilizadores(as) a escrever…", + "@numUsersTyping": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "obtainingLocation": "A obter localização…", + "@obtainingLocation": { + "type": "text", + "placeholders": {} + }, + "offensive": "Offensivo", + "@offensive": { + "type": "text", + "placeholders": {} + }, + "offline": "Offline", + "@offline": { + "type": "text", + "placeholders": {} + }, + "ok": "ok", + "@ok": { + "type": "text", + "placeholders": {} + }, + "online": "Online", + "@online": { + "type": "text", + "placeholders": {} + }, + "onlineKeyBackupEnabled": "A cópia de segurança online de chaves está ativada", + "@onlineKeyBackupEnabled": { + "type": "text", + "placeholders": {} + }, + "oopsPushError": "Ups! Infelizmente, ocorreu um erro ao configurar as notificações instantâneas.", + "@oopsPushError": { + "type": "text", + "placeholders": {} + }, + "oopsSomethingWentWrong": "Ups, algo correu mal…", + "@oopsSomethingWentWrong": { + "type": "text", + "placeholders": {} + }, + "openAppToReadMessages": "Abrir aplicação para ler mensagens", + "@openAppToReadMessages": { + "type": "text", + "placeholders": {} + }, + "openCamera": "Abrir câmara", + "@openCamera": { + "type": "text", + "placeholders": {} + }, + "oneClientLoggedOut": "Um dos teus clientes terminou sessão", + "@oneClientLoggedOut": {}, + "addAccount": "Adicionar conta", + "@addAccount": {}, + "editBundlesForAccount": "Editar pacotes para esta conta", + "@editBundlesForAccount": {}, + "addToBundle": "Adicionar ao pacote", + "@addToBundle": {}, + "removeFromBundle": "Remover deste pacote", + "@removeFromBundle": {}, + "bundleName": "Nome do pacote", + "@bundleName": {}, + "enableMultiAccounts": "(BETA) Ativar múltiplas contas neste dispositivo", + "@enableMultiAccounts": {}, + "openInMaps": "Abrir nos mapas", + "@openInMaps": { + "type": "text", + "placeholders": {} + }, + "link": "Ligação", + "@link": {}, + "serverRequiresEmail": "Este servidor precisa de validar o teu endereço de correio eletrónico para o registo.", + "@serverRequiresEmail": {}, + "optionalGroupName": "(Opcional) Nome do grupo", + "@optionalGroupName": { + "type": "text", + "placeholders": {} + }, + "or": "Ou", + "@or": { + "type": "text", + "placeholders": {} + }, + "participant": "Participante", + "@participant": { + "type": "text", + "placeholders": {} + }, + "passphraseOrKey": "senha ou chave de recuperação", + "@passphraseOrKey": { + "type": "text", + "placeholders": {} + }, + "password": "Palavra-passe", + "@password": { + "type": "text", + "placeholders": {} + }, + "passwordForgotten": "Palavra-passe esquecida", + "@passwordForgotten": { + "type": "text", + "placeholders": {} + }, + "passwordHasBeenChanged": "A palavra-passe foi alterada", + "@passwordHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "passwordRecovery": "Recuperação de palavra-passe", + "@passwordRecovery": { + "type": "text", + "placeholders": {} + }, + "people": "Pessoas", + "@people": { + "type": "text", + "placeholders": {} + }, + "pickImage": "Escolher uma imagem", + "@pickImage": { + "type": "text", + "placeholders": {} + }, + "pin": "Afixar", + "@pin": { + "type": "text", + "placeholders": {} + }, + "play": "Reproduzir {fileName}", + "@play": { + "type": "text", + "placeholders": { + "fileName": {} + } + }, + "pleaseChoose": "Por favor, escolhe", + "@pleaseChoose": { + "type": "text", + "placeholders": {} + }, + "pleaseChooseAPasscode": "Por favor, escolhe um código-passe", + "@pleaseChooseAPasscode": { + "type": "text", + "placeholders": {} + }, + "pleaseChooseAUsername": "Por favor, escolhe um nome de utilizador", + "@pleaseChooseAUsername": { + "type": "text", + "placeholders": {} + }, + "pleaseClickOnLink": "Por favor, clica na ligação no correio eletrónico e depois continua.", + "@pleaseClickOnLink": { + "type": "text", + "placeholders": {} + }, + "pleaseEnter4Digits": "Por favor, insere 4 dígitos ou deixa vazio para desativar o bloqueio da aplicação.", + "@pleaseEnter4Digits": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterAMatrixIdentifier": "Por favor, insere um ID Matrix.", + "@pleaseEnterAMatrixIdentifier": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourPassword": "Por favor, insere a tua palavra-passe", + "@pleaseEnterYourPassword": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourPin": "Por favor, insere o teu código", + "@pleaseEnterYourPin": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourUsername": "Por favor, insere o teu nome de utilizador", + "@pleaseEnterYourUsername": { + "type": "text", + "placeholders": {} + }, + "pleaseFollowInstructionsOnWeb": "Por favor, segue as instruções no website e clica em \"Seguinte\".", + "@pleaseFollowInstructionsOnWeb": { + "type": "text", + "placeholders": {} + }, + "privacy": "Privacidade", + "@privacy": { + "type": "text", + "placeholders": {} + }, + "publicRooms": "Salas públicas", + "@publicRooms": { + "type": "text", + "placeholders": {} + }, + "reason": "Razão", + "@reason": { + "type": "text", + "placeholders": {} + }, + "redactedAnEvent": "{username} eliminou um evento", + "@redactedAnEvent": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "recording": "A gravar", + "@recording": { + "type": "text", + "placeholders": {} + }, + "redactMessage": "Eliminar mensagem", + "@redactMessage": { + "type": "text", + "placeholders": {} + }, + "register": "Registar", + "@register": { + "type": "text", + "placeholders": {} + }, + "reject": "Rejeitar", + "@reject": { + "type": "text", + "placeholders": {} + }, + "rejectedTheInvitation": "{username} rejeitou o convite", + "@rejectedTheInvitation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "rejoin": "Reentrar", + "@rejoin": { + "type": "text", + "placeholders": {} + }, + "remove": "Remover", + "@remove": { + "type": "text", + "placeholders": {} + }, + "removeAllOtherDevices": "Remover todos os outros dispositivos", + "@removeAllOtherDevices": { + "type": "text", + "placeholders": {} + }, + "removedBy": "Removido por {username}", + "@removedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "removeDevice": "Remover dispositivo", + "@removeDevice": { + "type": "text", + "placeholders": {} + }, + "unbanFromChat": "Perdoar nesta conversa", + "@unbanFromChat": { + "type": "text", + "placeholders": {} + }, + "removeYourAvatar": "Remover o teu avatar", + "@removeYourAvatar": { + "type": "text", + "placeholders": {} + }, + "renderRichContent": "Exibir conteúdo de mensagem rico", + "@renderRichContent": { + "type": "text", + "placeholders": {} + }, + "replaceRoomWithNewerVersion": "Substituir sala com versão mais recente", + "@replaceRoomWithNewerVersion": { + "type": "text", + "placeholders": {} + }, + "reply": "Responder", + "@reply": { + "type": "text", + "placeholders": {} + }, + "reportMessage": "Reportar mensagem", + "@reportMessage": { + "type": "text", + "placeholders": {} + }, + "requestPermission": "Pedir permissão", + "@requestPermission": { + "type": "text", + "placeholders": {} + }, + "roomHasBeenUpgraded": "A sala foi atualizada", + "@roomHasBeenUpgraded": { + "type": "text", + "placeholders": {} + }, + "roomVersion": "Versão da sala", + "@roomVersion": { + "type": "text", + "placeholders": {} + }, + "saveFile": "Guardar ficheiro", + "@saveFile": { + "type": "text", + "placeholders": {} + }, + "search": "Procurar", + "@search": { + "type": "text", + "placeholders": {} + }, + "security": "Segurança", + "@security": { + "type": "text", + "placeholders": {} + }, + "seenByUser": "Visto por {username}", + "@seenByUser": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "seenByUserAndUser": "Visto por {username} e por {username2}", + "@seenByUserAndUser": { + "type": "text", + "placeholders": { + "username": {}, + "username2": {} + } + }, + "sendFile": "Enviar ficheiro", + "@sendFile": { + "type": "text", + "placeholders": {} + }, + "sendImage": "Enviar imagem", + "@sendImage": { + "type": "text", + "placeholders": {} + }, + "sendMessages": "Enviar mensagens", + "@sendMessages": { + "type": "text", + "placeholders": {} + }, + "sendOriginal": "Enviar original", + "@sendOriginal": { + "type": "text", + "placeholders": {} + }, + "sendSticker": "Enviar autocolante", + "@sendSticker": { + "type": "text", + "placeholders": {} + }, + "sendVideo": "Enviar vídeo", + "@sendVideo": { + "type": "text", + "placeholders": {} + }, + "sentAFile": "{username} enviar um ficheiro", + "@sentAFile": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sentAnAudio": "{username} enviar um áudio", + "@sentAnAudio": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sentAPicture": "{username} enviar uma imagem", + "@sentAPicture": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sentASticker": "{username} enviou um autocolante", + "@sentASticker": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sentAVideo": "{username} enviou um vídeo", + "@sentAVideo": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "updateAvailable": "Atualização do FluffyChat disponível", + "@updateAvailable": {}, + "updateNow": "Iniciar atualização me segundo plano", + "@updateNow": {}, + "commandHint_clearcache": "Limpar cache", + "@commandHint_clearcache": { + "type": "text", + "description": "Usage hint for the command /clearcache" + }, + "commandHint_create": "Criar uma conversa de grupo vazia\nUsa --no-encryption para desativar a encriptação", + "@commandHint_create": { + "type": "text", + "description": "Usage hint for the command /create" + }, + "commandHint_discardsession": "Descartar sessão", + "@commandHint_discardsession": { + "type": "text", + "description": "Usage hint for the command /discardsession" + }, + "commandHint_dm": "Iniciar uma conversa direta\nUsa --no-encryption para desativar a encriptação", + "@commandHint_dm": { + "type": "text", + "description": "Usage hint for the command /dm" + }, + "dehydrate": "Exportar sessão e limpar dispositivo", + "@dehydrate": {}, + "dehydrateWarning": "Esta ação não pode ser revertida. Assegura-te que guardas bem a cópia de segurança.", + "@dehydrateWarning": {}, + "hydrateTorLong": "Exportaste a tua sessão na última vez que estiveste no TOR? Importa-a rapidamente e continua a conversar.", + "@hydrateTorLong": {}, + "dehydrateTor": "Utilizadores do TOR: Exportar sessão", + "@dehydrateTor": {}, + "hydrate": "Restaurar a partir de cópia de segurança", + "@hydrate": {}, + "bubbleSize": "Tamanho da bolha", + "@bubbleSize": { + "type": "text", + "placeholders": {} + }, + "hydrateTor": "Utilizadores do TOR: Importar sessão", + "@hydrateTor": {}, + "dehydrateTorLong": "Para utilizadores do TOR, é recomendado exportar a sessão antes de fechar a janela.", + "@dehydrateTorLong": {}, + "showPassword": "", + "@showPassword": { + "type": "text", + "placeholders": {} + }, + "hugContent": "", + "@hugContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "theyMatch": "", + "@theyMatch": { + "type": "text", + "placeholders": {} + }, + "jumpToLastReadMessage": "", + "@jumpToLastReadMessage": {}, + "allRooms": "", + "@allRooms": { + "type": "text", + "placeholders": {} + }, + "whoCanSeeMyStories": "", + "@whoCanSeeMyStories": {}, + "commandHint_cuddle": "", + "@commandHint_cuddle": {}, + "widgetVideo": "", + "@widgetVideo": {}, + "dismiss": "", + "@dismiss": {}, + "unknownDevice": "", + "@unknownDevice": { + "type": "text", + "placeholders": {} + }, + "reportErrorDescription": "", + "@reportErrorDescription": {}, + "setPermissionsLevel": "", + "@setPermissionsLevel": { + "type": "text", + "placeholders": {} + }, + "unsupportedAndroidVersion": "", + "@unsupportedAndroidVersion": {}, + "widgetJitsi": "", + "@widgetJitsi": {}, + "youAreNoLongerParticipatingInThisChat": "", + "@youAreNoLongerParticipatingInThisChat": { + "type": "text", + "placeholders": {} + }, + "messageType": "", + "@messageType": {}, + "noEmailWarning": "", + "@noEmailWarning": {}, + "indexedDbErrorLong": "", + "@indexedDbErrorLong": {}, + "toggleMuted": "", + "@toggleMuted": { + "type": "text", + "placeholders": {} + }, + "title": "", + "@title": { + "description": "Title for the application", + "type": "text", + "placeholders": {} + }, + "verifySuccess": "", + "@verifySuccess": { + "type": "text", + "placeholders": {} + }, + "startFirstChat": "", + "@startFirstChat": {}, + "callingAccount": "", + "@callingAccount": {}, + "setColorTheme": "", + "@setColorTheme": {}, + "nextAccount": "", + "@nextAccount": {}, + "youAreInvitedToThisChat": "", + "@youAreInvitedToThisChat": { + "type": "text", + "placeholders": {} + }, + "singlesignon": "", + "@singlesignon": { + "type": "text", + "placeholders": {} + }, + "warning": "", + "@warning": { + "type": "text", + "placeholders": {} + }, + "allSpaces": "", + "@allSpaces": {}, + "supposedMxid": "", + "@supposedMxid": { + "type": "text", + "placeholders": { + "mxid": {} + } + }, + "user": "", + "@user": {}, + "videoCall": "", + "@videoCall": { + "type": "text", + "placeholders": {} + }, + "youAcceptedTheInvitation": "", + "@youAcceptedTheInvitation": {}, + "userAndOthersAreTyping": "", + "@userAndOthersAreTyping": { + "type": "text", + "placeholders": { + "username": {}, + "count": {} + } + }, + "youInvitedBy": "", + "@youInvitedBy": { + "placeholders": { + "user": {} + } + }, + "userIsTyping": "", + "@userIsTyping": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "banUserDescription": "", + "@banUserDescription": {}, + "requests": "", + "@requests": {}, + "widgetEtherpad": "", + "@widgetEtherpad": {}, + "waitingPartnerAcceptRequest": "", + "@waitingPartnerAcceptRequest": { + "type": "text", + "placeholders": {} + }, + "writeAMessage": "", + "@writeAMessage": { + "type": "text", + "placeholders": {} + }, + "stories": "", + "@stories": {}, + "addToStory": "", + "@addToStory": {}, + "removeDevicesDescription": "", + "@removeDevicesDescription": {}, + "separateChatTypes": "", + "@separateChatTypes": { + "type": "text", + "placeholders": {} + }, + "tryAgain": "", + "@tryAgain": {}, + "youKickedAndBanned": "", + "@youKickedAndBanned": { + "placeholders": { + "user": {} + } + }, + "showDirectChatsInSpaces": "", + "@showDirectChatsInSpaces": { + "type": "text", + "placeholders": {} + }, + "youCannotInviteYourself": "", + "@youCannotInviteYourself": { + "type": "text", + "placeholders": {} + }, + "unbanUserDescription": "", + "@unbanUserDescription": {}, + "todoLists": "", + "@todoLists": {}, + "userAndUserAreTyping": "", + "@userAndUserAreTyping": { + "type": "text", + "placeholders": { + "username": {}, + "username2": {} + } + }, + "seenByUserAndCountOthers": "", + "@seenByUserAndCountOthers": { + "type": "text", + "placeholders": { + "username": {}, + "count": {} + } + }, + "youRejectedTheInvitation": "", + "@youRejectedTheInvitation": {}, + "otherCallingPermissions": "", + "@otherCallingPermissions": {}, + "messagesStyle": "", + "@messagesStyle": {}, + "widgetUrlError": "", + "@widgetUrlError": {}, + "emailOrUsername": "", + "@emailOrUsername": {}, + "newSpaceDescription": "", + "@newSpaceDescription": {}, + "chatDescription": "", + "@chatDescription": {}, + "callingAccountDetails": "", + "@callingAccountDetails": {}, + "enterSpace": "", + "@enterSpace": {}, + "encryptThisChat": "", + "@encryptThisChat": {}, + "unavailable": "", + "@unavailable": { + "type": "text", + "placeholders": {} + }, + "previousAccount": "", + "@previousAccount": {}, + "fromTheInvitation": "", + "@fromTheInvitation": { + "type": "text", + "placeholders": {} + }, + "reopenChat": "", + "@reopenChat": {}, + "pleaseEnterRecoveryKey": "", + "@pleaseEnterRecoveryKey": {}, + "toggleFavorite": "", + "@toggleFavorite": { + "type": "text", + "placeholders": {} + }, + "widgetNameError": "", + "@widgetNameError": {}, + "unpin": "", + "@unpin": { + "type": "text", + "placeholders": {} + }, + "spaceIsPublic": "", + "@spaceIsPublic": { + "type": "text", + "placeholders": {} + }, + "addWidget": "", + "@addWidget": {}, + "unblockDevice": "", + "@unblockDevice": { + "type": "text", + "placeholders": {} + }, + "countFiles": "", + "@countFiles": { + "placeholders": { + "count": {} + } + }, + "noKeyForThisMessage": "", + "@noKeyForThisMessage": {}, + "shareLocation": "", + "@shareLocation": { + "type": "text", + "placeholders": {} + }, + "commandHint_markasgroup": "", + "@commandHint_markasgroup": {}, + "editTodo": "", + "@editTodo": {}, + "pushNotificationsNotAvailable": "", + "@pushNotificationsNotAvailable": {}, + "storeInAppleKeyChain": "", + "@storeInAppleKeyChain": {}, + "invalidServerName": "", + "@invalidServerName": {}, + "chatPermissions": "", + "@chatPermissions": {}, + "voiceMessage": "", + "@voiceMessage": { + "type": "text", + "placeholders": {} + }, + "wipeChatBackup": "", + "@wipeChatBackup": { + "type": "text", + "placeholders": {} + }, + "sender": "", + "@sender": {}, + "storeInAndroidKeystore": "", + "@storeInAndroidKeystore": {}, + "signInWithPassword": "", + "@signInWithPassword": {}, + "pleaseAddATitle": "", + "@pleaseAddATitle": {}, + "weSentYouAnEmail": "", + "@weSentYouAnEmail": { + "type": "text", + "placeholders": {} + }, + "makeAdminDescription": "", + "@makeAdminDescription": {}, + "synchronizingPleaseWait": "", + "@synchronizingPleaseWait": { + "type": "text", + "placeholders": {} + }, + "transferFromAnotherDevice": "", + "@transferFromAnotherDevice": { + "type": "text", + "placeholders": {} + }, + "pushRules": "", + "@pushRules": { + "type": "text", + "placeholders": {} + }, + "saveKeyManuallyDescription": "", + "@saveKeyManuallyDescription": {}, + "whyIsThisMessageEncrypted": "", + "@whyIsThisMessageEncrypted": {}, + "unreadChats": "", + "@unreadChats": { + "type": "text", + "placeholders": { + "unreadCount": {} + } + }, + "setChatDescription": "", + "@setChatDescription": {}, + "userLeftTheChat": "", + "@userLeftTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "spaceName": "", + "@spaceName": { + "type": "text", + "placeholders": {} + }, + "importFromZipFile": "", + "@importFromZipFile": {}, + "toggleUnread": "", + "@toggleUnread": { + "type": "text", + "placeholders": {} + }, + "noOtherDevicesFound": "", + "@noOtherDevicesFound": {}, + "whoIsAllowedToJoinThisGroup": "", + "@whoIsAllowedToJoinThisGroup": { + "type": "text", + "placeholders": {} + }, + "addDescription": "", + "@addDescription": {}, + "redactedBy": "", + "@redactedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "submit": "", + "@submit": { + "type": "text", + "placeholders": {} + }, + "videoCallsBetaWarning": "", + "@videoCallsBetaWarning": {}, + "unmuteChat": "", + "@unmuteChat": { + "type": "text", + "placeholders": {} + }, + "storyPrivacyWarning": "", + "@storyPrivacyWarning": {}, + "matrixWidgets": "", + "@matrixWidgets": {}, + "yes": "", + "@yes": { + "type": "text", + "placeholders": {} + }, + "signInWith": "", + "@signInWith": { + "type": "text", + "placeholders": { + "provider": {} + } + }, + "username": "", + "@username": { + "type": "text", + "placeholders": {} + }, + "fileIsTooBigForServer": "", + "@fileIsTooBigForServer": {}, + "noTodosYet": "", + "@noTodosYet": {}, + "verified": "", + "@verified": { + "type": "text", + "placeholders": {} + }, + "setStatus": "", + "@setStatus": { + "type": "text", + "placeholders": {} + }, + "callingPermissions": "", + "@callingPermissions": {}, + "readUpToHere": "", + "@readUpToHere": {}, + "start": "", + "@start": {}, + "unlockOldMessages": "", + "@unlockOldMessages": {}, + "numChats": "", + "@numChats": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "whatIsGoingOn": "", + "@whatIsGoingOn": {}, + "optionalRedactReason": "", + "@optionalRedactReason": {}, + "waitingPartnerEmoji": "", + "@waitingPartnerEmoji": { + "type": "text", + "placeholders": {} + }, + "tryToSendAgain": "", + "@tryToSendAgain": { + "type": "text", + "placeholders": {} + }, + "visibleForAllParticipants": "", + "@visibleForAllParticipants": { + "type": "text", + "placeholders": {} + }, + "archiveRoomDescription": "", + "@archiveRoomDescription": {}, + "exportEmotePack": "", + "@exportEmotePack": {}, + "switchToAccount": "", + "@switchToAccount": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "setAsCanonicalAlias": "", + "@setAsCanonicalAlias": { + "type": "text", + "placeholders": {} + }, + "whyDoYouWantToReportThis": "", + "@whyDoYouWantToReportThis": { + "type": "text", + "placeholders": {} + }, + "letsStart": "", + "@letsStart": {}, + "experimentalVideoCalls": "", + "@experimentalVideoCalls": {}, + "savedEmotePack": "", + "@savedEmotePack": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "pleaseEnterRecoveryKeyDescription": "", + "@pleaseEnterRecoveryKeyDescription": {}, + "withTheseAddressesRecoveryDescription": "", + "@withTheseAddressesRecoveryDescription": { + "type": "text", + "placeholders": {} + }, + "inviteContactToGroupQuestion": "", + "@inviteContactToGroupQuestion": {}, + "redactedByBecause": "", + "@redactedByBecause": { + "type": "text", + "placeholders": { + "username": {}, + "reason": {} + } + }, + "youHaveWithdrawnTheInvitationFor": "", + "@youHaveWithdrawnTheInvitationFor": { + "placeholders": { + "user": {} + } + }, + "skip": "", + "@skip": { + "type": "text", + "placeholders": {} + }, + "appearOnTopDetails": "", + "@appearOnTopDetails": {}, + "enterRoom": "", + "@enterRoom": {}, + "reportUser": "", + "@reportUser": {}, + "sharedTheLocation": "", + "@sharedTheLocation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "unbannedUser": "", + "@unbannedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "confirmEventUnpin": "", + "@confirmEventUnpin": {}, + "youInvitedUser": "", + "@youInvitedUser": { + "placeholders": { + "user": {} + } + }, + "fileHasBeenSavedAt": "", + "@fileHasBeenSavedAt": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "importZipFile": "", + "@importZipFile": {}, + "anyoneCanKnock": "", + "@anyoneCanKnock": {}, + "redactMessageDescription": "", + "@redactMessageDescription": {}, + "recoveryKey": "", + "@recoveryKey": {}, + "invalidInput": "", + "@invalidInput": {}, + "todosUnencrypted": "", + "@todosUnencrypted": {}, + "yourPublicKey": "", + "@yourPublicKey": { + "type": "text", + "placeholders": {} + }, + "tooManyRequestsWarning": "", + "@tooManyRequestsWarning": { + "type": "text", + "placeholders": {} + }, + "replyHasBeenSent": "", + "@replyHasBeenSent": {}, + "doNotShowAgain": "", + "@doNotShowAgain": {}, + "report": "", + "@report": {}, + "status": "", + "@status": { + "type": "text", + "placeholders": {} + }, + "verifyStart": "", + "@verifyStart": { + "type": "text", + "placeholders": {} + }, + "yourStory": "", + "@yourStory": {}, + "unverified": "", + "@unverified": {}, + "hideUnimportantStateEvents": "", + "@hideUnimportantStateEvents": {}, + "screenSharingTitle": "", + "@screenSharingTitle": {}, + "widgetCustom": "", + "@widgetCustom": {}, + "sentCallInformations": "", + "@sentCallInformations": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "addToSpaceDescription": "", + "@addToSpaceDescription": {}, + "googlyEyesContent": "", + "@googlyEyesContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "whoCanSeeMyStoriesDesc": "", + "@whoCanSeeMyStoriesDesc": {}, + "youBannedUser": "", + "@youBannedUser": { + "placeholders": { + "user": {} + } + }, + "theyDontMatch": "", + "@theyDontMatch": { + "type": "text", + "placeholders": {} + }, + "unsubscribeStories": "", + "@unsubscribeStories": {}, + "youHaveBeenBannedFromThisChat": "", + "@youHaveBeenBannedFromThisChat": { + "type": "text", + "placeholders": {} + }, + "addChatDescription": "", + "@addChatDescription": {}, + "hasKnocked": "", + "@hasKnocked": { + "placeholders": { + "user": {} + } + }, + "publish": "", + "@publish": {}, + "openLinkInBrowser": "", + "@openLinkInBrowser": {}, + "messageInfo": "", + "@messageInfo": {}, + "disableEncryptionWarning": "", + "@disableEncryptionWarning": {}, + "directChat": "", + "@directChat": {}, + "noOneCanJoin": "", + "@noOneCanJoin": {}, + "wrongPinEntered": "", + "@wrongPinEntered": { + "type": "text", + "placeholders": { + "seconds": {} + } + }, + "sendTypingNotifications": "", + "@sendTypingNotifications": {}, + "inviteGroupChat": "", + "@inviteGroupChat": {}, + "appearOnTop": "", + "@appearOnTop": {}, + "invitePrivateChat": "", + "@invitePrivateChat": {}, + "verifyTitle": "", + "@verifyTitle": { + "type": "text", + "placeholders": {} + }, + "foregroundServiceRunning": "", + "@foregroundServiceRunning": {}, + "voiceCall": "", + "@voiceCall": {}, + "unknownEncryptionAlgorithm": "", + "@unknownEncryptionAlgorithm": { + "type": "text", + "placeholders": {} + }, + "importEmojis": "", + "@importEmojis": {}, + "wasDirectChatDisplayName": "", + "@wasDirectChatDisplayName": { + "type": "text", + "placeholders": { + "oldDisplayName": {} + } + }, + "noChatDescriptionYet": "", + "@noChatDescriptionYet": {}, + "newTodo": "", + "@newTodo": {}, + "whoCanPerformWhichAction": "", + "@whoCanPerformWhichAction": { + "type": "text", + "placeholders": {} + }, + "confirmMatrixId": "", + "@confirmMatrixId": {}, + "learnMore": "", + "@learnMore": {}, + "you": "", + "@you": { + "type": "text", + "placeholders": {} + }, + "notAnImage": "", + "@notAnImage": {}, + "users": "", + "@users": {}, + "openGallery": "", + "@openGallery": {}, + "chatDescriptionHasBeenChanged": "", + "@chatDescriptionHasBeenChanged": {}, + "newGroup": "", + "@newGroup": {}, + "todoListChangedError": "", + "@todoListChangedError": {}, + "removeFromSpace": "", + "@removeFromSpace": {}, + "enterInviteLinkOrMatrixId": "", + "@enterInviteLinkOrMatrixId": {}, + "sourceCode": "", + "@sourceCode": { + "type": "text", + "placeholders": {} + }, + "roomUpgradeDescription": "", + "@roomUpgradeDescription": {}, + "userSentUnknownEvent": "", + "@userSentUnknownEvent": { + "type": "text", + "placeholders": { + "username": {}, + "type": {} + } + }, + "scanQrCode": "", + "@scanQrCode": {}, + "pleaseEnterANumber": "", + "@pleaseEnterANumber": {}, + "youKicked": "", + "@youKicked": { + "placeholders": { + "user": {} + } + }, + "profileNotFound": "", + "@profileNotFound": {}, + "jump": "", + "@jump": {}, + "reactedWith": "", + "@reactedWith": { + "type": "text", + "placeholders": { + "sender": {}, + "reaction": {} + } + }, + "sorryThatsNotPossible": "", + "@sorryThatsNotPossible": {}, + "storyFrom": "", + "@storyFrom": { + "type": "text", + "placeholders": { + "date": {}, + "body": {} + } + }, + "videoWithSize": "", + "@videoWithSize": { + "type": "text", + "placeholders": { + "size": {} + } + }, + "shareInviteLink": "", + "@shareInviteLink": {}, + "commandHint_markasdm": "", + "@commandHint_markasdm": {}, + "recoveryKeyLost": "", + "@recoveryKeyLost": {}, + "cuddleContent": "", + "@cuddleContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "deviceKeys": "", + "@deviceKeys": {}, + "waitingPartnerNumbers": "", + "@waitingPartnerNumbers": { + "type": "text", + "placeholders": {} + }, + "emoteKeyboardNoRecents": "", + "@emoteKeyboardNoRecents": { + "type": "text", + "placeholders": {} + }, + "setCustomEmotes": "", + "@setCustomEmotes": { + "type": "text", + "placeholders": {} + }, + "startedACall": "", + "@startedACall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "systemTheme": "", + "@systemTheme": { + "type": "text", + "placeholders": {} + }, + "endToEndEncryption": "", + "@endToEndEncryption": {}, + "visibilityOfTheChatHistory": "", + "@visibilityOfTheChatHistory": { + "type": "text", + "placeholders": {} + }, + "settings": "", + "@settings": { + "type": "text", + "placeholders": {} + }, + "setTheme": "", + "@setTheme": {}, + "youJoinedTheChat": "", + "@youJoinedTheChat": {}, + "wallpaper": "", + "@wallpaper": { + "type": "text", + "placeholders": {} + }, + "openVideoCamera": "", + "@openVideoCamera": { + "type": "text", + "placeholders": {} + }, + "statusExampleMessage": "", + "@statusExampleMessage": { + "type": "text", + "placeholders": {} + }, + "thisUserHasNotPostedAnythingYet": "", + "@thisUserHasNotPostedAnythingYet": {}, + "markAsRead": "", + "@markAsRead": {}, + "widgetName": "", + "@widgetName": {}, + "errorAddingWidget": "", + "@errorAddingWidget": {}, + "commandHint_hug": "", + "@commandHint_hug": {}, + "replace": "", + "@replace": {}, + "youUnbannedUser": "", + "@youUnbannedUser": { + "placeholders": { + "user": {} + } + }, + "visibleForEveryone": "", + "@visibleForEveryone": { + "type": "text", + "placeholders": {} + }, + "newSpace": "", + "@newSpace": {}, + "unknownEvent": "", + "@unknownEvent": { + "type": "text", + "placeholders": { + "type": {} + } + }, + "emojis": "", + "@emojis": {}, + "signUp": "", + "@signUp": { + "type": "text", + "placeholders": {} + }, + "share": "", + "@share": { + "type": "text", + "placeholders": {} + }, + "commandHint_googly": "", + "@commandHint_googly": {}, + "pleaseTryAgainLaterOrChooseDifferentServer": "", + "@pleaseTryAgainLaterOrChooseDifferentServer": {}, + "createGroup": "", + "@createGroup": {}, + "time": "", + "@time": {}, + "custom": "", + "@custom": {}, + "noBackupWarning": "", + "@noBackupWarning": {}, + "fromJoining": "", + "@fromJoining": { + "type": "text", + "placeholders": {} + }, + "verify": "", + "@verify": { + "type": "text", + "placeholders": {} + }, + "editWidgets": "", + "@editWidgets": {}, + "storeInSecureStorageDescription": "", + "@storeInSecureStorageDescription": {}, + "openChat": "", + "@openChat": {}, + "kickUserDescription": "", + "@kickUserDescription": {}, + "importNow": "", + "@importNow": {}, + "setInvitationLink": "", + "@setInvitationLink": { + "type": "text", + "placeholders": {} + }, + "pinMessage": "", + "@pinMessage": {}, + "invite": "", + "@invite": {}, + "continueWith": "", + "@continueWith": {}, + "indexedDbErrorTitle": "", + "@indexedDbErrorTitle": {}, + "discover": "", + "@discover": { + "type": "text", + "placeholders": {} + }, + "unsupportedAndroidVersionLong": "", + "@unsupportedAndroidVersionLong": {}, + "storeSecurlyOnThisDevice": "", + "@storeSecurlyOnThisDevice": {}, + "iUnderstand": "", + "@iUnderstand": {}, + "screenSharingDetail": "", + "@screenSharingDetail": {}, + "placeCall": "", + "@placeCall": {} +} diff --git a/assets/l10n/intl_ro.arb b/assets/l10n/intl_ro.arb index 2563901a2..b5a105da4 100644 --- a/assets/l10n/intl_ro.arb +++ b/assets/l10n/intl_ro.arb @@ -2502,5 +2502,152 @@ "pleaseTryAgainLaterOrChooseDifferentServer": "Vă rugăm să încercați din nou mai târziu sau să alegeți un server diferit.", "@pleaseTryAgainLaterOrChooseDifferentServer": {}, "signInWithPassword": "Conectați-vă cu parolă", - "@signInWithPassword": {} + "@signInWithPassword": {}, + "setColorTheme": "", + "@setColorTheme": {}, + "banUserDescription": "", + "@banUserDescription": {}, + "requests": "", + "@requests": {}, + "removeDevicesDescription": "", + "@removeDevicesDescription": {}, + "tryAgain": "", + "@tryAgain": {}, + "unbanUserDescription": "", + "@unbanUserDescription": {}, + "todoLists": "", + "@todoLists": {}, + "messagesStyle": "", + "@messagesStyle": {}, + "chatDescription": "", + "@chatDescription": {}, + "editTodo": "", + "@editTodo": {}, + "pushNotificationsNotAvailable": "", + "@pushNotificationsNotAvailable": {}, + "invalidServerName": "", + "@invalidServerName": {}, + "chatPermissions": "", + "@chatPermissions": {}, + "pleaseAddATitle": "", + "@pleaseAddATitle": {}, + "makeAdminDescription": "", + "@makeAdminDescription": {}, + "setChatDescription": "", + "@setChatDescription": {}, + "importFromZipFile": "", + "@importFromZipFile": {}, + "redactedBy": "", + "@redactedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "signInWith": "", + "@signInWith": { + "type": "text", + "placeholders": { + "provider": {} + } + }, + "noTodosYet": "", + "@noTodosYet": {}, + "optionalRedactReason": "", + "@optionalRedactReason": {}, + "archiveRoomDescription": "", + "@archiveRoomDescription": {}, + "exportEmotePack": "", + "@exportEmotePack": {}, + "savedEmotePack": "", + "@savedEmotePack": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "inviteContactToGroupQuestion": "", + "@inviteContactToGroupQuestion": {}, + "redactedByBecause": "", + "@redactedByBecause": { + "type": "text", + "placeholders": { + "username": {}, + "reason": {} + } + }, + "importZipFile": "", + "@importZipFile": {}, + "anyoneCanKnock": "", + "@anyoneCanKnock": {}, + "redactMessageDescription": "", + "@redactMessageDescription": {}, + "invalidInput": "", + "@invalidInput": {}, + "todosUnencrypted": "", + "@todosUnencrypted": {}, + "addChatDescription": "", + "@addChatDescription": {}, + "hasKnocked": "", + "@hasKnocked": { + "placeholders": { + "user": {} + } + }, + "directChat": "", + "@directChat": {}, + "noOneCanJoin": "", + "@noOneCanJoin": {}, + "wrongPinEntered": "", + "@wrongPinEntered": { + "type": "text", + "placeholders": { + "seconds": {} + } + }, + "sendTypingNotifications": "", + "@sendTypingNotifications": {}, + "inviteGroupChat": "", + "@inviteGroupChat": {}, + "invitePrivateChat": "", + "@invitePrivateChat": {}, + "importEmojis": "", + "@importEmojis": {}, + "noChatDescriptionYet": "", + "@noChatDescriptionYet": {}, + "newTodo": "", + "@newTodo": {}, + "learnMore": "", + "@learnMore": {}, + "notAnImage": "", + "@notAnImage": {}, + "chatDescriptionHasBeenChanged": "", + "@chatDescriptionHasBeenChanged": {}, + "todoListChangedError": "", + "@todoListChangedError": {}, + "roomUpgradeDescription": "", + "@roomUpgradeDescription": {}, + "pleaseEnterANumber": "", + "@pleaseEnterANumber": {}, + "profileNotFound": "", + "@profileNotFound": {}, + "shareInviteLink": "", + "@shareInviteLink": {}, + "emoteKeyboardNoRecents": "", + "@emoteKeyboardNoRecents": { + "type": "text", + "placeholders": {} + }, + "setTheme": "", + "@setTheme": {}, + "replace": "", + "@replace": {}, + "createGroup": "", + "@createGroup": {}, + "kickUserDescription": "", + "@kickUserDescription": {}, + "importNow": "", + "@importNow": {}, + "invite": "", + "@invite": {} } diff --git a/assets/l10n/intl_ru.arb b/assets/l10n/intl_ru.arb index 927d4eb61..56d5a2ce7 100644 --- a/assets/l10n/intl_ru.arb +++ b/assets/l10n/intl_ru.arb @@ -2617,5 +2617,45 @@ "@emoteKeyboardNoRecents": { "type": "text", "placeholders": {} - } + }, + "banUserDescription": "", + "@banUserDescription": {}, + "removeDevicesDescription": "", + "@removeDevicesDescription": {}, + "unbanUserDescription": "", + "@unbanUserDescription": {}, + "todoLists": "", + "@todoLists": {}, + "editTodo": "", + "@editTodo": {}, + "pushNotificationsNotAvailable": "", + "@pushNotificationsNotAvailable": {}, + "pleaseAddATitle": "", + "@pleaseAddATitle": {}, + "makeAdminDescription": "", + "@makeAdminDescription": {}, + "noTodosYet": "", + "@noTodosYet": {}, + "archiveRoomDescription": "", + "@archiveRoomDescription": {}, + "todosUnencrypted": "", + "@todosUnencrypted": {}, + "hasKnocked": "", + "@hasKnocked": { + "placeholders": { + "user": {} + } + }, + "newTodo": "", + "@newTodo": {}, + "learnMore": "", + "@learnMore": {}, + "todoListChangedError": "", + "@todoListChangedError": {}, + "roomUpgradeDescription": "", + "@roomUpgradeDescription": {}, + "pleaseEnterANumber": "", + "@pleaseEnterANumber": {}, + "kickUserDescription": "", + "@kickUserDescription": {} } diff --git a/assets/l10n/intl_sk.arb b/assets/l10n/intl_sk.arb index 5fd3ed698..5113b7743 100644 --- a/assets/l10n/intl_sk.arb +++ b/assets/l10n/intl_sk.arb @@ -1419,5 +1419,1229 @@ "updateNow": "Začať aktualizáciu na pozadí", "@updateNow": {}, "importNow": "Importovať teraz", - "@importNow": {} + "@importNow": {}, + "showPassword": "", + "@showPassword": { + "type": "text", + "placeholders": {} + }, + "hugContent": "", + "@hugContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "jumpToLastReadMessage": "", + "@jumpToLastReadMessage": {}, + "allRooms": "", + "@allRooms": { + "type": "text", + "placeholders": {} + }, + "obtainingLocation": "", + "@obtainingLocation": { + "type": "text", + "placeholders": {} + }, + "whoCanSeeMyStories": "", + "@whoCanSeeMyStories": {}, + "commandHint_cuddle": "", + "@commandHint_cuddle": {}, + "widgetVideo": "", + "@widgetVideo": {}, + "dismiss": "", + "@dismiss": {}, + "noEncryptionForPublicRooms": "", + "@noEncryptionForPublicRooms": { + "type": "text", + "placeholders": {} + }, + "reportErrorDescription": "", + "@reportErrorDescription": {}, + "directChats": "", + "@directChats": { + "type": "text", + "placeholders": {} + }, + "addAccount": "", + "@addAccount": {}, + "configureChat": "", + "@configureChat": { + "type": "text", + "placeholders": {} + }, + "chatHasBeenAddedToThisSpace": "", + "@chatHasBeenAddedToThisSpace": {}, + "removeYourAvatar": "", + "@removeYourAvatar": { + "type": "text", + "placeholders": {} + }, + "unsupportedAndroidVersion": "", + "@unsupportedAndroidVersion": {}, + "enterASpacepName": "", + "@enterASpacepName": {}, + "commandHint_html": "", + "@commandHint_html": { + "type": "text", + "description": "Usage hint for the command /html" + }, + "widgetJitsi": "", + "@widgetJitsi": {}, + "messageType": "", + "@messageType": {}, + "noEmailWarning": "", + "@noEmailWarning": {}, + "indexedDbErrorLong": "", + "@indexedDbErrorLong": {}, + "oneClientLoggedOut": "", + "@oneClientLoggedOut": {}, + "toggleMuted": "", + "@toggleMuted": { + "type": "text", + "placeholders": {} + }, + "startFirstChat": "", + "@startFirstChat": {}, + "callingAccount": "", + "@callingAccount": {}, + "setColorTheme": "", + "@setColorTheme": {}, + "nextAccount": "", + "@nextAccount": {}, + "commandHint_create": "", + "@commandHint_create": { + "type": "text", + "description": "Usage hint for the command /create" + }, + "singlesignon": "", + "@singlesignon": { + "type": "text", + "placeholders": {} + }, + "warning": "", + "@warning": { + "type": "text", + "placeholders": {} + }, + "allSpaces": "", + "@allSpaces": {}, + "supposedMxid": "", + "@supposedMxid": { + "type": "text", + "placeholders": { + "mxid": {} + } + }, + "user": "", + "@user": {}, + "youAcceptedTheInvitation": "", + "@youAcceptedTheInvitation": {}, + "noMatrixServer": "", + "@noMatrixServer": { + "type": "text", + "placeholders": { + "server1": {}, + "server2": {} + } + }, + "youInvitedBy": "", + "@youInvitedBy": { + "placeholders": { + "user": {} + } + }, + "banUserDescription": "", + "@banUserDescription": {}, + "requests": "", + "@requests": {}, + "widgetEtherpad": "", + "@widgetEtherpad": {}, + "stories": "", + "@stories": {}, + "addToStory": "", + "@addToStory": {}, + "removeDevicesDescription": "", + "@removeDevicesDescription": {}, + "separateChatTypes": "", + "@separateChatTypes": { + "type": "text", + "placeholders": {} + }, + "tryAgain": "", + "@tryAgain": {}, + "blocked": "", + "@blocked": { + "type": "text", + "placeholders": {} + }, + "youKickedAndBanned": "", + "@youKickedAndBanned": { + "placeholders": { + "user": {} + } + }, + "showDirectChatsInSpaces": "", + "@showDirectChatsInSpaces": { + "type": "text", + "placeholders": {} + }, + "unbanUserDescription": "", + "@unbanUserDescription": {}, + "todoLists": "", + "@todoLists": {}, + "pleaseClickOnLink": "", + "@pleaseClickOnLink": { + "type": "text", + "placeholders": {} + }, + "saveFile": "", + "@saveFile": { + "type": "text", + "placeholders": {} + }, + "youRejectedTheInvitation": "", + "@youRejectedTheInvitation": {}, + "otherCallingPermissions": "", + "@otherCallingPermissions": {}, + "messagesStyle": "", + "@messagesStyle": {}, + "link": "", + "@link": {}, + "widgetUrlError": "", + "@widgetUrlError": {}, + "emailOrUsername": "", + "@emailOrUsername": {}, + "newSpaceDescription": "", + "@newSpaceDescription": {}, + "chatDescription": "", + "@chatDescription": {}, + "callingAccountDetails": "", + "@callingAccountDetails": {}, + "next": "", + "@next": { + "type": "text", + "placeholders": {} + }, + "pleaseFollowInstructionsOnWeb": "", + "@pleaseFollowInstructionsOnWeb": { + "type": "text", + "placeholders": {} + }, + "editRoomAliases": "", + "@editRoomAliases": { + "type": "text", + "placeholders": {} + }, + "enterSpace": "", + "@enterSpace": {}, + "encryptThisChat": "", + "@encryptThisChat": {}, + "unavailable": "", + "@unavailable": { + "type": "text", + "placeholders": {} + }, + "previousAccount": "", + "@previousAccount": {}, + "reopenChat": "", + "@reopenChat": {}, + "pleaseEnterRecoveryKey": "", + "@pleaseEnterRecoveryKey": {}, + "toggleFavorite": "", + "@toggleFavorite": { + "type": "text", + "placeholders": {} + }, + "no": "", + "@no": { + "type": "text", + "placeholders": {} + }, + "widgetNameError": "", + "@widgetNameError": {}, + "inoffensive": "", + "@inoffensive": { + "type": "text", + "placeholders": {} + }, + "unpin": "", + "@unpin": { + "type": "text", + "placeholders": {} + }, + "addToBundle": "", + "@addToBundle": {}, + "spaceIsPublic": "", + "@spaceIsPublic": { + "type": "text", + "placeholders": {} + }, + "addWidget": "", + "@addWidget": {}, + "countFiles": "", + "@countFiles": { + "placeholders": { + "count": {} + } + }, + "noKeyForThisMessage": "", + "@noKeyForThisMessage": {}, + "shareLocation": "", + "@shareLocation": { + "type": "text", + "placeholders": {} + }, + "reason": "", + "@reason": { + "type": "text", + "placeholders": {} + }, + "commandHint_markasgroup": "", + "@commandHint_markasgroup": {}, + "editTodo": "", + "@editTodo": {}, + "errorObtainingLocation": "", + "@errorObtainingLocation": { + "type": "text", + "placeholders": { + "error": {} + } + }, + "hydrateTor": "", + "@hydrateTor": {}, + "pushNotificationsNotAvailable": "", + "@pushNotificationsNotAvailable": {}, + "passwordRecovery": "", + "@passwordRecovery": { + "type": "text", + "placeholders": {} + }, + "storeInAppleKeyChain": "", + "@storeInAppleKeyChain": {}, + "replaceRoomWithNewerVersion": "", + "@replaceRoomWithNewerVersion": { + "type": "text", + "placeholders": {} + }, + "hydrate": "", + "@hydrate": {}, + "invalidServerName": "", + "@invalidServerName": {}, + "chatPermissions": "", + "@chatPermissions": {}, + "wipeChatBackup": "", + "@wipeChatBackup": { + "type": "text", + "placeholders": {} + }, + "sender": "", + "@sender": {}, + "storeInAndroidKeystore": "", + "@storeInAndroidKeystore": {}, + "hideRedactedEvents": "", + "@hideRedactedEvents": { + "type": "text", + "placeholders": {} + }, + "online": "", + "@online": { + "type": "text", + "placeholders": {} + }, + "signInWithPassword": "", + "@signInWithPassword": {}, + "pleaseAddATitle": "", + "@pleaseAddATitle": {}, + "weSentYouAnEmail": "", + "@weSentYouAnEmail": { + "type": "text", + "placeholders": {} + }, + "offensive": "", + "@offensive": { + "type": "text", + "placeholders": {} + }, + "makeAdminDescription": "", + "@makeAdminDescription": {}, + "edit": "", + "@edit": { + "type": "text", + "placeholders": {} + }, + "synchronizingPleaseWait": "", + "@synchronizingPleaseWait": { + "type": "text", + "placeholders": {} + }, + "transferFromAnotherDevice": "", + "@transferFromAnotherDevice": { + "type": "text", + "placeholders": {} + }, + "pushRules": "", + "@pushRules": { + "type": "text", + "placeholders": {} + }, + "goToTheNewRoom": "", + "@goToTheNewRoom": { + "type": "text", + "placeholders": {} + }, + "commandHint_clearcache": "", + "@commandHint_clearcache": { + "type": "text", + "description": "Usage hint for the command /clearcache" + }, + "saveKeyManuallyDescription": "", + "@saveKeyManuallyDescription": {}, + "editBundlesForAccount": "", + "@editBundlesForAccount": {}, + "enableEncryption": "", + "@enableEncryption": { + "type": "text", + "placeholders": {} + }, + "whyIsThisMessageEncrypted": "", + "@whyIsThisMessageEncrypted": {}, + "setChatDescription": "", + "@setChatDescription": {}, + "spaceName": "", + "@spaceName": { + "type": "text", + "placeholders": {} + }, + "importFromZipFile": "", + "@importFromZipFile": {}, + "discover": "", + "@discover": { + "type": "text", + "placeholders": {} + }, + "toggleUnread": "", + "@toggleUnread": { + "type": "text", + "placeholders": {} + }, + "or": "", + "@or": { + "type": "text", + "placeholders": {} + }, + "dehydrateWarning": "", + "@dehydrateWarning": {}, + "noOtherDevicesFound": "", + "@noOtherDevicesFound": {}, + "addDescription": "", + "@addDescription": {}, + "redactedBy": "", + "@redactedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "videoCallsBetaWarning": "", + "@videoCallsBetaWarning": {}, + "autoplayImages": "", + "@autoplayImages": { + "type": "text", + "placeholder": {} + }, + "storyPrivacyWarning": "", + "@storyPrivacyWarning": {}, + "matrixWidgets": "", + "@matrixWidgets": {}, + "participant": "", + "@participant": { + "type": "text", + "placeholders": {} + }, + "containsDisplayName": "", + "@containsDisplayName": { + "type": "text", + "placeholders": {} + }, + "signInWith": "", + "@signInWith": { + "type": "text", + "placeholders": { + "provider": {} + } + }, + "fileIsTooBigForServer": "", + "@fileIsTooBigForServer": {}, + "homeserver": "", + "@homeserver": {}, + "noTodosYet": "", + "@noTodosYet": {}, + "verified": "", + "@verified": { + "type": "text", + "placeholders": {} + }, + "callingPermissions": "", + "@callingPermissions": {}, + "readUpToHere": "", + "@readUpToHere": {}, + "start": "", + "@start": {}, + "bubbleSize": "", + "@bubbleSize": { + "type": "text", + "placeholders": {} + }, + "deviceId": "", + "@deviceId": { + "type": "text", + "placeholders": {} + }, + "register": "", + "@register": { + "type": "text", + "placeholders": {} + }, + "unlockOldMessages": "", + "@unlockOldMessages": {}, + "numChats": "", + "@numChats": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "whatIsGoingOn": "", + "@whatIsGoingOn": {}, + "optionalRedactReason": "", + "@optionalRedactReason": {}, + "copyToClipboard": "", + "@copyToClipboard": { + "type": "text", + "placeholders": {} + }, + "dehydrate": "", + "@dehydrate": {}, + "locationPermissionDeniedNotice": "", + "@locationPermissionDeniedNotice": { + "type": "text", + "placeholders": {} + }, + "inviteForMe": "", + "@inviteForMe": { + "type": "text", + "placeholders": {} + }, + "archiveRoomDescription": "", + "@archiveRoomDescription": {}, + "exportEmotePack": "", + "@exportEmotePack": {}, + "switchToAccount": "", + "@switchToAccount": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "commandInvalid": "", + "@commandInvalid": { + "type": "text" + }, + "setAsCanonicalAlias": "", + "@setAsCanonicalAlias": { + "type": "text", + "placeholders": {} + }, + "whyDoYouWantToReportThis": "", + "@whyDoYouWantToReportThis": { + "type": "text", + "placeholders": {} + }, + "locationDisabledNotice": "", + "@locationDisabledNotice": { + "type": "text", + "placeholders": {} + }, + "letsStart": "", + "@letsStart": {}, + "newChat": "", + "@newChat": { + "type": "text", + "placeholders": {} + }, + "notifications": "", + "@notifications": { + "type": "text", + "placeholders": {} + }, + "commandHint_plain": "", + "@commandHint_plain": { + "type": "text", + "description": "Usage hint for the command /plain" + }, + "experimentalVideoCalls": "", + "@experimentalVideoCalls": {}, + "savedEmotePack": "", + "@savedEmotePack": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "pleaseEnterRecoveryKeyDescription": "", + "@pleaseEnterRecoveryKeyDescription": {}, + "mention": "", + "@mention": { + "type": "text", + "placeholders": {} + }, + "openInMaps": "", + "@openInMaps": { + "type": "text", + "placeholders": {} + }, + "inviteContactToGroupQuestion": "", + "@inviteContactToGroupQuestion": {}, + "redactedByBecause": "", + "@redactedByBecause": { + "type": "text", + "placeholders": { + "username": {}, + "reason": {} + } + }, + "youHaveWithdrawnTheInvitationFor": "", + "@youHaveWithdrawnTheInvitationFor": { + "placeholders": { + "user": {} + } + }, + "appearOnTopDetails": "", + "@appearOnTopDetails": {}, + "enterRoom": "", + "@enterRoom": {}, + "enableEmotesGlobally": "", + "@enableEmotesGlobally": { + "type": "text", + "placeholders": {} + }, + "ignoreListDescription": "", + "@ignoreListDescription": { + "type": "text", + "placeholders": {} + }, + "pleaseChooseAPasscode": "", + "@pleaseChooseAPasscode": { + "type": "text", + "placeholders": {} + }, + "reportUser": "", + "@reportUser": {}, + "commandHint_send": "", + "@commandHint_send": { + "type": "text", + "description": "Usage hint for the command /send" + }, + "confirmEventUnpin": "", + "@confirmEventUnpin": {}, + "youInvitedUser": "", + "@youInvitedUser": { + "placeholders": { + "user": {} + } + }, + "noConnectionToTheServer": "", + "@noConnectionToTheServer": { + "type": "text", + "placeholders": {} + }, + "fileHasBeenSavedAt": "", + "@fileHasBeenSavedAt": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "importZipFile": "", + "@importZipFile": {}, + "anyoneCanKnock": "", + "@anyoneCanKnock": {}, + "commandMissing": "", + "@commandMissing": { + "type": "text", + "placeholders": { + "command": {} + }, + "description": "State that {command} is not a valid /command." + }, + "redactMessageDescription": "", + "@redactMessageDescription": {}, + "recoveryKey": "", + "@recoveryKey": {}, + "redactMessage": "", + "@redactMessage": { + "type": "text", + "placeholders": {} + }, + "commandHint_discardsession": "", + "@commandHint_discardsession": { + "type": "text", + "description": "Usage hint for the command /discardsession" + }, + "invalidInput": "", + "@invalidInput": {}, + "hideUnknownEvents": "", + "@hideUnknownEvents": { + "type": "text", + "placeholders": {} + }, + "todosUnencrypted": "", + "@todosUnencrypted": {}, + "dehydrateTorLong": "", + "@dehydrateTorLong": {}, + "yourPublicKey": "", + "@yourPublicKey": { + "type": "text", + "placeholders": {} + }, + "tooManyRequestsWarning": "", + "@tooManyRequestsWarning": { + "type": "text", + "placeholders": {} + }, + "commandHint_myroomnick": "", + "@commandHint_myroomnick": { + "type": "text", + "description": "Usage hint for the command /myroomnick" + }, + "offline": "", + "@offline": { + "type": "text", + "placeholders": {} + }, + "replyHasBeenSent": "", + "@replyHasBeenSent": {}, + "doNotShowAgain": "", + "@doNotShowAgain": {}, + "report": "", + "@report": {}, + "status": "", + "@status": { + "type": "text", + "placeholders": {} + }, + "yourStory": "", + "@yourStory": {}, + "memberChanges": "", + "@memberChanges": { + "type": "text", + "placeholders": {} + }, + "ignoreUsername": "", + "@ignoreUsername": { + "type": "text", + "placeholders": {} + }, + "unverified": "", + "@unverified": {}, + "howOffensiveIsThisContent": "", + "@howOffensiveIsThisContent": { + "type": "text", + "placeholders": {} + }, + "serverRequiresEmail": "", + "@serverRequiresEmail": {}, + "hideUnimportantStateEvents": "", + "@hideUnimportantStateEvents": {}, + "screenSharingTitle": "", + "@screenSharingTitle": {}, + "widgetCustom": "", + "@widgetCustom": {}, + "addToSpaceDescription": "", + "@addToSpaceDescription": {}, + "googlyEyesContent": "", + "@googlyEyesContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "whoCanSeeMyStoriesDesc": "", + "@whoCanSeeMyStoriesDesc": {}, + "youBannedUser": "", + "@youBannedUser": { + "placeholders": { + "user": {} + } + }, + "unsubscribeStories": "", + "@unsubscribeStories": {}, + "loginWithOneClick": "", + "@loginWithOneClick": {}, + "addChatDescription": "", + "@addChatDescription": {}, + "editRoomAvatar": "", + "@editRoomAvatar": { + "type": "text", + "placeholders": {} + }, + "encrypted": "", + "@encrypted": { + "type": "text", + "placeholders": {} + }, + "commandHint_leave": "", + "@commandHint_leave": { + "type": "text", + "description": "Usage hint for the command /leave" + }, + "commandHint_myroomavatar": "", + "@commandHint_myroomavatar": { + "type": "text", + "description": "Usage hint for the command /myroomavatar" + }, + "hasKnocked": "", + "@hasKnocked": { + "placeholders": { + "user": {} + } + }, + "publish": "", + "@publish": {}, + "openLinkInBrowser": "", + "@openLinkInBrowser": {}, + "clearArchive": "", + "@clearArchive": {}, + "commandHint_react": "", + "@commandHint_react": { + "type": "text", + "description": "Usage hint for the command /react" + }, + "commandHint_me": "", + "@commandHint_me": { + "type": "text", + "description": "Usage hint for the command /me" + }, + "messageInfo": "", + "@messageInfo": {}, + "disableEncryptionWarning": "", + "@disableEncryptionWarning": {}, + "directChat": "", + "@directChat": {}, + "noOneCanJoin": "", + "@noOneCanJoin": {}, + "wrongPinEntered": "", + "@wrongPinEntered": { + "type": "text", + "placeholders": { + "seconds": {} + } + }, + "sendTypingNotifications": "", + "@sendTypingNotifications": {}, + "inviteGroupChat": "", + "@inviteGroupChat": {}, + "appearOnTop": "", + "@appearOnTop": {}, + "invitePrivateChat": "", + "@invitePrivateChat": {}, + "foregroundServiceRunning": "", + "@foregroundServiceRunning": {}, + "enterAnEmailAddress": "", + "@enterAnEmailAddress": { + "type": "text", + "placeholders": {} + }, + "voiceCall": "", + "@voiceCall": {}, + "commandHint_kick": "", + "@commandHint_kick": { + "type": "text", + "description": "Usage hint for the command /kick" + }, + "createNewSpace": "", + "@createNewSpace": { + "type": "text", + "placeholders": {} + }, + "commandHint_unban": "", + "@commandHint_unban": { + "type": "text", + "description": "Usage hint for the command /unban" + }, + "commandHint_ban": "", + "@commandHint_ban": { + "type": "text", + "description": "Usage hint for the command /ban" + }, + "importEmojis": "", + "@importEmojis": {}, + "wasDirectChatDisplayName": "", + "@wasDirectChatDisplayName": { + "type": "text", + "placeholders": { + "oldDisplayName": {} + } + }, + "noChatDescriptionYet": "", + "@noChatDescriptionYet": {}, + "defaultPermissionLevel": "", + "@defaultPermissionLevel": { + "type": "text", + "placeholders": {} + }, + "newTodo": "", + "@newTodo": {}, + "removeFromBundle": "", + "@removeFromBundle": {}, + "numUsersTyping": "", + "@numUsersTyping": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "fontSize": "", + "@fontSize": { + "type": "text", + "placeholders": {} + }, + "whoCanPerformWhichAction": "", + "@whoCanPerformWhichAction": { + "type": "text", + "placeholders": {} + }, + "confirmMatrixId": "", + "@confirmMatrixId": {}, + "learnMore": "", + "@learnMore": {}, + "iHaveClickedOnLink": "", + "@iHaveClickedOnLink": { + "type": "text", + "placeholders": {} + }, + "notAnImage": "", + "@notAnImage": {}, + "users": "", + "@users": {}, + "openGallery": "", + "@openGallery": {}, + "chatDescriptionHasBeenChanged": "", + "@chatDescriptionHasBeenChanged": {}, + "newGroup": "", + "@newGroup": {}, + "bundleName": "", + "@bundleName": {}, + "dehydrateTor": "", + "@dehydrateTor": {}, + "todoListChangedError": "", + "@todoListChangedError": {}, + "removeFromSpace": "", + "@removeFromSpace": {}, + "enterInviteLinkOrMatrixId": "", + "@enterInviteLinkOrMatrixId": {}, + "commandHint_op": "", + "@commandHint_op": { + "type": "text", + "description": "Usage hint for the command /op" + }, + "commandHint_join": "", + "@commandHint_join": { + "type": "text", + "description": "Usage hint for the command /join" + }, + "roomUpgradeDescription": "", + "@roomUpgradeDescription": {}, + "commandHint_invite": "", + "@commandHint_invite": { + "type": "text", + "description": "Usage hint for the command /invite" + }, + "scanQrCode": "", + "@scanQrCode": {}, + "pleaseEnterANumber": "", + "@pleaseEnterANumber": {}, + "youKicked": "", + "@youKicked": { + "placeholders": { + "user": {} + } + }, + "profileNotFound": "", + "@profileNotFound": {}, + "jump": "", + "@jump": {}, + "groups": "", + "@groups": { + "type": "text", + "placeholders": {} + }, + "reactedWith": "", + "@reactedWith": { + "type": "text", + "placeholders": { + "sender": {}, + "reaction": {} + } + }, + "sorryThatsNotPossible": "", + "@sorryThatsNotPossible": {}, + "storyFrom": "", + "@storyFrom": { + "type": "text", + "placeholders": { + "date": {}, + "body": {} + } + }, + "videoWithSize": "", + "@videoWithSize": { + "type": "text", + "placeholders": { + "size": {} + } + }, + "shareInviteLink": "", + "@shareInviteLink": {}, + "commandHint_markasdm": "", + "@commandHint_markasdm": {}, + "recoveryKeyLost": "", + "@recoveryKeyLost": {}, + "cuddleContent": "", + "@cuddleContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "messages": "", + "@messages": { + "type": "text", + "placeholders": {} + }, + "deviceKeys": "", + "@deviceKeys": {}, + "everythingReady": "", + "@everythingReady": { + "type": "text", + "placeholders": {} + }, + "emoteKeyboardNoRecents": "", + "@emoteKeyboardNoRecents": { + "type": "text", + "placeholders": {} + }, + "setCustomEmotes": "", + "@setCustomEmotes": { + "type": "text", + "placeholders": {} + }, + "startedACall": "", + "@startedACall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "endToEndEncryption": "", + "@endToEndEncryption": {}, + "notificationsEnabledForThisAccount": "", + "@notificationsEnabledForThisAccount": { + "type": "text", + "placeholders": {} + }, + "setTheme": "", + "@setTheme": {}, + "youJoinedTheChat": "", + "@youJoinedTheChat": {}, + "openVideoCamera": "", + "@openVideoCamera": { + "type": "text", + "placeholders": {} + }, + "chatBackupDescription": "", + "@chatBackupDescription": { + "type": "text", + "placeholders": {} + }, + "thisUserHasNotPostedAnythingYet": "", + "@thisUserHasNotPostedAnythingYet": {}, + "markAsRead": "", + "@markAsRead": {}, + "widgetName": "", + "@widgetName": {}, + "errorAddingWidget": "", + "@errorAddingWidget": {}, + "commandHint_dm": "", + "@commandHint_dm": { + "type": "text", + "description": "Usage hint for the command /dm" + }, + "commandHint_hug": "", + "@commandHint_hug": {}, + "replace": "", + "@replace": {}, + "editBlockedServers": "", + "@editBlockedServers": { + "type": "text", + "placeholders": {} + }, + "oopsPushError": "", + "@oopsPushError": { + "type": "text", + "placeholders": {} + }, + "youUnbannedUser": "", + "@youUnbannedUser": { + "placeholders": { + "user": {} + } + }, + "deactivateAccountWarning": "", + "@deactivateAccountWarning": { + "type": "text", + "placeholders": {} + }, + "pleaseEnter4Digits": "", + "@pleaseEnter4Digits": { + "type": "text", + "placeholders": {} + }, + "newSpace": "", + "@newSpace": {}, + "emojis": "", + "@emojis": {}, + "pleaseEnterYourPin": "", + "@pleaseEnterYourPin": { + "type": "text", + "placeholders": {} + }, + "pleaseChoose": "", + "@pleaseChoose": { + "type": "text", + "placeholders": {} + }, + "commandHint_googly": "", + "@commandHint_googly": {}, + "pleaseTryAgainLaterOrChooseDifferentServer": "", + "@pleaseTryAgainLaterOrChooseDifferentServer": {}, + "createGroup": "", + "@createGroup": {}, + "privacy": "", + "@privacy": { + "type": "text", + "placeholders": {} + }, + "changeYourAvatar": "", + "@changeYourAvatar": { + "type": "text", + "placeholders": {} + }, + "hydrateTorLong": "", + "@hydrateTorLong": {}, + "time": "", + "@time": {}, + "botMessages": "", + "@botMessages": { + "type": "text", + "placeholders": {} + }, + "contentHasBeenReported": "", + "@contentHasBeenReported": { + "type": "text", + "placeholders": {} + }, + "custom": "", + "@custom": {}, + "noBackupWarning": "", + "@noBackupWarning": {}, + "editWidgets": "", + "@editWidgets": {}, + "storeInSecureStorageDescription": "", + "@storeInSecureStorageDescription": {}, + "openChat": "", + "@openChat": {}, + "kickUserDescription": "", + "@kickUserDescription": {}, + "pin": "", + "@pin": { + "type": "text", + "placeholders": {} + }, + "deleteAccount": "", + "@deleteAccount": { + "type": "text", + "placeholders": {} + }, + "pinMessage": "", + "@pinMessage": {}, + "invite": "", + "@invite": {}, + "enableMultiAccounts": "", + "@enableMultiAccounts": {}, + "emotePacks": "", + "@emotePacks": { + "type": "text", + "placeholders": {} + }, + "continueWith": "", + "@continueWith": {}, + "indexedDbErrorTitle": "", + "@indexedDbErrorTitle": {}, + "endedTheCall": "", + "@endedTheCall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "unsupportedAndroidVersionLong": "", + "@unsupportedAndroidVersionLong": {}, + "storeSecurlyOnThisDevice": "", + "@storeSecurlyOnThisDevice": {}, + "iUnderstand": "", + "@iUnderstand": {}, + "screenSharingDetail": "", + "@screenSharingDetail": {}, + "passwordHasBeenChanged": "", + "@passwordHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "withTheseAddressesRecoveryDescription": "", + "@withTheseAddressesRecoveryDescription": { + "type": "text", + "placeholders": {} + }, + "noPasswordRecoveryDescription": "", + "@noPasswordRecoveryDescription": { + "type": "text", + "placeholders": {} + }, + "sentCallInformations": "", + "@sentCallInformations": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "containsUserName": "", + "@containsUserName": { + "type": "text", + "placeholders": {} + }, + "passwordForgotten": "", + "@passwordForgotten": { + "type": "text", + "placeholders": {} + }, + "placeCall": "", + "@placeCall": {}, + "extremeOffensive": "", + "@extremeOffensive": { + "type": "text", + "placeholders": {} + } } diff --git a/assets/l10n/intl_sl.arb b/assets/l10n/intl_sl.arb index d450ec2e2..f2c32d758 100644 --- a/assets/l10n/intl_sl.arb +++ b/assets/l10n/intl_sl.arb @@ -1,606 +1,2630 @@ { - "passwordsDoNotMatch": "Geslo se ne ujema!", - "@passwordsDoNotMatch": {}, - "pleaseEnterValidEmail": "Vnesite veljaven elektronski naslov.", - "@pleaseEnterValidEmail": {}, - "repeatPassword": "Ponovite geslo", - "@repeatPassword": {}, - "about": "O aplikaciji", - "@about": { - "type": "text", - "placeholders": {} - }, - "accept": "Sprejmi", - "@accept": { - "type": "text", - "placeholders": {} - }, - "account": "Račun", - "@account": { - "type": "text", - "placeholders": {} - }, - "activatedEndToEndEncryption": "Uporabnik {username} je aktiviral šifriranje od konca do konca", - "@activatedEndToEndEncryption": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "addEmail": "Dodajte e-pošto", - "@addEmail": { - "type": "text", - "placeholders": {} - }, - "addGroupDescription": "Dodajte opis skupine", - "@addGroupDescription": { - "type": "text", - "placeholders": {} - }, - "addToSpace": "Dodajte v prostor", - "@addToSpace": {}, - "alias": "vzdevek", - "@alias": { - "type": "text", - "placeholders": {} - }, - "all": "Vse", - "@all": { - "type": "text", - "placeholders": {} - }, - "allChats": "Vsi klepeti", - "@allChats": { - "type": "text", - "placeholders": {} - }, - "answeredTheCall": "Oseba {senderName} je odgovorila na klic", - "@answeredTheCall": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "anyoneCanJoin": "Pridruži se lahko vsak", - "@anyoneCanJoin": { - "type": "text", - "placeholders": {} - }, - "appLock": "Zaklepanje aplikacije", - "@appLock": { - "type": "text", - "placeholders": {} - }, - "askSSSSSign": "Če želite podpisati drugo osebo, vnesite geslo za varno trgovino ali obnovitveni ključ.", - "@askSSSSSign": { - "type": "text", - "placeholders": {} - }, - "askVerificationRequest": "Ali želite sprejeti to zahtevo za preverjanje od {username}?", - "@askVerificationRequest": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "autoplayImages": "Samodejno predvajajte animirane nalepke in čustva", - "@autoplayImages": { - "type": "text", - "placeholder": {} - }, - "badServerLoginTypesException": "Domači strežnik podpira vrste prijave:\n{serverVersions}\nToda ta aplikacija podpira samo:\n{supportedVersions}", - "@badServerLoginTypesException": { - "type": "text", - "placeholders": { - "serverVersions": {}, - "supportedVersions": {} - } - }, - "sendOnEnter": "Pošlji ob vstopu", - "@sendOnEnter": {}, - "banFromChat": "Prepoved klepeta", - "@banFromChat": { - "type": "text", - "placeholders": {} - }, - "banned": "Prepovedano", - "@banned": { - "type": "text", - "placeholders": {} - }, - "bannedUser": "{username} je prepovedan v {targetName}", - "@bannedUser": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "blockDevice": "Blokirana naprava", - "@blockDevice": { - "type": "text", - "placeholders": {} - }, - "blocked": "Blokirano", - "@blocked": { - "type": "text", - "placeholders": {} - }, - "botMessages": "Botova sporočila", - "@botMessages": { - "type": "text", - "placeholders": {} - }, - "cancel": "Prekliči", - "@cancel": { - "type": "text", - "placeholders": {} - }, - "cantOpenUri": "URI-ja {uri} ni mogoče odpreti", - "@cantOpenUri": { - "type": "text", - "placeholders": { - "uri": {} - } - }, - "changedTheChatAvatar": "{username} je spremenil avatar za klepet", - "@changedTheChatAvatar": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheChatPermissions": "{username} je spremenila dovoljenja za klepet", - "@changedTheChatPermissions": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheDisplaynameTo": "{username} je spremenil svoje prikazno ime v: '{displayname}'", - "@changedTheDisplaynameTo": { - "type": "text", - "placeholders": { - "username": {}, - "displayname": {} - } - }, - "changedTheGuestAccessRules": "{username} je spremenila pravila dostopa za goste", - "@changedTheGuestAccessRules": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheGuestAccessRulesTo": "{username} je spremenila pravila dostopa za goste v: {rules}", - "@changedTheGuestAccessRulesTo": { - "type": "text", - "placeholders": { - "username": {}, - "rules": {} - } - }, - "changedTheHistoryVisibilityTo": "{username} je spremenil vidnost zgodovine v: {rules}", - "@changedTheHistoryVisibilityTo": { - "type": "text", - "placeholders": { - "username": {}, - "rules": {} - } - }, - "changedTheJoinRules": "{username} je spremenil pravila za pridružitev", - "@changedTheJoinRules": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheJoinRulesTo": "{username} je spremenila pravila pridružitve v: {joinRules}", - "@changedTheJoinRulesTo": { - "type": "text", - "placeholders": { - "username": {}, - "joinRules": {} - } - }, - "changedTheProfileAvatar": "{username} je spremenil avatar", - "@changedTheProfileAvatar": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheRoomAliases": "{username} je spremenil vzdevke sobe", - "@changedTheRoomAliases": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheRoomInvitationLink": "{username} je spremenil povezavo za povabilo", - "@changedTheRoomInvitationLink": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changePassword": "Spremeni geslo", - "@changePassword": { - "type": "text", - "placeholders": {} - }, - "changeTheHomeserver": "Spremenite domači strežnik", - "@changeTheHomeserver": { - "type": "text", - "placeholders": {} - }, - "changeTheme": "Spremenite svoj slog", - "@changeTheme": { - "type": "text", - "placeholders": {} - }, - "changeTheNameOfTheGroup": "Spremenite ime skupine", - "@changeTheNameOfTheGroup": { - "type": "text", - "placeholders": {} - }, - "changeYourAvatar": "Spremenite svoj avatar", - "@changeYourAvatar": { - "type": "text", - "placeholders": {} - }, - "chat": "Klepet", - "@chat": { - "type": "text", - "placeholders": {} - }, - "yourChatBackupHasBeenSetUp": "Varnostna kopija klepeta je nastavljena.", - "@yourChatBackupHasBeenSetUp": {}, - "chatBackup": "Varnostno kopiranje klepeta", - "@chatBackup": { - "type": "text", - "placeholders": {} - }, - "chatDetails": "Podrobnosti klepeta", - "@chatDetails": { - "type": "text", - "placeholders": {} - }, - "chatHasBeenAddedToThisSpace": "Klepet je bil dodan v ta prostor", - "@chatHasBeenAddedToThisSpace": {}, - "chats": "Klepeti", - "@chats": { - "type": "text", - "placeholders": {} - }, - "chooseAStrongPassword": "Izberite močno geslo", - "@chooseAStrongPassword": { - "type": "text", - "placeholders": {} - }, - "chooseAUsername": "Izberi uporabniško ime", - "@chooseAUsername": { - "type": "text", - "placeholders": {} - }, - "clearArchive": "Počisti arhiv", - "@clearArchive": {}, - "close": "Zapri", - "@close": { - "type": "text", - "placeholders": {} - }, - "commandHint_ban": "Izključi določenega uporabnika iz te sobe", - "@commandHint_ban": { - "type": "text", - "description": "Usage hint for the command /ban" - }, - "commandHint_html": "Pošljite besedilo v obliki HTML", - "@commandHint_html": { - "type": "text", - "description": "Usage hint for the command /html" - }, - "commandHint_invite": "Povabi danega uporabnika v to sobo", - "@commandHint_invite": { - "type": "text", - "description": "Usage hint for the command /invite" - }, - "commandHint_join": "Pridružite se dani sobi", - "@commandHint_join": { - "type": "text", - "description": "Usage hint for the command /join" - }, - "commandHint_kick": "Odstranite danega uporabnika iz te sobe", - "@commandHint_kick": { - "type": "text", - "description": "Usage hint for the command /kick" - }, - "commandHint_me": "Opisi sebe", - "@commandHint_me": { - "type": "text", - "description": "Usage hint for the command /me" - }, - "commandHint_myroomavatar": "Nastavite svojo sliko za to sobo", - "@commandHint_myroomavatar": { - "type": "text", - "description": "Usage hint for the command /myroomavatar" - }, - "commandHint_op": "Nastavite raven moči danega uporabnika (privzeto: 50)", - "@commandHint_op": { - "type": "text", - "description": "Usage hint for the command /op" - }, - "commandHint_react": "Pošljite odgovor kot reakcijo", - "@commandHint_react": { - "type": "text", - "description": "Usage hint for the command /react" - }, - "commandHint_send": "Pošlji besedilo", - "@commandHint_send": { - "type": "text", - "description": "Usage hint for the command /send" - }, - "commandHint_unban": "Prekliči izključitev določenega uporabnika iz te sobe", - "@commandHint_unban": { - "type": "text", - "description": "Usage hint for the command /unban" - }, - "commandInvalid": "Ukaz ni veljaven", - "@commandInvalid": { - "type": "text" - }, - "commandMissing": "{command} is not a command.", - "@commandMissing": { - "type": "text", - "placeholders": { - "command": {} - }, - "description": "State that {command} is not a valid /command." - }, - "compareEmojiMatch": "Primerjajte in se prepričajte, da se naslednji emoji ujemajo s tistimi iz druge naprave:", - "@compareEmojiMatch": { - "type": "text", - "placeholders": {} - }, - "compareNumbersMatch": "Primerjajte in se prepričajte, da se naslednje številke ujemajo s številkami druge naprave:", - "@compareNumbersMatch": { - "type": "text", - "placeholders": {} - }, - "configureChat": "Konfigurirajte klepet", - "@configureChat": { - "type": "text", - "placeholders": {} - }, - "confirm": "Potrdi", - "@confirm": { - "type": "text", - "placeholders": {} - }, - "containsDisplayName": "Vsebuje prikazno ime", - "@containsDisplayName": { - "type": "text", - "placeholders": {} - }, - "containsUserName": "Vsebuje uporabniško ime", - "@containsUserName": { - "type": "text", - "placeholders": {} - }, - "pleaseChooseAtLeastChars": "Izberite najmanj {min} znakov.", - "@pleaseChooseAtLeastChars": { - "type": "text", - "placeholders": { - "min": {} - } - }, - "archive": "Arhiv", - "@archive": { - "type": "text", - "placeholders": {} - }, - "areYouSure": "Ali si prepričan?", - "@areYouSure": { - "type": "text", - "placeholders": {} - }, - "acceptedTheInvitation": "{username} je sprejel povabilo", - "@acceptedTheInvitation": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "areYouSureYouWantToLogout": "Ali ste prepričani, da se želite odjaviti?", - "@areYouSureYouWantToLogout": { - "type": "text", - "placeholders": {} - }, - "changedTheChatDescriptionTo": "{username} je spremenil opis klepeta v: '{description}'", - "@changedTheChatDescriptionTo": { - "type": "text", - "placeholders": { - "username": {}, - "description": {} - } - }, - "areGuestsAllowedToJoin": "Ali se lahko gostujoči uporabniki pridružijo", - "@areGuestsAllowedToJoin": { - "type": "text", - "placeholders": {} - }, - "admin": "Admin", - "@admin": { - "type": "text", - "placeholders": {} - }, - "badServerVersionsException": "Domači strežnik podpira različice Spec:\n{serverVersions}\nToda ta aplikacija podpira samo {supportedVersions}", - "@badServerVersionsException": { - "type": "text", - "placeholders": { - "serverVersions": {}, - "supportedVersions": {} - } - }, - "changedTheChatNameTo": "{username} je spremenil ime klepeta v: '{chatname}'", - "@changedTheChatNameTo": { - "type": "text", - "placeholders": { - "username": {}, - "chatname": {} - } - }, - "changeDeviceName": "Spremenite ime naprave", - "@changeDeviceName": { - "type": "text", - "placeholders": {} - }, - "changeWallpaper": "Spremeni ozadje", - "@changeWallpaper": { - "type": "text", - "placeholders": {} - }, - "changedTheHistoryVisibility": "{username} je spremenila vidnost zgodovine", - "@changedTheHistoryVisibility": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "channelCorruptedDecryptError": "Šifriranje je poškodovano", - "@channelCorruptedDecryptError": { - "type": "text", - "placeholders": {} - }, - "contentHasBeenReported": "Vsebina je bila prijavljena skrbnikom strežnika", - "@contentHasBeenReported": { - "type": "text", - "placeholders": {} - }, - "chatBackupDescription": "Varnostna kopija klepeta je zavarovana z varnostnim ključem. Prosimo, pazite, da ga ne izgubite.", - "@chatBackupDescription": { - "type": "text", - "placeholders": {} - }, - "commandHint_myroomnick": "Nastavite prikazno ime za to sobo", - "@commandHint_myroomnick": { - "type": "text", - "description": "Usage hint for the command /myroomnick" - }, - "connect": "Povežite se", - "@connect": { - "type": "text", - "placeholders": {} - }, - "contactHasBeenInvitedToTheGroup": "Kontakt je bil povabljen v skupino", - "@contactHasBeenInvitedToTheGroup": { - "type": "text", - "placeholders": {} - }, - "commandHint_leave": "Zapusti to sobo", - "@commandHint_leave": { - "type": "text", - "description": "Usage hint for the command /leave" - }, - "commandHint_plain": "Pošlji neformatirano besedilo", - "@commandHint_plain": { - "type": "text", - "description": "Usage hint for the command /plain" - }, - "copiedToClipboard": "Kopirano v odložišče", - "@copiedToClipboard": { - "type": "text", - "placeholders": {} - }, - "copy": "Kopiraj", - "@copy": { - "type": "text", - "placeholders": {} - }, - "copyToClipboard": "Kopiraj v odložišče", - "@copyToClipboard": { - "type": "text", - "placeholders": {} - }, - "couldNotDecryptMessage": "Sporočila ni bilo mogoče dešifrirati: {error}", - "@couldNotDecryptMessage": { - "type": "text", - "placeholders": { - "error": {} - } - }, - "countParticipants": "{count} udeležencev", - "@countParticipants": { - "type": "text", - "placeholders": { - "count": {} - } - }, - "create": "Ustvari", - "@create": { - "type": "text", - "placeholders": {} - }, - "createNewGroup": "Ustvari novo skupino", - "@createNewGroup": { - "type": "text", - "placeholders": {} - }, - "createNewSpace": "Nov prostor", - "@createNewSpace": { - "type": "text", - "placeholders": {} - }, - "currentlyActive": "Trenutno aktiven", - "@currentlyActive": { - "type": "text", - "placeholders": {} - }, - "darkTheme": "Temno", - "@darkTheme": { - "type": "text", - "placeholders": {} - }, - "defaultPermissionLevel": "Privzeta raven dovoljenja", - "@defaultPermissionLevel": { - "type": "text", - "placeholders": {} - }, - "dateWithYear": "{day}-{month}-{year}", - "@dateWithYear": { - "type": "text", - "placeholders": { - "year": {}, - "month": {}, - "day": {} - } - }, - "dateWithoutYear": "{month}-{day}", - "@dateWithoutYear": { - "type": "text", - "placeholders": { - "month": {}, - "day": {} - } - }, - "createdTheChat": "{username} je ustvaril klepet", - "@createdTheChat": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "dateAndTimeOfDay": "{date}, {timeOfDay}", - "@dateAndTimeOfDay": { - "type": "text", - "placeholders": { - "date": {}, - "timeOfDay": {} - } - }, - "deactivateAccountWarning": "S tem boste deaktivirali vaš uporabniški račun. Tega ni mogoče razveljaviti! Ali si prepričan?", - "@deactivateAccountWarning": { - "type": "text", - "placeholders": {} + "passwordsDoNotMatch": "Geslo se ne ujema!", + "@passwordsDoNotMatch": {}, + "pleaseEnterValidEmail": "Vnesite veljaven elektronski naslov.", + "@pleaseEnterValidEmail": {}, + "repeatPassword": "Ponovite geslo", + "@repeatPassword": {}, + "about": "O aplikaciji", + "@about": { + "type": "text", + "placeholders": {} + }, + "accept": "Sprejmi", + "@accept": { + "type": "text", + "placeholders": {} + }, + "account": "Račun", + "@account": { + "type": "text", + "placeholders": {} + }, + "activatedEndToEndEncryption": "Uporabnik {username} je aktiviral šifriranje od konca do konca", + "@activatedEndToEndEncryption": { + "type": "text", + "placeholders": { + "username": {} } -} \ No newline at end of file + }, + "addEmail": "Dodajte e-pošto", + "@addEmail": { + "type": "text", + "placeholders": {} + }, + "addGroupDescription": "Dodajte opis skupine", + "@addGroupDescription": { + "type": "text", + "placeholders": {} + }, + "addToSpace": "Dodajte v prostor", + "@addToSpace": {}, + "alias": "vzdevek", + "@alias": { + "type": "text", + "placeholders": {} + }, + "all": "Vse", + "@all": { + "type": "text", + "placeholders": {} + }, + "allChats": "Vsi klepeti", + "@allChats": { + "type": "text", + "placeholders": {} + }, + "answeredTheCall": "Oseba {senderName} je odgovorila na klic", + "@answeredTheCall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "anyoneCanJoin": "Pridruži se lahko vsak", + "@anyoneCanJoin": { + "type": "text", + "placeholders": {} + }, + "appLock": "Zaklepanje aplikacije", + "@appLock": { + "type": "text", + "placeholders": {} + }, + "askSSSSSign": "Če želite podpisati drugo osebo, vnesite geslo za varno trgovino ali obnovitveni ključ.", + "@askSSSSSign": { + "type": "text", + "placeholders": {} + }, + "askVerificationRequest": "Ali želite sprejeti to zahtevo za preverjanje od {username}?", + "@askVerificationRequest": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "autoplayImages": "Samodejno predvajajte animirane nalepke in čustva", + "@autoplayImages": { + "type": "text", + "placeholder": {} + }, + "badServerLoginTypesException": "Domači strežnik podpira vrste prijave:\n{serverVersions}\nToda ta aplikacija podpira samo:\n{supportedVersions}", + "@badServerLoginTypesException": { + "type": "text", + "placeholders": { + "serverVersions": {}, + "supportedVersions": {} + } + }, + "sendOnEnter": "Pošlji ob vstopu", + "@sendOnEnter": {}, + "banFromChat": "Prepoved klepeta", + "@banFromChat": { + "type": "text", + "placeholders": {} + }, + "banned": "Prepovedano", + "@banned": { + "type": "text", + "placeholders": {} + }, + "bannedUser": "{username} je prepovedan v {targetName}", + "@bannedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "blockDevice": "Blokirana naprava", + "@blockDevice": { + "type": "text", + "placeholders": {} + }, + "blocked": "Blokirano", + "@blocked": { + "type": "text", + "placeholders": {} + }, + "botMessages": "Botova sporočila", + "@botMessages": { + "type": "text", + "placeholders": {} + }, + "cancel": "Prekliči", + "@cancel": { + "type": "text", + "placeholders": {} + }, + "cantOpenUri": "URI-ja {uri} ni mogoče odpreti", + "@cantOpenUri": { + "type": "text", + "placeholders": { + "uri": {} + } + }, + "changedTheChatAvatar": "{username} je spremenil avatar za klepet", + "@changedTheChatAvatar": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheChatPermissions": "{username} je spremenila dovoljenja za klepet", + "@changedTheChatPermissions": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheDisplaynameTo": "{username} je spremenil svoje prikazno ime v: '{displayname}'", + "@changedTheDisplaynameTo": { + "type": "text", + "placeholders": { + "username": {}, + "displayname": {} + } + }, + "changedTheGuestAccessRules": "{username} je spremenila pravila dostopa za goste", + "@changedTheGuestAccessRules": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheGuestAccessRulesTo": "{username} je spremenila pravila dostopa za goste v: {rules}", + "@changedTheGuestAccessRulesTo": { + "type": "text", + "placeholders": { + "username": {}, + "rules": {} + } + }, + "changedTheHistoryVisibilityTo": "{username} je spremenil vidnost zgodovine v: {rules}", + "@changedTheHistoryVisibilityTo": { + "type": "text", + "placeholders": { + "username": {}, + "rules": {} + } + }, + "changedTheJoinRules": "{username} je spremenil pravila za pridružitev", + "@changedTheJoinRules": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheJoinRulesTo": "{username} je spremenila pravila pridružitve v: {joinRules}", + "@changedTheJoinRulesTo": { + "type": "text", + "placeholders": { + "username": {}, + "joinRules": {} + } + }, + "changedTheProfileAvatar": "{username} je spremenil avatar", + "@changedTheProfileAvatar": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheRoomAliases": "{username} je spremenil vzdevke sobe", + "@changedTheRoomAliases": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheRoomInvitationLink": "{username} je spremenil povezavo za povabilo", + "@changedTheRoomInvitationLink": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changePassword": "Spremeni geslo", + "@changePassword": { + "type": "text", + "placeholders": {} + }, + "changeTheHomeserver": "Spremenite domači strežnik", + "@changeTheHomeserver": { + "type": "text", + "placeholders": {} + }, + "changeTheme": "Spremenite svoj slog", + "@changeTheme": { + "type": "text", + "placeholders": {} + }, + "changeTheNameOfTheGroup": "Spremenite ime skupine", + "@changeTheNameOfTheGroup": { + "type": "text", + "placeholders": {} + }, + "changeYourAvatar": "Spremenite svoj avatar", + "@changeYourAvatar": { + "type": "text", + "placeholders": {} + }, + "chat": "Klepet", + "@chat": { + "type": "text", + "placeholders": {} + }, + "yourChatBackupHasBeenSetUp": "Varnostna kopija klepeta je nastavljena.", + "@yourChatBackupHasBeenSetUp": {}, + "chatBackup": "Varnostno kopiranje klepeta", + "@chatBackup": { + "type": "text", + "placeholders": {} + }, + "chatDetails": "Podrobnosti klepeta", + "@chatDetails": { + "type": "text", + "placeholders": {} + }, + "chatHasBeenAddedToThisSpace": "Klepet je bil dodan v ta prostor", + "@chatHasBeenAddedToThisSpace": {}, + "chats": "Klepeti", + "@chats": { + "type": "text", + "placeholders": {} + }, + "chooseAStrongPassword": "Izberite močno geslo", + "@chooseAStrongPassword": { + "type": "text", + "placeholders": {} + }, + "chooseAUsername": "Izberi uporabniško ime", + "@chooseAUsername": { + "type": "text", + "placeholders": {} + }, + "clearArchive": "Počisti arhiv", + "@clearArchive": {}, + "close": "Zapri", + "@close": { + "type": "text", + "placeholders": {} + }, + "commandHint_ban": "Izključi določenega uporabnika iz te sobe", + "@commandHint_ban": { + "type": "text", + "description": "Usage hint for the command /ban" + }, + "commandHint_html": "Pošljite besedilo v obliki HTML", + "@commandHint_html": { + "type": "text", + "description": "Usage hint for the command /html" + }, + "commandHint_invite": "Povabi danega uporabnika v to sobo", + "@commandHint_invite": { + "type": "text", + "description": "Usage hint for the command /invite" + }, + "commandHint_join": "Pridružite se dani sobi", + "@commandHint_join": { + "type": "text", + "description": "Usage hint for the command /join" + }, + "commandHint_kick": "Odstranite danega uporabnika iz te sobe", + "@commandHint_kick": { + "type": "text", + "description": "Usage hint for the command /kick" + }, + "commandHint_me": "Opisi sebe", + "@commandHint_me": { + "type": "text", + "description": "Usage hint for the command /me" + }, + "commandHint_myroomavatar": "Nastavite svojo sliko za to sobo", + "@commandHint_myroomavatar": { + "type": "text", + "description": "Usage hint for the command /myroomavatar" + }, + "commandHint_op": "Nastavite raven moči danega uporabnika (privzeto: 50)", + "@commandHint_op": { + "type": "text", + "description": "Usage hint for the command /op" + }, + "commandHint_react": "Pošljite odgovor kot reakcijo", + "@commandHint_react": { + "type": "text", + "description": "Usage hint for the command /react" + }, + "commandHint_send": "Pošlji besedilo", + "@commandHint_send": { + "type": "text", + "description": "Usage hint for the command /send" + }, + "commandHint_unban": "Prekliči izključitev določenega uporabnika iz te sobe", + "@commandHint_unban": { + "type": "text", + "description": "Usage hint for the command /unban" + }, + "commandInvalid": "Ukaz ni veljaven", + "@commandInvalid": { + "type": "text" + }, + "commandMissing": "{command} is not a command.", + "@commandMissing": { + "type": "text", + "placeholders": { + "command": {} + }, + "description": "State that {command} is not a valid /command." + }, + "compareEmojiMatch": "Primerjajte in se prepričajte, da se naslednji emoji ujemajo s tistimi iz druge naprave:", + "@compareEmojiMatch": { + "type": "text", + "placeholders": {} + }, + "compareNumbersMatch": "Primerjajte in se prepričajte, da se naslednje številke ujemajo s številkami druge naprave:", + "@compareNumbersMatch": { + "type": "text", + "placeholders": {} + }, + "configureChat": "Konfigurirajte klepet", + "@configureChat": { + "type": "text", + "placeholders": {} + }, + "confirm": "Potrdi", + "@confirm": { + "type": "text", + "placeholders": {} + }, + "containsDisplayName": "Vsebuje prikazno ime", + "@containsDisplayName": { + "type": "text", + "placeholders": {} + }, + "containsUserName": "Vsebuje uporabniško ime", + "@containsUserName": { + "type": "text", + "placeholders": {} + }, + "pleaseChooseAtLeastChars": "Izberite najmanj {min} znakov.", + "@pleaseChooseAtLeastChars": { + "type": "text", + "placeholders": { + "min": {} + } + }, + "archive": "Arhiv", + "@archive": { + "type": "text", + "placeholders": {} + }, + "areYouSure": "Ali si prepričan?", + "@areYouSure": { + "type": "text", + "placeholders": {} + }, + "acceptedTheInvitation": "{username} je sprejel povabilo", + "@acceptedTheInvitation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "areYouSureYouWantToLogout": "Ali ste prepričani, da se želite odjaviti?", + "@areYouSureYouWantToLogout": { + "type": "text", + "placeholders": {} + }, + "changedTheChatDescriptionTo": "{username} je spremenil opis klepeta v: '{description}'", + "@changedTheChatDescriptionTo": { + "type": "text", + "placeholders": { + "username": {}, + "description": {} + } + }, + "areGuestsAllowedToJoin": "Ali se lahko gostujoči uporabniki pridružijo", + "@areGuestsAllowedToJoin": { + "type": "text", + "placeholders": {} + }, + "admin": "Admin", + "@admin": { + "type": "text", + "placeholders": {} + }, + "badServerVersionsException": "Domači strežnik podpira različice Spec:\n{serverVersions}\nToda ta aplikacija podpira samo {supportedVersions}", + "@badServerVersionsException": { + "type": "text", + "placeholders": { + "serverVersions": {}, + "supportedVersions": {} + } + }, + "changedTheChatNameTo": "{username} je spremenil ime klepeta v: '{chatname}'", + "@changedTheChatNameTo": { + "type": "text", + "placeholders": { + "username": {}, + "chatname": {} + } + }, + "changeDeviceName": "Spremenite ime naprave", + "@changeDeviceName": { + "type": "text", + "placeholders": {} + }, + "changeWallpaper": "Spremeni ozadje", + "@changeWallpaper": { + "type": "text", + "placeholders": {} + }, + "changedTheHistoryVisibility": "{username} je spremenila vidnost zgodovine", + "@changedTheHistoryVisibility": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "channelCorruptedDecryptError": "Šifriranje je poškodovano", + "@channelCorruptedDecryptError": { + "type": "text", + "placeholders": {} + }, + "contentHasBeenReported": "Vsebina je bila prijavljena skrbnikom strežnika", + "@contentHasBeenReported": { + "type": "text", + "placeholders": {} + }, + "chatBackupDescription": "Varnostna kopija klepeta je zavarovana z varnostnim ključem. Prosimo, pazite, da ga ne izgubite.", + "@chatBackupDescription": { + "type": "text", + "placeholders": {} + }, + "commandHint_myroomnick": "Nastavite prikazno ime za to sobo", + "@commandHint_myroomnick": { + "type": "text", + "description": "Usage hint for the command /myroomnick" + }, + "connect": "Povežite se", + "@connect": { + "type": "text", + "placeholders": {} + }, + "contactHasBeenInvitedToTheGroup": "Kontakt je bil povabljen v skupino", + "@contactHasBeenInvitedToTheGroup": { + "type": "text", + "placeholders": {} + }, + "commandHint_leave": "Zapusti to sobo", + "@commandHint_leave": { + "type": "text", + "description": "Usage hint for the command /leave" + }, + "commandHint_plain": "Pošlji neformatirano besedilo", + "@commandHint_plain": { + "type": "text", + "description": "Usage hint for the command /plain" + }, + "copiedToClipboard": "Kopirano v odložišče", + "@copiedToClipboard": { + "type": "text", + "placeholders": {} + }, + "copy": "Kopiraj", + "@copy": { + "type": "text", + "placeholders": {} + }, + "copyToClipboard": "Kopiraj v odložišče", + "@copyToClipboard": { + "type": "text", + "placeholders": {} + }, + "couldNotDecryptMessage": "Sporočila ni bilo mogoče dešifrirati: {error}", + "@couldNotDecryptMessage": { + "type": "text", + "placeholders": { + "error": {} + } + }, + "countParticipants": "{count} udeležencev", + "@countParticipants": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "create": "Ustvari", + "@create": { + "type": "text", + "placeholders": {} + }, + "createNewGroup": "Ustvari novo skupino", + "@createNewGroup": { + "type": "text", + "placeholders": {} + }, + "createNewSpace": "Nov prostor", + "@createNewSpace": { + "type": "text", + "placeholders": {} + }, + "currentlyActive": "Trenutno aktiven", + "@currentlyActive": { + "type": "text", + "placeholders": {} + }, + "darkTheme": "Temno", + "@darkTheme": { + "type": "text", + "placeholders": {} + }, + "defaultPermissionLevel": "Privzeta raven dovoljenja", + "@defaultPermissionLevel": { + "type": "text", + "placeholders": {} + }, + "dateWithYear": "{day}-{month}-{year}", + "@dateWithYear": { + "type": "text", + "placeholders": { + "year": {}, + "month": {}, + "day": {} + } + }, + "dateWithoutYear": "{month}-{day}", + "@dateWithoutYear": { + "type": "text", + "placeholders": { + "month": {}, + "day": {} + } + }, + "createdTheChat": "{username} je ustvaril klepet", + "@createdTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "dateAndTimeOfDay": "{date}, {timeOfDay}", + "@dateAndTimeOfDay": { + "type": "text", + "placeholders": { + "date": {}, + "timeOfDay": {} + } + }, + "deactivateAccountWarning": "S tem boste deaktivirali vaš uporabniški račun. Tega ni mogoče razveljaviti! Ali si prepričan?", + "@deactivateAccountWarning": { + "type": "text", + "placeholders": {} + }, + "showPassword": "", + "@showPassword": { + "type": "text", + "placeholders": {} + }, + "hugContent": "", + "@hugContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "passphraseOrKey": "", + "@passphraseOrKey": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourPassword": "", + "@pleaseEnterYourPassword": { + "type": "text", + "placeholders": {} + }, + "theyMatch": "", + "@theyMatch": { + "type": "text", + "placeholders": {} + }, + "jumpToLastReadMessage": "", + "@jumpToLastReadMessage": {}, + "allRooms": "", + "@allRooms": { + "type": "text", + "placeholders": {} + }, + "obtainingLocation": "", + "@obtainingLocation": { + "type": "text", + "placeholders": {} + }, + "whoCanSeeMyStories": "", + "@whoCanSeeMyStories": {}, + "commandHint_cuddle": "", + "@commandHint_cuddle": {}, + "widgetVideo": "", + "@widgetVideo": {}, + "dismiss": "", + "@dismiss": {}, + "unknownDevice": "", + "@unknownDevice": { + "type": "text", + "placeholders": {} + }, + "emoteShortcode": "", + "@emoteShortcode": { + "type": "text", + "placeholders": {} + }, + "noEncryptionForPublicRooms": "", + "@noEncryptionForPublicRooms": { + "type": "text", + "placeholders": {} + }, + "reportErrorDescription": "", + "@reportErrorDescription": {}, + "directChats": "", + "@directChats": { + "type": "text", + "placeholders": {} + }, + "setPermissionsLevel": "", + "@setPermissionsLevel": { + "type": "text", + "placeholders": {} + }, + "inviteContactToGroup": "", + "@inviteContactToGroup": { + "type": "text", + "placeholders": { + "groupName": {} + } + }, + "addAccount": "", + "@addAccount": {}, + "seenByUserAndUser": "", + "@seenByUserAndUser": { + "type": "text", + "placeholders": { + "username": {}, + "username2": {} + } + }, + "reply": "", + "@reply": { + "type": "text", + "placeholders": {} + }, + "removeYourAvatar": "", + "@removeYourAvatar": { + "type": "text", + "placeholders": {} + }, + "unsupportedAndroidVersion": "", + "@unsupportedAndroidVersion": {}, + "enterASpacepName": "", + "@enterASpacepName": {}, + "device": "", + "@device": { + "type": "text", + "placeholders": {} + }, + "widgetJitsi": "", + "@widgetJitsi": {}, + "youAreNoLongerParticipatingInThisChat": "", + "@youAreNoLongerParticipatingInThisChat": { + "type": "text", + "placeholders": {} + }, + "encryption": "", + "@encryption": { + "type": "text", + "placeholders": {} + }, + "messageType": "", + "@messageType": {}, + "noEmailWarning": "", + "@noEmailWarning": {}, + "indexedDbErrorLong": "", + "@indexedDbErrorLong": {}, + "oneClientLoggedOut": "", + "@oneClientLoggedOut": {}, + "toggleMuted": "", + "@toggleMuted": { + "type": "text", + "placeholders": {} + }, + "kicked": "", + "@kicked": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "title": "", + "@title": { + "description": "Title for the application", + "type": "text", + "placeholders": {} + }, + "verifySuccess": "", + "@verifySuccess": { + "type": "text", + "placeholders": {} + }, + "sendFile": "", + "@sendFile": { + "type": "text", + "placeholders": {} + }, + "newVerificationRequest": "", + "@newVerificationRequest": { + "type": "text", + "placeholders": {} + }, + "startFirstChat": "", + "@startFirstChat": {}, + "callingAccount": "", + "@callingAccount": {}, + "requestPermission": "", + "@requestPermission": { + "type": "text", + "placeholders": {} + }, + "sentAPicture": "", + "@sentAPicture": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "invited": "", + "@invited": { + "type": "text", + "placeholders": {} + }, + "setColorTheme": "", + "@setColorTheme": {}, + "nextAccount": "", + "@nextAccount": {}, + "commandHint_create": "", + "@commandHint_create": { + "type": "text", + "description": "Usage hint for the command /create" + }, + "youAreInvitedToThisChat": "", + "@youAreInvitedToThisChat": { + "type": "text", + "placeholders": {} + }, + "singlesignon": "", + "@singlesignon": { + "type": "text", + "placeholders": {} + }, + "warning": "", + "@warning": { + "type": "text", + "placeholders": {} + }, + "password": "", + "@password": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterAMatrixIdentifier": "", + "@pleaseEnterAMatrixIdentifier": { + "type": "text", + "placeholders": {} + }, + "allSpaces": "", + "@allSpaces": {}, + "supposedMxid": "", + "@supposedMxid": { + "type": "text", + "placeholders": { + "mxid": {} + } + }, + "editDisplayname": "", + "@editDisplayname": { + "type": "text", + "placeholders": {} + }, + "user": "", + "@user": {}, + "roomVersion": "", + "@roomVersion": { + "type": "text", + "placeholders": {} + }, + "sentAFile": "", + "@sentAFile": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "videoCall": "", + "@videoCall": { + "type": "text", + "placeholders": {} + }, + "youAcceptedTheInvitation": "", + "@youAcceptedTheInvitation": {}, + "noMatrixServer": "", + "@noMatrixServer": { + "type": "text", + "placeholders": { + "server1": {}, + "server2": {} + } + }, + "userAndOthersAreTyping": "", + "@userAndOthersAreTyping": { + "type": "text", + "placeholders": { + "username": {}, + "count": {} + } + }, + "youInvitedBy": "", + "@youInvitedBy": { + "placeholders": { + "user": {} + } + }, + "userIsTyping": "", + "@userIsTyping": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "openAppToReadMessages": "", + "@openAppToReadMessages": { + "type": "text", + "placeholders": {} + }, + "sentAVideo": "", + "@sentAVideo": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "banUserDescription": "", + "@banUserDescription": {}, + "inviteContact": "", + "@inviteContact": { + "type": "text", + "placeholders": {} + }, + "requests": "", + "@requests": {}, + "widgetEtherpad": "", + "@widgetEtherpad": {}, + "waitingPartnerAcceptRequest": "", + "@waitingPartnerAcceptRequest": { + "type": "text", + "placeholders": {} + }, + "remove": "", + "@remove": { + "type": "text", + "placeholders": {} + }, + "writeAMessage": "", + "@writeAMessage": { + "type": "text", + "placeholders": {} + }, + "stories": "", + "@stories": {}, + "id": "", + "@id": { + "type": "text", + "placeholders": {} + }, + "addToStory": "", + "@addToStory": {}, + "removeDevicesDescription": "", + "@removeDevicesDescription": {}, + "separateChatTypes": "", + "@separateChatTypes": { + "type": "text", + "placeholders": {} + }, + "tryAgain": "", + "@tryAgain": {}, + "youKickedAndBanned": "", + "@youKickedAndBanned": { + "placeholders": { + "user": {} + } + }, + "showDirectChatsInSpaces": "", + "@showDirectChatsInSpaces": { + "type": "text", + "placeholders": {} + }, + "removeDevice": "", + "@removeDevice": { + "type": "text", + "placeholders": {} + }, + "youCannotInviteYourself": "", + "@youCannotInviteYourself": { + "type": "text", + "placeholders": {} + }, + "unbanUserDescription": "", + "@unbanUserDescription": {}, + "todoLists": "", + "@todoLists": {}, + "userAndUserAreTyping": "", + "@userAndUserAreTyping": { + "type": "text", + "placeholders": { + "username": {}, + "username2": {} + } + }, + "pleaseClickOnLink": "", + "@pleaseClickOnLink": { + "type": "text", + "placeholders": {} + }, + "saveFile": "", + "@saveFile": { + "type": "text", + "placeholders": {} + }, + "seenByUserAndCountOthers": "", + "@seenByUserAndCountOthers": { + "type": "text", + "placeholders": { + "username": {}, + "count": {} + } + }, + "pickImage": "", + "@pickImage": { + "type": "text", + "placeholders": {} + }, + "youRejectedTheInvitation": "", + "@youRejectedTheInvitation": {}, + "otherCallingPermissions": "", + "@otherCallingPermissions": {}, + "messagesStyle": "", + "@messagesStyle": {}, + "invitedUsersOnly": "", + "@invitedUsersOnly": { + "type": "text", + "placeholders": {} + }, + "link": "", + "@link": {}, + "widgetUrlError": "", + "@widgetUrlError": {}, + "emailOrUsername": "", + "@emailOrUsername": {}, + "newSpaceDescription": "", + "@newSpaceDescription": {}, + "chatDescription": "", + "@chatDescription": {}, + "callingAccountDetails": "", + "@callingAccountDetails": {}, + "next": "", + "@next": { + "type": "text", + "placeholders": {} + }, + "pleaseFollowInstructionsOnWeb": "", + "@pleaseFollowInstructionsOnWeb": { + "type": "text", + "placeholders": {} + }, + "editRoomAliases": "", + "@editRoomAliases": { + "type": "text", + "placeholders": {} + }, + "enterSpace": "", + "@enterSpace": {}, + "encryptThisChat": "", + "@encryptThisChat": {}, + "fileName": "", + "@fileName": { + "type": "text", + "placeholders": {} + }, + "unavailable": "", + "@unavailable": { + "type": "text", + "placeholders": {} + }, + "previousAccount": "", + "@previousAccount": {}, + "publicRooms": "", + "@publicRooms": { + "type": "text", + "placeholders": {} + }, + "fromTheInvitation": "", + "@fromTheInvitation": { + "type": "text", + "placeholders": {} + }, + "sendMessages": "", + "@sendMessages": { + "type": "text", + "placeholders": {} + }, + "incorrectPassphraseOrKey": "", + "@incorrectPassphraseOrKey": { + "type": "text", + "placeholders": {} + }, + "emoteWarnNeedToPick": "", + "@emoteWarnNeedToPick": { + "type": "text", + "placeholders": {} + }, + "reopenChat": "", + "@reopenChat": {}, + "pleaseEnterRecoveryKey": "", + "@pleaseEnterRecoveryKey": {}, + "toggleFavorite": "", + "@toggleFavorite": { + "type": "text", + "placeholders": {} + }, + "no": "", + "@no": { + "type": "text", + "placeholders": {} + }, + "widgetNameError": "", + "@widgetNameError": {}, + "inoffensive": "", + "@inoffensive": { + "type": "text", + "placeholders": {} + }, + "unpin": "", + "@unpin": { + "type": "text", + "placeholders": {} + }, + "addToBundle": "", + "@addToBundle": {}, + "reportMessage": "", + "@reportMessage": { + "type": "text", + "placeholders": {} + }, + "spaceIsPublic": "", + "@spaceIsPublic": { + "type": "text", + "placeholders": {} + }, + "addWidget": "", + "@addWidget": {}, + "removeAllOtherDevices": "", + "@removeAllOtherDevices": { + "type": "text", + "placeholders": {} + }, + "unblockDevice": "", + "@unblockDevice": { + "type": "text", + "placeholders": {} + }, + "countFiles": "", + "@countFiles": { + "placeholders": { + "count": {} + } + }, + "noKeyForThisMessage": "", + "@noKeyForThisMessage": {}, + "enableEncryptionWarning": "", + "@enableEncryptionWarning": { + "type": "text", + "placeholders": {} + }, + "inviteText": "", + "@inviteText": { + "type": "text", + "placeholders": { + "username": {}, + "link": {} + } + }, + "shareLocation": "", + "@shareLocation": { + "type": "text", + "placeholders": {} + }, + "reason": "", + "@reason": { + "type": "text", + "placeholders": {} + }, + "commandHint_markasgroup": "", + "@commandHint_markasgroup": {}, + "editTodo": "", + "@editTodo": {}, + "errorObtainingLocation": "", + "@errorObtainingLocation": { + "type": "text", + "placeholders": { + "error": {} + } + }, + "hydrateTor": "", + "@hydrateTor": {}, + "pushNotificationsNotAvailable": "", + "@pushNotificationsNotAvailable": {}, + "passwordRecovery": "", + "@passwordRecovery": { + "type": "text", + "placeholders": {} + }, + "storeInAppleKeyChain": "", + "@storeInAppleKeyChain": {}, + "replaceRoomWithNewerVersion": "", + "@replaceRoomWithNewerVersion": { + "type": "text", + "placeholders": {} + }, + "hydrate": "", + "@hydrate": {}, + "invalidServerName": "", + "@invalidServerName": {}, + "chatPermissions": "", + "@chatPermissions": {}, + "voiceMessage": "", + "@voiceMessage": { + "type": "text", + "placeholders": {} + }, + "wipeChatBackup": "", + "@wipeChatBackup": { + "type": "text", + "placeholders": {} + }, + "sender": "", + "@sender": {}, + "storeInAndroidKeystore": "", + "@storeInAndroidKeystore": {}, + "optionalGroupName": "", + "@optionalGroupName": { + "type": "text", + "placeholders": {} + }, + "hideRedactedEvents": "", + "@hideRedactedEvents": { + "type": "text", + "placeholders": {} + }, + "online": "", + "@online": { + "type": "text", + "placeholders": {} + }, + "signInWithPassword": "", + "@signInWithPassword": {}, + "pleaseAddATitle": "", + "@pleaseAddATitle": {}, + "updateNow": "", + "@updateNow": {}, + "ignoredUsers": "", + "@ignoredUsers": { + "type": "text", + "placeholders": {} + }, + "lastActiveAgo": "", + "@lastActiveAgo": { + "type": "text", + "placeholders": { + "localizedTimeShort": {} + } + }, + "weSentYouAnEmail": "", + "@weSentYouAnEmail": { + "type": "text", + "placeholders": {} + }, + "offensive": "", + "@offensive": { + "type": "text", + "placeholders": {} + }, + "needPantalaimonWarning": "", + "@needPantalaimonWarning": { + "type": "text", + "placeholders": {} + }, + "makeAdminDescription": "", + "@makeAdminDescription": {}, + "edit": "", + "@edit": { + "type": "text", + "placeholders": {} + }, + "loadMore": "", + "@loadMore": { + "type": "text", + "placeholders": {} + }, + "noEmotesFound": "", + "@noEmotesFound": { + "type": "text", + "placeholders": {} + }, + "synchronizingPleaseWait": "", + "@synchronizingPleaseWait": { + "type": "text", + "placeholders": {} + }, + "transferFromAnotherDevice": "", + "@transferFromAnotherDevice": { + "type": "text", + "placeholders": {} + }, + "passwordHasBeenChanged": "", + "@passwordHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "pushRules": "", + "@pushRules": { + "type": "text", + "placeholders": {} + }, + "goToTheNewRoom": "", + "@goToTheNewRoom": { + "type": "text", + "placeholders": {} + }, + "commandHint_clearcache": "", + "@commandHint_clearcache": { + "type": "text", + "description": "Usage hint for the command /clearcache" + }, + "loadingPleaseWait": "", + "@loadingPleaseWait": { + "type": "text", + "placeholders": {} + }, + "saveKeyManuallyDescription": "", + "@saveKeyManuallyDescription": {}, + "none": "", + "@none": { + "type": "text", + "placeholders": {} + }, + "editBundlesForAccount": "", + "@editBundlesForAccount": {}, + "renderRichContent": "", + "@renderRichContent": { + "type": "text", + "placeholders": {} + }, + "enableEncryption": "", + "@enableEncryption": { + "type": "text", + "placeholders": {} + }, + "whyIsThisMessageEncrypted": "", + "@whyIsThisMessageEncrypted": {}, + "unreadChats": "", + "@unreadChats": { + "type": "text", + "placeholders": { + "unreadCount": {} + } + }, + "rejectedTheInvitation": "", + "@rejectedTheInvitation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "setChatDescription": "", + "@setChatDescription": {}, + "userLeftTheChat": "", + "@userLeftTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "spaceName": "", + "@spaceName": { + "type": "text", + "placeholders": {} + }, + "importFromZipFile": "", + "@importFromZipFile": {}, + "discover": "", + "@discover": { + "type": "text", + "placeholders": {} + }, + "toggleUnread": "", + "@toggleUnread": { + "type": "text", + "placeholders": {} + }, + "or": "", + "@or": { + "type": "text", + "placeholders": {} + }, + "dehydrateWarning": "", + "@dehydrateWarning": {}, + "sendOriginal": "", + "@sendOriginal": { + "type": "text", + "placeholders": {} + }, + "noOtherDevicesFound": "", + "@noOtherDevicesFound": {}, + "whoIsAllowedToJoinThisGroup": "", + "@whoIsAllowedToJoinThisGroup": { + "type": "text", + "placeholders": {} + }, + "emptyChat": "", + "@emptyChat": { + "type": "text", + "placeholders": {} + }, + "seenByUser": "", + "@seenByUser": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "addDescription": "", + "@addDescription": {}, + "redactedBy": "", + "@redactedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "submit": "", + "@submit": { + "type": "text", + "placeholders": {} + }, + "videoCallsBetaWarning": "", + "@videoCallsBetaWarning": {}, + "unmuteChat": "", + "@unmuteChat": { + "type": "text", + "placeholders": {} + }, + "redactedAnEvent": "", + "@redactedAnEvent": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "storyPrivacyWarning": "", + "@storyPrivacyWarning": {}, + "matrixWidgets": "", + "@matrixWidgets": {}, + "participant": "", + "@participant": { + "type": "text", + "placeholders": {} + }, + "logInTo": "", + "@logInTo": { + "type": "text", + "placeholders": { + "homeserver": {} + } + }, + "yes": "", + "@yes": { + "type": "text", + "placeholders": {} + }, + "signInWith": "", + "@signInWith": { + "type": "text", + "placeholders": { + "provider": {} + } + }, + "username": "", + "@username": { + "type": "text", + "placeholders": {} + }, + "updateAvailable": "", + "@updateAvailable": {}, + "fileIsTooBigForServer": "", + "@fileIsTooBigForServer": {}, + "homeserver": "", + "@homeserver": {}, + "help": "", + "@help": { + "type": "text", + "placeholders": {} + }, + "noTodosYet": "", + "@noTodosYet": {}, + "people": "", + "@people": { + "type": "text", + "placeholders": {} + }, + "leftTheChat": "", + "@leftTheChat": { + "type": "text", + "placeholders": {} + }, + "verified": "", + "@verified": { + "type": "text", + "placeholders": {} + }, + "setStatus": "", + "@setStatus": { + "type": "text", + "placeholders": {} + }, + "groupWith": "", + "@groupWith": { + "type": "text", + "placeholders": { + "displayname": {} + } + }, + "callingPermissions": "", + "@callingPermissions": {}, + "delete": "", + "@delete": { + "type": "text", + "placeholders": {} + }, + "newMessageInFluffyChat": "", + "@newMessageInFluffyChat": { + "type": "text", + "placeholders": {} + }, + "readUpToHere": "", + "@readUpToHere": {}, + "start": "", + "@start": {}, + "bubbleSize": "", + "@bubbleSize": { + "type": "text", + "placeholders": {} + }, + "downloadFile": "", + "@downloadFile": { + "type": "text", + "placeholders": {} + }, + "deviceId": "", + "@deviceId": { + "type": "text", + "placeholders": {} + }, + "register": "", + "@register": { + "type": "text", + "placeholders": {} + }, + "unlockOldMessages": "", + "@unlockOldMessages": {}, + "identity": "", + "@identity": { + "type": "text", + "placeholders": {} + }, + "numChats": "", + "@numChats": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "ignore": "", + "@ignore": { + "type": "text", + "placeholders": {} + }, + "whatIsGoingOn": "", + "@whatIsGoingOn": {}, + "recording": "", + "@recording": { + "type": "text", + "placeholders": {} + }, + "moderator": "", + "@moderator": { + "type": "text", + "placeholders": {} + }, + "optionalRedactReason": "", + "@optionalRedactReason": {}, + "waitingPartnerEmoji": "", + "@waitingPartnerEmoji": { + "type": "text", + "placeholders": {} + }, + "tryToSendAgain": "", + "@tryToSendAgain": { + "type": "text", + "placeholders": {} + }, + "guestsCanJoin": "", + "@guestsCanJoin": { + "type": "text", + "placeholders": {} + }, + "ok": "", + "@ok": { + "type": "text", + "placeholders": {} + }, + "dehydrate": "", + "@dehydrate": {}, + "locationPermissionDeniedNotice": "", + "@locationPermissionDeniedNotice": { + "type": "text", + "placeholders": {} + }, + "send": "", + "@send": { + "type": "text", + "placeholders": {} + }, + "hasWithdrawnTheInvitationFor": "", + "@hasWithdrawnTheInvitationFor": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "visibleForAllParticipants": "", + "@visibleForAllParticipants": { + "type": "text", + "placeholders": {} + }, + "noRoomsFound": "", + "@noRoomsFound": { + "type": "text", + "placeholders": {} + }, + "sendAsText": "", + "@sendAsText": { + "type": "text" + }, + "inviteForMe": "", + "@inviteForMe": { + "type": "text", + "placeholders": {} + }, + "archiveRoomDescription": "", + "@archiveRoomDescription": {}, + "exportEmotePack": "", + "@exportEmotePack": {}, + "sendSticker": "", + "@sendSticker": { + "type": "text", + "placeholders": {} + }, + "switchToAccount": "", + "@switchToAccount": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "setAsCanonicalAlias": "", + "@setAsCanonicalAlias": { + "type": "text", + "placeholders": {} + }, + "whyDoYouWantToReportThis": "", + "@whyDoYouWantToReportThis": { + "type": "text", + "placeholders": {} + }, + "locationDisabledNotice": "", + "@locationDisabledNotice": { + "type": "text", + "placeholders": {} + }, + "letsStart": "", + "@letsStart": {}, + "removedBy": "", + "@removedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "newChat": "", + "@newChat": { + "type": "text", + "placeholders": {} + }, + "notifications": "", + "@notifications": { + "type": "text", + "placeholders": {} + }, + "emoteSettings": "", + "@emoteSettings": { + "type": "text", + "placeholders": {} + }, + "experimentalVideoCalls": "", + "@experimentalVideoCalls": {}, + "savedEmotePack": "", + "@savedEmotePack": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "openCamera": "", + "@openCamera": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterRecoveryKeyDescription": "", + "@pleaseEnterRecoveryKeyDescription": {}, + "guestsAreForbidden": "", + "@guestsAreForbidden": { + "type": "text", + "placeholders": {} + }, + "mention": "", + "@mention": { + "type": "text", + "placeholders": {} + }, + "openInMaps": "", + "@openInMaps": { + "type": "text", + "placeholders": {} + }, + "withTheseAddressesRecoveryDescription": "", + "@withTheseAddressesRecoveryDescription": { + "type": "text", + "placeholders": {} + }, + "inviteContactToGroupQuestion": "", + "@inviteContactToGroupQuestion": {}, + "emoteExists": "", + "@emoteExists": { + "type": "text", + "placeholders": {} + }, + "redactedByBecause": "", + "@redactedByBecause": { + "type": "text", + "placeholders": { + "username": {}, + "reason": {} + } + }, + "isTyping": "", + "@isTyping": { + "type": "text", + "placeholders": {} + }, + "youHaveWithdrawnTheInvitationFor": "", + "@youHaveWithdrawnTheInvitationFor": { + "placeholders": { + "user": {} + } + }, + "group": "", + "@group": { + "type": "text", + "placeholders": {} + }, + "leave": "", + "@leave": { + "type": "text", + "placeholders": {} + }, + "skip": "", + "@skip": { + "type": "text", + "placeholders": {} + }, + "appearOnTopDetails": "", + "@appearOnTopDetails": {}, + "roomHasBeenUpgraded": "", + "@roomHasBeenUpgraded": { + "type": "text", + "placeholders": {} + }, + "enterRoom": "", + "@enterRoom": {}, + "enableEmotesGlobally": "", + "@enableEmotesGlobally": { + "type": "text", + "placeholders": {} + }, + "ignoreListDescription": "", + "@ignoreListDescription": { + "type": "text", + "placeholders": {} + }, + "pleaseChooseAPasscode": "", + "@pleaseChooseAPasscode": { + "type": "text", + "placeholders": {} + }, + "noPasswordRecoveryDescription": "", + "@noPasswordRecoveryDescription": { + "type": "text", + "placeholders": {} + }, + "reportUser": "", + "@reportUser": {}, + "sharedTheLocation": "", + "@sharedTheLocation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "onlineKeyBackupEnabled": "", + "@onlineKeyBackupEnabled": { + "type": "text", + "placeholders": {} + }, + "unbannedUser": "", + "@unbannedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "confirmEventUnpin": "", + "@confirmEventUnpin": {}, + "youInvitedUser": "", + "@youInvitedUser": { + "placeholders": { + "user": {} + } + }, + "kickedAndBanned": "", + "@kickedAndBanned": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "noConnectionToTheServer": "", + "@noConnectionToTheServer": { + "type": "text", + "placeholders": {} + }, + "fileHasBeenSavedAt": "", + "@fileHasBeenSavedAt": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "license": "", + "@license": { + "type": "text", + "placeholders": {} + }, + "unbanFromChat": "", + "@unbanFromChat": { + "type": "text", + "placeholders": {} + }, + "importZipFile": "", + "@importZipFile": {}, + "anyoneCanKnock": "", + "@anyoneCanKnock": {}, + "redactMessageDescription": "", + "@redactMessageDescription": {}, + "rejoin": "", + "@rejoin": { + "type": "text", + "placeholders": {} + }, + "recoveryKey": "", + "@recoveryKey": {}, + "redactMessage": "", + "@redactMessage": { + "type": "text", + "placeholders": {} + }, + "forward": "", + "@forward": { + "type": "text", + "placeholders": {} + }, + "commandHint_discardsession": "", + "@commandHint_discardsession": { + "type": "text", + "description": "Usage hint for the command /discardsession" + }, + "invalidInput": "", + "@invalidInput": {}, + "hideUnknownEvents": "", + "@hideUnknownEvents": { + "type": "text", + "placeholders": {} + }, + "todosUnencrypted": "", + "@todosUnencrypted": {}, + "dehydrateTorLong": "", + "@dehydrateTorLong": {}, + "yourPublicKey": "", + "@yourPublicKey": { + "type": "text", + "placeholders": {} + }, + "tooManyRequestsWarning": "", + "@tooManyRequestsWarning": { + "type": "text", + "placeholders": {} + }, + "invitedUser": "", + "@invitedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "kickFromChat": "", + "@kickFromChat": { + "type": "text", + "placeholders": {} + }, + "offline": "", + "@offline": { + "type": "text", + "placeholders": {} + }, + "replyHasBeenSent": "", + "@replyHasBeenSent": {}, + "noPermission": "", + "@noPermission": { + "type": "text", + "placeholders": {} + }, + "doNotShowAgain": "", + "@doNotShowAgain": {}, + "report": "", + "@report": {}, + "status": "", + "@status": { + "type": "text", + "placeholders": {} + }, + "deny": "", + "@deny": { + "type": "text", + "placeholders": {} + }, + "groupIsPublic": "", + "@groupIsPublic": { + "type": "text", + "placeholders": {} + }, + "verifyStart": "", + "@verifyStart": { + "type": "text", + "placeholders": {} + }, + "yourStory": "", + "@yourStory": {}, + "memberChanges": "", + "@memberChanges": { + "type": "text", + "placeholders": {} + }, + "joinRoom": "", + "@joinRoom": { + "type": "text", + "placeholders": {} + }, + "ignoreUsername": "", + "@ignoreUsername": { + "type": "text", + "placeholders": {} + }, + "unverified": "", + "@unverified": {}, + "fluffychat": "", + "@fluffychat": { + "type": "text", + "placeholders": {} + }, + "howOffensiveIsThisContent": "", + "@howOffensiveIsThisContent": { + "type": "text", + "placeholders": {} + }, + "serverRequiresEmail": "", + "@serverRequiresEmail": {}, + "hideUnimportantStateEvents": "", + "@hideUnimportantStateEvents": {}, + "screenSharingTitle": "", + "@screenSharingTitle": {}, + "widgetCustom": "", + "@widgetCustom": {}, + "sentCallInformations": "", + "@sentCallInformations": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "addToSpaceDescription": "", + "@addToSpaceDescription": {}, + "googlyEyesContent": "", + "@googlyEyesContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "whoCanSeeMyStoriesDesc": "", + "@whoCanSeeMyStoriesDesc": {}, + "youBannedUser": "", + "@youBannedUser": { + "placeholders": { + "user": {} + } + }, + "theyDontMatch": "", + "@theyDontMatch": { + "type": "text", + "placeholders": {} + }, + "unsubscribeStories": "", + "@unsubscribeStories": {}, + "youHaveBeenBannedFromThisChat": "", + "@youHaveBeenBannedFromThisChat": { + "type": "text", + "placeholders": {} + }, + "displaynameHasBeenChanged": "", + "@displaynameHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "loginWithOneClick": "", + "@loginWithOneClick": {}, + "addChatDescription": "", + "@addChatDescription": {}, + "sentAnAudio": "", + "@sentAnAudio": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "editRoomAvatar": "", + "@editRoomAvatar": { + "type": "text", + "placeholders": {} + }, + "encrypted": "", + "@encrypted": { + "type": "text", + "placeholders": {} + }, + "hasKnocked": "", + "@hasKnocked": { + "placeholders": { + "user": {} + } + }, + "publish": "", + "@publish": {}, + "openLinkInBrowser": "", + "@openLinkInBrowser": {}, + "pleaseEnterYourUsername": "", + "@pleaseEnterYourUsername": { + "type": "text", + "placeholders": {} + }, + "messageInfo": "", + "@messageInfo": {}, + "disableEncryptionWarning": "", + "@disableEncryptionWarning": {}, + "directChat": "", + "@directChat": {}, + "noOneCanJoin": "", + "@noOneCanJoin": {}, + "encryptionNotEnabled": "", + "@encryptionNotEnabled": { + "type": "text", + "placeholders": {} + }, + "wrongPinEntered": "", + "@wrongPinEntered": { + "type": "text", + "placeholders": { + "seconds": {} + } + }, + "sendTypingNotifications": "", + "@sendTypingNotifications": {}, + "lightTheme": "", + "@lightTheme": { + "type": "text", + "placeholders": {} + }, + "inviteGroupChat": "", + "@inviteGroupChat": {}, + "appearOnTop": "", + "@appearOnTop": {}, + "invitePrivateChat": "", + "@invitePrivateChat": {}, + "verifyTitle": "", + "@verifyTitle": { + "type": "text", + "placeholders": {} + }, + "foregroundServiceRunning": "", + "@foregroundServiceRunning": {}, + "enterAnEmailAddress": "", + "@enterAnEmailAddress": { + "type": "text", + "placeholders": {} + }, + "voiceCall": "", + "@voiceCall": {}, + "unknownEncryptionAlgorithm": "", + "@unknownEncryptionAlgorithm": { + "type": "text", + "placeholders": {} + }, + "importEmojis": "", + "@importEmojis": {}, + "wasDirectChatDisplayName": "", + "@wasDirectChatDisplayName": { + "type": "text", + "placeholders": { + "oldDisplayName": {} + } + }, + "noChatDescriptionYet": "", + "@noChatDescriptionYet": {}, + "newTodo": "", + "@newTodo": {}, + "removeFromBundle": "", + "@removeFromBundle": {}, + "numUsersTyping": "", + "@numUsersTyping": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "fontSize": "", + "@fontSize": { + "type": "text", + "placeholders": {} + }, + "whoCanPerformWhichAction": "", + "@whoCanPerformWhichAction": { + "type": "text", + "placeholders": {} + }, + "confirmMatrixId": "", + "@confirmMatrixId": {}, + "learnMore": "", + "@learnMore": {}, + "iHaveClickedOnLink": "", + "@iHaveClickedOnLink": { + "type": "text", + "placeholders": {} + }, + "you": "", + "@you": { + "type": "text", + "placeholders": {} + }, + "notAnImage": "", + "@notAnImage": {}, + "users": "", + "@users": {}, + "openGallery": "", + "@openGallery": {}, + "chatDescriptionHasBeenChanged": "", + "@chatDescriptionHasBeenChanged": {}, + "search": "", + "@search": { + "type": "text", + "placeholders": {} + }, + "newGroup": "", + "@newGroup": {}, + "bundleName": "", + "@bundleName": {}, + "dehydrateTor": "", + "@dehydrateTor": {}, + "todoListChangedError": "", + "@todoListChangedError": {}, + "removeFromSpace": "", + "@removeFromSpace": {}, + "enterInviteLinkOrMatrixId": "", + "@enterInviteLinkOrMatrixId": {}, + "sourceCode": "", + "@sourceCode": { + "type": "text", + "placeholders": {} + }, + "enterAGroupName": "", + "@enterAGroupName": { + "type": "text", + "placeholders": {} + }, + "roomUpgradeDescription": "", + "@roomUpgradeDescription": {}, + "userSentUnknownEvent": "", + "@userSentUnknownEvent": { + "type": "text", + "placeholders": { + "username": {}, + "type": {} + } + }, + "scanQrCode": "", + "@scanQrCode": {}, + "logout": "", + "@logout": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterANumber": "", + "@pleaseEnterANumber": {}, + "youKicked": "", + "@youKicked": { + "placeholders": { + "user": {} + } + }, + "profileNotFound": "", + "@profileNotFound": {}, + "jump": "", + "@jump": {}, + "groups": "", + "@groups": { + "type": "text", + "placeholders": {} + }, + "reactedWith": "", + "@reactedWith": { + "type": "text", + "placeholders": { + "sender": {}, + "reaction": {} + } + }, + "sorryThatsNotPossible": "", + "@sorryThatsNotPossible": {}, + "storyFrom": "", + "@storyFrom": { + "type": "text", + "placeholders": { + "date": {}, + "body": {} + } + }, + "videoWithSize": "", + "@videoWithSize": { + "type": "text", + "placeholders": { + "size": {} + } + }, + "oopsSomethingWentWrong": "", + "@oopsSomethingWentWrong": { + "type": "text", + "placeholders": {} + }, + "loadCountMoreParticipants": "", + "@loadCountMoreParticipants": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "shareInviteLink": "", + "@shareInviteLink": {}, + "commandHint_markasdm": "", + "@commandHint_markasdm": {}, + "recoveryKeyLost": "", + "@recoveryKeyLost": {}, + "cuddleContent": "", + "@cuddleContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "messages": "", + "@messages": { + "type": "text", + "placeholders": {} + }, + "login": "", + "@login": { + "type": "text", + "placeholders": {} + }, + "deviceKeys": "", + "@deviceKeys": {}, + "waitingPartnerNumbers": "", + "@waitingPartnerNumbers": { + "type": "text", + "placeholders": {} + }, + "noGoogleServicesWarning": "", + "@noGoogleServicesWarning": { + "type": "text", + "placeholders": {} + }, + "everythingReady": "", + "@everythingReady": { + "type": "text", + "placeholders": {} + }, + "emoteKeyboardNoRecents": "", + "@emoteKeyboardNoRecents": { + "type": "text", + "placeholders": {} + }, + "setCustomEmotes": "", + "@setCustomEmotes": { + "type": "text", + "placeholders": {} + }, + "startedACall": "", + "@startedACall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "emoteInvalid": "", + "@emoteInvalid": { + "type": "text", + "placeholders": {} + }, + "systemTheme": "", + "@systemTheme": { + "type": "text", + "placeholders": {} + }, + "messageWillBeRemovedWarning": "", + "@messageWillBeRemovedWarning": { + "type": "text", + "placeholders": {} + }, + "endToEndEncryption": "", + "@endToEndEncryption": {}, + "notificationsEnabledForThisAccount": "", + "@notificationsEnabledForThisAccount": { + "type": "text", + "placeholders": {} + }, + "deleteMessage": "", + "@deleteMessage": { + "type": "text", + "placeholders": {} + }, + "visibilityOfTheChatHistory": "", + "@visibilityOfTheChatHistory": { + "type": "text", + "placeholders": {} + }, + "settings": "", + "@settings": { + "type": "text", + "placeholders": {} + }, + "setTheme": "", + "@setTheme": {}, + "youJoinedTheChat": "", + "@youJoinedTheChat": {}, + "wallpaper": "", + "@wallpaper": { + "type": "text", + "placeholders": {} + }, + "openVideoCamera": "", + "@openVideoCamera": { + "type": "text", + "placeholders": {} + }, + "play": "", + "@play": { + "type": "text", + "placeholders": { + "fileName": {} + } + }, + "lastSeenLongTimeAgo": "", + "@lastSeenLongTimeAgo": { + "type": "text", + "placeholders": {} + }, + "passwordForgotten": "", + "@passwordForgotten": { + "type": "text", + "placeholders": {} + }, + "statusExampleMessage": "", + "@statusExampleMessage": { + "type": "text", + "placeholders": {} + }, + "thisUserHasNotPostedAnythingYet": "", + "@thisUserHasNotPostedAnythingYet": {}, + "security": "", + "@security": { + "type": "text", + "placeholders": {} + }, + "markAsRead": "", + "@markAsRead": {}, + "sendAudio": "", + "@sendAudio": { + "type": "text", + "placeholders": {} + }, + "widgetName": "", + "@widgetName": {}, + "sentASticker": "", + "@sentASticker": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "errorAddingWidget": "", + "@errorAddingWidget": {}, + "commandHint_dm": "", + "@commandHint_dm": { + "type": "text", + "description": "Usage hint for the command /dm" + }, + "commandHint_hug": "", + "@commandHint_hug": {}, + "replace": "", + "@replace": {}, + "reject": "", + "@reject": { + "type": "text", + "placeholders": {} + }, + "extremeOffensive": "", + "@extremeOffensive": { + "type": "text", + "placeholders": {} + }, + "editBlockedServers": "", + "@editBlockedServers": { + "type": "text", + "placeholders": {} + }, + "oopsPushError": "", + "@oopsPushError": { + "type": "text", + "placeholders": {} + }, + "youUnbannedUser": "", + "@youUnbannedUser": { + "placeholders": { + "user": {} + } + }, + "joinedTheChat": "", + "@joinedTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "visibleForEveryone": "", + "@visibleForEveryone": { + "type": "text", + "placeholders": {} + }, + "pleaseEnter4Digits": "", + "@pleaseEnter4Digits": { + "type": "text", + "placeholders": {} + }, + "newSpace": "", + "@newSpace": {}, + "devices": "", + "@devices": { + "type": "text", + "placeholders": {} + }, + "unknownEvent": "", + "@unknownEvent": { + "type": "text", + "placeholders": { + "type": {} + } + }, + "emojis": "", + "@emojis": {}, + "signUp": "", + "@signUp": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourPin": "", + "@pleaseEnterYourPin": { + "type": "text", + "placeholders": {} + }, + "pleaseChoose": "", + "@pleaseChoose": { + "type": "text", + "placeholders": {} + }, + "share": "", + "@share": { + "type": "text", + "placeholders": {} + }, + "commandHint_googly": "", + "@commandHint_googly": {}, + "pleaseTryAgainLaterOrChooseDifferentServer": "", + "@pleaseTryAgainLaterOrChooseDifferentServer": {}, + "createGroup": "", + "@createGroup": {}, + "privacy": "", + "@privacy": { + "type": "text", + "placeholders": {} + }, + "sendImage": "", + "@sendImage": { + "type": "text", + "placeholders": {} + }, + "hydrateTorLong": "", + "@hydrateTorLong": {}, + "time": "", + "@time": {}, + "enterYourHomeserver": "", + "@enterYourHomeserver": { + "type": "text", + "placeholders": {} + }, + "custom": "", + "@custom": {}, + "noBackupWarning": "", + "@noBackupWarning": {}, + "fromJoining": "", + "@fromJoining": { + "type": "text", + "placeholders": {} + }, + "verify": "", + "@verify": { + "type": "text", + "placeholders": {} + }, + "sendVideo": "", + "@sendVideo": { + "type": "text", + "placeholders": {} + }, + "editWidgets": "", + "@editWidgets": {}, + "storeInSecureStorageDescription": "", + "@storeInSecureStorageDescription": {}, + "openChat": "", + "@openChat": {}, + "kickUserDescription": "", + "@kickUserDescription": {}, + "sendAMessage": "", + "@sendAMessage": { + "type": "text", + "placeholders": {} + }, + "pin": "", + "@pin": { + "type": "text", + "placeholders": {} + }, + "importNow": "", + "@importNow": {}, + "deleteAccount": "", + "@deleteAccount": { + "type": "text", + "placeholders": {} + }, + "setInvitationLink": "", + "@setInvitationLink": { + "type": "text", + "placeholders": {} + }, + "pinMessage": "", + "@pinMessage": {}, + "muteChat": "", + "@muteChat": { + "type": "text", + "placeholders": {} + }, + "invite": "", + "@invite": {}, + "enableMultiAccounts": "", + "@enableMultiAccounts": {}, + "emotePacks": "", + "@emotePacks": { + "type": "text", + "placeholders": {} + }, + "makeSureTheIdentifierIsValid": "", + "@makeSureTheIdentifierIsValid": { + "type": "text", + "placeholders": {} + }, + "continueWith": "", + "@continueWith": {}, + "indexedDbErrorTitle": "", + "@indexedDbErrorTitle": {}, + "pleaseChooseAUsername": "", + "@pleaseChooseAUsername": { + "type": "text", + "placeholders": {} + }, + "endedTheCall": "", + "@endedTheCall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "unsupportedAndroidVersionLong": "", + "@unsupportedAndroidVersionLong": {}, + "storeSecurlyOnThisDevice": "", + "@storeSecurlyOnThisDevice": {}, + "iUnderstand": "", + "@iUnderstand": {}, + "screenSharingDetail": "", + "@screenSharingDetail": {}, + "placeCall": "", + "@placeCall": {} +} diff --git a/assets/l10n/intl_sr.arb b/assets/l10n/intl_sr.arb index a2210c7f5..c9c26f937 100644 --- a/assets/l10n/intl_sr.arb +++ b/assets/l10n/intl_sr.arb @@ -1,1933 +1,2658 @@ { - "@@last_modified": "2021-08-14 12:41:09.857024", - "about": "О програму", - "@about": { - "type": "text", - "placeholders": {} - }, - "accept": "Прихвати", - "@accept": { - "type": "text", - "placeholders": {} - }, - "acceptedTheInvitation": "{username} прихвата позивницу", - "@acceptedTheInvitation": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "account": "Налог", - "@account": { - "type": "text", - "placeholders": {} - }, - "activatedEndToEndEncryption": "{username} укључи шифровање с краја на крај", - "@activatedEndToEndEncryption": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "addEmail": "Додај е-адресу", - "@addEmail": { - "type": "text", - "placeholders": {} - }, - "addGroupDescription": "Додај опис групе", - "@addGroupDescription": { - "type": "text", - "placeholders": {} - }, - "admin": "Админ", - "@admin": { - "type": "text", - "placeholders": {} - }, - "alias": "алијас", - "@alias": { - "type": "text", - "placeholders": {} - }, - "all": "Сви", - "@all": { - "type": "text", - "placeholders": {} - }, - "answeredTheCall": "{senderName} одговори на позив", - "@answeredTheCall": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "anyoneCanJoin": "свако може да се придружи", - "@anyoneCanJoin": { - "type": "text", - "placeholders": {} - }, - "appLock": "Закључавање апликације", - "@appLock": { - "type": "text", - "placeholders": {} - }, - "archive": "Архива", - "@archive": { - "type": "text", - "placeholders": {} - }, - "areGuestsAllowedToJoin": "Да ли је гостима дозвољен приступ", - "@areGuestsAllowedToJoin": { - "type": "text", - "placeholders": {} - }, - "areYouSure": "Сигурни сте?", - "@areYouSure": { - "type": "text", - "placeholders": {} - }, - "areYouSureYouWantToLogout": "Заиста желите да се одјавите?", - "@areYouSureYouWantToLogout": { - "type": "text", - "placeholders": {} - }, - "askSSSSSign": "Да бисте могли да пријавите другу особу, унесите своју безбедносну фразу или кључ опоравка.", - "@askSSSSSign": { - "type": "text", - "placeholders": {} - }, - "askVerificationRequest": "Прихватате ли захтев за верификацију од корисника {username}?", - "@askVerificationRequest": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "badServerLoginTypesException": "Домаћи сервер подржава начине пријаве:\n{serverVersions}\nали ова апликација подржава само:\n{supportedVersions}", - "@badServerLoginTypesException": { - "type": "text", - "placeholders": { - "serverVersions": {}, - "supportedVersions": {} - } - }, - "badServerVersionsException": "Домаћи сервер подржава верзије:\n{serverVersions}\nали ова апликација подржава само {supportedVersions}", - "@badServerVersionsException": { - "type": "text", - "placeholders": { - "serverVersions": {}, - "supportedVersions": {} - } - }, - "banFromChat": "Забрани у ћаскању", - "@banFromChat": { - "type": "text", - "placeholders": {} - }, - "banned": "Забрањен", - "@banned": { - "type": "text", - "placeholders": {} - }, - "bannedUser": "{username} забрани корисника {targetName}", - "@bannedUser": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "blockDevice": "Блокирај уређај", - "@blockDevice": { - "type": "text", - "placeholders": {} - }, - "blocked": "Блокиран", - "@blocked": { - "type": "text", - "placeholders": {} - }, - "botMessages": "Поруке Бота", - "@botMessages": { - "type": "text", - "placeholders": {} - }, - "cancel": "Откажи", - "@cancel": { - "type": "text", - "placeholders": {} - }, - "changeDeviceName": "Промени назив уређаја", - "@changeDeviceName": { - "type": "text", - "placeholders": {} - }, - "changedTheChatAvatar": "{username} промени аватар ћаскања", - "@changedTheChatAvatar": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheChatDescriptionTo": "{username} промени опис ћаскања у: „{description}“", - "@changedTheChatDescriptionTo": { - "type": "text", - "placeholders": { - "username": {}, - "description": {} - } - }, - "changedTheChatNameTo": "{username} промени назив ћаскања у: „{chatname}“", - "@changedTheChatNameTo": { - "type": "text", - "placeholders": { - "username": {}, - "chatname": {} - } - }, - "changedTheChatPermissions": "{username} измени дозволе ћаскања", - "@changedTheChatPermissions": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheDisplaynameTo": "{username} промени приказно име на: „{displayname}“", - "@changedTheDisplaynameTo": { - "type": "text", - "placeholders": { - "username": {}, - "displayname": {} - } - }, - "changedTheGuestAccessRules": "{username} измени правила за приступ гостију", - "@changedTheGuestAccessRules": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheGuestAccessRulesTo": "{username} измени правила за приступ гостију на: {rules}", - "@changedTheGuestAccessRulesTo": { - "type": "text", - "placeholders": { - "username": {}, - "rules": {} - } - }, - "changedTheHistoryVisibility": "{username} измени видљивост историје", - "@changedTheHistoryVisibility": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheHistoryVisibilityTo": "{username} измени видљивост историје на: {rules}", - "@changedTheHistoryVisibilityTo": { - "type": "text", - "placeholders": { - "username": {}, - "rules": {} - } - }, - "changedTheJoinRules": "{username} измени правила приступања", - "@changedTheJoinRules": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheJoinRulesTo": "{username} измени правила приступања на: {joinRules}", - "@changedTheJoinRulesTo": { - "type": "text", - "placeholders": { - "username": {}, - "joinRules": {} - } - }, - "changedTheProfileAvatar": "{username} измени свој аватар", - "@changedTheProfileAvatar": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheRoomAliases": "{username} измени алијас собе", - "@changedTheRoomAliases": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheRoomInvitationLink": "{username} измени везу позивнице", - "@changedTheRoomInvitationLink": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changePassword": "Измени лозинку", - "@changePassword": { - "type": "text", - "placeholders": {} - }, - "changeTheHomeserver": "Промени домаћи сервер", - "@changeTheHomeserver": { - "type": "text", - "placeholders": {} - }, - "changeTheme": "Измените изглед", - "@changeTheme": { - "type": "text", - "placeholders": {} - }, - "changeTheNameOfTheGroup": "Измени назив групе", - "@changeTheNameOfTheGroup": { - "type": "text", - "placeholders": {} - }, - "changeWallpaper": "Измени тапет", - "@changeWallpaper": { - "type": "text", - "placeholders": {} - }, - "changeYourAvatar": "Измените свој аватар", - "@changeYourAvatar": { - "type": "text", - "placeholders": {} - }, - "channelCorruptedDecryptError": "Шифровање је покварено", - "@channelCorruptedDecryptError": { - "type": "text", - "placeholders": {} - }, - "chat": "Ћаскање", - "@chat": { - "type": "text", - "placeholders": {} - }, - "chatBackup": "Копија ћаскања", - "@chatBackup": { - "type": "text", - "placeholders": {} - }, - "chatBackupDescription": "Ваша резервна копија ћаскања је обезбеђена кључем. Немојте да га изгубите.", - "@chatBackupDescription": { - "type": "text", - "placeholders": {} - }, - "chatDetails": "Детаљи ћаскања", - "@chatDetails": { - "type": "text", - "placeholders": {} - }, - "chats": "Ћаскања", - "@chats": { - "type": "text", - "placeholders": {} - }, - "chooseAStrongPassword": "Изаберите јаку лозинку", - "@chooseAStrongPassword": { - "type": "text", - "placeholders": {} - }, - "chooseAUsername": "Изаберите корисничко име", - "@chooseAUsername": { - "type": "text", - "placeholders": {} - }, - "clearArchive": "Очисти архиву", - "@clearArchive": {}, - "close": "Затвори", - "@close": { - "type": "text", - "placeholders": {} - }, - "commandHint_ban": "Блокирај задатог корисника за ову собу", - "@commandHint_ban": { - "type": "text", - "description": "Usage hint for the command /ban" - }, - "commandHint_html": "Шаљи ХТМЛ обликован текст", - "@commandHint_html": { - "type": "text", - "description": "Usage hint for the command /html" - }, - "commandHint_invite": "Позови задатог корисника у собу", - "@commandHint_invite": { - "type": "text", - "description": "Usage hint for the command /invite" - }, - "commandHint_join": "Придружи се наведеној соби", - "@commandHint_join": { - "type": "text", - "description": "Usage hint for the command /join" - }, - "commandHint_kick": "Уклони задатог корисника из собе", - "@commandHint_kick": { - "type": "text", - "description": "Usage hint for the command /kick" - }, - "commandHint_leave": "Напусти ову собу", - "@commandHint_leave": { - "type": "text", - "description": "Usage hint for the command /leave" - }, - "commandHint_me": "Опишите себе", - "@commandHint_me": { - "type": "text", - "description": "Usage hint for the command /me" - }, - "commandHint_myroomnick": "Поставља ваш надимак за ову собу", - "@commandHint_myroomnick": { - "type": "text", - "description": "Usage hint for the command /myroomnick" - }, - "commandHint_op": "Подеси ниво задатог корисника (подразумевано: 50)", - "@commandHint_op": { - "type": "text", - "description": "Usage hint for the command /op" - }, - "commandHint_plain": "Шаљи неформатиран текст", - "@commandHint_plain": { - "type": "text", - "description": "Usage hint for the command /plain" - }, - "commandHint_react": "Шаљи одговор као реакцију", - "@commandHint_react": { - "type": "text", - "description": "Usage hint for the command /react" - }, - "commandHint_send": "Пошаљи текст", - "@commandHint_send": { - "type": "text", - "description": "Usage hint for the command /send" - }, - "commandHint_unban": "Скини забрану задатом кориснику за ову собу", - "@commandHint_unban": { - "type": "text", - "description": "Usage hint for the command /unban" - }, - "compareEmojiMatch": "Упоредите и проверите да су емоџији идентични као на другом уређају:", - "@compareEmojiMatch": { - "type": "text", - "placeholders": {} - }, - "compareNumbersMatch": "Упоредите и проверите да су следећи бројеви идентични као на другом уређају:", - "@compareNumbersMatch": { - "type": "text", - "placeholders": {} - }, - "configureChat": "Подешавање ћаскања", - "@configureChat": { - "type": "text", - "placeholders": {} - }, - "confirm": "Потврди", - "@confirm": { - "type": "text", - "placeholders": {} - }, - "connect": "Повежи се", - "@connect": { - "type": "text", - "placeholders": {} - }, - "contactHasBeenInvitedToTheGroup": "Особа је позвана у групу", - "@contactHasBeenInvitedToTheGroup": { - "type": "text", - "placeholders": {} - }, - "containsDisplayName": "Садржи приказно име", - "@containsDisplayName": { - "type": "text", - "placeholders": {} - }, - "containsUserName": "Садржи корисничко име", - "@containsUserName": { - "type": "text", - "placeholders": {} - }, - "contentHasBeenReported": "Садржај је пријављен администраторима сервера", - "@contentHasBeenReported": { - "type": "text", - "placeholders": {} - }, - "copiedToClipboard": "Копирано у клипборд", - "@copiedToClipboard": { - "type": "text", - "placeholders": {} - }, - "copy": "Копирај", - "@copy": { - "type": "text", - "placeholders": {} - }, - "copyToClipboard": "Копирај у клипборд", - "@copyToClipboard": { - "type": "text", - "placeholders": {} - }, - "couldNotDecryptMessage": "Не могу да дешифрујем поруку: {error}", - "@couldNotDecryptMessage": { - "type": "text", - "placeholders": { - "error": {} - } - }, - "countParticipants": "учесника: {count}", - "@countParticipants": { - "type": "text", - "placeholders": { - "count": {} - } - }, - "create": "Направи", - "@create": { - "type": "text", - "placeholders": {} - }, - "createdTheChat": "{username} направи ћаскање", - "@createdTheChat": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "createNewGroup": "Направи нову групу", - "@createNewGroup": { - "type": "text", - "placeholders": {} - }, - "currentlyActive": "Тренутно активно", - "@currentlyActive": { - "type": "text", - "placeholders": {} - }, - "darkTheme": "тамни", - "@darkTheme": { - "type": "text", - "placeholders": {} - }, - "dateAndTimeOfDay": "{date}, {timeOfDay}", - "@dateAndTimeOfDay": { - "type": "text", - "placeholders": { - "date": {}, - "timeOfDay": {} - } - }, - "dateWithoutYear": "{day} {month}", - "@dateWithoutYear": { - "type": "text", - "placeholders": { - "month": {}, - "day": {} - } - }, - "dateWithYear": "{day} {month} {year}", - "@dateWithYear": { - "type": "text", - "placeholders": { - "year": {}, - "month": {}, - "day": {} - } - }, - "deactivateAccountWarning": "Ово ће деактивирати ваш кориснички налог. Не може се повратити! Сигурни сте?", - "@deactivateAccountWarning": { - "type": "text", - "placeholders": {} - }, - "defaultPermissionLevel": "Подразумевани ниво приступа", - "@defaultPermissionLevel": { - "type": "text", - "placeholders": {} - }, - "delete": "Обриши", - "@delete": { - "type": "text", - "placeholders": {} - }, - "deleteAccount": "Обриши налог", - "@deleteAccount": { - "type": "text", - "placeholders": {} - }, - "deleteMessage": "Брисање поруке", - "@deleteMessage": { - "type": "text", - "placeholders": {} - }, - "deny": "Одбиј", - "@deny": { - "type": "text", - "placeholders": {} - }, - "device": "Уређај", - "@device": { - "type": "text", - "placeholders": {} - }, - "deviceId": "ИД уређаја", - "@deviceId": { - "type": "text", - "placeholders": {} - }, - "devices": "Уређаји", - "@devices": { - "type": "text", - "placeholders": {} - }, - "directChats": "Директна ћаскања", - "@directChats": { - "type": "text", - "placeholders": {} - }, - "displaynameHasBeenChanged": "Име за приказ је измењено", - "@displaynameHasBeenChanged": { - "type": "text", - "placeholders": {} - }, - "downloadFile": "Преузми фајл", - "@downloadFile": { - "type": "text", - "placeholders": {} - }, - "edit": "Уреди", - "@edit": { - "type": "text", - "placeholders": {} - }, - "editBlockedServers": "Уреди блокиране сервере", - "@editBlockedServers": { - "type": "text", - "placeholders": {} - }, - "editChatPermissions": "Уредите дозволе ћаскања", - "@editChatPermissions": { - "type": "text", - "placeholders": {} - }, - "editDisplayname": "Уреди име за приказ", - "@editDisplayname": { - "type": "text", - "placeholders": {} - }, - "editRoomAliases": "Уреди алијасе собе", - "@editRoomAliases": { - "type": "text", - "placeholders": {} - }, - "editRoomAvatar": "Уређује аватар собе", - "@editRoomAvatar": { - "type": "text", - "placeholders": {} - }, - "emoteExists": "Емоти већ постоји!", - "@emoteExists": { - "type": "text", - "placeholders": {} - }, - "emoteInvalid": "Неисправна скраћеница за емоти!", - "@emoteInvalid": { - "type": "text", - "placeholders": {} - }, - "emotePacks": "Пакети емотија за собу", - "@emotePacks": { - "type": "text", - "placeholders": {} - }, - "emoteSettings": "Поставке емотија", - "@emoteSettings": { - "type": "text", - "placeholders": {} - }, - "emoteShortcode": "скраћеница", - "@emoteShortcode": { - "type": "text", - "placeholders": {} - }, - "emoteWarnNeedToPick": "Морате да изаберете скраћеницу и слику за емоти!", - "@emoteWarnNeedToPick": { - "type": "text", - "placeholders": {} - }, - "emptyChat": "празно ћаскање", - "@emptyChat": { - "type": "text", - "placeholders": {} - }, - "enableEmotesGlobally": "Глобално укључи пакет емотија", - "@enableEmotesGlobally": { - "type": "text", - "placeholders": {} - }, - "enableEncryption": "Укључује шифровање", - "@enableEncryption": { - "type": "text", - "placeholders": {} - }, - "enableEncryptionWarning": "Шифровање више нећете моћи да искључите. Сигурни сте?", - "@enableEncryptionWarning": { - "type": "text", - "placeholders": {} - }, - "encrypted": "Шифровано", - "@encrypted": { - "type": "text", - "placeholders": {} - }, - "encryption": "Шифровање", - "@encryption": { - "type": "text", - "placeholders": {} - }, - "encryptionNotEnabled": "Шифровање није укључено", - "@encryptionNotEnabled": { - "type": "text", - "placeholders": {} - }, - "endedTheCall": "{senderName} заврши позив", - "@endedTheCall": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "enterAGroupName": "унесите назив групе", - "@enterAGroupName": { - "type": "text", - "placeholders": {} - }, - "enterAnEmailAddress": "Унесите адресу е-поште", - "@enterAnEmailAddress": { - "type": "text", - "placeholders": {} - }, - "enterYourHomeserver": "Унесите свој домаћи сервер", - "@enterYourHomeserver": { - "type": "text", - "placeholders": {} - }, - "everythingReady": "Све је спремно!", - "@everythingReady": { - "type": "text", - "placeholders": {} - }, - "extremeOffensive": "Екстремно увредљив", - "@extremeOffensive": { - "type": "text", - "placeholders": {} - }, - "fileName": "Назив фајла", - "@fileName": { - "type": "text", - "placeholders": {} - }, - "fluffychat": "FluffyChat", - "@fluffychat": { - "type": "text", - "placeholders": {} - }, - "fontSize": "Величина фонта", - "@fontSize": { - "type": "text", - "placeholders": {} - }, - "forward": "Напред", - "@forward": { - "type": "text", - "placeholders": {} - }, - "fromJoining": "од приступања", - "@fromJoining": { - "type": "text", - "placeholders": {} - }, - "fromTheInvitation": "од позивања", - "@fromTheInvitation": { - "type": "text", - "placeholders": {} - }, - "goToTheNewRoom": "Иди у нову собу", - "@goToTheNewRoom": { - "type": "text", - "placeholders": {} - }, - "group": "Група", - "@group": { - "type": "text", - "placeholders": {} - }, - "groupDescription": "Опис групе", - "@groupDescription": { - "type": "text", - "placeholders": {} - }, - "groupDescriptionHasBeenChanged": "Опис групе измењен", - "@groupDescriptionHasBeenChanged": { - "type": "text", - "placeholders": {} - }, - "groupIsPublic": "Група је јавна", - "@groupIsPublic": { - "type": "text", - "placeholders": {} - }, - "groups": "Групе", - "@groups": { - "type": "text", - "placeholders": {} - }, - "groupWith": "Група са корисником {displayname}", - "@groupWith": { - "type": "text", - "placeholders": { - "displayname": {} - } - }, - "guestsAreForbidden": "гости су забрањени", - "@guestsAreForbidden": { - "type": "text", - "placeholders": {} - }, - "guestsCanJoin": "гости могу приступити", - "@guestsCanJoin": { - "type": "text", - "placeholders": {} - }, - "hasWithdrawnTheInvitationFor": "{username} поништи позивницу за корисника {targetName}", - "@hasWithdrawnTheInvitationFor": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "help": "Помоћ", - "@help": { - "type": "text", - "placeholders": {} - }, - "hideRedactedEvents": "Сакриј редиговане догађаје", - "@hideRedactedEvents": { - "type": "text", - "placeholders": {} - }, - "hideUnknownEvents": "Сакриј непознате догађаје", - "@hideUnknownEvents": { - "type": "text", - "placeholders": {} - }, - "howOffensiveIsThisContent": "Колико је увредљив овај садржај?", - "@howOffensiveIsThisContent": { - "type": "text", - "placeholders": {} - }, - "id": "ИД", - "@id": { - "type": "text", - "placeholders": {} - }, - "identity": "Идентитет", - "@identity": { - "type": "text", - "placeholders": {} - }, - "ignore": "Игнориши", - "@ignore": { - "type": "text", - "placeholders": {} - }, - "ignoredUsers": "Игнорисани корисници", - "@ignoredUsers": { - "type": "text", - "placeholders": {} - }, - "ignoreListDescription": "Можете игнорисати кориснике који вас нервирају. Нећете примати никакве поруке нити позивнице од корисника са ваше листе за игнорисање.", - "@ignoreListDescription": { - "type": "text", - "placeholders": {} - }, - "ignoreUsername": "Игнориши корисника", - "@ignoreUsername": { - "type": "text", - "placeholders": {} - }, - "iHaveClickedOnLink": "Кликнуо сам на везу", - "@iHaveClickedOnLink": { - "type": "text", - "placeholders": {} - }, - "incorrectPassphraseOrKey": "Неисправна фраза или кључ опоравка", - "@incorrectPassphraseOrKey": { - "type": "text", - "placeholders": {} - }, - "inoffensive": "Није увредљив", - "@inoffensive": { - "type": "text", - "placeholders": {} - }, - "inviteContact": "Позивање особа", - "@inviteContact": { - "type": "text", - "placeholders": {} - }, - "inviteContactToGroup": "Позови особу у групу {groupName}", - "@inviteContactToGroup": { - "type": "text", - "placeholders": { - "groupName": {} - } - }, - "invited": "Позван", - "@invited": { - "type": "text", - "placeholders": {} - }, - "invitedUser": "{username} позва корисника {targetName}", - "@invitedUser": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "invitedUsersOnly": "само позвани корисници", - "@invitedUsersOnly": { - "type": "text", - "placeholders": {} - }, - "inviteForMe": "Позивнице за мене", - "@inviteForMe": { - "type": "text", - "placeholders": {} - }, - "inviteText": "{username} вас позива у FluffyChat. \n1. Инсталирајте FluffyChat: https://fluffychat.im \n2. Региструјте се или пријавите \n3. Отворите везу позивнице: {link}", - "@inviteText": { - "type": "text", - "placeholders": { - "username": {}, - "link": {} - } - }, - "isTyping": "куца…", - "@isTyping": { - "type": "text", - "placeholders": {} - }, - "joinedTheChat": "{username} се придружи ћаскању", - "@joinedTheChat": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "joinRoom": "Придружи се соби", - "@joinRoom": { - "type": "text", - "placeholders": {} - }, - "kicked": "{username} избаци корисника {targetName}", - "@kicked": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "kickedAndBanned": "{username} избаци и забрани корисника {targetName}", - "@kickedAndBanned": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "kickFromChat": "Избаци из ћаскања", - "@kickFromChat": { - "type": "text", - "placeholders": {} - }, - "lastActiveAgo": "Последња активност: {localizedTimeShort}", - "@lastActiveAgo": { - "type": "text", - "placeholders": { - "localizedTimeShort": {} - } - }, - "lastSeenLongTimeAgo": "одавно није на мрежи", - "@lastSeenLongTimeAgo": { - "type": "text", - "placeholders": {} - }, - "leave": "Напусти", - "@leave": { - "type": "text", - "placeholders": {} - }, - "leftTheChat": "Напусти ћаскање", - "@leftTheChat": { - "type": "text", - "placeholders": {} - }, - "license": "Лиценца", - "@license": { - "type": "text", - "placeholders": {} - }, - "lightTheme": "светли", - "@lightTheme": { - "type": "text", - "placeholders": {} - }, - "loadCountMoreParticipants": "Учитај још {count} учесника", - "@loadCountMoreParticipants": { - "type": "text", - "placeholders": { - "count": {} - } - }, - "loadingPleaseWait": "Учитавам… Сачекајте.", - "@loadingPleaseWait": { - "type": "text", - "placeholders": {} - }, - "loadMore": "Учитај још…", - "@loadMore": { - "type": "text", - "placeholders": {} - }, - "login": "Пријава", - "@login": { - "type": "text", - "placeholders": {} - }, - "logInTo": "Пријава на {homeserver}", - "@logInTo": { - "type": "text", - "placeholders": { - "homeserver": {} - } - }, - "loginWith": "{brand} за пријаву", - "@loginWith": { - "type": "text", - "placeholders": { - "brand": {} - } - }, - "logout": "Одјава", - "@logout": { - "type": "text", - "placeholders": {} - }, - "makeSureTheIdentifierIsValid": "Проверите да је идентификатор исправан", - "@makeSureTheIdentifierIsValid": { - "type": "text", - "placeholders": {} - }, - "memberChanges": "Измене чланова", - "@memberChanges": { - "type": "text", - "placeholders": {} - }, - "mention": "Спомени", - "@mention": { - "type": "text", - "placeholders": {} - }, - "messages": "Поруке", - "@messages": { - "type": "text", - "placeholders": {} - }, - "messageWillBeRemovedWarning": "Поруке ће бити уклоњене за све учеснике", - "@messageWillBeRemovedWarning": { - "type": "text", - "placeholders": {} - }, - "moderator": "Модератор", - "@moderator": { - "type": "text", - "placeholders": {} - }, - "muteChat": "Ућуткај ћаскање", - "@muteChat": { - "type": "text", - "placeholders": {} - }, - "needPantalaimonWarning": "За сада, потребан је Пантелејмон (Pantalaimon) да бисте користили шифровање с краја на крај.", - "@needPantalaimonWarning": { - "type": "text", - "placeholders": {} - }, - "newChat": "Ново ћаскање", - "@newChat": { - "type": "text", - "placeholders": {} - }, - "newMessageInFluffyChat": "Нова порука — FluffyChat", - "@newMessageInFluffyChat": { - "type": "text", - "placeholders": {} - }, - "newVerificationRequest": "Нови захтев за верификацију!", - "@newVerificationRequest": { - "type": "text", - "placeholders": {} - }, - "next": "Следеће", - "@next": { - "type": "text", - "placeholders": {} - }, - "no": "Не", - "@no": { - "type": "text", - "placeholders": {} - }, - "noConnectionToTheServer": "Нема везе са сервером", - "@noConnectionToTheServer": { - "type": "text", - "placeholders": {} - }, - "noEmotesFound": "Нема емотија. 😕", - "@noEmotesFound": { - "type": "text", - "placeholders": {} - }, - "noEncryptionForPublicRooms": "Шифровање се може активирати након што соба престане да буде јавно доступна.", - "@noEncryptionForPublicRooms": { - "type": "text", - "placeholders": {} - }, - "noGoogleServicesWarning": "Чини се да немате Гугл услуге на телефону. То је добра одлука за вашу приватност! Да би се протурале нотификације у FluffyChat, препоручујемо коришћење https://microg.org/ или https://unifiedpush.org/", - "@noGoogleServicesWarning": { - "type": "text", - "placeholders": {} - }, - "none": "Ништа", - "@none": { - "type": "text", - "placeholders": {} - }, - "noPasswordRecoveryDescription": "Још нисте одредили начин за опоравак лозинке.", - "@noPasswordRecoveryDescription": { - "type": "text", - "placeholders": {} - }, - "noPermission": "Нема дозвола", - "@noPermission": { - "type": "text", - "placeholders": {} - }, - "noRoomsFound": "Нисам нашао собе…", - "@noRoomsFound": { - "type": "text", - "placeholders": {} - }, - "notifications": "Обавештења", - "@notifications": { - "type": "text", - "placeholders": {} - }, - "notificationsEnabledForThisAccount": "Обавештења укључена за овај налог", - "@notificationsEnabledForThisAccount": { - "type": "text", - "placeholders": {} - }, - "numUsersTyping": "{count} корисника куца…", - "@numUsersTyping": { - "type": "text", - "placeholders": { - "count": {} - } - }, - "offensive": "Увредљив", - "@offensive": { - "type": "text", - "placeholders": {} - }, - "offline": "Ван везе", - "@offline": { - "type": "text", - "placeholders": {} - }, - "ok": "у реду", - "@ok": { - "type": "text", - "placeholders": {} - }, - "online": "На вези", - "@online": { - "type": "text", - "placeholders": {} - }, - "onlineKeyBackupEnabled": "Резерва кључева на мрежи је укључена", - "@onlineKeyBackupEnabled": { - "type": "text", - "placeholders": {} - }, - "oopsPushError": "Нажалост, дошло је до грешке при подешавању дотурања обавештења.", - "@oopsPushError": { - "type": "text", - "placeholders": {} - }, - "oopsSomethingWentWrong": "Нешто је пошло наопако…", - "@oopsSomethingWentWrong": { - "type": "text", - "placeholders": {} - }, - "openAppToReadMessages": "Отворите апликацију да прочитате поруке", - "@openAppToReadMessages": { - "type": "text", - "placeholders": {} - }, - "openCamera": "Отвори камеру", - "@openCamera": { - "type": "text", - "placeholders": {} - }, - "optionalGroupName": "(опционо) назив групе", - "@optionalGroupName": { - "type": "text", - "placeholders": {} - }, - "or": "или", - "@or": { - "type": "text", - "placeholders": {} - }, - "participant": "Учесник", - "@participant": { - "type": "text", - "placeholders": {} - }, - "passphraseOrKey": "фраза или кључ опоравка", - "@passphraseOrKey": { - "type": "text", - "placeholders": {} - }, - "password": "Лозинка", - "@password": { - "type": "text", - "placeholders": {} - }, - "passwordForgotten": "Заборављена лозинка", - "@passwordForgotten": { - "type": "text", - "placeholders": {} - }, - "passwordHasBeenChanged": "Лозинка је промењена", - "@passwordHasBeenChanged": { - "type": "text", - "placeholders": {} - }, - "passwordRecovery": "Опоравак лозинке", - "@passwordRecovery": { - "type": "text", - "placeholders": {} - }, - "people": "Људи", - "@people": { - "type": "text", - "placeholders": {} - }, - "pickImage": "Избор слике", - "@pickImage": { - "type": "text", - "placeholders": {} - }, - "pin": "Закачи", - "@pin": { - "type": "text", - "placeholders": {} - }, - "play": "Пусти {fileName}", - "@play": { - "type": "text", - "placeholders": { - "fileName": {} - } - }, - "pleaseChoose": "Изаберите", - "@pleaseChoose": { - "type": "text", - "placeholders": {} - }, - "pleaseChooseAPasscode": "Изаберите код за пролаз", - "@pleaseChooseAPasscode": { - "type": "text", - "placeholders": {} - }, - "pleaseChooseAUsername": "Изаберите корисничко име", - "@pleaseChooseAUsername": { - "type": "text", - "placeholders": {} - }, - "pleaseClickOnLink": "Кликните на везу у примљеној е-пошти па наставите.", - "@pleaseClickOnLink": { - "type": "text", - "placeholders": {} - }, - "pleaseEnter4Digits": "Унесите 4 цифре или оставите празно да не закључавате апликацију.", - "@pleaseEnter4Digits": { - "type": "text", - "placeholders": {} - }, - "pleaseEnterAMatrixIdentifier": "Унесите ИД са Матрикса.", - "@pleaseEnterAMatrixIdentifier": { - "type": "text", - "placeholders": {} - }, - "pleaseEnterYourPassword": "Унесите своју лозинку", - "@pleaseEnterYourPassword": { - "type": "text", - "placeholders": {} - }, - "pleaseEnterYourPin": "Унесите свој пин", - "@pleaseEnterYourPin": { - "type": "text", - "placeholders": {} - }, - "pleaseEnterYourUsername": "Унесите своје корисничко име", - "@pleaseEnterYourUsername": { - "type": "text", - "placeholders": {} - }, - "pleaseFollowInstructionsOnWeb": "Испратите упутства на веб сајту и тапните на „Следеће“.", - "@pleaseFollowInstructionsOnWeb": { - "type": "text", - "placeholders": {} - }, - "privacy": "Приватност", - "@privacy": { - "type": "text", - "placeholders": {} - }, - "publicRooms": "Јавне собе", - "@publicRooms": { - "type": "text", - "placeholders": {} - }, - "pushRules": "Правила протурања", - "@pushRules": { - "type": "text", - "placeholders": {} - }, - "reason": "Разлог", - "@reason": { - "type": "text", - "placeholders": {} - }, - "recording": "Снимам", - "@recording": { - "type": "text", - "placeholders": {} - }, - "redactedAnEvent": "{username} редигова догађај", - "@redactedAnEvent": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "redactMessage": "Редигуј поруку", - "@redactMessage": { - "type": "text", - "placeholders": {} - }, - "register": "Регистрација", - "@register": { - "type": "text", - "placeholders": {} - }, - "reject": "Одбиј", - "@reject": { - "type": "text", - "placeholders": {} - }, - "rejectedTheInvitation": "{username} одби позивницу", - "@rejectedTheInvitation": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "rejoin": "Поново се придружи", - "@rejoin": { - "type": "text", - "placeholders": {} - }, - "remove": "Уклони", - "@remove": { - "type": "text", - "placeholders": {} - }, - "removeAllOtherDevices": "Уклони све остале уређаје", - "@removeAllOtherDevices": { - "type": "text", - "placeholders": {} - }, - "removedBy": "Уклонио корисник {username}", - "@removedBy": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "removeDevice": "Уклони уређај", - "@removeDevice": { - "type": "text", - "placeholders": {} - }, - "unbanFromChat": "Уклони изгнанство", - "@unbanFromChat": { - "type": "text", - "placeholders": {} - }, - "removeYourAvatar": "Уклоните свој аватар", - "@removeYourAvatar": { - "type": "text", - "placeholders": {} - }, - "renderRichContent": "Приказуј обогаћен садржај поруке", - "@renderRichContent": { - "type": "text", - "placeholders": {} - }, - "replaceRoomWithNewerVersion": "Замени собу новијом верзијом", - "@replaceRoomWithNewerVersion": { - "type": "text", - "placeholders": {} - }, - "reply": "Одговори", - "@reply": { - "type": "text", - "placeholders": {} - }, - "reportMessage": "Пријави поруку", - "@reportMessage": { - "type": "text", - "placeholders": {} - }, - "requestPermission": "Затражи дозволу", - "@requestPermission": { - "type": "text", - "placeholders": {} - }, - "roomHasBeenUpgraded": "Соба је надограђена", - "@roomHasBeenUpgraded": { - "type": "text", - "placeholders": {} - }, - "roomVersion": "Верзија собе", - "@roomVersion": { - "type": "text", - "placeholders": {} - }, - "search": "Претражи", - "@search": { - "type": "text", - "placeholders": {} - }, - "security": "Безбедност", - "@security": { - "type": "text", - "placeholders": {} - }, - "seenByUser": "{username} прегледа", - "@seenByUser": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "seenByUserAndCountOthers": "{count, plural, other{{username} прегледа и {count} осталих}}", - "@seenByUserAndCountOthers": { - "type": "text", - "placeholders": { - "username": {}, - "count": {} - } - }, - "seenByUserAndUser": "Прегледали {username} и {username2}", - "@seenByUserAndUser": { - "type": "text", - "placeholders": { - "username": {}, - "username2": {} - } - }, - "send": "Пошаљи", - "@send": { - "type": "text", - "placeholders": {} - }, - "sendAMessage": "Пошаљи поруку", - "@sendAMessage": { - "type": "text", - "placeholders": {} - }, - "sendAudio": "Пошаљи аудио", - "@sendAudio": { - "type": "text", - "placeholders": {} - }, - "sendFile": "Пошаљи фајл", - "@sendFile": { - "type": "text", - "placeholders": {} - }, - "sendImage": "Пошаљи слику", - "@sendImage": { - "type": "text", - "placeholders": {} - }, - "sendMessages": "Слање порука", - "@sendMessages": { - "type": "text", - "placeholders": {} - }, - "sendOriginal": "Пошаљи оригинал", - "@sendOriginal": { - "type": "text", - "placeholders": {} - }, - "sendVideo": "Пошаљи видео", - "@sendVideo": { - "type": "text", - "placeholders": {} - }, - "sentAFile": "{username} посла фајл", - "@sentAFile": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sentAnAudio": "{username} посла аудио", - "@sentAnAudio": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sentAPicture": "{username} посла слику", - "@sentAPicture": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sentASticker": "{username} посла налепницу", - "@sentASticker": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sentAVideo": "{username} посла видео", - "@sentAVideo": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sentCallInformations": "{senderName} посла податке о позиву", - "@sentCallInformations": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "setAsCanonicalAlias": "Постави као главни алијас", - "@setAsCanonicalAlias": { - "type": "text", - "placeholders": {} - }, - "setCustomEmotes": "постави посебне емотије", - "@setCustomEmotes": { - "type": "text", - "placeholders": {} - }, - "setGroupDescription": "Постави опис групе", - "@setGroupDescription": { - "type": "text", - "placeholders": {} - }, - "setInvitationLink": "Поставља везу позивнице", - "@setInvitationLink": { - "type": "text", - "placeholders": {} - }, - "setPermissionsLevel": "Одреди ниво дозволе", - "@setPermissionsLevel": { - "type": "text", - "placeholders": {} - }, - "setStatus": "Постави статус", - "@setStatus": { - "type": "text", - "placeholders": {} - }, - "settings": "Поставке", - "@settings": { - "type": "text", - "placeholders": {} - }, - "share": "Подели", - "@share": { - "type": "text", - "placeholders": {} - }, - "sharedTheLocation": "{username} подели локацију", - "@sharedTheLocation": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "showPassword": "Прикажи лозинку", - "@showPassword": { - "type": "text", - "placeholders": {} - }, - "signUp": "Регистрација", - "@signUp": { - "type": "text", - "placeholders": {} - }, - "singlesignon": "Јединствена пријава", - "@singlesignon": { - "type": "text", - "placeholders": {} - }, - "skip": "Прескочи", - "@skip": { - "type": "text", - "placeholders": {} - }, - "sourceCode": "Изворни код", - "@sourceCode": { - "type": "text", - "placeholders": {} - }, - "startedACall": "{senderName} започе позив", - "@startedACall": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "status": "Стање", - "@status": { - "type": "text", - "placeholders": {} - }, - "statusExampleMessage": "Како сте данас?", - "@statusExampleMessage": { - "type": "text", - "placeholders": {} - }, - "submit": "Пошаљи", - "@submit": { - "type": "text", - "placeholders": {} - }, - "systemTheme": "системски", - "@systemTheme": { - "type": "text", - "placeholders": {} - }, - "theyDontMatch": "Не поклапају се", - "@theyDontMatch": { - "type": "text", - "placeholders": {} - }, - "theyMatch": "Поклапају се", - "@theyMatch": { - "type": "text", - "placeholders": {} - }, - "title": "FluffyChat", - "@title": { - "description": "Title for the application", - "type": "text", - "placeholders": {} - }, - "toggleFavorite": "Мењај омиљеност", - "@toggleFavorite": { - "type": "text", - "placeholders": {} - }, - "toggleMuted": "Мењај ућутканост", - "@toggleMuted": { - "type": "text", - "placeholders": {} - }, - "toggleUnread": "Означи не/прочитано", - "@toggleUnread": { - "type": "text", - "placeholders": {} - }, - "tooManyRequestsWarning": "Превише упита. Покушајте касније!", - "@tooManyRequestsWarning": { - "type": "text", - "placeholders": {} - }, - "transferFromAnotherDevice": "Пренос са другог уређаја", - "@transferFromAnotherDevice": { - "type": "text", - "placeholders": {} - }, - "tryToSendAgain": "Покушај слање поново", - "@tryToSendAgain": { - "type": "text", - "placeholders": {} - }, - "unavailable": "Недоступно", - "@unavailable": { - "type": "text", - "placeholders": {} - }, - "unbannedUser": "{username} одблокира корисника {targetName}", - "@unbannedUser": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "unblockDevice": "Одблокирај уређај", - "@unblockDevice": { - "type": "text", - "placeholders": {} - }, - "unknownDevice": "Непознат уређај", - "@unknownDevice": { - "type": "text", - "placeholders": {} - }, - "unknownEncryptionAlgorithm": "Непознат алгоритам шифровања", - "@unknownEncryptionAlgorithm": { - "type": "text", - "placeholders": {} - }, - "unknownEvent": "Непознат догађај „{type}“", - "@unknownEvent": { - "type": "text", - "placeholders": { - "type": {} - } - }, - "unmuteChat": "Врати обавештења", - "@unmuteChat": { - "type": "text", - "placeholders": {} - }, - "unpin": "Откачи", - "@unpin": { - "type": "text", - "placeholders": {} - }, - "unreadChats": "{unreadCount, plural, other{непрочитаних ћаскања: {unreadCount}}}", - "@unreadChats": { - "type": "text", - "placeholders": { - "unreadCount": {} - } - }, - "userAndOthersAreTyping": "{username} и {count} корисника куцају…", - "@userAndOthersAreTyping": { - "type": "text", - "placeholders": { - "username": {}, - "count": {} - } - }, - "userAndUserAreTyping": "{username} и {username2} куцају…", - "@userAndUserAreTyping": { - "type": "text", - "placeholders": { - "username": {}, - "username2": {} - } - }, - "userIsTyping": "{username} куца…", - "@userIsTyping": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "userLeftTheChat": "{username} напусти ћаскање", - "@userLeftTheChat": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "username": "Корисничко име", - "@username": { - "type": "text", - "placeholders": {} - }, - "userSentUnknownEvent": "{username} посла {type} догађај", - "@userSentUnknownEvent": { - "type": "text", - "placeholders": { - "username": {}, - "type": {} - } - }, - "verified": "Оверен", - "@verified": { - "type": "text", - "placeholders": {} - }, - "verify": "Верификуј", - "@verify": { - "type": "text", - "placeholders": {} - }, - "verifyStart": "Покрени верификацију", - "@verifyStart": { - "type": "text", - "placeholders": {} - }, - "verifySuccess": "Успешно сте верификовали!", - "@verifySuccess": { - "type": "text", - "placeholders": {} - }, - "verifyTitle": "Верификујем други налог", - "@verifyTitle": { - "type": "text", - "placeholders": {} - }, - "videoCall": "Видео позив", - "@videoCall": { - "type": "text", - "placeholders": {} - }, - "visibilityOfTheChatHistory": "Одреди видљивост историје", - "@visibilityOfTheChatHistory": { - "type": "text", - "placeholders": {} - }, - "visibleForAllParticipants": "видљиво свим учесницима", - "@visibleForAllParticipants": { - "type": "text", - "placeholders": {} - }, - "visibleForEveryone": "видљиво свима", - "@visibleForEveryone": { - "type": "text", - "placeholders": {} - }, - "voiceMessage": "Гласовна порука", - "@voiceMessage": { - "type": "text", - "placeholders": {} - }, - "waitingPartnerAcceptRequest": "Чекам да саговорник прихвати захтев…", - "@waitingPartnerAcceptRequest": { - "type": "text", - "placeholders": {} - }, - "waitingPartnerEmoji": "Чекам да саговорник прихвати емоџије…", - "@waitingPartnerEmoji": { - "type": "text", - "placeholders": {} - }, - "waitingPartnerNumbers": "Чекам да саговорник прихвати бројеве…", - "@waitingPartnerNumbers": { - "type": "text", - "placeholders": {} - }, - "wallpaper": "Тапета", - "@wallpaper": { - "type": "text", - "placeholders": {} - }, - "warning": "Упозорење!", - "@warning": { - "type": "text", - "placeholders": {} - }, - "weSentYouAnEmail": "Послали смо вам е-пошту", - "@weSentYouAnEmail": { - "type": "text", - "placeholders": {} - }, - "whoCanPerformWhichAction": "ко може шта да ради", - "@whoCanPerformWhichAction": { - "type": "text", - "placeholders": {} - }, - "whoIsAllowedToJoinThisGroup": "Ко може да се придружи групи", - "@whoIsAllowedToJoinThisGroup": { - "type": "text", - "placeholders": {} - }, - "whyDoYouWantToReportThis": "Зашто желите ово да пријавите?", - "@whyDoYouWantToReportThis": { - "type": "text", - "placeholders": {} - }, - "wipeChatBackup": "Да обришем резервну копију како би направио нови сигурносни кључ?", - "@wipeChatBackup": { - "type": "text", - "placeholders": {} - }, - "withTheseAddressesRecoveryDescription": "Са овим адресама можете опоравити своју лозинку.", - "@withTheseAddressesRecoveryDescription": { - "type": "text", - "placeholders": {} - }, - "writeAMessage": "напишите поруку…", - "@writeAMessage": { - "type": "text", - "placeholders": {} - }, - "yes": "Да", - "@yes": { - "type": "text", - "placeholders": {} - }, - "you": "Ви", - "@you": { - "type": "text", - "placeholders": {} - }, - "youAreInvitedToThisChat": "Позвани сте у ово ћаскање", - "@youAreInvitedToThisChat": { - "type": "text", - "placeholders": {} - }, - "youAreNoLongerParticipatingInThisChat": "Више не учествујете у овом ћаскању", - "@youAreNoLongerParticipatingInThisChat": { - "type": "text", - "placeholders": {} - }, - "youCannotInviteYourself": "Не можете позвати себе", - "@youCannotInviteYourself": { - "type": "text", - "placeholders": {} - }, - "youHaveBeenBannedFromThisChat": "Забрањено вам је ово ћаскање", - "@youHaveBeenBannedFromThisChat": { - "type": "text", - "placeholders": {} - }, - "yourPublicKey": "Ваш јавни кључ", - "@yourPublicKey": { - "type": "text", - "placeholders": {} + "@@last_modified": "2021-08-14 12:41:09.857024", + "about": "О програму", + "@about": { + "type": "text", + "placeholders": {} + }, + "accept": "Прихвати", + "@accept": { + "type": "text", + "placeholders": {} + }, + "acceptedTheInvitation": "{username} прихвата позивницу", + "@acceptedTheInvitation": { + "type": "text", + "placeholders": { + "username": {} } -} \ No newline at end of file + }, + "account": "Налог", + "@account": { + "type": "text", + "placeholders": {} + }, + "activatedEndToEndEncryption": "{username} укључи шифровање с краја на крај", + "@activatedEndToEndEncryption": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "addEmail": "Додај е-адресу", + "@addEmail": { + "type": "text", + "placeholders": {} + }, + "addGroupDescription": "Додај опис групе", + "@addGroupDescription": { + "type": "text", + "placeholders": {} + }, + "admin": "Админ", + "@admin": { + "type": "text", + "placeholders": {} + }, + "alias": "алијас", + "@alias": { + "type": "text", + "placeholders": {} + }, + "all": "Сви", + "@all": { + "type": "text", + "placeholders": {} + }, + "answeredTheCall": "{senderName} одговори на позив", + "@answeredTheCall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "anyoneCanJoin": "свако може да се придружи", + "@anyoneCanJoin": { + "type": "text", + "placeholders": {} + }, + "appLock": "Закључавање апликације", + "@appLock": { + "type": "text", + "placeholders": {} + }, + "archive": "Архива", + "@archive": { + "type": "text", + "placeholders": {} + }, + "areGuestsAllowedToJoin": "Да ли је гостима дозвољен приступ", + "@areGuestsAllowedToJoin": { + "type": "text", + "placeholders": {} + }, + "areYouSure": "Сигурни сте?", + "@areYouSure": { + "type": "text", + "placeholders": {} + }, + "areYouSureYouWantToLogout": "Заиста желите да се одјавите?", + "@areYouSureYouWantToLogout": { + "type": "text", + "placeholders": {} + }, + "askSSSSSign": "Да бисте могли да пријавите другу особу, унесите своју безбедносну фразу или кључ опоравка.", + "@askSSSSSign": { + "type": "text", + "placeholders": {} + }, + "askVerificationRequest": "Прихватате ли захтев за верификацију од корисника {username}?", + "@askVerificationRequest": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "badServerLoginTypesException": "Домаћи сервер подржава начине пријаве:\n{serverVersions}\nали ова апликација подржава само:\n{supportedVersions}", + "@badServerLoginTypesException": { + "type": "text", + "placeholders": { + "serverVersions": {}, + "supportedVersions": {} + } + }, + "badServerVersionsException": "Домаћи сервер подржава верзије:\n{serverVersions}\nали ова апликација подржава само {supportedVersions}", + "@badServerVersionsException": { + "type": "text", + "placeholders": { + "serverVersions": {}, + "supportedVersions": {} + } + }, + "banFromChat": "Забрани у ћаскању", + "@banFromChat": { + "type": "text", + "placeholders": {} + }, + "banned": "Забрањен", + "@banned": { + "type": "text", + "placeholders": {} + }, + "bannedUser": "{username} забрани корисника {targetName}", + "@bannedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "blockDevice": "Блокирај уређај", + "@blockDevice": { + "type": "text", + "placeholders": {} + }, + "blocked": "Блокиран", + "@blocked": { + "type": "text", + "placeholders": {} + }, + "botMessages": "Поруке Бота", + "@botMessages": { + "type": "text", + "placeholders": {} + }, + "cancel": "Откажи", + "@cancel": { + "type": "text", + "placeholders": {} + }, + "changeDeviceName": "Промени назив уређаја", + "@changeDeviceName": { + "type": "text", + "placeholders": {} + }, + "changedTheChatAvatar": "{username} промени аватар ћаскања", + "@changedTheChatAvatar": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheChatDescriptionTo": "{username} промени опис ћаскања у: „{description}“", + "@changedTheChatDescriptionTo": { + "type": "text", + "placeholders": { + "username": {}, + "description": {} + } + }, + "changedTheChatNameTo": "{username} промени назив ћаскања у: „{chatname}“", + "@changedTheChatNameTo": { + "type": "text", + "placeholders": { + "username": {}, + "chatname": {} + } + }, + "changedTheChatPermissions": "{username} измени дозволе ћаскања", + "@changedTheChatPermissions": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheDisplaynameTo": "{username} промени приказно име на: „{displayname}“", + "@changedTheDisplaynameTo": { + "type": "text", + "placeholders": { + "username": {}, + "displayname": {} + } + }, + "changedTheGuestAccessRules": "{username} измени правила за приступ гостију", + "@changedTheGuestAccessRules": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheGuestAccessRulesTo": "{username} измени правила за приступ гостију на: {rules}", + "@changedTheGuestAccessRulesTo": { + "type": "text", + "placeholders": { + "username": {}, + "rules": {} + } + }, + "changedTheHistoryVisibility": "{username} измени видљивост историје", + "@changedTheHistoryVisibility": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheHistoryVisibilityTo": "{username} измени видљивост историје на: {rules}", + "@changedTheHistoryVisibilityTo": { + "type": "text", + "placeholders": { + "username": {}, + "rules": {} + } + }, + "changedTheJoinRules": "{username} измени правила приступања", + "@changedTheJoinRules": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheJoinRulesTo": "{username} измени правила приступања на: {joinRules}", + "@changedTheJoinRulesTo": { + "type": "text", + "placeholders": { + "username": {}, + "joinRules": {} + } + }, + "changedTheProfileAvatar": "{username} измени свој аватар", + "@changedTheProfileAvatar": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheRoomAliases": "{username} измени алијас собе", + "@changedTheRoomAliases": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheRoomInvitationLink": "{username} измени везу позивнице", + "@changedTheRoomInvitationLink": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changePassword": "Измени лозинку", + "@changePassword": { + "type": "text", + "placeholders": {} + }, + "changeTheHomeserver": "Промени домаћи сервер", + "@changeTheHomeserver": { + "type": "text", + "placeholders": {} + }, + "changeTheme": "Измените изглед", + "@changeTheme": { + "type": "text", + "placeholders": {} + }, + "changeTheNameOfTheGroup": "Измени назив групе", + "@changeTheNameOfTheGroup": { + "type": "text", + "placeholders": {} + }, + "changeWallpaper": "Измени тапет", + "@changeWallpaper": { + "type": "text", + "placeholders": {} + }, + "changeYourAvatar": "Измените свој аватар", + "@changeYourAvatar": { + "type": "text", + "placeholders": {} + }, + "channelCorruptedDecryptError": "Шифровање је покварено", + "@channelCorruptedDecryptError": { + "type": "text", + "placeholders": {} + }, + "chat": "Ћаскање", + "@chat": { + "type": "text", + "placeholders": {} + }, + "chatBackup": "Копија ћаскања", + "@chatBackup": { + "type": "text", + "placeholders": {} + }, + "chatBackupDescription": "Ваша резервна копија ћаскања је обезбеђена кључем. Немојте да га изгубите.", + "@chatBackupDescription": { + "type": "text", + "placeholders": {} + }, + "chatDetails": "Детаљи ћаскања", + "@chatDetails": { + "type": "text", + "placeholders": {} + }, + "chats": "Ћаскања", + "@chats": { + "type": "text", + "placeholders": {} + }, + "chooseAStrongPassword": "Изаберите јаку лозинку", + "@chooseAStrongPassword": { + "type": "text", + "placeholders": {} + }, + "chooseAUsername": "Изаберите корисничко име", + "@chooseAUsername": { + "type": "text", + "placeholders": {} + }, + "clearArchive": "Очисти архиву", + "@clearArchive": {}, + "close": "Затвори", + "@close": { + "type": "text", + "placeholders": {} + }, + "commandHint_ban": "Блокирај задатог корисника за ову собу", + "@commandHint_ban": { + "type": "text", + "description": "Usage hint for the command /ban" + }, + "commandHint_html": "Шаљи ХТМЛ обликован текст", + "@commandHint_html": { + "type": "text", + "description": "Usage hint for the command /html" + }, + "commandHint_invite": "Позови задатог корисника у собу", + "@commandHint_invite": { + "type": "text", + "description": "Usage hint for the command /invite" + }, + "commandHint_join": "Придружи се наведеној соби", + "@commandHint_join": { + "type": "text", + "description": "Usage hint for the command /join" + }, + "commandHint_kick": "Уклони задатог корисника из собе", + "@commandHint_kick": { + "type": "text", + "description": "Usage hint for the command /kick" + }, + "commandHint_leave": "Напусти ову собу", + "@commandHint_leave": { + "type": "text", + "description": "Usage hint for the command /leave" + }, + "commandHint_me": "Опишите себе", + "@commandHint_me": { + "type": "text", + "description": "Usage hint for the command /me" + }, + "commandHint_myroomnick": "Поставља ваш надимак за ову собу", + "@commandHint_myroomnick": { + "type": "text", + "description": "Usage hint for the command /myroomnick" + }, + "commandHint_op": "Подеси ниво задатог корисника (подразумевано: 50)", + "@commandHint_op": { + "type": "text", + "description": "Usage hint for the command /op" + }, + "commandHint_plain": "Шаљи неформатиран текст", + "@commandHint_plain": { + "type": "text", + "description": "Usage hint for the command /plain" + }, + "commandHint_react": "Шаљи одговор као реакцију", + "@commandHint_react": { + "type": "text", + "description": "Usage hint for the command /react" + }, + "commandHint_send": "Пошаљи текст", + "@commandHint_send": { + "type": "text", + "description": "Usage hint for the command /send" + }, + "commandHint_unban": "Скини забрану задатом кориснику за ову собу", + "@commandHint_unban": { + "type": "text", + "description": "Usage hint for the command /unban" + }, + "compareEmojiMatch": "Упоредите и проверите да су емоџији идентични као на другом уређају:", + "@compareEmojiMatch": { + "type": "text", + "placeholders": {} + }, + "compareNumbersMatch": "Упоредите и проверите да су следећи бројеви идентични као на другом уређају:", + "@compareNumbersMatch": { + "type": "text", + "placeholders": {} + }, + "configureChat": "Подешавање ћаскања", + "@configureChat": { + "type": "text", + "placeholders": {} + }, + "confirm": "Потврди", + "@confirm": { + "type": "text", + "placeholders": {} + }, + "connect": "Повежи се", + "@connect": { + "type": "text", + "placeholders": {} + }, + "contactHasBeenInvitedToTheGroup": "Особа је позвана у групу", + "@contactHasBeenInvitedToTheGroup": { + "type": "text", + "placeholders": {} + }, + "containsDisplayName": "Садржи приказно име", + "@containsDisplayName": { + "type": "text", + "placeholders": {} + }, + "containsUserName": "Садржи корисничко име", + "@containsUserName": { + "type": "text", + "placeholders": {} + }, + "contentHasBeenReported": "Садржај је пријављен администраторима сервера", + "@contentHasBeenReported": { + "type": "text", + "placeholders": {} + }, + "copiedToClipboard": "Копирано у клипборд", + "@copiedToClipboard": { + "type": "text", + "placeholders": {} + }, + "copy": "Копирај", + "@copy": { + "type": "text", + "placeholders": {} + }, + "copyToClipboard": "Копирај у клипборд", + "@copyToClipboard": { + "type": "text", + "placeholders": {} + }, + "couldNotDecryptMessage": "Не могу да дешифрујем поруку: {error}", + "@couldNotDecryptMessage": { + "type": "text", + "placeholders": { + "error": {} + } + }, + "countParticipants": "учесника: {count}", + "@countParticipants": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "create": "Направи", + "@create": { + "type": "text", + "placeholders": {} + }, + "createdTheChat": "{username} направи ћаскање", + "@createdTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "createNewGroup": "Направи нову групу", + "@createNewGroup": { + "type": "text", + "placeholders": {} + }, + "currentlyActive": "Тренутно активно", + "@currentlyActive": { + "type": "text", + "placeholders": {} + }, + "darkTheme": "тамни", + "@darkTheme": { + "type": "text", + "placeholders": {} + }, + "dateAndTimeOfDay": "{date}, {timeOfDay}", + "@dateAndTimeOfDay": { + "type": "text", + "placeholders": { + "date": {}, + "timeOfDay": {} + } + }, + "dateWithoutYear": "{day} {month}", + "@dateWithoutYear": { + "type": "text", + "placeholders": { + "month": {}, + "day": {} + } + }, + "dateWithYear": "{day} {month} {year}", + "@dateWithYear": { + "type": "text", + "placeholders": { + "year": {}, + "month": {}, + "day": {} + } + }, + "deactivateAccountWarning": "Ово ће деактивирати ваш кориснички налог. Не може се повратити! Сигурни сте?", + "@deactivateAccountWarning": { + "type": "text", + "placeholders": {} + }, + "defaultPermissionLevel": "Подразумевани ниво приступа", + "@defaultPermissionLevel": { + "type": "text", + "placeholders": {} + }, + "delete": "Обриши", + "@delete": { + "type": "text", + "placeholders": {} + }, + "deleteAccount": "Обриши налог", + "@deleteAccount": { + "type": "text", + "placeholders": {} + }, + "deleteMessage": "Брисање поруке", + "@deleteMessage": { + "type": "text", + "placeholders": {} + }, + "deny": "Одбиј", + "@deny": { + "type": "text", + "placeholders": {} + }, + "device": "Уређај", + "@device": { + "type": "text", + "placeholders": {} + }, + "deviceId": "ИД уређаја", + "@deviceId": { + "type": "text", + "placeholders": {} + }, + "devices": "Уређаји", + "@devices": { + "type": "text", + "placeholders": {} + }, + "directChats": "Директна ћаскања", + "@directChats": { + "type": "text", + "placeholders": {} + }, + "displaynameHasBeenChanged": "Име за приказ је измењено", + "@displaynameHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "downloadFile": "Преузми фајл", + "@downloadFile": { + "type": "text", + "placeholders": {} + }, + "edit": "Уреди", + "@edit": { + "type": "text", + "placeholders": {} + }, + "editBlockedServers": "Уреди блокиране сервере", + "@editBlockedServers": { + "type": "text", + "placeholders": {} + }, + "editChatPermissions": "Уредите дозволе ћаскања", + "@editChatPermissions": { + "type": "text", + "placeholders": {} + }, + "editDisplayname": "Уреди име за приказ", + "@editDisplayname": { + "type": "text", + "placeholders": {} + }, + "editRoomAliases": "Уреди алијасе собе", + "@editRoomAliases": { + "type": "text", + "placeholders": {} + }, + "editRoomAvatar": "Уређује аватар собе", + "@editRoomAvatar": { + "type": "text", + "placeholders": {} + }, + "emoteExists": "Емоти већ постоји!", + "@emoteExists": { + "type": "text", + "placeholders": {} + }, + "emoteInvalid": "Неисправна скраћеница за емоти!", + "@emoteInvalid": { + "type": "text", + "placeholders": {} + }, + "emotePacks": "Пакети емотија за собу", + "@emotePacks": { + "type": "text", + "placeholders": {} + }, + "emoteSettings": "Поставке емотија", + "@emoteSettings": { + "type": "text", + "placeholders": {} + }, + "emoteShortcode": "скраћеница", + "@emoteShortcode": { + "type": "text", + "placeholders": {} + }, + "emoteWarnNeedToPick": "Морате да изаберете скраћеницу и слику за емоти!", + "@emoteWarnNeedToPick": { + "type": "text", + "placeholders": {} + }, + "emptyChat": "празно ћаскање", + "@emptyChat": { + "type": "text", + "placeholders": {} + }, + "enableEmotesGlobally": "Глобално укључи пакет емотија", + "@enableEmotesGlobally": { + "type": "text", + "placeholders": {} + }, + "enableEncryption": "Укључује шифровање", + "@enableEncryption": { + "type": "text", + "placeholders": {} + }, + "enableEncryptionWarning": "Шифровање више нећете моћи да искључите. Сигурни сте?", + "@enableEncryptionWarning": { + "type": "text", + "placeholders": {} + }, + "encrypted": "Шифровано", + "@encrypted": { + "type": "text", + "placeholders": {} + }, + "encryption": "Шифровање", + "@encryption": { + "type": "text", + "placeholders": {} + }, + "encryptionNotEnabled": "Шифровање није укључено", + "@encryptionNotEnabled": { + "type": "text", + "placeholders": {} + }, + "endedTheCall": "{senderName} заврши позив", + "@endedTheCall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "enterAGroupName": "унесите назив групе", + "@enterAGroupName": { + "type": "text", + "placeholders": {} + }, + "enterAnEmailAddress": "Унесите адресу е-поште", + "@enterAnEmailAddress": { + "type": "text", + "placeholders": {} + }, + "enterYourHomeserver": "Унесите свој домаћи сервер", + "@enterYourHomeserver": { + "type": "text", + "placeholders": {} + }, + "everythingReady": "Све је спремно!", + "@everythingReady": { + "type": "text", + "placeholders": {} + }, + "extremeOffensive": "Екстремно увредљив", + "@extremeOffensive": { + "type": "text", + "placeholders": {} + }, + "fileName": "Назив фајла", + "@fileName": { + "type": "text", + "placeholders": {} + }, + "fluffychat": "FluffyChat", + "@fluffychat": { + "type": "text", + "placeholders": {} + }, + "fontSize": "Величина фонта", + "@fontSize": { + "type": "text", + "placeholders": {} + }, + "forward": "Напред", + "@forward": { + "type": "text", + "placeholders": {} + }, + "fromJoining": "од приступања", + "@fromJoining": { + "type": "text", + "placeholders": {} + }, + "fromTheInvitation": "од позивања", + "@fromTheInvitation": { + "type": "text", + "placeholders": {} + }, + "goToTheNewRoom": "Иди у нову собу", + "@goToTheNewRoom": { + "type": "text", + "placeholders": {} + }, + "group": "Група", + "@group": { + "type": "text", + "placeholders": {} + }, + "groupDescription": "Опис групе", + "@groupDescription": { + "type": "text", + "placeholders": {} + }, + "groupDescriptionHasBeenChanged": "Опис групе измењен", + "@groupDescriptionHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "groupIsPublic": "Група је јавна", + "@groupIsPublic": { + "type": "text", + "placeholders": {} + }, + "groups": "Групе", + "@groups": { + "type": "text", + "placeholders": {} + }, + "groupWith": "Група са корисником {displayname}", + "@groupWith": { + "type": "text", + "placeholders": { + "displayname": {} + } + }, + "guestsAreForbidden": "гости су забрањени", + "@guestsAreForbidden": { + "type": "text", + "placeholders": {} + }, + "guestsCanJoin": "гости могу приступити", + "@guestsCanJoin": { + "type": "text", + "placeholders": {} + }, + "hasWithdrawnTheInvitationFor": "{username} поништи позивницу за корисника {targetName}", + "@hasWithdrawnTheInvitationFor": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "help": "Помоћ", + "@help": { + "type": "text", + "placeholders": {} + }, + "hideRedactedEvents": "Сакриј редиговане догађаје", + "@hideRedactedEvents": { + "type": "text", + "placeholders": {} + }, + "hideUnknownEvents": "Сакриј непознате догађаје", + "@hideUnknownEvents": { + "type": "text", + "placeholders": {} + }, + "howOffensiveIsThisContent": "Колико је увредљив овај садржај?", + "@howOffensiveIsThisContent": { + "type": "text", + "placeholders": {} + }, + "id": "ИД", + "@id": { + "type": "text", + "placeholders": {} + }, + "identity": "Идентитет", + "@identity": { + "type": "text", + "placeholders": {} + }, + "ignore": "Игнориши", + "@ignore": { + "type": "text", + "placeholders": {} + }, + "ignoredUsers": "Игнорисани корисници", + "@ignoredUsers": { + "type": "text", + "placeholders": {} + }, + "ignoreListDescription": "Можете игнорисати кориснике који вас нервирају. Нећете примати никакве поруке нити позивнице од корисника са ваше листе за игнорисање.", + "@ignoreListDescription": { + "type": "text", + "placeholders": {} + }, + "ignoreUsername": "Игнориши корисника", + "@ignoreUsername": { + "type": "text", + "placeholders": {} + }, + "iHaveClickedOnLink": "Кликнуо сам на везу", + "@iHaveClickedOnLink": { + "type": "text", + "placeholders": {} + }, + "incorrectPassphraseOrKey": "Неисправна фраза или кључ опоравка", + "@incorrectPassphraseOrKey": { + "type": "text", + "placeholders": {} + }, + "inoffensive": "Није увредљив", + "@inoffensive": { + "type": "text", + "placeholders": {} + }, + "inviteContact": "Позивање особа", + "@inviteContact": { + "type": "text", + "placeholders": {} + }, + "inviteContactToGroup": "Позови особу у групу {groupName}", + "@inviteContactToGroup": { + "type": "text", + "placeholders": { + "groupName": {} + } + }, + "invited": "Позван", + "@invited": { + "type": "text", + "placeholders": {} + }, + "invitedUser": "{username} позва корисника {targetName}", + "@invitedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "invitedUsersOnly": "само позвани корисници", + "@invitedUsersOnly": { + "type": "text", + "placeholders": {} + }, + "inviteForMe": "Позивнице за мене", + "@inviteForMe": { + "type": "text", + "placeholders": {} + }, + "inviteText": "{username} вас позива у FluffyChat. \n1. Инсталирајте FluffyChat: https://fluffychat.im \n2. Региструјте се или пријавите \n3. Отворите везу позивнице: {link}", + "@inviteText": { + "type": "text", + "placeholders": { + "username": {}, + "link": {} + } + }, + "isTyping": "куца…", + "@isTyping": { + "type": "text", + "placeholders": {} + }, + "joinedTheChat": "{username} се придружи ћаскању", + "@joinedTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "joinRoom": "Придружи се соби", + "@joinRoom": { + "type": "text", + "placeholders": {} + }, + "kicked": "{username} избаци корисника {targetName}", + "@kicked": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "kickedAndBanned": "{username} избаци и забрани корисника {targetName}", + "@kickedAndBanned": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "kickFromChat": "Избаци из ћаскања", + "@kickFromChat": { + "type": "text", + "placeholders": {} + }, + "lastActiveAgo": "Последња активност: {localizedTimeShort}", + "@lastActiveAgo": { + "type": "text", + "placeholders": { + "localizedTimeShort": {} + } + }, + "lastSeenLongTimeAgo": "одавно није на мрежи", + "@lastSeenLongTimeAgo": { + "type": "text", + "placeholders": {} + }, + "leave": "Напусти", + "@leave": { + "type": "text", + "placeholders": {} + }, + "leftTheChat": "Напусти ћаскање", + "@leftTheChat": { + "type": "text", + "placeholders": {} + }, + "license": "Лиценца", + "@license": { + "type": "text", + "placeholders": {} + }, + "lightTheme": "светли", + "@lightTheme": { + "type": "text", + "placeholders": {} + }, + "loadCountMoreParticipants": "Учитај још {count} учесника", + "@loadCountMoreParticipants": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "loadingPleaseWait": "Учитавам… Сачекајте.", + "@loadingPleaseWait": { + "type": "text", + "placeholders": {} + }, + "loadMore": "Учитај још…", + "@loadMore": { + "type": "text", + "placeholders": {} + }, + "login": "Пријава", + "@login": { + "type": "text", + "placeholders": {} + }, + "logInTo": "Пријава на {homeserver}", + "@logInTo": { + "type": "text", + "placeholders": { + "homeserver": {} + } + }, + "loginWith": "{brand} за пријаву", + "@loginWith": { + "type": "text", + "placeholders": { + "brand": {} + } + }, + "logout": "Одјава", + "@logout": { + "type": "text", + "placeholders": {} + }, + "makeSureTheIdentifierIsValid": "Проверите да је идентификатор исправан", + "@makeSureTheIdentifierIsValid": { + "type": "text", + "placeholders": {} + }, + "memberChanges": "Измене чланова", + "@memberChanges": { + "type": "text", + "placeholders": {} + }, + "mention": "Спомени", + "@mention": { + "type": "text", + "placeholders": {} + }, + "messages": "Поруке", + "@messages": { + "type": "text", + "placeholders": {} + }, + "messageWillBeRemovedWarning": "Поруке ће бити уклоњене за све учеснике", + "@messageWillBeRemovedWarning": { + "type": "text", + "placeholders": {} + }, + "moderator": "Модератор", + "@moderator": { + "type": "text", + "placeholders": {} + }, + "muteChat": "Ућуткај ћаскање", + "@muteChat": { + "type": "text", + "placeholders": {} + }, + "needPantalaimonWarning": "За сада, потребан је Пантелејмон (Pantalaimon) да бисте користили шифровање с краја на крај.", + "@needPantalaimonWarning": { + "type": "text", + "placeholders": {} + }, + "newChat": "Ново ћаскање", + "@newChat": { + "type": "text", + "placeholders": {} + }, + "newMessageInFluffyChat": "Нова порука — FluffyChat", + "@newMessageInFluffyChat": { + "type": "text", + "placeholders": {} + }, + "newVerificationRequest": "Нови захтев за верификацију!", + "@newVerificationRequest": { + "type": "text", + "placeholders": {} + }, + "next": "Следеће", + "@next": { + "type": "text", + "placeholders": {} + }, + "no": "Не", + "@no": { + "type": "text", + "placeholders": {} + }, + "noConnectionToTheServer": "Нема везе са сервером", + "@noConnectionToTheServer": { + "type": "text", + "placeholders": {} + }, + "noEmotesFound": "Нема емотија. 😕", + "@noEmotesFound": { + "type": "text", + "placeholders": {} + }, + "noEncryptionForPublicRooms": "Шифровање се може активирати након што соба престане да буде јавно доступна.", + "@noEncryptionForPublicRooms": { + "type": "text", + "placeholders": {} + }, + "noGoogleServicesWarning": "Чини се да немате Гугл услуге на телефону. То је добра одлука за вашу приватност! Да би се протурале нотификације у FluffyChat, препоручујемо коришћење https://microg.org/ или https://unifiedpush.org/", + "@noGoogleServicesWarning": { + "type": "text", + "placeholders": {} + }, + "none": "Ништа", + "@none": { + "type": "text", + "placeholders": {} + }, + "noPasswordRecoveryDescription": "Још нисте одредили начин за опоравак лозинке.", + "@noPasswordRecoveryDescription": { + "type": "text", + "placeholders": {} + }, + "noPermission": "Нема дозвола", + "@noPermission": { + "type": "text", + "placeholders": {} + }, + "noRoomsFound": "Нисам нашао собе…", + "@noRoomsFound": { + "type": "text", + "placeholders": {} + }, + "notifications": "Обавештења", + "@notifications": { + "type": "text", + "placeholders": {} + }, + "notificationsEnabledForThisAccount": "Обавештења укључена за овај налог", + "@notificationsEnabledForThisAccount": { + "type": "text", + "placeholders": {} + }, + "numUsersTyping": "{count} корисника куца…", + "@numUsersTyping": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "offensive": "Увредљив", + "@offensive": { + "type": "text", + "placeholders": {} + }, + "offline": "Ван везе", + "@offline": { + "type": "text", + "placeholders": {} + }, + "ok": "у реду", + "@ok": { + "type": "text", + "placeholders": {} + }, + "online": "На вези", + "@online": { + "type": "text", + "placeholders": {} + }, + "onlineKeyBackupEnabled": "Резерва кључева на мрежи је укључена", + "@onlineKeyBackupEnabled": { + "type": "text", + "placeholders": {} + }, + "oopsPushError": "Нажалост, дошло је до грешке при подешавању дотурања обавештења.", + "@oopsPushError": { + "type": "text", + "placeholders": {} + }, + "oopsSomethingWentWrong": "Нешто је пошло наопако…", + "@oopsSomethingWentWrong": { + "type": "text", + "placeholders": {} + }, + "openAppToReadMessages": "Отворите апликацију да прочитате поруке", + "@openAppToReadMessages": { + "type": "text", + "placeholders": {} + }, + "openCamera": "Отвори камеру", + "@openCamera": { + "type": "text", + "placeholders": {} + }, + "optionalGroupName": "(опционо) назив групе", + "@optionalGroupName": { + "type": "text", + "placeholders": {} + }, + "or": "или", + "@or": { + "type": "text", + "placeholders": {} + }, + "participant": "Учесник", + "@participant": { + "type": "text", + "placeholders": {} + }, + "passphraseOrKey": "фраза или кључ опоравка", + "@passphraseOrKey": { + "type": "text", + "placeholders": {} + }, + "password": "Лозинка", + "@password": { + "type": "text", + "placeholders": {} + }, + "passwordForgotten": "Заборављена лозинка", + "@passwordForgotten": { + "type": "text", + "placeholders": {} + }, + "passwordHasBeenChanged": "Лозинка је промењена", + "@passwordHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "passwordRecovery": "Опоравак лозинке", + "@passwordRecovery": { + "type": "text", + "placeholders": {} + }, + "people": "Људи", + "@people": { + "type": "text", + "placeholders": {} + }, + "pickImage": "Избор слике", + "@pickImage": { + "type": "text", + "placeholders": {} + }, + "pin": "Закачи", + "@pin": { + "type": "text", + "placeholders": {} + }, + "play": "Пусти {fileName}", + "@play": { + "type": "text", + "placeholders": { + "fileName": {} + } + }, + "pleaseChoose": "Изаберите", + "@pleaseChoose": { + "type": "text", + "placeholders": {} + }, + "pleaseChooseAPasscode": "Изаберите код за пролаз", + "@pleaseChooseAPasscode": { + "type": "text", + "placeholders": {} + }, + "pleaseChooseAUsername": "Изаберите корисничко име", + "@pleaseChooseAUsername": { + "type": "text", + "placeholders": {} + }, + "pleaseClickOnLink": "Кликните на везу у примљеној е-пошти па наставите.", + "@pleaseClickOnLink": { + "type": "text", + "placeholders": {} + }, + "pleaseEnter4Digits": "Унесите 4 цифре или оставите празно да не закључавате апликацију.", + "@pleaseEnter4Digits": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterAMatrixIdentifier": "Унесите ИД са Матрикса.", + "@pleaseEnterAMatrixIdentifier": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourPassword": "Унесите своју лозинку", + "@pleaseEnterYourPassword": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourPin": "Унесите свој пин", + "@pleaseEnterYourPin": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourUsername": "Унесите своје корисничко име", + "@pleaseEnterYourUsername": { + "type": "text", + "placeholders": {} + }, + "pleaseFollowInstructionsOnWeb": "Испратите упутства на веб сајту и тапните на „Следеће“.", + "@pleaseFollowInstructionsOnWeb": { + "type": "text", + "placeholders": {} + }, + "privacy": "Приватност", + "@privacy": { + "type": "text", + "placeholders": {} + }, + "publicRooms": "Јавне собе", + "@publicRooms": { + "type": "text", + "placeholders": {} + }, + "pushRules": "Правила протурања", + "@pushRules": { + "type": "text", + "placeholders": {} + }, + "reason": "Разлог", + "@reason": { + "type": "text", + "placeholders": {} + }, + "recording": "Снимам", + "@recording": { + "type": "text", + "placeholders": {} + }, + "redactedAnEvent": "{username} редигова догађај", + "@redactedAnEvent": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "redactMessage": "Редигуј поруку", + "@redactMessage": { + "type": "text", + "placeholders": {} + }, + "register": "Регистрација", + "@register": { + "type": "text", + "placeholders": {} + }, + "reject": "Одбиј", + "@reject": { + "type": "text", + "placeholders": {} + }, + "rejectedTheInvitation": "{username} одби позивницу", + "@rejectedTheInvitation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "rejoin": "Поново се придружи", + "@rejoin": { + "type": "text", + "placeholders": {} + }, + "remove": "Уклони", + "@remove": { + "type": "text", + "placeholders": {} + }, + "removeAllOtherDevices": "Уклони све остале уређаје", + "@removeAllOtherDevices": { + "type": "text", + "placeholders": {} + }, + "removedBy": "Уклонио корисник {username}", + "@removedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "removeDevice": "Уклони уређај", + "@removeDevice": { + "type": "text", + "placeholders": {} + }, + "unbanFromChat": "Уклони изгнанство", + "@unbanFromChat": { + "type": "text", + "placeholders": {} + }, + "removeYourAvatar": "Уклоните свој аватар", + "@removeYourAvatar": { + "type": "text", + "placeholders": {} + }, + "renderRichContent": "Приказуј обогаћен садржај поруке", + "@renderRichContent": { + "type": "text", + "placeholders": {} + }, + "replaceRoomWithNewerVersion": "Замени собу новијом верзијом", + "@replaceRoomWithNewerVersion": { + "type": "text", + "placeholders": {} + }, + "reply": "Одговори", + "@reply": { + "type": "text", + "placeholders": {} + }, + "reportMessage": "Пријави поруку", + "@reportMessage": { + "type": "text", + "placeholders": {} + }, + "requestPermission": "Затражи дозволу", + "@requestPermission": { + "type": "text", + "placeholders": {} + }, + "roomHasBeenUpgraded": "Соба је надограђена", + "@roomHasBeenUpgraded": { + "type": "text", + "placeholders": {} + }, + "roomVersion": "Верзија собе", + "@roomVersion": { + "type": "text", + "placeholders": {} + }, + "search": "Претражи", + "@search": { + "type": "text", + "placeholders": {} + }, + "security": "Безбедност", + "@security": { + "type": "text", + "placeholders": {} + }, + "seenByUser": "{username} прегледа", + "@seenByUser": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "seenByUserAndCountOthers": "{count, plural, other{{username} прегледа и {count} осталих}}", + "@seenByUserAndCountOthers": { + "type": "text", + "placeholders": { + "username": {}, + "count": {} + } + }, + "seenByUserAndUser": "Прегледали {username} и {username2}", + "@seenByUserAndUser": { + "type": "text", + "placeholders": { + "username": {}, + "username2": {} + } + }, + "send": "Пошаљи", + "@send": { + "type": "text", + "placeholders": {} + }, + "sendAMessage": "Пошаљи поруку", + "@sendAMessage": { + "type": "text", + "placeholders": {} + }, + "sendAudio": "Пошаљи аудио", + "@sendAudio": { + "type": "text", + "placeholders": {} + }, + "sendFile": "Пошаљи фајл", + "@sendFile": { + "type": "text", + "placeholders": {} + }, + "sendImage": "Пошаљи слику", + "@sendImage": { + "type": "text", + "placeholders": {} + }, + "sendMessages": "Слање порука", + "@sendMessages": { + "type": "text", + "placeholders": {} + }, + "sendOriginal": "Пошаљи оригинал", + "@sendOriginal": { + "type": "text", + "placeholders": {} + }, + "sendVideo": "Пошаљи видео", + "@sendVideo": { + "type": "text", + "placeholders": {} + }, + "sentAFile": "{username} посла фајл", + "@sentAFile": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sentAnAudio": "{username} посла аудио", + "@sentAnAudio": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sentAPicture": "{username} посла слику", + "@sentAPicture": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sentASticker": "{username} посла налепницу", + "@sentASticker": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sentAVideo": "{username} посла видео", + "@sentAVideo": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sentCallInformations": "{senderName} посла податке о позиву", + "@sentCallInformations": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "setAsCanonicalAlias": "Постави као главни алијас", + "@setAsCanonicalAlias": { + "type": "text", + "placeholders": {} + }, + "setCustomEmotes": "постави посебне емотије", + "@setCustomEmotes": { + "type": "text", + "placeholders": {} + }, + "setGroupDescription": "Постави опис групе", + "@setGroupDescription": { + "type": "text", + "placeholders": {} + }, + "setInvitationLink": "Поставља везу позивнице", + "@setInvitationLink": { + "type": "text", + "placeholders": {} + }, + "setPermissionsLevel": "Одреди ниво дозволе", + "@setPermissionsLevel": { + "type": "text", + "placeholders": {} + }, + "setStatus": "Постави статус", + "@setStatus": { + "type": "text", + "placeholders": {} + }, + "settings": "Поставке", + "@settings": { + "type": "text", + "placeholders": {} + }, + "share": "Подели", + "@share": { + "type": "text", + "placeholders": {} + }, + "sharedTheLocation": "{username} подели локацију", + "@sharedTheLocation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "showPassword": "Прикажи лозинку", + "@showPassword": { + "type": "text", + "placeholders": {} + }, + "signUp": "Регистрација", + "@signUp": { + "type": "text", + "placeholders": {} + }, + "singlesignon": "Јединствена пријава", + "@singlesignon": { + "type": "text", + "placeholders": {} + }, + "skip": "Прескочи", + "@skip": { + "type": "text", + "placeholders": {} + }, + "sourceCode": "Изворни код", + "@sourceCode": { + "type": "text", + "placeholders": {} + }, + "startedACall": "{senderName} започе позив", + "@startedACall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "status": "Стање", + "@status": { + "type": "text", + "placeholders": {} + }, + "statusExampleMessage": "Како сте данас?", + "@statusExampleMessage": { + "type": "text", + "placeholders": {} + }, + "submit": "Пошаљи", + "@submit": { + "type": "text", + "placeholders": {} + }, + "systemTheme": "системски", + "@systemTheme": { + "type": "text", + "placeholders": {} + }, + "theyDontMatch": "Не поклапају се", + "@theyDontMatch": { + "type": "text", + "placeholders": {} + }, + "theyMatch": "Поклапају се", + "@theyMatch": { + "type": "text", + "placeholders": {} + }, + "title": "FluffyChat", + "@title": { + "description": "Title for the application", + "type": "text", + "placeholders": {} + }, + "toggleFavorite": "Мењај омиљеност", + "@toggleFavorite": { + "type": "text", + "placeholders": {} + }, + "toggleMuted": "Мењај ућутканост", + "@toggleMuted": { + "type": "text", + "placeholders": {} + }, + "toggleUnread": "Означи не/прочитано", + "@toggleUnread": { + "type": "text", + "placeholders": {} + }, + "tooManyRequestsWarning": "Превише упита. Покушајте касније!", + "@tooManyRequestsWarning": { + "type": "text", + "placeholders": {} + }, + "transferFromAnotherDevice": "Пренос са другог уређаја", + "@transferFromAnotherDevice": { + "type": "text", + "placeholders": {} + }, + "tryToSendAgain": "Покушај слање поново", + "@tryToSendAgain": { + "type": "text", + "placeholders": {} + }, + "unavailable": "Недоступно", + "@unavailable": { + "type": "text", + "placeholders": {} + }, + "unbannedUser": "{username} одблокира корисника {targetName}", + "@unbannedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "unblockDevice": "Одблокирај уређај", + "@unblockDevice": { + "type": "text", + "placeholders": {} + }, + "unknownDevice": "Непознат уређај", + "@unknownDevice": { + "type": "text", + "placeholders": {} + }, + "unknownEncryptionAlgorithm": "Непознат алгоритам шифровања", + "@unknownEncryptionAlgorithm": { + "type": "text", + "placeholders": {} + }, + "unknownEvent": "Непознат догађај „{type}“", + "@unknownEvent": { + "type": "text", + "placeholders": { + "type": {} + } + }, + "unmuteChat": "Врати обавештења", + "@unmuteChat": { + "type": "text", + "placeholders": {} + }, + "unpin": "Откачи", + "@unpin": { + "type": "text", + "placeholders": {} + }, + "unreadChats": "{unreadCount, plural, other{непрочитаних ћаскања: {unreadCount}}}", + "@unreadChats": { + "type": "text", + "placeholders": { + "unreadCount": {} + } + }, + "userAndOthersAreTyping": "{username} и {count} корисника куцају…", + "@userAndOthersAreTyping": { + "type": "text", + "placeholders": { + "username": {}, + "count": {} + } + }, + "userAndUserAreTyping": "{username} и {username2} куцају…", + "@userAndUserAreTyping": { + "type": "text", + "placeholders": { + "username": {}, + "username2": {} + } + }, + "userIsTyping": "{username} куца…", + "@userIsTyping": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "userLeftTheChat": "{username} напусти ћаскање", + "@userLeftTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "username": "Корисничко име", + "@username": { + "type": "text", + "placeholders": {} + }, + "userSentUnknownEvent": "{username} посла {type} догађај", + "@userSentUnknownEvent": { + "type": "text", + "placeholders": { + "username": {}, + "type": {} + } + }, + "verified": "Оверен", + "@verified": { + "type": "text", + "placeholders": {} + }, + "verify": "Верификуј", + "@verify": { + "type": "text", + "placeholders": {} + }, + "verifyStart": "Покрени верификацију", + "@verifyStart": { + "type": "text", + "placeholders": {} + }, + "verifySuccess": "Успешно сте верификовали!", + "@verifySuccess": { + "type": "text", + "placeholders": {} + }, + "verifyTitle": "Верификујем други налог", + "@verifyTitle": { + "type": "text", + "placeholders": {} + }, + "videoCall": "Видео позив", + "@videoCall": { + "type": "text", + "placeholders": {} + }, + "visibilityOfTheChatHistory": "Одреди видљивост историје", + "@visibilityOfTheChatHistory": { + "type": "text", + "placeholders": {} + }, + "visibleForAllParticipants": "видљиво свим учесницима", + "@visibleForAllParticipants": { + "type": "text", + "placeholders": {} + }, + "visibleForEveryone": "видљиво свима", + "@visibleForEveryone": { + "type": "text", + "placeholders": {} + }, + "voiceMessage": "Гласовна порука", + "@voiceMessage": { + "type": "text", + "placeholders": {} + }, + "waitingPartnerAcceptRequest": "Чекам да саговорник прихвати захтев…", + "@waitingPartnerAcceptRequest": { + "type": "text", + "placeholders": {} + }, + "waitingPartnerEmoji": "Чекам да саговорник прихвати емоџије…", + "@waitingPartnerEmoji": { + "type": "text", + "placeholders": {} + }, + "waitingPartnerNumbers": "Чекам да саговорник прихвати бројеве…", + "@waitingPartnerNumbers": { + "type": "text", + "placeholders": {} + }, + "wallpaper": "Тапета", + "@wallpaper": { + "type": "text", + "placeholders": {} + }, + "warning": "Упозорење!", + "@warning": { + "type": "text", + "placeholders": {} + }, + "weSentYouAnEmail": "Послали смо вам е-пошту", + "@weSentYouAnEmail": { + "type": "text", + "placeholders": {} + }, + "whoCanPerformWhichAction": "ко може шта да ради", + "@whoCanPerformWhichAction": { + "type": "text", + "placeholders": {} + }, + "whoIsAllowedToJoinThisGroup": "Ко може да се придружи групи", + "@whoIsAllowedToJoinThisGroup": { + "type": "text", + "placeholders": {} + }, + "whyDoYouWantToReportThis": "Зашто желите ово да пријавите?", + "@whyDoYouWantToReportThis": { + "type": "text", + "placeholders": {} + }, + "wipeChatBackup": "Да обришем резервну копију како би направио нови сигурносни кључ?", + "@wipeChatBackup": { + "type": "text", + "placeholders": {} + }, + "withTheseAddressesRecoveryDescription": "Са овим адресама можете опоравити своју лозинку.", + "@withTheseAddressesRecoveryDescription": { + "type": "text", + "placeholders": {} + }, + "writeAMessage": "напишите поруку…", + "@writeAMessage": { + "type": "text", + "placeholders": {} + }, + "yes": "Да", + "@yes": { + "type": "text", + "placeholders": {} + }, + "you": "Ви", + "@you": { + "type": "text", + "placeholders": {} + }, + "youAreInvitedToThisChat": "Позвани сте у ово ћаскање", + "@youAreInvitedToThisChat": { + "type": "text", + "placeholders": {} + }, + "youAreNoLongerParticipatingInThisChat": "Више не учествујете у овом ћаскању", + "@youAreNoLongerParticipatingInThisChat": { + "type": "text", + "placeholders": {} + }, + "youCannotInviteYourself": "Не можете позвати себе", + "@youCannotInviteYourself": { + "type": "text", + "placeholders": {} + }, + "youHaveBeenBannedFromThisChat": "Забрањено вам је ово ћаскање", + "@youHaveBeenBannedFromThisChat": { + "type": "text", + "placeholders": {} + }, + "yourPublicKey": "Ваш јавни кључ", + "@yourPublicKey": { + "type": "text", + "placeholders": {} + }, + "discover": "", + "@discover": { + "type": "text", + "placeholders": {} + }, + "hugContent": "", + "@hugContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "jumpToLastReadMessage": "", + "@jumpToLastReadMessage": {}, + "allRooms": "", + "@allRooms": { + "type": "text", + "placeholders": {} + }, + "obtainingLocation": "", + "@obtainingLocation": { + "type": "text", + "placeholders": {} + }, + "whoCanSeeMyStories": "", + "@whoCanSeeMyStories": {}, + "commandHint_cuddle": "", + "@commandHint_cuddle": {}, + "widgetVideo": "", + "@widgetVideo": {}, + "dismiss": "", + "@dismiss": {}, + "reportErrorDescription": "", + "@reportErrorDescription": {}, + "addAccount": "", + "@addAccount": {}, + "chatHasBeenAddedToThisSpace": "", + "@chatHasBeenAddedToThisSpace": {}, + "unsupportedAndroidVersion": "", + "@unsupportedAndroidVersion": {}, + "enterASpacepName": "", + "@enterASpacepName": {}, + "widgetJitsi": "", + "@widgetJitsi": {}, + "messageType": "", + "@messageType": {}, + "noEmailWarning": "", + "@noEmailWarning": {}, + "indexedDbErrorLong": "", + "@indexedDbErrorLong": {}, + "oneClientLoggedOut": "", + "@oneClientLoggedOut": {}, + "startFirstChat": "", + "@startFirstChat": {}, + "callingAccount": "", + "@callingAccount": {}, + "setColorTheme": "", + "@setColorTheme": {}, + "nextAccount": "", + "@nextAccount": {}, + "commandHint_create": "", + "@commandHint_create": { + "type": "text", + "description": "Usage hint for the command /create" + }, + "allSpaces": "", + "@allSpaces": {}, + "supposedMxid": "", + "@supposedMxid": { + "type": "text", + "placeholders": { + "mxid": {} + } + }, + "user": "", + "@user": {}, + "youAcceptedTheInvitation": "", + "@youAcceptedTheInvitation": {}, + "noMatrixServer": "", + "@noMatrixServer": { + "type": "text", + "placeholders": { + "server1": {}, + "server2": {} + } + }, + "youInvitedBy": "", + "@youInvitedBy": { + "placeholders": { + "user": {} + } + }, + "banUserDescription": "", + "@banUserDescription": {}, + "requests": "", + "@requests": {}, + "widgetEtherpad": "", + "@widgetEtherpad": {}, + "stories": "", + "@stories": {}, + "addToStory": "", + "@addToStory": {}, + "removeDevicesDescription": "", + "@removeDevicesDescription": {}, + "separateChatTypes": "", + "@separateChatTypes": { + "type": "text", + "placeholders": {} + }, + "tryAgain": "", + "@tryAgain": {}, + "youKickedAndBanned": "", + "@youKickedAndBanned": { + "placeholders": { + "user": {} + } + }, + "showDirectChatsInSpaces": "", + "@showDirectChatsInSpaces": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterValidEmail": "", + "@pleaseEnterValidEmail": {}, + "unbanUserDescription": "", + "@unbanUserDescription": {}, + "todoLists": "", + "@todoLists": {}, + "saveFile": "", + "@saveFile": { + "type": "text", + "placeholders": {} + }, + "sendOnEnter": "", + "@sendOnEnter": {}, + "youRejectedTheInvitation": "", + "@youRejectedTheInvitation": {}, + "otherCallingPermissions": "", + "@otherCallingPermissions": {}, + "messagesStyle": "", + "@messagesStyle": {}, + "link": "", + "@link": {}, + "widgetUrlError": "", + "@widgetUrlError": {}, + "emailOrUsername": "", + "@emailOrUsername": {}, + "newSpaceDescription": "", + "@newSpaceDescription": {}, + "chatDescription": "", + "@chatDescription": {}, + "callingAccountDetails": "", + "@callingAccountDetails": {}, + "pleaseChooseAtLeastChars": "", + "@pleaseChooseAtLeastChars": { + "type": "text", + "placeholders": { + "min": {} + } + }, + "enterSpace": "", + "@enterSpace": {}, + "encryptThisChat": "", + "@encryptThisChat": {}, + "previousAccount": "", + "@previousAccount": {}, + "reopenChat": "", + "@reopenChat": {}, + "pleaseEnterRecoveryKey": "", + "@pleaseEnterRecoveryKey": {}, + "widgetNameError": "", + "@widgetNameError": {}, + "addToBundle": "", + "@addToBundle": {}, + "spaceIsPublic": "", + "@spaceIsPublic": { + "type": "text", + "placeholders": {} + }, + "addWidget": "", + "@addWidget": {}, + "countFiles": "", + "@countFiles": { + "placeholders": { + "count": {} + } + }, + "noKeyForThisMessage": "", + "@noKeyForThisMessage": {}, + "shareLocation": "", + "@shareLocation": { + "type": "text", + "placeholders": {} + }, + "commandHint_markasgroup": "", + "@commandHint_markasgroup": {}, + "editTodo": "", + "@editTodo": {}, + "errorObtainingLocation": "", + "@errorObtainingLocation": { + "type": "text", + "placeholders": { + "error": {} + } + }, + "hydrateTor": "", + "@hydrateTor": {}, + "pushNotificationsNotAvailable": "", + "@pushNotificationsNotAvailable": {}, + "storeInAppleKeyChain": "", + "@storeInAppleKeyChain": {}, + "hydrate": "", + "@hydrate": {}, + "invalidServerName": "", + "@invalidServerName": {}, + "chatPermissions": "", + "@chatPermissions": {}, + "cantOpenUri": "", + "@cantOpenUri": { + "type": "text", + "placeholders": { + "uri": {} + } + }, + "sender": "", + "@sender": {}, + "storeInAndroidKeystore": "", + "@storeInAndroidKeystore": {}, + "signInWithPassword": "", + "@signInWithPassword": {}, + "pleaseAddATitle": "", + "@pleaseAddATitle": {}, + "updateNow": "", + "@updateNow": {}, + "makeAdminDescription": "", + "@makeAdminDescription": {}, + "synchronizingPleaseWait": "", + "@synchronizingPleaseWait": { + "type": "text", + "placeholders": {} + }, + "commandHint_clearcache": "", + "@commandHint_clearcache": { + "type": "text", + "description": "Usage hint for the command /clearcache" + }, + "saveKeyManuallyDescription": "", + "@saveKeyManuallyDescription": {}, + "editBundlesForAccount": "", + "@editBundlesForAccount": {}, + "whyIsThisMessageEncrypted": "", + "@whyIsThisMessageEncrypted": {}, + "setChatDescription": "", + "@setChatDescription": {}, + "spaceName": "", + "@spaceName": { + "type": "text", + "placeholders": {} + }, + "importFromZipFile": "", + "@importFromZipFile": {}, + "dehydrateWarning": "", + "@dehydrateWarning": {}, + "noOtherDevicesFound": "", + "@noOtherDevicesFound": {}, + "yourChatBackupHasBeenSetUp": "", + "@yourChatBackupHasBeenSetUp": {}, + "addDescription": "", + "@addDescription": {}, + "redactedBy": "", + "@redactedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "videoCallsBetaWarning": "", + "@videoCallsBetaWarning": {}, + "autoplayImages": "", + "@autoplayImages": { + "type": "text", + "placeholder": {} + }, + "storyPrivacyWarning": "", + "@storyPrivacyWarning": {}, + "matrixWidgets": "", + "@matrixWidgets": {}, + "signInWith": "", + "@signInWith": { + "type": "text", + "placeholders": { + "provider": {} + } + }, + "updateAvailable": "", + "@updateAvailable": {}, + "fileIsTooBigForServer": "", + "@fileIsTooBigForServer": {}, + "homeserver": "", + "@homeserver": {}, + "noTodosYet": "", + "@noTodosYet": {}, + "repeatPassword": "", + "@repeatPassword": {}, + "callingPermissions": "", + "@callingPermissions": {}, + "readUpToHere": "", + "@readUpToHere": {}, + "start": "", + "@start": {}, + "bubbleSize": "", + "@bubbleSize": { + "type": "text", + "placeholders": {} + }, + "unlockOldMessages": "", + "@unlockOldMessages": {}, + "numChats": "", + "@numChats": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "whatIsGoingOn": "", + "@whatIsGoingOn": {}, + "optionalRedactReason": "", + "@optionalRedactReason": {}, + "dehydrate": "", + "@dehydrate": {}, + "locationPermissionDeniedNotice": "", + "@locationPermissionDeniedNotice": { + "type": "text", + "placeholders": {} + }, + "sendAsText": "", + "@sendAsText": { + "type": "text" + }, + "archiveRoomDescription": "", + "@archiveRoomDescription": {}, + "exportEmotePack": "", + "@exportEmotePack": {}, + "sendSticker": "", + "@sendSticker": { + "type": "text", + "placeholders": {} + }, + "switchToAccount": "", + "@switchToAccount": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "commandInvalid": "", + "@commandInvalid": { + "type": "text" + }, + "locationDisabledNotice": "", + "@locationDisabledNotice": { + "type": "text", + "placeholders": {} + }, + "letsStart": "", + "@letsStart": {}, + "experimentalVideoCalls": "", + "@experimentalVideoCalls": {}, + "savedEmotePack": "", + "@savedEmotePack": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "pleaseEnterRecoveryKeyDescription": "", + "@pleaseEnterRecoveryKeyDescription": {}, + "openInMaps": "", + "@openInMaps": { + "type": "text", + "placeholders": {} + }, + "inviteContactToGroupQuestion": "", + "@inviteContactToGroupQuestion": {}, + "redactedByBecause": "", + "@redactedByBecause": { + "type": "text", + "placeholders": { + "username": {}, + "reason": {} + } + }, + "youHaveWithdrawnTheInvitationFor": "", + "@youHaveWithdrawnTheInvitationFor": { + "placeholders": { + "user": {} + } + }, + "appearOnTopDetails": "", + "@appearOnTopDetails": {}, + "enterRoom": "", + "@enterRoom": {}, + "allChats": "", + "@allChats": { + "type": "text", + "placeholders": {} + }, + "reportUser": "", + "@reportUser": {}, + "confirmEventUnpin": "", + "@confirmEventUnpin": {}, + "youInvitedUser": "", + "@youInvitedUser": { + "placeholders": { + "user": {} + } + }, + "fileHasBeenSavedAt": "", + "@fileHasBeenSavedAt": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "addToSpace": "", + "@addToSpace": {}, + "importZipFile": "", + "@importZipFile": {}, + "anyoneCanKnock": "", + "@anyoneCanKnock": {}, + "commandMissing": "", + "@commandMissing": { + "type": "text", + "placeholders": { + "command": {} + }, + "description": "State that {command} is not a valid /command." + }, + "redactMessageDescription": "", + "@redactMessageDescription": {}, + "recoveryKey": "", + "@recoveryKey": {}, + "commandHint_discardsession": "", + "@commandHint_discardsession": { + "type": "text", + "description": "Usage hint for the command /discardsession" + }, + "invalidInput": "", + "@invalidInput": {}, + "todosUnencrypted": "", + "@todosUnencrypted": {}, + "dehydrateTorLong": "", + "@dehydrateTorLong": {}, + "replyHasBeenSent": "", + "@replyHasBeenSent": {}, + "doNotShowAgain": "", + "@doNotShowAgain": {}, + "report": "", + "@report": {}, + "yourStory": "", + "@yourStory": {}, + "unverified": "", + "@unverified": {}, + "serverRequiresEmail": "", + "@serverRequiresEmail": {}, + "hideUnimportantStateEvents": "", + "@hideUnimportantStateEvents": {}, + "screenSharingTitle": "", + "@screenSharingTitle": {}, + "widgetCustom": "", + "@widgetCustom": {}, + "addToSpaceDescription": "", + "@addToSpaceDescription": {}, + "googlyEyesContent": "", + "@googlyEyesContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "whoCanSeeMyStoriesDesc": "", + "@whoCanSeeMyStoriesDesc": {}, + "youBannedUser": "", + "@youBannedUser": { + "placeholders": { + "user": {} + } + }, + "unsubscribeStories": "", + "@unsubscribeStories": {}, + "loginWithOneClick": "", + "@loginWithOneClick": {}, + "addChatDescription": "", + "@addChatDescription": {}, + "commandHint_myroomavatar": "", + "@commandHint_myroomavatar": { + "type": "text", + "description": "Usage hint for the command /myroomavatar" + }, + "hasKnocked": "", + "@hasKnocked": { + "placeholders": { + "user": {} + } + }, + "publish": "", + "@publish": {}, + "openLinkInBrowser": "", + "@openLinkInBrowser": {}, + "messageInfo": "", + "@messageInfo": {}, + "disableEncryptionWarning": "", + "@disableEncryptionWarning": {}, + "directChat": "", + "@directChat": {}, + "noOneCanJoin": "", + "@noOneCanJoin": {}, + "wrongPinEntered": "", + "@wrongPinEntered": { + "type": "text", + "placeholders": { + "seconds": {} + } + }, + "sendTypingNotifications": "", + "@sendTypingNotifications": {}, + "inviteGroupChat": "", + "@inviteGroupChat": {}, + "appearOnTop": "", + "@appearOnTop": {}, + "invitePrivateChat": "", + "@invitePrivateChat": {}, + "foregroundServiceRunning": "", + "@foregroundServiceRunning": {}, + "voiceCall": "", + "@voiceCall": {}, + "createNewSpace": "", + "@createNewSpace": { + "type": "text", + "placeholders": {} + }, + "importEmojis": "", + "@importEmojis": {}, + "wasDirectChatDisplayName": "", + "@wasDirectChatDisplayName": { + "type": "text", + "placeholders": { + "oldDisplayName": {} + } + }, + "noChatDescriptionYet": "", + "@noChatDescriptionYet": {}, + "newTodo": "", + "@newTodo": {}, + "removeFromBundle": "", + "@removeFromBundle": {}, + "confirmMatrixId": "", + "@confirmMatrixId": {}, + "learnMore": "", + "@learnMore": {}, + "notAnImage": "", + "@notAnImage": {}, + "users": "", + "@users": {}, + "openGallery": "", + "@openGallery": {}, + "chatDescriptionHasBeenChanged": "", + "@chatDescriptionHasBeenChanged": {}, + "newGroup": "", + "@newGroup": {}, + "bundleName": "", + "@bundleName": {}, + "dehydrateTor": "", + "@dehydrateTor": {}, + "todoListChangedError": "", + "@todoListChangedError": {}, + "removeFromSpace": "", + "@removeFromSpace": {}, + "enterInviteLinkOrMatrixId": "", + "@enterInviteLinkOrMatrixId": {}, + "roomUpgradeDescription": "", + "@roomUpgradeDescription": {}, + "scanQrCode": "", + "@scanQrCode": {}, + "pleaseEnterANumber": "", + "@pleaseEnterANumber": {}, + "youKicked": "", + "@youKicked": { + "placeholders": { + "user": {} + } + }, + "profileNotFound": "", + "@profileNotFound": {}, + "jump": "", + "@jump": {}, + "reactedWith": "", + "@reactedWith": { + "type": "text", + "placeholders": { + "sender": {}, + "reaction": {} + } + }, + "sorryThatsNotPossible": "", + "@sorryThatsNotPossible": {}, + "storyFrom": "", + "@storyFrom": { + "type": "text", + "placeholders": { + "date": {}, + "body": {} + } + }, + "videoWithSize": "", + "@videoWithSize": { + "type": "text", + "placeholders": { + "size": {} + } + }, + "shareInviteLink": "", + "@shareInviteLink": {}, + "commandHint_markasdm": "", + "@commandHint_markasdm": {}, + "recoveryKeyLost": "", + "@recoveryKeyLost": {}, + "cuddleContent": "", + "@cuddleContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "deviceKeys": "", + "@deviceKeys": {}, + "emoteKeyboardNoRecents": "", + "@emoteKeyboardNoRecents": { + "type": "text", + "placeholders": {} + }, + "endToEndEncryption": "", + "@endToEndEncryption": {}, + "setTheme": "", + "@setTheme": {}, + "youJoinedTheChat": "", + "@youJoinedTheChat": {}, + "openVideoCamera": "", + "@openVideoCamera": { + "type": "text", + "placeholders": {} + }, + "thisUserHasNotPostedAnythingYet": "", + "@thisUserHasNotPostedAnythingYet": {}, + "markAsRead": "", + "@markAsRead": {}, + "widgetName": "", + "@widgetName": {}, + "errorAddingWidget": "", + "@errorAddingWidget": {}, + "commandHint_dm": "", + "@commandHint_dm": { + "type": "text", + "description": "Usage hint for the command /dm" + }, + "commandHint_hug": "", + "@commandHint_hug": {}, + "replace": "", + "@replace": {}, + "youUnbannedUser": "", + "@youUnbannedUser": { + "placeholders": { + "user": {} + } + }, + "newSpace": "", + "@newSpace": {}, + "emojis": "", + "@emojis": {}, + "commandHint_googly": "", + "@commandHint_googly": {}, + "pleaseTryAgainLaterOrChooseDifferentServer": "", + "@pleaseTryAgainLaterOrChooseDifferentServer": {}, + "createGroup": "", + "@createGroup": {}, + "hydrateTorLong": "", + "@hydrateTorLong": {}, + "time": "", + "@time": {}, + "custom": "", + "@custom": {}, + "noBackupWarning": "", + "@noBackupWarning": {}, + "editWidgets": "", + "@editWidgets": {}, + "storeInSecureStorageDescription": "", + "@storeInSecureStorageDescription": {}, + "openChat": "", + "@openChat": {}, + "kickUserDescription": "", + "@kickUserDescription": {}, + "importNow": "", + "@importNow": {}, + "pinMessage": "", + "@pinMessage": {}, + "invite": "", + "@invite": {}, + "enableMultiAccounts": "", + "@enableMultiAccounts": {}, + "continueWith": "", + "@continueWith": {}, + "indexedDbErrorTitle": "", + "@indexedDbErrorTitle": {}, + "unsupportedAndroidVersionLong": "", + "@unsupportedAndroidVersionLong": {}, + "storeSecurlyOnThisDevice": "", + "@storeSecurlyOnThisDevice": {}, + "passwordsDoNotMatch": "", + "@passwordsDoNotMatch": {}, + "iUnderstand": "", + "@iUnderstand": {}, + "screenSharingDetail": "", + "@screenSharingDetail": {}, + "placeCall": "", + "@placeCall": {} +} diff --git a/assets/l10n/intl_sv.arb b/assets/l10n/intl_sv.arb index afe99a2fc..e40e7d655 100644 --- a/assets/l10n/intl_sv.arb +++ b/assets/l10n/intl_sv.arb @@ -1,2489 +1,2660 @@ { - "@@last_modified": "2021-08-14 12:41:09.835634", - "about": "Om", - "@about": { - "type": "text", - "placeholders": {} - }, - "accept": "Acceptera", - "@accept": { - "type": "text", - "placeholders": {} - }, - "acceptedTheInvitation": "👍 {username} accepterade inbjudan", - "@acceptedTheInvitation": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "account": "Konto", - "@account": { - "type": "text", - "placeholders": {} - }, - "activatedEndToEndEncryption": "🔐 {username} aktiverade ändpunktskryptering", - "@activatedEndToEndEncryption": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "addGroupDescription": "Lägg till en gruppbeskrivning", - "@addGroupDescription": { - "type": "text", - "placeholders": {} - }, - "admin": "Admin", - "@admin": { - "type": "text", - "placeholders": {} - }, - "alias": "alias", - "@alias": { - "type": "text", - "placeholders": {} - }, - "all": "Alla", - "@all": { - "type": "text", - "placeholders": {} - }, - "answeredTheCall": "{senderName} besvarade samtalet", - "@answeredTheCall": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "anyoneCanJoin": "Vem som helst kan gå med", - "@anyoneCanJoin": { - "type": "text", - "placeholders": {} - }, - "appLock": "App-lås", - "@appLock": { - "type": "text", - "placeholders": {} - }, - "archive": "Arkiv", - "@archive": { - "type": "text", - "placeholders": {} - }, - "areGuestsAllowedToJoin": "Får gästanvändare gå med", - "@areGuestsAllowedToJoin": { - "type": "text", - "placeholders": {} - }, - "areYouSure": "Är du säker?", - "@areYouSure": { - "type": "text", - "placeholders": {} - }, - "areYouSureYouWantToLogout": "Är du säker på att du vill logga ut?", - "@areYouSureYouWantToLogout": { - "type": "text", - "placeholders": {} - }, - "askSSSSSign": "För att kunna signera den andra personen, vänligen ange din lösenfras eller återställningsnyckel för säker lagring.", - "@askSSSSSign": { - "type": "text", - "placeholders": {} - }, - "askVerificationRequest": "Acceptera denna verifikationsförfrågan från {username}?", - "@askVerificationRequest": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "badServerVersionsException": "Hemservern stöjder Spec-versionen:\n{serverVersions}\nMen denna app stödjer enbart {supportedVersions}", - "@badServerVersionsException": { - "type": "text", - "placeholders": { - "serverVersions": {}, - "supportedVersions": {} - } - }, - "banFromChat": "Bannlys från chatt", - "@banFromChat": { - "type": "text", - "placeholders": {} - }, - "banned": "Bannlyst", - "@banned": { - "type": "text", - "placeholders": {} - }, - "bannedUser": "{username} bannlös {targetName}", - "@bannedUser": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "blockDevice": "Blockera Enhet", - "@blockDevice": { - "type": "text", - "placeholders": {} - }, - "botMessages": "Bot meddelanden", - "@botMessages": { - "type": "text", - "placeholders": {} - }, - "cancel": "Avbryt", - "@cancel": { - "type": "text", - "placeholders": {} - }, - "changeDeviceName": "Ändra enhetsnamn", - "@changeDeviceName": { - "type": "text", - "placeholders": {} - }, - "changedTheChatAvatar": "{username} ändrade sin chatt-avatar", - "@changedTheChatAvatar": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheChatDescriptionTo": "{username} ändrade chatt-beskrivningen till: '{description}'", - "@changedTheChatDescriptionTo": { - "type": "text", - "placeholders": { - "username": {}, - "description": {} - } - }, - "changedTheChatNameTo": "{username} ändrade sitt chatt-namn till: '{chatname}'", - "@changedTheChatNameTo": { - "type": "text", - "placeholders": { - "username": {}, - "chatname": {} - } - }, - "changedTheChatPermissions": "{username} ändrade chatt-rättigheterna", - "@changedTheChatPermissions": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheDisplaynameTo": "{username} ändrade visningsnamnet till: '{displayname}'", - "@changedTheDisplaynameTo": { - "type": "text", - "placeholders": { - "username": {}, - "displayname": {} - } - }, - "changedTheGuestAccessRules": "{username} ändrade reglerna för gästaccess", - "@changedTheGuestAccessRules": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheGuestAccessRulesTo": "{username} ändrade reglerna för gästaccess till: {rules}", - "@changedTheGuestAccessRulesTo": { - "type": "text", - "placeholders": { - "username": {}, - "rules": {} - } - }, - "changedTheHistoryVisibility": "{username} ändrade historikens synlighet", - "@changedTheHistoryVisibility": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheHistoryVisibilityTo": "{username} ändrade historikens synlighet till: {rules}", - "@changedTheHistoryVisibilityTo": { - "type": "text", - "placeholders": { - "username": {}, - "rules": {} - } - }, - "changedTheJoinRules": "{username} ändrade anslutningsreglerna", - "@changedTheJoinRules": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheJoinRulesTo": "{username} ändrade anslutningsreglerna till {joinRules}", - "@changedTheJoinRulesTo": { - "type": "text", - "placeholders": { - "username": {}, - "joinRules": {} - } - }, - "changedTheProfileAvatar": "{username} ändrade sin avatar", - "@changedTheProfileAvatar": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheRoomAliases": "{username} ändrade rummets alias", - "@changedTheRoomAliases": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheRoomInvitationLink": "{username} ändrade inbjudningslänken", - "@changedTheRoomInvitationLink": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changePassword": "Ändra lösenord", - "@changePassword": { - "type": "text", - "placeholders": {} - }, - "changeTheHomeserver": "Ändra hemserver", - "@changeTheHomeserver": { - "type": "text", - "placeholders": {} - }, - "changeTheme": "Ändra din stil", - "@changeTheme": { - "type": "text", - "placeholders": {} - }, - "changeTheNameOfTheGroup": "Ändra namn på gruppen", - "@changeTheNameOfTheGroup": { - "type": "text", - "placeholders": {} - }, - "changeWallpaper": "Ändra bakgrund", - "@changeWallpaper": { - "type": "text", - "placeholders": {} - }, - "channelCorruptedDecryptError": "Krypteringen har blivit korrupt", - "@channelCorruptedDecryptError": { - "type": "text", - "placeholders": {} - }, - "chat": "Chatt", - "@chat": { - "type": "text", - "placeholders": {} - }, - "chatDetails": "Chatt-detaljer", - "@chatDetails": { - "type": "text", - "placeholders": {} - }, - "chooseAStrongPassword": "Välj ett starkt lösenord", - "@chooseAStrongPassword": { - "type": "text", - "placeholders": {} - }, - "chooseAUsername": "Välj ett användarnamn", - "@chooseAUsername": { - "type": "text", - "placeholders": {} - }, - "close": "Stäng", - "@close": { - "type": "text", - "placeholders": {} - }, - "compareEmojiMatch": "Vänligen jämför uttryckssymbolerna", - "@compareEmojiMatch": { - "type": "text", - "placeholders": {} - }, - "compareNumbersMatch": "Vänligen jämför siffrorna", - "@compareNumbersMatch": { - "type": "text", - "placeholders": {} - }, - "configureChat": "Konfigurera chatt", - "@configureChat": { - "type": "text", - "placeholders": {} - }, - "confirm": "Bekräfta", - "@confirm": { - "type": "text", - "placeholders": {} - }, - "connect": "Anslut", - "@connect": { - "type": "text", - "placeholders": {} - }, - "contactHasBeenInvitedToTheGroup": "Kontakten har blivit inbjuden till gruppen", - "@contactHasBeenInvitedToTheGroup": { - "type": "text", - "placeholders": {} - }, - "containsDisplayName": "Innehåller visningsnamn", - "@containsDisplayName": { - "type": "text", - "placeholders": {} - }, - "containsUserName": "Innehåller användarnamn", - "@containsUserName": { - "type": "text", - "placeholders": {} - }, - "contentHasBeenReported": "Innehållet har rapporterats till server-admins", - "@contentHasBeenReported": { - "type": "text", - "placeholders": {} - }, - "copiedToClipboard": "Kopierat till urklipp", - "@copiedToClipboard": { - "type": "text", - "placeholders": {} - }, - "copy": "Kopiera", - "@copy": { - "type": "text", - "placeholders": {} - }, - "couldNotDecryptMessage": "Kunde ej avkoda meddelande: {error}", - "@couldNotDecryptMessage": { - "type": "text", - "placeholders": { - "error": {} - } - }, - "countParticipants": "{count} deltagare", - "@countParticipants": { - "type": "text", - "placeholders": { - "count": {} - } - }, - "create": "Skapa", - "@create": { - "type": "text", - "placeholders": {} - }, - "createdTheChat": "💬 {username} skapade chatten", - "@createdTheChat": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "createNewGroup": "Skapa ny grupp", - "@createNewGroup": { - "type": "text", - "placeholders": {} - }, - "currentlyActive": "För närvarande aktiv", - "@currentlyActive": { - "type": "text", - "placeholders": {} - }, - "darkTheme": "Mörkt", - "@darkTheme": { - "type": "text", - "placeholders": {} - }, - "dateAndTimeOfDay": "{date}, {timeOfDay}", - "@dateAndTimeOfDay": { - "type": "text", - "placeholders": { - "date": {}, - "timeOfDay": {} - } - }, - "dateWithoutYear": "{day}-{month}", - "@dateWithoutYear": { - "type": "text", - "placeholders": { - "month": {}, - "day": {} - } - }, - "dateWithYear": "{year}-{month}-{day}", - "@dateWithYear": { - "type": "text", - "placeholders": { - "year": {}, - "month": {}, - "day": {} - } - }, - "deactivateAccountWarning": "Detta kommer att avaktivera ditt konto. Det här går inte att ångra! Är du säker?", - "@deactivateAccountWarning": { - "type": "text", - "placeholders": {} - }, - "defaultPermissionLevel": "Standard behörighetsnivå", - "@defaultPermissionLevel": { - "type": "text", - "placeholders": {} - }, - "delete": "Radera", - "@delete": { - "type": "text", - "placeholders": {} - }, - "deleteAccount": "Ta bort konto", - "@deleteAccount": { - "type": "text", - "placeholders": {} - }, - "deleteMessage": "Ta bort meddelande", - "@deleteMessage": { - "type": "text", - "placeholders": {} - }, - "deny": "Neka", - "@deny": { - "type": "text", - "placeholders": {} - }, - "device": "Enhet", - "@device": { - "type": "text", - "placeholders": {} - }, - "deviceId": "Enhets-ID", - "@deviceId": { - "type": "text", - "placeholders": {} - }, - "devices": "Enheter", - "@devices": { - "type": "text", - "placeholders": {} - }, - "directChats": "Direkt Chatt", - "@directChats": { - "type": "text", - "placeholders": {} - }, - "displaynameHasBeenChanged": "Visningsnamn har ändrats", - "@displaynameHasBeenChanged": { - "type": "text", - "placeholders": {} - }, - "downloadFile": "Ladda ner fil", - "@downloadFile": { - "type": "text", - "placeholders": {} - }, - "edit": "Ändra", - "@edit": { - "type": "text", - "placeholders": {} - }, - "editBlockedServers": "redigera blockerade servrar", - "@editBlockedServers": { - "type": "text", - "placeholders": {} - }, - "editChatPermissions": "Ändra chatt-rättigheter", - "@editChatPermissions": { - "type": "text", - "placeholders": {} - }, - "editDisplayname": "Ändra visningsnamn", - "@editDisplayname": { - "type": "text", - "placeholders": {} - }, - "editRoomAvatar": "redigera rumsavatar", - "@editRoomAvatar": { - "type": "text", - "placeholders": {} - }, - "emoteExists": "Dekalen existerar redan!", - "@emoteExists": { - "type": "text", - "placeholders": {} - }, - "emoteInvalid": "Ogiltig dekal-kod!", - "@emoteInvalid": { - "type": "text", - "placeholders": {} - }, - "emotePacks": "Dekalpaket för rummet", - "@emotePacks": { - "type": "text", - "placeholders": {} - }, - "emoteSettings": "Emote inställningar", - "@emoteSettings": { - "type": "text", - "placeholders": {} - }, - "emoteShortcode": "Dekal kod", - "@emoteShortcode": { - "type": "text", - "placeholders": {} - }, - "emoteWarnNeedToPick": "Du måste välja en dekal-kod och en bild!", - "@emoteWarnNeedToPick": { - "type": "text", - "placeholders": {} - }, - "emptyChat": "Tom chatt", - "@emptyChat": { - "type": "text", - "placeholders": {} - }, - "enableEmotesGlobally": "Aktivera dekal-paket globalt", - "@enableEmotesGlobally": { - "type": "text", - "placeholders": {} - }, - "enableEncryption": "Aktivera kryptering", - "@enableEncryption": { - "type": "text", - "placeholders": {} - }, - "enableEncryptionWarning": "Du kommer inte ha fortsatt möjlighet till att inaktivera krypteringen. Är du säker?", - "@enableEncryptionWarning": { - "type": "text", - "placeholders": {} - }, - "encrypted": "Krypterad", - "@encrypted": { - "type": "text", - "placeholders": {} - }, - "encryption": "Kryptering", - "@encryption": { - "type": "text", - "placeholders": {} - }, - "encryptionNotEnabled": "Kryptering är ej aktiverad", - "@encryptionNotEnabled": { - "type": "text", - "placeholders": {} - }, - "endedTheCall": "{senderName} avslutade samtalet", - "@endedTheCall": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "enterAGroupName": "Ange ett gruppnamn", - "@enterAGroupName": { - "type": "text", - "placeholders": {} - }, - "enterAnEmailAddress": "Ange en e-postaddress", - "@enterAnEmailAddress": { - "type": "text", - "placeholders": {} - }, - "enterYourHomeserver": "Ange din hemserver", - "@enterYourHomeserver": { - "type": "text", - "placeholders": {} - }, - "extremeOffensive": "Extremt stötande", - "@extremeOffensive": { - "type": "text", - "placeholders": {} - }, - "fileName": "Filnamn", - "@fileName": { - "type": "text", - "placeholders": {} - }, - "fluffychat": "FluffyChat", - "@fluffychat": { - "type": "text", - "placeholders": {} - }, - "forward": "Framåt", - "@forward": { - "type": "text", - "placeholders": {} - }, - "fromJoining": "Från att gå med", - "@fromJoining": { - "type": "text", - "placeholders": {} - }, - "fromTheInvitation": "Från inbjudan", - "@fromTheInvitation": { - "type": "text", - "placeholders": {} - }, - "group": "Grupp", - "@group": { - "type": "text", - "placeholders": {} - }, - "groupDescription": "Gruppbeskrivning", - "@groupDescription": { - "type": "text", - "placeholders": {} - }, - "groupDescriptionHasBeenChanged": "Gruppbeskrivningen ändrad", - "@groupDescriptionHasBeenChanged": { - "type": "text", - "placeholders": {} - }, - "groupIsPublic": "Gruppen är publik", - "@groupIsPublic": { - "type": "text", - "placeholders": {} - }, - "groups": "Grupper", - "@groups": { - "type": "text", - "placeholders": {} - }, - "groupWith": "Gruppen med {displayname}", - "@groupWith": { - "type": "text", - "placeholders": { - "displayname": {} - } - }, - "guestsAreForbidden": "Gäster är förbjudna", - "@guestsAreForbidden": { - "type": "text", - "placeholders": {} - }, - "guestsCanJoin": "Gäster kan ansluta", - "@guestsCanJoin": { - "type": "text", - "placeholders": {} - }, - "hasWithdrawnTheInvitationFor": "{username} har tagit tillbaka inbjudan för {targetName}", - "@hasWithdrawnTheInvitationFor": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "help": "Hjälp", - "@help": { - "type": "text", - "placeholders": {} - }, - "hideRedactedEvents": "Göm redigerade händelser", - "@hideRedactedEvents": { - "type": "text", - "placeholders": {} - }, - "hideUnknownEvents": "Göm okända händelser", - "@hideUnknownEvents": { - "type": "text", - "placeholders": {} - }, - "howOffensiveIsThisContent": "Hur stötande är detta innehåll?", - "@howOffensiveIsThisContent": { - "type": "text", - "placeholders": {} - }, - "id": "ID", - "@id": { - "type": "text", - "placeholders": {} - }, - "identity": "Identitet", - "@identity": { - "type": "text", - "placeholders": {} - }, - "ignore": "Ignorera", - "@ignore": { - "type": "text", - "placeholders": {} - }, - "ignoredUsers": "Ignorera användare", - "@ignoredUsers": { - "type": "text", - "placeholders": {} - }, - "ignoreListDescription": "Du kan ignorera användare som stör dig. Du kommer inte att ha möjlighet att få några meddelanden eller rums-inbjudningar från användare på din personliga ignoreringslista.", - "@ignoreListDescription": { - "type": "text", - "placeholders": {} - }, - "ignoreUsername": "Ignorera användarnamn", - "@ignoreUsername": { - "type": "text", - "placeholders": {} - }, - "iHaveClickedOnLink": "Jag har klickat på länken", - "@iHaveClickedOnLink": { - "type": "text", - "placeholders": {} - }, - "incorrectPassphraseOrKey": "Felaktig lösenordsfras eller åsterställningsnyckel", - "@incorrectPassphraseOrKey": { - "type": "text", - "placeholders": {} - }, - "inoffensive": "Oförargligt", - "@inoffensive": { - "type": "text", - "placeholders": {} - }, - "inviteContact": "Bjud in kontakt", - "@inviteContact": { - "type": "text", - "placeholders": {} - }, - "inviteContactToGroup": "Bjud in kontakt till {groupName}", - "@inviteContactToGroup": { - "type": "text", - "placeholders": { - "groupName": {} - } - }, - "invited": "Inbjuden", - "@invited": { - "type": "text", - "placeholders": {} - }, - "invitedUser": "📩 {username} bjöd in {targetName}", - "@invitedUser": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "invitedUsersOnly": "Endast inbjudna användare", - "@invitedUsersOnly": { - "type": "text", - "placeholders": {} - }, - "inviteForMe": "Inbjudning till mig", - "@inviteForMe": { - "type": "text", - "placeholders": {} - }, - "inviteText": "{username} bjöd in dig till FluffyChat. \n1. Installera FluffyChat: https://fluffychat.im \n2. Registrera dig eller logga in \n3. Öppna inbjudningslänk: {link}", - "@inviteText": { - "type": "text", - "placeholders": { - "username": {}, - "link": {} - } - }, - "isTyping": "skriver…", - "@isTyping": { - "type": "text", - "placeholders": {} - }, - "joinedTheChat": "👋 {username} anslöt till chatten", - "@joinedTheChat": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "joinRoom": "Anslut till rum", - "@joinRoom": { - "type": "text", - "placeholders": {} - }, - "kicked": "👞 {username} sparkade ut {targetName}", - "@kicked": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "kickedAndBanned": "🙅 {username} sparkade och bannade {targetName}", - "@kickedAndBanned": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "kickFromChat": "Sparka från chatt", - "@kickFromChat": { - "type": "text", - "placeholders": {} - }, - "lastActiveAgo": "Senast aktiv: {localizedTimeShort}", - "@lastActiveAgo": { - "type": "text", - "placeholders": { - "localizedTimeShort": {} - } - }, - "lastSeenLongTimeAgo": "Sågs för längesedan", - "@lastSeenLongTimeAgo": { - "type": "text", - "placeholders": {} - }, - "leave": "Lämna", - "@leave": { - "type": "text", - "placeholders": {} - }, - "leftTheChat": "Lämnade chatten", - "@leftTheChat": { - "type": "text", - "placeholders": {} - }, - "license": "Licens", - "@license": { - "type": "text", - "placeholders": {} - }, - "lightTheme": "Ljust", - "@lightTheme": { - "type": "text", - "placeholders": {} - }, - "loadCountMoreParticipants": "Ladda {count} mer deltagare", - "@loadCountMoreParticipants": { - "type": "text", - "placeholders": { - "count": {} - } - }, - "loadingPleaseWait": "Laddar... Var god vänta.", - "@loadingPleaseWait": { - "type": "text", - "placeholders": {} - }, - "loadMore": "Ladda mer…", - "@loadMore": { - "type": "text", - "placeholders": {} - }, - "login": "Logga in", - "@login": { - "type": "text", - "placeholders": {} - }, - "logInTo": "Logga in till {homeserver}", - "@logInTo": { - "type": "text", - "placeholders": { - "homeserver": {} - } - }, - "logout": "Logga ut", - "@logout": { - "type": "text", - "placeholders": {} - }, - "makeSureTheIdentifierIsValid": "Se till att identifieraren är giltig", - "@makeSureTheIdentifierIsValid": { - "type": "text", - "placeholders": {} - }, - "memberChanges": "Medlemsändringar", - "@memberChanges": { - "type": "text", - "placeholders": {} - }, - "mention": "Nämn", - "@mention": { - "type": "text", - "placeholders": {} - }, - "messages": "Meddelanden", - "@messages": { - "type": "text", - "placeholders": {} - }, - "messageWillBeRemovedWarning": "Meddelandet kommer tas bort för alla deltagare", - "@messageWillBeRemovedWarning": { - "type": "text", - "placeholders": {} - }, - "moderator": "Moderator", - "@moderator": { - "type": "text", - "placeholders": {} - }, - "muteChat": "Tysta chatt", - "@muteChat": { - "type": "text", - "placeholders": {} - }, - "needPantalaimonWarning": "Var medveten om att du behöver Pantalaimon för att använda ändpunktskryptering tillsvidare.", - "@needPantalaimonWarning": { - "type": "text", - "placeholders": {} - }, - "newChat": "Ny chatt", - "@newChat": { - "type": "text", - "placeholders": {} - }, - "newMessageInFluffyChat": "💬 Nya meddelanden i FluffyChat", - "@newMessageInFluffyChat": { - "type": "text", - "placeholders": {} - }, - "newVerificationRequest": "Ny verifikationsbegäran!", - "@newVerificationRequest": { - "type": "text", - "placeholders": {} - }, - "next": "Nästa", - "@next": { - "type": "text", - "placeholders": {} - }, - "no": "Nej", - "@no": { - "type": "text", - "placeholders": {} - }, - "noConnectionToTheServer": "Ingen anslutning till servern", - "@noConnectionToTheServer": { - "type": "text", - "placeholders": {} - }, - "noEmotesFound": "Hittade inga dekaler. 😕", - "@noEmotesFound": { - "type": "text", - "placeholders": {} - }, - "noGoogleServicesWarning": "De ser ut som att du inte har google-tjänster på din telefon. Det är ett bra beslut för din integritet! För att få push notifikationer i FluffyChat rekommenderar vi att använda https://microg.org/ eller https://unifiedpush.org/ .", - "@noGoogleServicesWarning": { - "type": "text", - "placeholders": {} - }, - "none": "Ingen", - "@none": { - "type": "text", - "placeholders": {} - }, - "noPasswordRecoveryDescription": "Du har inte lagt till något sätt för att återställa ditt lösenord än.", - "@noPasswordRecoveryDescription": { - "type": "text", - "placeholders": {} - }, - "noPermission": "Ingen behörighet", - "@noPermission": { - "type": "text", - "placeholders": {} - }, - "noRoomsFound": "Hittade inga rum…", - "@noRoomsFound": { - "type": "text", - "placeholders": {} - }, - "notifications": "Aviseringar", - "@notifications": { - "type": "text", - "placeholders": {} - }, - "notificationsEnabledForThisAccount": "Notifikationer är påslaget för detta konto", - "@notificationsEnabledForThisAccount": { - "type": "text", - "placeholders": {} - }, - "numUsersTyping": "{count} användare skriver…", - "@numUsersTyping": { - "type": "text", - "placeholders": { - "count": {} - } - }, - "offensive": "Stötande", - "@offensive": { - "type": "text", - "placeholders": {} - }, - "offline": "Offline", - "@offline": { - "type": "text", - "placeholders": {} - }, - "ok": "OK", - "@ok": { - "type": "text", - "placeholders": {} - }, - "online": "Online", - "@online": { - "type": "text", - "placeholders": {} - }, - "onlineKeyBackupEnabled": "Online Nyckel-backup är aktiverad", - "@onlineKeyBackupEnabled": { - "type": "text", - "placeholders": {} - }, - "oopsSomethingWentWrong": "Hoppsan, något gick fel…", - "@oopsSomethingWentWrong": { - "type": "text", - "placeholders": {} - }, - "openAppToReadMessages": "Öppna app för att lästa meddelanden", - "@openAppToReadMessages": { - "type": "text", - "placeholders": {} - }, - "openCamera": "Öppna kamera", - "@openCamera": { - "type": "text", - "placeholders": {} - }, - "optionalGroupName": "(Optional) Gruppnamn", - "@optionalGroupName": { - "type": "text", - "placeholders": {} - }, - "participant": "Deltagare", - "@participant": { - "type": "text", - "placeholders": {} - }, - "passphraseOrKey": "lösenord eller återställningsnyckel", - "@passphraseOrKey": { - "type": "text", - "placeholders": {} - }, - "password": "Lösenord", - "@password": { - "type": "text", - "placeholders": {} - }, - "passwordForgotten": "Glömt lösenord", - "@passwordForgotten": { - "type": "text", - "placeholders": {} - }, - "passwordHasBeenChanged": "Lösenordet har ändrats", - "@passwordHasBeenChanged": { - "type": "text", - "placeholders": {} - }, - "passwordRecovery": "Återställ lösenord", - "@passwordRecovery": { - "type": "text", - "placeholders": {} - }, - "pickImage": "Välj en bild", - "@pickImage": { - "type": "text", - "placeholders": {} - }, - "pin": "Nåla fast", - "@pin": { - "type": "text", - "placeholders": {} - }, - "play": "Spela {fileName}", - "@play": { - "type": "text", - "placeholders": { - "fileName": {} - } - }, - "pleaseChooseAPasscode": "Ange ett lösenord", - "@pleaseChooseAPasscode": { - "type": "text", - "placeholders": {} - }, - "pleaseChooseAUsername": "Välj ett användarnamn", - "@pleaseChooseAUsername": { - "type": "text", - "placeholders": {} - }, - "pleaseClickOnLink": "Klicka på länken i e-postmeddelandet för att sedan fortsätta.", - "@pleaseClickOnLink": { - "type": "text", - "placeholders": {} - }, - "pleaseEnter4Digits": "Ange 4 siffror eller lämna tom för att inaktivera app-lås.", - "@pleaseEnter4Digits": { - "type": "text", - "placeholders": {} - }, - "pleaseEnterAMatrixIdentifier": "Ange ditt Matrix ID.", - "@pleaseEnterAMatrixIdentifier": { - "type": "text", - "placeholders": {} - }, - "pleaseEnterYourPassword": "Ange ditt lösenord", - "@pleaseEnterYourPassword": { - "type": "text", - "placeholders": {} - }, - "pleaseEnterYourUsername": "Ange ditt användarnamn", - "@pleaseEnterYourUsername": { - "type": "text", - "placeholders": {} - }, - "pleaseFollowInstructionsOnWeb": "Följ instruktionerna på hemsidan och tryck på nästa.", - "@pleaseFollowInstructionsOnWeb": { - "type": "text", - "placeholders": {} - }, - "privacy": "Integritet", - "@privacy": { - "type": "text", - "placeholders": {} - }, - "publicRooms": "Publika Rum", - "@publicRooms": { - "type": "text", - "placeholders": {} - }, - "pushRules": "Push regler", - "@pushRules": { - "type": "text", - "placeholders": {} - }, - "reason": "Anledning", - "@reason": { - "type": "text", - "placeholders": {} - }, - "recording": "Spelar in", - "@recording": { - "type": "text", - "placeholders": {} - }, - "redactedAnEvent": "{username} redigerade en händelse", - "@redactedAnEvent": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "redactMessage": "Redigera meddelande", - "@redactMessage": { - "type": "text", - "placeholders": {} - }, - "reject": "Avböj", - "@reject": { - "type": "text", - "placeholders": {} - }, - "rejectedTheInvitation": "{username} avböjde inbjudan", - "@rejectedTheInvitation": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "rejoin": "Återanslut", - "@rejoin": { - "type": "text", - "placeholders": {} - }, - "remove": "Ta bort", - "@remove": { - "type": "text", - "placeholders": {} - }, - "removeAllOtherDevices": "Ta bort alla andra enheter", - "@removeAllOtherDevices": { - "type": "text", - "placeholders": {} - }, - "removedBy": "Bortagen av {username}", - "@removedBy": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "removeDevice": "Ta bort enhet", - "@removeDevice": { - "type": "text", - "placeholders": {} - }, - "unbanFromChat": "Ta bort chatt-blockering", - "@unbanFromChat": { - "type": "text", - "placeholders": {} - }, - "renderRichContent": "Återge innehåll med rikt meddelande", - "@renderRichContent": { - "type": "text", - "placeholders": {} - }, - "replaceRoomWithNewerVersion": "Ersätt rum med nyare version", - "@replaceRoomWithNewerVersion": { - "type": "text", - "placeholders": {} - }, - "reply": "Svara", - "@reply": { - "type": "text", - "placeholders": {} - }, - "reportMessage": "Rapportera meddelande", - "@reportMessage": { - "type": "text", - "placeholders": {} - }, - "requestPermission": "Begär behörighet", - "@requestPermission": { - "type": "text", - "placeholders": {} - }, - "roomHasBeenUpgraded": "Rummet har blivit uppgraderat", - "@roomHasBeenUpgraded": { - "type": "text", - "placeholders": {} - }, - "search": "Sök", - "@search": { - "type": "text", - "placeholders": {} - }, - "security": "Säkerhet", - "@security": { - "type": "text", - "placeholders": {} - }, - "seenByUser": "Sedd av {username}", - "@seenByUser": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "seenByUserAndCountOthers": "{count, plural, other{Sedd av {username} och {count} andra}}", - "@seenByUserAndCountOthers": { - "type": "text", - "placeholders": { - "username": {}, - "count": {} - } - }, - "seenByUserAndUser": "Sedd av {username} och {username2}", - "@seenByUserAndUser": { - "type": "text", - "placeholders": { - "username": {}, - "username2": {} - } - }, - "send": "Skicka", - "@send": { - "type": "text", - "placeholders": {} - }, - "sendAMessage": "Skicka ett meddelande", - "@sendAMessage": { - "type": "text", - "placeholders": {} - }, - "sendAudio": "Skicka ljud", - "@sendAudio": { - "type": "text", - "placeholders": {} - }, - "sendFile": "Skicka fil", - "@sendFile": { - "type": "text", - "placeholders": {} - }, - "sendImage": "Skicka bild", - "@sendImage": { - "type": "text", - "placeholders": {} - }, - "sendMessages": "Skickade meddelanden", - "@sendMessages": { - "type": "text", - "placeholders": {} - }, - "sendOriginal": "Skicka orginal", - "@sendOriginal": { - "type": "text", - "placeholders": {} - }, - "sendVideo": "Skicka video", - "@sendVideo": { - "type": "text", - "placeholders": {} - }, - "sentAFile": "📁 {username} skickade en fil", - "@sentAFile": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sentAnAudio": "🎤 {username} skickade ett ljudklipp", - "@sentAnAudio": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sentAPicture": "🖼️ {username} skickade en bild", - "@sentAPicture": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sentASticker": "😊 {username} skickade ett klistermärke", - "@sentASticker": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sentAVideo": "🎥 {username} skickade en video", - "@sentAVideo": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sentCallInformations": "{senderName} skickade samtalsinformation", - "@sentCallInformations": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "setCustomEmotes": "Ställ in anpassade dekaler", - "@setCustomEmotes": { - "type": "text", - "placeholders": {} - }, - "setGroupDescription": "Ställ in gruppbeskrivning", - "@setGroupDescription": { - "type": "text", - "placeholders": {} - }, - "setInvitationLink": "Ställ in inbjudningslänk", - "@setInvitationLink": { - "type": "text", - "placeholders": {} - }, - "setPermissionsLevel": "Ställ in behörighetsnivå", - "@setPermissionsLevel": { - "type": "text", - "placeholders": {} - }, - "setStatus": "Ställ in status", - "@setStatus": { - "type": "text", - "placeholders": {} - }, - "settings": "Inställningar", - "@settings": { - "type": "text", - "placeholders": {} - }, - "share": "Dela", - "@share": { - "type": "text", - "placeholders": {} - }, - "sharedTheLocation": "{username} delade sin position", - "@sharedTheLocation": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "signUp": "Registrera", - "@signUp": { - "type": "text", - "placeholders": {} - }, - "skip": "Hoppa över", - "@skip": { - "type": "text", - "placeholders": {} - }, - "sourceCode": "Källkod", - "@sourceCode": { - "type": "text", - "placeholders": {} - }, - "startedACall": "{senderName} startade ett samtal", - "@startedACall": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "status": "Status", - "@status": { - "type": "text", - "placeholders": {} - }, - "statusExampleMessage": "Hur mår du i dag?", - "@statusExampleMessage": { - "type": "text", - "placeholders": {} - }, - "submit": "Skicka in", - "@submit": { - "type": "text", - "placeholders": {} - }, - "systemTheme": "System", - "@systemTheme": { - "type": "text", - "placeholders": {} - }, - "theyDontMatch": "Dom Matchar Inte", - "@theyDontMatch": { - "type": "text", - "placeholders": {} - }, - "theyMatch": "Dom Matchar", - "@theyMatch": { - "type": "text", - "placeholders": {} - }, - "title": "FluffyChat", - "@title": { - "description": "Title for the application", - "type": "text", - "placeholders": {} - }, - "toggleFavorite": "Växla favorit", - "@toggleFavorite": { - "type": "text", - "placeholders": {} - }, - "toggleMuted": "Växla tystad", - "@toggleMuted": { - "type": "text", - "placeholders": {} - }, - "toggleUnread": "Markera läst/oläst", - "@toggleUnread": { - "type": "text", - "placeholders": {} - }, - "tooManyRequestsWarning": "För många förfrågningar. Vänligen försök senare!", - "@tooManyRequestsWarning": { - "type": "text", - "placeholders": {} - }, - "tryToSendAgain": "Försök att skicka igen", - "@tryToSendAgain": { - "type": "text", - "placeholders": {} - }, - "unavailable": "Upptagen", - "@unavailable": { - "type": "text", - "placeholders": {} - }, - "unbannedUser": "{username} avbannade {targetName}", - "@unbannedUser": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "unblockDevice": "Avblockera enhet", - "@unblockDevice": { - "type": "text", - "placeholders": {} - }, - "unknownDevice": "Okänd enhet", - "@unknownDevice": { - "type": "text", - "placeholders": {} - }, - "unknownEncryptionAlgorithm": "Okänd krypteringsalgoritm", - "@unknownEncryptionAlgorithm": { - "type": "text", - "placeholders": {} - }, - "unknownEvent": "Okänd händelse '{type}'", - "@unknownEvent": { - "type": "text", - "placeholders": { - "type": {} - } - }, - "unmuteChat": "Slå på ljudet för chatten", - "@unmuteChat": { - "type": "text", - "placeholders": {} - }, - "unpin": "Avnåla", - "@unpin": { - "type": "text", - "placeholders": {} - }, - "unreadChats": "{unreadCount, plural, =1{en oläst chatt} other{{unreadCount} olästa chattar}}", - "@unreadChats": { - "type": "text", - "placeholders": { - "unreadCount": {} - } - }, - "userAndOthersAreTyping": "{username} och {count} andra skriver…", - "@userAndOthersAreTyping": { - "type": "text", - "placeholders": { - "username": {}, - "count": {} - } - }, - "userAndUserAreTyping": "{username} och {username2} skriver…", - "@userAndUserAreTyping": { - "type": "text", - "placeholders": { - "username": {}, - "username2": {} - } - }, - "userIsTyping": "{username} skriver…", - "@userIsTyping": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "userLeftTheChat": "🚪 {username} lämnade chatten", - "@userLeftTheChat": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "username": "Användarnamn", - "@username": { - "type": "text", - "placeholders": {} - }, - "userSentUnknownEvent": "{username} skickade en {type} händelse", - "@userSentUnknownEvent": { - "type": "text", - "placeholders": { - "username": {}, - "type": {} - } - }, - "verify": "Verifiera", - "@verify": { - "type": "text", - "placeholders": {} - }, - "verifyStart": "Starta verifiering", - "@verifyStart": { - "type": "text", - "placeholders": {} - }, - "verifySuccess": "Du har lyckats verifiera!", - "@verifySuccess": { - "type": "text", - "placeholders": {} - }, - "verifyTitle": "Verifiera andra konton", - "@verifyTitle": { - "type": "text", - "placeholders": {} - }, - "videoCall": "Videosamtal", - "@videoCall": { - "type": "text", - "placeholders": {} - }, - "visibilityOfTheChatHistory": "Chatt-historikens synlighet", - "@visibilityOfTheChatHistory": { - "type": "text", - "placeholders": {} - }, - "visibleForAllParticipants": "Synlig för alla deltagare", - "@visibleForAllParticipants": { - "type": "text", - "placeholders": {} - }, - "visibleForEveryone": "Synlig för alla", - "@visibleForEveryone": { - "type": "text", - "placeholders": {} - }, - "voiceMessage": "Röstmeddelande", - "@voiceMessage": { - "type": "text", - "placeholders": {} - }, - "waitingPartnerAcceptRequest": "Väntar på att deltagaren accepterar begäran…", - "@waitingPartnerAcceptRequest": { - "type": "text", - "placeholders": {} - }, - "waitingPartnerEmoji": "Väntar på att deltagaren accepterar emojien…", - "@waitingPartnerEmoji": { - "type": "text", - "placeholders": {} - }, - "waitingPartnerNumbers": "Väntar på att deltagaren accepterar nummer…", - "@waitingPartnerNumbers": { - "type": "text", - "placeholders": {} - }, - "wallpaper": "Bakgrund", - "@wallpaper": { - "type": "text", - "placeholders": {} - }, - "warning": "Varning!", - "@warning": { - "type": "text", - "placeholders": {} - }, - "weSentYouAnEmail": "Vi skickade dig ett e-postmeddelande", - "@weSentYouAnEmail": { - "type": "text", - "placeholders": {} - }, - "whoCanPerformWhichAction": "Vem kan utföra vilken åtgärd", - "@whoCanPerformWhichAction": { - "type": "text", - "placeholders": {} - }, - "whoIsAllowedToJoinThisGroup": "Vilka som är tilllåtna att ansluta till denna grupp", - "@whoIsAllowedToJoinThisGroup": { - "type": "text", - "placeholders": {} - }, - "whyDoYouWantToReportThis": "Varför vill du rapportera detta?", - "@whyDoYouWantToReportThis": { - "type": "text", - "placeholders": {} - }, - "withTheseAddressesRecoveryDescription": "Med dessa addresser kan du återställa ditt lösenord.", - "@withTheseAddressesRecoveryDescription": { - "type": "text", - "placeholders": {} - }, - "writeAMessage": "Skriv ett meddelande…", - "@writeAMessage": { - "type": "text", - "placeholders": {} - }, - "yes": "Ja", - "@yes": { - "type": "text", - "placeholders": {} - }, - "you": "Du", - "@you": { - "type": "text", - "placeholders": {} - }, - "youAreInvitedToThisChat": "Du är inbjuden till denna chatt", - "@youAreInvitedToThisChat": { - "type": "text", - "placeholders": {} - }, - "youAreNoLongerParticipatingInThisChat": "Du deltar inte längre i denna chatt", - "@youAreNoLongerParticipatingInThisChat": { - "type": "text", - "placeholders": {} - }, - "youCannotInviteYourself": "Du kan inte bjuda in dig själv", - "@youCannotInviteYourself": { - "type": "text", - "placeholders": {} - }, - "youHaveBeenBannedFromThisChat": "Du har blivit bannad från denna chatt", - "@youHaveBeenBannedFromThisChat": { - "type": "text", - "placeholders": {} - }, - "yourPublicKey": "Din publika nyckel", - "@yourPublicKey": { - "type": "text", - "placeholders": {} - }, - "commandHint_html": "Skicka HTML-formatted text", - "@commandHint_html": { - "type": "text", - "description": "Usage hint for the command /html" - }, - "commandHint_ban": "Bannlys användaren från detta rum", - "@commandHint_ban": { - "type": "text", - "description": "Usage hint for the command /ban" - }, - "clearArchive": "Rensa arkiv", - "@clearArchive": {}, - "chats": "Chatter", - "@chats": { - "type": "text", - "placeholders": {} - }, - "chatHasBeenAddedToThisSpace": "Chatt har lagts till i detta utrymme", - "@chatHasBeenAddedToThisSpace": {}, - "chatBackup": "Chatt backup", - "@chatBackup": { - "type": "text", - "placeholders": {} - }, - "changeYourAvatar": "Ändra din avatar", - "@changeYourAvatar": { - "type": "text", - "placeholders": {} - }, - "cantOpenUri": "Kan inte öppna URL {uri}", - "@cantOpenUri": { - "type": "text", - "placeholders": { - "uri": {} - } - }, - "blocked": "Blockerad", - "@blocked": { - "type": "text", - "placeholders": {} - }, - "badServerLoginTypesException": "Hemma servern stödjer följande inloggnings typer :\n {serverVersions}\nMen denna applikation stödjer enbart:\n{supportedVersions}", - "@badServerLoginTypesException": { - "type": "text", - "placeholders": { - "serverVersions": {}, - "supportedVersions": {} - } - }, - "autoplayImages": "Automatisk spela upp animerade klistermärken och emoji", - "@autoplayImages": { - "type": "text", - "placeholder": {} - }, - "allChats": "Alla chattar", - "@allChats": { - "type": "text", - "placeholders": {} - }, - "addToSpace": "Lägg till i utrymme", - "@addToSpace": {}, - "addEmail": "Lägg till e-post", - "@addEmail": { - "type": "text", - "placeholders": {} - }, - "commandHint_myroomavatar": "Sätt din bild för detta rum (by mxc-uri)", - "@commandHint_myroomavatar": { - "type": "text", - "description": "Usage hint for the command /myroomavatar" - }, - "commandHint_me": "Beskriv dig själv", - "@commandHint_me": { - "type": "text", - "description": "Usage hint for the command /me" - }, - "commandHint_leave": "Lämna detta rum", - "@commandHint_leave": { - "type": "text", - "description": "Usage hint for the command /leave" - }, - "commandHint_kick": "Ta bort användare från detta rum", - "@commandHint_kick": { - "type": "text", - "description": "Usage hint for the command /kick" - }, - "commandHint_join": "Gå med i rum", - "@commandHint_join": { - "type": "text", - "description": "Usage hint for the command /join" - }, - "commandHint_invite": "Bjud in användaren till detta rum", - "@commandHint_invite": { - "type": "text", - "description": "Usage hint for the command /invite" - }, - "locationPermissionDeniedNotice": "Plats åtkomst nekad. Var god godkän detta för att kunna dela din plats.", - "@locationPermissionDeniedNotice": { - "type": "text", - "placeholders": {} - }, - "locationDisabledNotice": "Platstjänster är inaktiverade. Var god aktivera dom för att kunna dela din plats.", - "@locationDisabledNotice": { - "type": "text", - "placeholders": {} - }, - "goToTheNewRoom": "Gå till det nya rummet", - "@goToTheNewRoom": { - "type": "text", - "placeholders": {} - }, - "fontSize": "Teckensnitt storlek", - "@fontSize": { - "type": "text", - "placeholders": {} - }, - "everythingReady": "Allt är klart!", - "@everythingReady": { - "type": "text", - "placeholders": {} - }, - "errorObtainingLocation": "Fel vid erhållande av plats: {error}", - "@errorObtainingLocation": { - "type": "text", - "placeholders": { - "error": {} - } - }, - "enterASpacepName": "Ange utrymmets namn", - "@enterASpacepName": {}, - "editRoomAliases": "Redigera rum alias", - "@editRoomAliases": { - "type": "text", - "placeholders": {} - }, - "createNewSpace": "Nytt utrymme", - "@createNewSpace": { - "type": "text", - "placeholders": {} - }, - "copyToClipboard": "Kopiera till urklipp", - "@copyToClipboard": { - "type": "text", - "placeholders": {} - }, - "commandMissing": "{command} är inte ett kommando.", - "@commandMissing": { - "type": "text", - "placeholders": { - "command": {} - }, - "description": "State that {command} is not a valid /command." - }, - "commandInvalid": "Felaktigt kommando", - "@commandInvalid": { - "type": "text" - }, - "commandHint_unban": "Tillåt användare i rummet", - "@commandHint_unban": { - "type": "text", - "description": "Usage hint for the command /unban" - }, - "commandHint_send": "Skicka text", - "@commandHint_send": { - "type": "text", - "description": "Usage hint for the command /send" - }, - "commandHint_react": "Skicka svar som reaktion", - "@commandHint_react": { - "type": "text", - "description": "Usage hint for the command /react" - }, - "commandHint_plain": "Skicka oformaterad text", - "@commandHint_plain": { - "type": "text", - "description": "Usage hint for the command /plain" - }, - "commandHint_op": "Sätt användarens kraft nivå ( standard: 50)", - "@commandHint_op": { - "type": "text", - "description": "Usage hint for the command /op" - }, - "commandHint_myroomnick": "Sätt ditt användarnamn för rummet", - "@commandHint_myroomnick": { - "type": "text", - "description": "Usage hint for the command /myroomnick" - }, - "noEncryptionForPublicRooms": "Du kan endast aktivera kryptering när rummet inte längre är publikt tillgängligt.", - "@noEncryptionForPublicRooms": { - "type": "text", - "placeholders": {} - }, - "loginWith": "Logga in med {brand}", - "@loginWith": { - "type": "text", - "placeholders": { - "brand": {} - } - }, - "noMatrixServer": "{server1} är inte en matrix server, använd {server2} istället?", - "@noMatrixServer": { - "type": "text", - "placeholders": { - "server1": {}, - "server2": {} - } - }, - "obtainingLocation": "Erhåller plats…", - "@obtainingLocation": { - "type": "text", - "placeholders": {} - }, - "pleaseChoose": "Var god välj", - "@pleaseChoose": { - "type": "text", - "placeholders": {} - }, - "people": "Människor", - "@people": { - "type": "text", - "placeholders": {} - }, - "or": "Eller", - "@or": { - "type": "text", - "placeholders": {} - }, - "openInMaps": "Öppna i karta", - "@openInMaps": { - "type": "text", - "placeholders": {} - }, - "oopsPushError": "Oj! Tyvärr uppstod ett fel vid upprättande av push notiser.", - "@oopsPushError": { - "type": "text", - "placeholders": {} - }, - "synchronizingPleaseWait": "Synkroniserar… Var god vänta.", - "@synchronizingPleaseWait": { - "type": "text", - "placeholders": {} - }, - "spaceName": "Utrymmes namn", - "@spaceName": { - "type": "text", - "placeholders": {} - }, - "spaceIsPublic": "Utrymme är publikt", - "@spaceIsPublic": { - "type": "text", - "placeholders": {} - }, - "showPassword": "Visa lösenord", - "@showPassword": { - "type": "text", - "placeholders": {} - }, - "shareLocation": "Dela plats", - "@shareLocation": { - "type": "text", - "placeholders": {} - }, - "setAsCanonicalAlias": "Sätt som primärt alias", - "@setAsCanonicalAlias": { - "type": "text", - "placeholders": {} - }, - "sendSticker": "Skicka klistermärke", - "@sendSticker": { - "type": "text", - "placeholders": {} - }, - "sendAsText": "Skicka som text", - "@sendAsText": { - "type": "text" - }, - "saveFile": "Spara fil", - "@saveFile": { - "type": "text", - "placeholders": {} - }, - "roomVersion": "Rum version", - "@roomVersion": { - "type": "text", - "placeholders": {} - }, - "removeYourAvatar": "Ta bort din avatar", - "@removeYourAvatar": { - "type": "text", - "placeholders": {} - }, - "register": "Registrera", - "@register": { - "type": "text", - "placeholders": {} - }, - "pleaseEnterYourPin": "Ange din pin-kod", - "@pleaseEnterYourPin": { - "type": "text", - "placeholders": {} - }, - "wipeChatBackup": "Radera din chatt-backup för att skapa en ny återställningsnyckel?", - "@wipeChatBackup": { - "type": "text", - "placeholders": {} - }, - "verified": "Verifierad", - "@verified": { - "type": "text", - "placeholders": {} - }, - "transferFromAnotherDevice": "Överför till annan enhet", - "@transferFromAnotherDevice": { - "type": "text", - "placeholders": {} - }, - "shareYourInviteLink": "Dela din inbjudan", - "@shareYourInviteLink": {}, - "chatBackupDescription": "Din chatt backup är skyddad av en säkerhetsnyckel. Se till att du inte förlorar den.", - "@chatBackupDescription": { - "type": "text", - "placeholders": {} - }, - "commandHint_create": "Skapa en tom grupp-chatt\nAnvänd --no-encryption för att inaktivera kryptering", - "@commandHint_create": { - "type": "text", - "description": "Usage hint for the command /create" - }, - "commandHint_discardsession": "Kasta bort sessionen", - "@commandHint_discardsession": { - "type": "text", - "description": "Usage hint for the command /discardsession" - }, - "commandHint_dm": "Starta en direkt-chatt\nAnvänd --no-encryption för att inaktivera kryptering", - "@commandHint_dm": { - "type": "text", - "description": "Usage hint for the command /dm" - }, - "homeserver": "Hemserver", - "@homeserver": {}, - "oneClientLoggedOut": "En av dina klienter har loggats ut", - "@oneClientLoggedOut": {}, - "addAccount": "Lägg till konto", - "@addAccount": {}, - "editBundlesForAccount": "Lägg till paket för detta konto", - "@editBundlesForAccount": {}, - "addToBundle": "Utöka paket", - "@addToBundle": {}, - "bundleName": "Paketnamn", - "@bundleName": {}, - "serverRequiresEmail": "Servern behöver validera din e-postadress för registrering.", - "@serverRequiresEmail": {}, - "singlesignon": "Single Sign On", - "@singlesignon": { - "type": "text", - "placeholders": {} - }, - "unverified": "Ej verifierad", - "@unverified": {}, - "messageInfo": "Meddelandeinformation", - "@messageInfo": {}, - "messageType": "Meddelandetyp", - "@messageType": {}, - "time": "Tid", - "@time": {}, - "sender": "Avsändare", - "@sender": {}, - "removeFromSpace": "Ta bort från utrymme", - "@removeFromSpace": {}, - "addToSpaceDescription": "Välj ett utrymme som chatten skall läggas till i.", - "@addToSpaceDescription": {}, - "start": "Starta", - "@start": {}, - "iUnderstand": "Jag förstår", - "@iUnderstand": {}, - "yourStory": "Din berättelse", - "@yourStory": {}, - "openGallery": "Öppna galleri", - "@openGallery": {}, - "storyFrom": "Berättelse från {date}: \n{body}", - "@storyFrom": { - "type": "text", - "placeholders": { - "date": {}, - "body": {} - } - }, - "passwordsDoNotMatch": "Lösenorden stämmer inte överens!", - "@passwordsDoNotMatch": {}, - "repeatPassword": "Upprepa lösenord", - "@repeatPassword": {}, - "pleaseChooseAtLeastChars": "Vänligen ange minst {min} tecken.", - "@pleaseChooseAtLeastChars": { - "type": "text", - "placeholders": { - "min": {} - } - }, - "markAsRead": "Markera som läst", - "@markAsRead": {}, - "commandHint_clearcache": "Rensa cache", - "@commandHint_clearcache": { - "type": "text", - "description": "Usage hint for the command /clearcache" - }, - "openVideoCamera": "Aktivera kamera för video", - "@openVideoCamera": { - "type": "text", - "placeholders": {} - }, - "link": "Länk", - "@link": {}, - "publish": "Publicera", - "@publish": {}, - "unsubscribeStories": "Avprenumerera berättelser", - "@unsubscribeStories": {}, - "replyHasBeenSent": "Svar har skickats", - "@replyHasBeenSent": {}, - "videoWithSize": "Video ({size})", - "@videoWithSize": { - "type": "text", - "placeholders": { - "size": {} - } - }, - "whatIsGoingOn": "Vad händer?", - "@whatIsGoingOn": {}, - "addDescription": "Lägg till beskrivning", - "@addDescription": {}, - "reportUser": "Rapportera användare", - "@reportUser": {}, - "openChat": "Öppna Chatt", - "@openChat": {}, - "sendOnEnter": "Skicka med Enter", - "@sendOnEnter": {}, - "addToStory": "Addera till berättelse", - "@addToStory": {}, - "pleaseEnterValidEmail": "Vänligen ange en giltig e-postadress.", - "@pleaseEnterValidEmail": {}, - "scanQrCode": "Skanna QR-kod", - "@scanQrCode": {}, - "bubbleSize": "Storlek på bubbla", - "@bubbleSize": { - "type": "text", - "placeholders": {} - }, - "yourChatBackupHasBeenSetUp": "Din chatt-backup har konfigurerats.", - "@yourChatBackupHasBeenSetUp": {}, - "loginWithOneClick": "Logga in med ett klick", - "@loginWithOneClick": {}, - "removeFromBundle": "Ta bort från paket", - "@removeFromBundle": {}, - "enableMultiAccounts": "(BETA) Aktivera multi-konton på denna enhet", - "@enableMultiAccounts": {}, - "whoCanSeeMyStories": "Vem kan se mina berättelser?", - "@whoCanSeeMyStories": {}, - "whoCanSeeMyStoriesDesc": "Notera att användare kan se och kontakta varandra i din berättelse.", - "@whoCanSeeMyStoriesDesc": {}, - "thisUserHasNotPostedAnythingYet": "Den här användaren har inte lagt till något till deras berättelse än", - "@thisUserHasNotPostedAnythingYet": {}, - "storyPrivacyWarning": "Notera att användare kan se och kontakta varandra i din berättelse. Din berättelse är synlig i 24 timmar, men det finns ingen garanti för att berättelser raderas från alla enheter och servrar.", - "@storyPrivacyWarning": {}, - "emojis": "Uttryckssymboler", - "@emojis": {}, - "placeCall": "Ring", - "@placeCall": {}, - "voiceCall": "Röstsamtal", - "@voiceCall": {}, - "unsupportedAndroidVersion": "Inget stöd för denna version av Android", - "@unsupportedAndroidVersion": {}, - "videoCallsBetaWarning": "Videosamtal är för närvarande under testning. De kanske inte fungerar som det är tänkt eller på alla plattformar.", - "@videoCallsBetaWarning": {}, - "unsupportedAndroidVersionLong": "Denna funktion kräver en senare version av Android.", - "@unsupportedAndroidVersionLong": {}, - "dismiss": "Avfärda", - "@dismiss": {}, - "matrixWidgets": "Matrix widgetar", - "@matrixWidgets": {}, - "reactedWith": "{sender} reagerade med {reaction}", - "@reactedWith": { - "type": "text", - "placeholders": { - "sender": {}, - "reaction": {} - } - }, - "pinMessage": "Fäst i rum", - "@pinMessage": {}, - "confirmEventUnpin": "Är du säker på att händelsen inte längre skall vara fastnålad?", - "@confirmEventUnpin": {}, - "experimentalVideoCalls": "Experimentella videosamtal", - "@experimentalVideoCalls": {}, - "switchToAccount": "Byt till konto {number}", - "@switchToAccount": { - "type": "number", - "placeholders": { - "number": {} - } - }, - "nextAccount": "Nästa konto", - "@nextAccount": {}, - "previousAccount": "Föregående konto", - "@previousAccount": {}, - "emailOrUsername": "Användarnamn eller e-postadress", - "@emailOrUsername": {}, - "addWidget": "Lägg till widget", - "@addWidget": {}, - "widgetVideo": "Video", - "@widgetVideo": {}, - "widgetEtherpad": "Anteckning", - "@widgetEtherpad": {}, - "widgetCustom": "Anpassad", - "@widgetCustom": {}, - "widgetName": "Namn", - "@widgetName": {}, - "widgetUrlError": "Detta är inte en giltig URL.", - "@widgetUrlError": {}, - "errorAddingWidget": "Ett fel uppstod när widgeten skulle läggas till.", - "@errorAddingWidget": {}, - "editWidgets": "Redigera widgetar", - "@editWidgets": {}, - "widgetJitsi": "Jitsi-möte", - "@widgetJitsi": {}, - "widgetNameError": "Vänligen ange ett visningsnamn.", - "@widgetNameError": {}, - "storeSecurlyOnThisDevice": "Lagra säkert på denna enhet", - "@storeSecurlyOnThisDevice": {}, - "youJoinedTheChat": "Du gick med i chatten", - "@youJoinedTheChat": {}, - "youAcceptedTheInvitation": "👍 Du accepterade inbjudan", - "@youAcceptedTheInvitation": {}, - "youKicked": "👞 Du sparkade ut {user}", - "@youKicked": { - "placeholders": { - "user": {} - } - }, - "hugContent": "{senderName} kramar dig", - "@hugContent": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "commandHint_markasgroup": "Märk som grupp", - "@commandHint_markasgroup": {}, - "recoveryKeyLost": "Borttappad återställningsnyckel?", - "@recoveryKeyLost": {}, - "indexedDbErrorTitle": "Problem med privat läge", - "@indexedDbErrorTitle": {}, - "youHaveWithdrawnTheInvitationFor": "Du har återkallat inbjudan till {user}", - "@youHaveWithdrawnTheInvitationFor": { - "placeholders": { - "user": {} - } - }, - "youUnbannedUser": "Du återkallade förbudet för {user}", - "@youUnbannedUser": { - "placeholders": { - "user": {} - } - }, - "unlockOldMessages": "Lås upp äldre meddelanden", - "@unlockOldMessages": {}, - "newSpace": "Nytt utrymme", - "@newSpace": {}, - "googlyEyesContent": "{senderName} skickar dig googly ögon", - "@googlyEyesContent": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "dehydrate": "Exportera sessionen och rensa enheten", - "@dehydrate": {}, - "dehydrateWarning": "Denna åtgärd kan inte ångras. Försäkra dig om att backupen är i säkert förvar.", - "@dehydrateWarning": {}, - "dehydrateTor": "TOR-användare: Exportera session", - "@dehydrateTor": {}, - "hydrateTor": "TOR-användare: Importera session från tidigare export", - "@hydrateTor": {}, - "hydrateTorLong": "Exporterade du sessionen när du senast använde TOR? Importera den enkelt och fortsätt chatta.", - "@hydrateTorLong": {}, - "recoveryKey": "Återställningsnyckel", - "@recoveryKey": {}, - "separateChatTypes": "Separata direktchattar och grupper", - "@separateChatTypes": { - "type": "text", - "placeholders": {} - }, - "showDirectChatsInSpaces": "Visa relaterade direktchattar i utrymmen", - "@showDirectChatsInSpaces": { - "type": "text", - "placeholders": {} - }, - "startFirstChat": "Starta din första chatt", - "@startFirstChat": {}, - "pleaseEnterRecoveryKeyDescription": "Ange din återställningsnyckel från en tidigare session för att låsa upp äldre meddelanden. Din återställningsnyckel är INTE ditt lösenord.", - "@pleaseEnterRecoveryKeyDescription": {}, - "encryptThisChat": "Kryptera denna chatt", - "@encryptThisChat": {}, - "enterInviteLinkOrMatrixId": "Ange länk för inbjudan eller Matrix-ID...", - "@enterInviteLinkOrMatrixId": {}, - "dehydrateTorLong": "TOR-användare rekommenderas att exportera sessionen innan fönstret stängs.", - "@dehydrateTorLong": {}, - "noBackupWarning": "Varning! Om du inte aktiverar säkerhetskopiering av chattar så tappar du åtkomst till krypterade meddelanden. Det är rekommenderat att du aktiverar säkerhetskopiering innan du loggar ut.", - "@noBackupWarning": {}, - "noOtherDevicesFound": "Inga andra enheter hittades", - "@noOtherDevicesFound": {}, - "endToEndEncryption": "Totalsträckskryptering", - "@endToEndEncryption": {}, - "disableEncryptionWarning": "Av säkerhetsskäl kan du inte stänga av kryptering i en chatt där det tidigare aktiverats.", - "@disableEncryptionWarning": {}, - "sorryThatsNotPossible": "Det där är inte möjligt", - "@sorryThatsNotPossible": {}, - "confirmMatrixId": "Bekräfta ditt Matrix-ID för att radera ditt konto.", - "@confirmMatrixId": {}, - "updateAvailable": "FluffyChat-uppdatering tillgänglig", - "@updateAvailable": {}, - "updateNow": "Påbörja uppdatering i bakgrunden", - "@updateNow": {}, - "supposedMxid": "Detta bör vara {mxid}", - "@supposedMxid": { - "type": "text", - "placeholders": { - "mxid": {} - } - }, - "pleaseEnterRecoveryKey": "Ange din återställningsnyckel:", - "@pleaseEnterRecoveryKey": {}, - "commandHint_markasdm": "Märk som rum för direktmeddelanden", - "@commandHint_markasdm": {}, - "noEmailWarning": "Utan en giltig e-postadress kommer du inte kunna återställa ditt lösenord. Om du inte vill ange en e-postadress, tryck på knappen igen för att fortsätta.", - "@noEmailWarning": {}, - "user": "Användare", - "@user": {}, - "indexedDbErrorLong": "Meddelandelagring är tyvärr inte aktiverat i privat läge som standard.\nGå till\n - about:config\n - sätt dom.indexedDB.privateBrowsing.enabled till true\nAnnars går det inte att använda FluffyChat.", - "@indexedDbErrorLong": {}, - "storeInSecureStorageDescription": "Lagra återställningsnyckeln på säker plats på denna enhet.", - "@storeInSecureStorageDescription": {}, - "storeInAppleKeyChain": "Lagra i Apples nyckelkedja (KeyChain)", - "@storeInAppleKeyChain": {}, - "foregroundServiceRunning": "Denna notifikation visas när förgrundstjänsten körs.", - "@foregroundServiceRunning": {}, - "custom": "Anpassad", - "@custom": {}, - "countFiles": "{count} filer", - "@countFiles": { - "placeholders": { - "count": {} - } - }, - "screenSharingTitle": "skärmdelning", - "@screenSharingTitle": {}, - "noKeyForThisMessage": "Detta kan hända om meddelandet skickades innan du loggade in på ditt konto i den här enheten.\n\nDet kan också vara så att avsändaren har blockerat din enhet eller att något gick fel med internetanslutningen.\n\nKan du läsa meddelandet i en annan session? I sådana fall kan du överföra meddelandet från den sessionen! Gå till Inställningar > Enhet och säkerställ att dina enheter har verifierat varandra. När du öppnar rummet nästa gång och båda sessionerna är i förgrunden, så kommer nycklarna att överföras automatiskt.\n\nVill du inte förlora nycklarna vid utloggning eller när du byter enhet? Säkerställ att du har aktiverat säkerhetskopiering för chatten i inställningarna.", - "@noKeyForThisMessage": {}, - "fileIsTooBigForServer": "Servern informerar om att filen är för stor för att skickas.", - "@fileIsTooBigForServer": {}, - "deviceKeys": "Enhetsnycklar:", - "@deviceKeys": {}, - "enterSpace": "Gå till utrymme", - "@enterSpace": {}, - "commandHint_googly": "Skicka några googly ögon", - "@commandHint_googly": {}, - "commandHint_cuddle": "Skicka en omfamning", - "@commandHint_cuddle": {}, - "commandHint_hug": "Skicka en kram", - "@commandHint_hug": {}, - "users": "Användare", - "@users": {}, - "cuddleContent": "{senderName} omfamnar dig", - "@cuddleContent": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "hydrate": "Återställ från säkerhetskopia", - "@hydrate": {}, - "screenSharingDetail": "Du delar din skärm i FluffyChat", - "@screenSharingDetail": {}, - "letsStart": "Lås oss börja", - "@letsStart": {}, - "youRejectedTheInvitation": "Du avvisade inbjudan", - "@youRejectedTheInvitation": {}, - "youBannedUser": "Du förbjöd {user}", - "@youBannedUser": { - "placeholders": { - "user": {} - } - }, - "youInvitedBy": "📩 Du har blivit inbjuden av {user}", - "@youInvitedBy": { - "placeholders": { - "user": {} - } - }, - "youInvitedUser": "📩 Du bjöd in {user}", - "@youInvitedUser": { - "placeholders": { - "user": {} - } - }, - "youKickedAndBanned": "🙅 Du sparkade ut och förbjöd {user}", - "@youKickedAndBanned": { - "placeholders": { - "user": {} - } - }, - "stories": "Berättelser", - "@stories": {}, - "saveKeyManuallyDescription": "Spara nyckeln manuellt genom att aktivera dela-funktionen eller urklippshanteraren på enheten.", - "@saveKeyManuallyDescription": {}, - "storeInAndroidKeystore": "Lagra i Androids nyckellagring (KeyStore)", - "@storeInAndroidKeystore": {}, - "callingPermissions": "Samtalsbehörighet", - "@callingPermissions": {}, - "callingAccount": "Samtalskonto", - "@callingAccount": {}, - "callingAccountDetails": "Tillåt FluffyChat att använda Androids ring-app.", - "@callingAccountDetails": {}, - "appearOnTop": "Visa ovanpå", - "@appearOnTop": {}, - "appearOnTopDetails": "Tillåt att appen visas ovanpå (behövs inte om du redan har FluffyChat konfigurerat som ett samtalskonto)", - "@appearOnTopDetails": {}, - "otherCallingPermissions": "Mikrofon, kamera och andra behörigheter för FluffyChat", - "@otherCallingPermissions": {}, - "whyIsThisMessageEncrypted": "Varför kan inte detta meddelande läsas?", - "@whyIsThisMessageEncrypted": {}, - "newGroup": "Ny grupp", - "@newGroup": {}, - "enterRoom": "Gå till rummet", - "@enterRoom": {}, - "allSpaces": "Alla utrymmen", - "@allSpaces": {}, - "numChats": "{number} chattar", - "@numChats": { - "type": "number", - "placeholders": { - "number": {} - } - }, - "hideUnimportantStateEvents": "Göm oviktiga tillståndshändelser", - "@hideUnimportantStateEvents": {}, - "doNotShowAgain": "Visa inte igen", - "@doNotShowAgain": {}, - "wasDirectChatDisplayName": "Tom chatt (var {oldDisplayName})", - "@wasDirectChatDisplayName": { - "type": "text", - "placeholders": { - "oldDisplayName": {} - } - }, - "newSpaceDescription": "Utrymmen möjliggör konsolidering av chattar och att bygga privata eller offentliga gemenskaper.", - "@newSpaceDescription": {}, - "reopenChat": "Återöppna chatt", - "@reopenChat": {}, - "jumpToLastReadMessage": "Hoppa till det senast lästa meddelandet", - "@jumpToLastReadMessage": {}, - "readUpToHere": "Läs upp till hit", - "@readUpToHere": {}, - "fileHasBeenSavedAt": "Filen har sparats i {path}", - "@fileHasBeenSavedAt": { - "type": "text", - "placeholders": { - "path": {} - } + "@@last_modified": "2021-08-14 12:41:09.835634", + "about": "Om", + "@about": { + "type": "text", + "placeholders": {} + }, + "accept": "Acceptera", + "@accept": { + "type": "text", + "placeholders": {} + }, + "acceptedTheInvitation": "👍 {username} accepterade inbjudan", + "@acceptedTheInvitation": { + "type": "text", + "placeholders": { + "username": {} } -} \ No newline at end of file + }, + "account": "Konto", + "@account": { + "type": "text", + "placeholders": {} + }, + "activatedEndToEndEncryption": "🔐 {username} aktiverade ändpunktskryptering", + "@activatedEndToEndEncryption": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "addGroupDescription": "Lägg till en gruppbeskrivning", + "@addGroupDescription": { + "type": "text", + "placeholders": {} + }, + "admin": "Admin", + "@admin": { + "type": "text", + "placeholders": {} + }, + "alias": "alias", + "@alias": { + "type": "text", + "placeholders": {} + }, + "all": "Alla", + "@all": { + "type": "text", + "placeholders": {} + }, + "answeredTheCall": "{senderName} besvarade samtalet", + "@answeredTheCall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "anyoneCanJoin": "Vem som helst kan gå med", + "@anyoneCanJoin": { + "type": "text", + "placeholders": {} + }, + "appLock": "App-lås", + "@appLock": { + "type": "text", + "placeholders": {} + }, + "archive": "Arkiv", + "@archive": { + "type": "text", + "placeholders": {} + }, + "areGuestsAllowedToJoin": "Får gästanvändare gå med", + "@areGuestsAllowedToJoin": { + "type": "text", + "placeholders": {} + }, + "areYouSure": "Är du säker?", + "@areYouSure": { + "type": "text", + "placeholders": {} + }, + "areYouSureYouWantToLogout": "Är du säker på att du vill logga ut?", + "@areYouSureYouWantToLogout": { + "type": "text", + "placeholders": {} + }, + "askSSSSSign": "För att kunna signera den andra personen, vänligen ange din lösenfras eller återställningsnyckel för säker lagring.", + "@askSSSSSign": { + "type": "text", + "placeholders": {} + }, + "askVerificationRequest": "Acceptera denna verifikationsförfrågan från {username}?", + "@askVerificationRequest": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "badServerVersionsException": "Hemservern stöjder Spec-versionen:\n{serverVersions}\nMen denna app stödjer enbart {supportedVersions}", + "@badServerVersionsException": { + "type": "text", + "placeholders": { + "serverVersions": {}, + "supportedVersions": {} + } + }, + "banFromChat": "Bannlys från chatt", + "@banFromChat": { + "type": "text", + "placeholders": {} + }, + "banned": "Bannlyst", + "@banned": { + "type": "text", + "placeholders": {} + }, + "bannedUser": "{username} bannlös {targetName}", + "@bannedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "blockDevice": "Blockera Enhet", + "@blockDevice": { + "type": "text", + "placeholders": {} + }, + "botMessages": "Bot meddelanden", + "@botMessages": { + "type": "text", + "placeholders": {} + }, + "cancel": "Avbryt", + "@cancel": { + "type": "text", + "placeholders": {} + }, + "changeDeviceName": "Ändra enhetsnamn", + "@changeDeviceName": { + "type": "text", + "placeholders": {} + }, + "changedTheChatAvatar": "{username} ändrade sin chatt-avatar", + "@changedTheChatAvatar": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheChatDescriptionTo": "{username} ändrade chatt-beskrivningen till: '{description}'", + "@changedTheChatDescriptionTo": { + "type": "text", + "placeholders": { + "username": {}, + "description": {} + } + }, + "changedTheChatNameTo": "{username} ändrade sitt chatt-namn till: '{chatname}'", + "@changedTheChatNameTo": { + "type": "text", + "placeholders": { + "username": {}, + "chatname": {} + } + }, + "changedTheChatPermissions": "{username} ändrade chatt-rättigheterna", + "@changedTheChatPermissions": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheDisplaynameTo": "{username} ändrade visningsnamnet till: '{displayname}'", + "@changedTheDisplaynameTo": { + "type": "text", + "placeholders": { + "username": {}, + "displayname": {} + } + }, + "changedTheGuestAccessRules": "{username} ändrade reglerna för gästaccess", + "@changedTheGuestAccessRules": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheGuestAccessRulesTo": "{username} ändrade reglerna för gästaccess till: {rules}", + "@changedTheGuestAccessRulesTo": { + "type": "text", + "placeholders": { + "username": {}, + "rules": {} + } + }, + "changedTheHistoryVisibility": "{username} ändrade historikens synlighet", + "@changedTheHistoryVisibility": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheHistoryVisibilityTo": "{username} ändrade historikens synlighet till: {rules}", + "@changedTheHistoryVisibilityTo": { + "type": "text", + "placeholders": { + "username": {}, + "rules": {} + } + }, + "changedTheJoinRules": "{username} ändrade anslutningsreglerna", + "@changedTheJoinRules": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheJoinRulesTo": "{username} ändrade anslutningsreglerna till {joinRules}", + "@changedTheJoinRulesTo": { + "type": "text", + "placeholders": { + "username": {}, + "joinRules": {} + } + }, + "changedTheProfileAvatar": "{username} ändrade sin avatar", + "@changedTheProfileAvatar": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheRoomAliases": "{username} ändrade rummets alias", + "@changedTheRoomAliases": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheRoomInvitationLink": "{username} ändrade inbjudningslänken", + "@changedTheRoomInvitationLink": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changePassword": "Ändra lösenord", + "@changePassword": { + "type": "text", + "placeholders": {} + }, + "changeTheHomeserver": "Ändra hemserver", + "@changeTheHomeserver": { + "type": "text", + "placeholders": {} + }, + "changeTheme": "Ändra din stil", + "@changeTheme": { + "type": "text", + "placeholders": {} + }, + "changeTheNameOfTheGroup": "Ändra namn på gruppen", + "@changeTheNameOfTheGroup": { + "type": "text", + "placeholders": {} + }, + "changeWallpaper": "Ändra bakgrund", + "@changeWallpaper": { + "type": "text", + "placeholders": {} + }, + "channelCorruptedDecryptError": "Krypteringen har blivit korrupt", + "@channelCorruptedDecryptError": { + "type": "text", + "placeholders": {} + }, + "chat": "Chatt", + "@chat": { + "type": "text", + "placeholders": {} + }, + "chatDetails": "Chatt-detaljer", + "@chatDetails": { + "type": "text", + "placeholders": {} + }, + "chooseAStrongPassword": "Välj ett starkt lösenord", + "@chooseAStrongPassword": { + "type": "text", + "placeholders": {} + }, + "chooseAUsername": "Välj ett användarnamn", + "@chooseAUsername": { + "type": "text", + "placeholders": {} + }, + "close": "Stäng", + "@close": { + "type": "text", + "placeholders": {} + }, + "compareEmojiMatch": "Vänligen jämför uttryckssymbolerna", + "@compareEmojiMatch": { + "type": "text", + "placeholders": {} + }, + "compareNumbersMatch": "Vänligen jämför siffrorna", + "@compareNumbersMatch": { + "type": "text", + "placeholders": {} + }, + "configureChat": "Konfigurera chatt", + "@configureChat": { + "type": "text", + "placeholders": {} + }, + "confirm": "Bekräfta", + "@confirm": { + "type": "text", + "placeholders": {} + }, + "connect": "Anslut", + "@connect": { + "type": "text", + "placeholders": {} + }, + "contactHasBeenInvitedToTheGroup": "Kontakten har blivit inbjuden till gruppen", + "@contactHasBeenInvitedToTheGroup": { + "type": "text", + "placeholders": {} + }, + "containsDisplayName": "Innehåller visningsnamn", + "@containsDisplayName": { + "type": "text", + "placeholders": {} + }, + "containsUserName": "Innehåller användarnamn", + "@containsUserName": { + "type": "text", + "placeholders": {} + }, + "contentHasBeenReported": "Innehållet har rapporterats till server-admins", + "@contentHasBeenReported": { + "type": "text", + "placeholders": {} + }, + "copiedToClipboard": "Kopierat till urklipp", + "@copiedToClipboard": { + "type": "text", + "placeholders": {} + }, + "copy": "Kopiera", + "@copy": { + "type": "text", + "placeholders": {} + }, + "couldNotDecryptMessage": "Kunde ej avkoda meddelande: {error}", + "@couldNotDecryptMessage": { + "type": "text", + "placeholders": { + "error": {} + } + }, + "countParticipants": "{count} deltagare", + "@countParticipants": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "create": "Skapa", + "@create": { + "type": "text", + "placeholders": {} + }, + "createdTheChat": "💬 {username} skapade chatten", + "@createdTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "createNewGroup": "Skapa ny grupp", + "@createNewGroup": { + "type": "text", + "placeholders": {} + }, + "currentlyActive": "För närvarande aktiv", + "@currentlyActive": { + "type": "text", + "placeholders": {} + }, + "darkTheme": "Mörkt", + "@darkTheme": { + "type": "text", + "placeholders": {} + }, + "dateAndTimeOfDay": "{date}, {timeOfDay}", + "@dateAndTimeOfDay": { + "type": "text", + "placeholders": { + "date": {}, + "timeOfDay": {} + } + }, + "dateWithoutYear": "{day}-{month}", + "@dateWithoutYear": { + "type": "text", + "placeholders": { + "month": {}, + "day": {} + } + }, + "dateWithYear": "{year}-{month}-{day}", + "@dateWithYear": { + "type": "text", + "placeholders": { + "year": {}, + "month": {}, + "day": {} + } + }, + "deactivateAccountWarning": "Detta kommer att avaktivera ditt konto. Det här går inte att ångra! Är du säker?", + "@deactivateAccountWarning": { + "type": "text", + "placeholders": {} + }, + "defaultPermissionLevel": "Standard behörighetsnivå", + "@defaultPermissionLevel": { + "type": "text", + "placeholders": {} + }, + "delete": "Radera", + "@delete": { + "type": "text", + "placeholders": {} + }, + "deleteAccount": "Ta bort konto", + "@deleteAccount": { + "type": "text", + "placeholders": {} + }, + "deleteMessage": "Ta bort meddelande", + "@deleteMessage": { + "type": "text", + "placeholders": {} + }, + "deny": "Neka", + "@deny": { + "type": "text", + "placeholders": {} + }, + "device": "Enhet", + "@device": { + "type": "text", + "placeholders": {} + }, + "deviceId": "Enhets-ID", + "@deviceId": { + "type": "text", + "placeholders": {} + }, + "devices": "Enheter", + "@devices": { + "type": "text", + "placeholders": {} + }, + "directChats": "Direkt Chatt", + "@directChats": { + "type": "text", + "placeholders": {} + }, + "displaynameHasBeenChanged": "Visningsnamn har ändrats", + "@displaynameHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "downloadFile": "Ladda ner fil", + "@downloadFile": { + "type": "text", + "placeholders": {} + }, + "edit": "Ändra", + "@edit": { + "type": "text", + "placeholders": {} + }, + "editBlockedServers": "redigera blockerade servrar", + "@editBlockedServers": { + "type": "text", + "placeholders": {} + }, + "editChatPermissions": "Ändra chatt-rättigheter", + "@editChatPermissions": { + "type": "text", + "placeholders": {} + }, + "editDisplayname": "Ändra visningsnamn", + "@editDisplayname": { + "type": "text", + "placeholders": {} + }, + "editRoomAvatar": "redigera rumsavatar", + "@editRoomAvatar": { + "type": "text", + "placeholders": {} + }, + "emoteExists": "Dekalen existerar redan!", + "@emoteExists": { + "type": "text", + "placeholders": {} + }, + "emoteInvalid": "Ogiltig dekal-kod!", + "@emoteInvalid": { + "type": "text", + "placeholders": {} + }, + "emotePacks": "Dekalpaket för rummet", + "@emotePacks": { + "type": "text", + "placeholders": {} + }, + "emoteSettings": "Emote inställningar", + "@emoteSettings": { + "type": "text", + "placeholders": {} + }, + "emoteShortcode": "Dekal kod", + "@emoteShortcode": { + "type": "text", + "placeholders": {} + }, + "emoteWarnNeedToPick": "Du måste välja en dekal-kod och en bild!", + "@emoteWarnNeedToPick": { + "type": "text", + "placeholders": {} + }, + "emptyChat": "Tom chatt", + "@emptyChat": { + "type": "text", + "placeholders": {} + }, + "enableEmotesGlobally": "Aktivera dekal-paket globalt", + "@enableEmotesGlobally": { + "type": "text", + "placeholders": {} + }, + "enableEncryption": "Aktivera kryptering", + "@enableEncryption": { + "type": "text", + "placeholders": {} + }, + "enableEncryptionWarning": "Du kommer inte ha fortsatt möjlighet till att inaktivera krypteringen. Är du säker?", + "@enableEncryptionWarning": { + "type": "text", + "placeholders": {} + }, + "encrypted": "Krypterad", + "@encrypted": { + "type": "text", + "placeholders": {} + }, + "encryption": "Kryptering", + "@encryption": { + "type": "text", + "placeholders": {} + }, + "encryptionNotEnabled": "Kryptering är ej aktiverad", + "@encryptionNotEnabled": { + "type": "text", + "placeholders": {} + }, + "endedTheCall": "{senderName} avslutade samtalet", + "@endedTheCall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "enterAGroupName": "Ange ett gruppnamn", + "@enterAGroupName": { + "type": "text", + "placeholders": {} + }, + "enterAnEmailAddress": "Ange en e-postaddress", + "@enterAnEmailAddress": { + "type": "text", + "placeholders": {} + }, + "enterYourHomeserver": "Ange din hemserver", + "@enterYourHomeserver": { + "type": "text", + "placeholders": {} + }, + "extremeOffensive": "Extremt stötande", + "@extremeOffensive": { + "type": "text", + "placeholders": {} + }, + "fileName": "Filnamn", + "@fileName": { + "type": "text", + "placeholders": {} + }, + "fluffychat": "FluffyChat", + "@fluffychat": { + "type": "text", + "placeholders": {} + }, + "forward": "Framåt", + "@forward": { + "type": "text", + "placeholders": {} + }, + "fromJoining": "Från att gå med", + "@fromJoining": { + "type": "text", + "placeholders": {} + }, + "fromTheInvitation": "Från inbjudan", + "@fromTheInvitation": { + "type": "text", + "placeholders": {} + }, + "group": "Grupp", + "@group": { + "type": "text", + "placeholders": {} + }, + "groupDescription": "Gruppbeskrivning", + "@groupDescription": { + "type": "text", + "placeholders": {} + }, + "groupDescriptionHasBeenChanged": "Gruppbeskrivningen ändrad", + "@groupDescriptionHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "groupIsPublic": "Gruppen är publik", + "@groupIsPublic": { + "type": "text", + "placeholders": {} + }, + "groups": "Grupper", + "@groups": { + "type": "text", + "placeholders": {} + }, + "groupWith": "Gruppen med {displayname}", + "@groupWith": { + "type": "text", + "placeholders": { + "displayname": {} + } + }, + "guestsAreForbidden": "Gäster är förbjudna", + "@guestsAreForbidden": { + "type": "text", + "placeholders": {} + }, + "guestsCanJoin": "Gäster kan ansluta", + "@guestsCanJoin": { + "type": "text", + "placeholders": {} + }, + "hasWithdrawnTheInvitationFor": "{username} har tagit tillbaka inbjudan för {targetName}", + "@hasWithdrawnTheInvitationFor": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "help": "Hjälp", + "@help": { + "type": "text", + "placeholders": {} + }, + "hideRedactedEvents": "Göm redigerade händelser", + "@hideRedactedEvents": { + "type": "text", + "placeholders": {} + }, + "hideUnknownEvents": "Göm okända händelser", + "@hideUnknownEvents": { + "type": "text", + "placeholders": {} + }, + "howOffensiveIsThisContent": "Hur stötande är detta innehåll?", + "@howOffensiveIsThisContent": { + "type": "text", + "placeholders": {} + }, + "id": "ID", + "@id": { + "type": "text", + "placeholders": {} + }, + "identity": "Identitet", + "@identity": { + "type": "text", + "placeholders": {} + }, + "ignore": "Ignorera", + "@ignore": { + "type": "text", + "placeholders": {} + }, + "ignoredUsers": "Ignorera användare", + "@ignoredUsers": { + "type": "text", + "placeholders": {} + }, + "ignoreListDescription": "Du kan ignorera användare som stör dig. Du kommer inte att ha möjlighet att få några meddelanden eller rums-inbjudningar från användare på din personliga ignoreringslista.", + "@ignoreListDescription": { + "type": "text", + "placeholders": {} + }, + "ignoreUsername": "Ignorera användarnamn", + "@ignoreUsername": { + "type": "text", + "placeholders": {} + }, + "iHaveClickedOnLink": "Jag har klickat på länken", + "@iHaveClickedOnLink": { + "type": "text", + "placeholders": {} + }, + "incorrectPassphraseOrKey": "Felaktig lösenordsfras eller åsterställningsnyckel", + "@incorrectPassphraseOrKey": { + "type": "text", + "placeholders": {} + }, + "inoffensive": "Oförargligt", + "@inoffensive": { + "type": "text", + "placeholders": {} + }, + "inviteContact": "Bjud in kontakt", + "@inviteContact": { + "type": "text", + "placeholders": {} + }, + "inviteContactToGroup": "Bjud in kontakt till {groupName}", + "@inviteContactToGroup": { + "type": "text", + "placeholders": { + "groupName": {} + } + }, + "invited": "Inbjuden", + "@invited": { + "type": "text", + "placeholders": {} + }, + "invitedUser": "📩 {username} bjöd in {targetName}", + "@invitedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "invitedUsersOnly": "Endast inbjudna användare", + "@invitedUsersOnly": { + "type": "text", + "placeholders": {} + }, + "inviteForMe": "Inbjudning till mig", + "@inviteForMe": { + "type": "text", + "placeholders": {} + }, + "inviteText": "{username} bjöd in dig till FluffyChat. \n1. Installera FluffyChat: https://fluffychat.im \n2. Registrera dig eller logga in \n3. Öppna inbjudningslänk: {link}", + "@inviteText": { + "type": "text", + "placeholders": { + "username": {}, + "link": {} + } + }, + "isTyping": "skriver…", + "@isTyping": { + "type": "text", + "placeholders": {} + }, + "joinedTheChat": "👋 {username} anslöt till chatten", + "@joinedTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "joinRoom": "Anslut till rum", + "@joinRoom": { + "type": "text", + "placeholders": {} + }, + "kicked": "👞 {username} sparkade ut {targetName}", + "@kicked": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "kickedAndBanned": "🙅 {username} sparkade och bannade {targetName}", + "@kickedAndBanned": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "kickFromChat": "Sparka från chatt", + "@kickFromChat": { + "type": "text", + "placeholders": {} + }, + "lastActiveAgo": "Senast aktiv: {localizedTimeShort}", + "@lastActiveAgo": { + "type": "text", + "placeholders": { + "localizedTimeShort": {} + } + }, + "lastSeenLongTimeAgo": "Sågs för längesedan", + "@lastSeenLongTimeAgo": { + "type": "text", + "placeholders": {} + }, + "leave": "Lämna", + "@leave": { + "type": "text", + "placeholders": {} + }, + "leftTheChat": "Lämnade chatten", + "@leftTheChat": { + "type": "text", + "placeholders": {} + }, + "license": "Licens", + "@license": { + "type": "text", + "placeholders": {} + }, + "lightTheme": "Ljust", + "@lightTheme": { + "type": "text", + "placeholders": {} + }, + "loadCountMoreParticipants": "Ladda {count} mer deltagare", + "@loadCountMoreParticipants": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "loadingPleaseWait": "Laddar... Var god vänta.", + "@loadingPleaseWait": { + "type": "text", + "placeholders": {} + }, + "loadMore": "Ladda mer…", + "@loadMore": { + "type": "text", + "placeholders": {} + }, + "login": "Logga in", + "@login": { + "type": "text", + "placeholders": {} + }, + "logInTo": "Logga in till {homeserver}", + "@logInTo": { + "type": "text", + "placeholders": { + "homeserver": {} + } + }, + "logout": "Logga ut", + "@logout": { + "type": "text", + "placeholders": {} + }, + "makeSureTheIdentifierIsValid": "Se till att identifieraren är giltig", + "@makeSureTheIdentifierIsValid": { + "type": "text", + "placeholders": {} + }, + "memberChanges": "Medlemsändringar", + "@memberChanges": { + "type": "text", + "placeholders": {} + }, + "mention": "Nämn", + "@mention": { + "type": "text", + "placeholders": {} + }, + "messages": "Meddelanden", + "@messages": { + "type": "text", + "placeholders": {} + }, + "messageWillBeRemovedWarning": "Meddelandet kommer tas bort för alla deltagare", + "@messageWillBeRemovedWarning": { + "type": "text", + "placeholders": {} + }, + "moderator": "Moderator", + "@moderator": { + "type": "text", + "placeholders": {} + }, + "muteChat": "Tysta chatt", + "@muteChat": { + "type": "text", + "placeholders": {} + }, + "needPantalaimonWarning": "Var medveten om att du behöver Pantalaimon för att använda ändpunktskryptering tillsvidare.", + "@needPantalaimonWarning": { + "type": "text", + "placeholders": {} + }, + "newChat": "Ny chatt", + "@newChat": { + "type": "text", + "placeholders": {} + }, + "newMessageInFluffyChat": "💬 Nya meddelanden i FluffyChat", + "@newMessageInFluffyChat": { + "type": "text", + "placeholders": {} + }, + "newVerificationRequest": "Ny verifikationsbegäran!", + "@newVerificationRequest": { + "type": "text", + "placeholders": {} + }, + "next": "Nästa", + "@next": { + "type": "text", + "placeholders": {} + }, + "no": "Nej", + "@no": { + "type": "text", + "placeholders": {} + }, + "noConnectionToTheServer": "Ingen anslutning till servern", + "@noConnectionToTheServer": { + "type": "text", + "placeholders": {} + }, + "noEmotesFound": "Hittade inga dekaler. 😕", + "@noEmotesFound": { + "type": "text", + "placeholders": {} + }, + "noGoogleServicesWarning": "De ser ut som att du inte har google-tjänster på din telefon. Det är ett bra beslut för din integritet! För att få push notifikationer i FluffyChat rekommenderar vi att använda https://microg.org/ eller https://unifiedpush.org/ .", + "@noGoogleServicesWarning": { + "type": "text", + "placeholders": {} + }, + "none": "Ingen", + "@none": { + "type": "text", + "placeholders": {} + }, + "noPasswordRecoveryDescription": "Du har inte lagt till något sätt för att återställa ditt lösenord än.", + "@noPasswordRecoveryDescription": { + "type": "text", + "placeholders": {} + }, + "noPermission": "Ingen behörighet", + "@noPermission": { + "type": "text", + "placeholders": {} + }, + "noRoomsFound": "Hittade inga rum…", + "@noRoomsFound": { + "type": "text", + "placeholders": {} + }, + "notifications": "Aviseringar", + "@notifications": { + "type": "text", + "placeholders": {} + }, + "notificationsEnabledForThisAccount": "Notifikationer är påslaget för detta konto", + "@notificationsEnabledForThisAccount": { + "type": "text", + "placeholders": {} + }, + "numUsersTyping": "{count} användare skriver…", + "@numUsersTyping": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "offensive": "Stötande", + "@offensive": { + "type": "text", + "placeholders": {} + }, + "offline": "Offline", + "@offline": { + "type": "text", + "placeholders": {} + }, + "ok": "OK", + "@ok": { + "type": "text", + "placeholders": {} + }, + "online": "Online", + "@online": { + "type": "text", + "placeholders": {} + }, + "onlineKeyBackupEnabled": "Online Nyckel-backup är aktiverad", + "@onlineKeyBackupEnabled": { + "type": "text", + "placeholders": {} + }, + "oopsSomethingWentWrong": "Hoppsan, något gick fel…", + "@oopsSomethingWentWrong": { + "type": "text", + "placeholders": {} + }, + "openAppToReadMessages": "Öppna app för att lästa meddelanden", + "@openAppToReadMessages": { + "type": "text", + "placeholders": {} + }, + "openCamera": "Öppna kamera", + "@openCamera": { + "type": "text", + "placeholders": {} + }, + "optionalGroupName": "(Optional) Gruppnamn", + "@optionalGroupName": { + "type": "text", + "placeholders": {} + }, + "participant": "Deltagare", + "@participant": { + "type": "text", + "placeholders": {} + }, + "passphraseOrKey": "lösenord eller återställningsnyckel", + "@passphraseOrKey": { + "type": "text", + "placeholders": {} + }, + "password": "Lösenord", + "@password": { + "type": "text", + "placeholders": {} + }, + "passwordForgotten": "Glömt lösenord", + "@passwordForgotten": { + "type": "text", + "placeholders": {} + }, + "passwordHasBeenChanged": "Lösenordet har ändrats", + "@passwordHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "passwordRecovery": "Återställ lösenord", + "@passwordRecovery": { + "type": "text", + "placeholders": {} + }, + "pickImage": "Välj en bild", + "@pickImage": { + "type": "text", + "placeholders": {} + }, + "pin": "Nåla fast", + "@pin": { + "type": "text", + "placeholders": {} + }, + "play": "Spela {fileName}", + "@play": { + "type": "text", + "placeholders": { + "fileName": {} + } + }, + "pleaseChooseAPasscode": "Ange ett lösenord", + "@pleaseChooseAPasscode": { + "type": "text", + "placeholders": {} + }, + "pleaseChooseAUsername": "Välj ett användarnamn", + "@pleaseChooseAUsername": { + "type": "text", + "placeholders": {} + }, + "pleaseClickOnLink": "Klicka på länken i e-postmeddelandet för att sedan fortsätta.", + "@pleaseClickOnLink": { + "type": "text", + "placeholders": {} + }, + "pleaseEnter4Digits": "Ange 4 siffror eller lämna tom för att inaktivera app-lås.", + "@pleaseEnter4Digits": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterAMatrixIdentifier": "Ange ditt Matrix ID.", + "@pleaseEnterAMatrixIdentifier": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourPassword": "Ange ditt lösenord", + "@pleaseEnterYourPassword": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourUsername": "Ange ditt användarnamn", + "@pleaseEnterYourUsername": { + "type": "text", + "placeholders": {} + }, + "pleaseFollowInstructionsOnWeb": "Följ instruktionerna på hemsidan och tryck på nästa.", + "@pleaseFollowInstructionsOnWeb": { + "type": "text", + "placeholders": {} + }, + "privacy": "Integritet", + "@privacy": { + "type": "text", + "placeholders": {} + }, + "publicRooms": "Publika Rum", + "@publicRooms": { + "type": "text", + "placeholders": {} + }, + "pushRules": "Push regler", + "@pushRules": { + "type": "text", + "placeholders": {} + }, + "reason": "Anledning", + "@reason": { + "type": "text", + "placeholders": {} + }, + "recording": "Spelar in", + "@recording": { + "type": "text", + "placeholders": {} + }, + "redactedAnEvent": "{username} redigerade en händelse", + "@redactedAnEvent": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "redactMessage": "Redigera meddelande", + "@redactMessage": { + "type": "text", + "placeholders": {} + }, + "reject": "Avböj", + "@reject": { + "type": "text", + "placeholders": {} + }, + "rejectedTheInvitation": "{username} avböjde inbjudan", + "@rejectedTheInvitation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "rejoin": "Återanslut", + "@rejoin": { + "type": "text", + "placeholders": {} + }, + "remove": "Ta bort", + "@remove": { + "type": "text", + "placeholders": {} + }, + "removeAllOtherDevices": "Ta bort alla andra enheter", + "@removeAllOtherDevices": { + "type": "text", + "placeholders": {} + }, + "removedBy": "Bortagen av {username}", + "@removedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "removeDevice": "Ta bort enhet", + "@removeDevice": { + "type": "text", + "placeholders": {} + }, + "unbanFromChat": "Ta bort chatt-blockering", + "@unbanFromChat": { + "type": "text", + "placeholders": {} + }, + "renderRichContent": "Återge innehåll med rikt meddelande", + "@renderRichContent": { + "type": "text", + "placeholders": {} + }, + "replaceRoomWithNewerVersion": "Ersätt rum med nyare version", + "@replaceRoomWithNewerVersion": { + "type": "text", + "placeholders": {} + }, + "reply": "Svara", + "@reply": { + "type": "text", + "placeholders": {} + }, + "reportMessage": "Rapportera meddelande", + "@reportMessage": { + "type": "text", + "placeholders": {} + }, + "requestPermission": "Begär behörighet", + "@requestPermission": { + "type": "text", + "placeholders": {} + }, + "roomHasBeenUpgraded": "Rummet har blivit uppgraderat", + "@roomHasBeenUpgraded": { + "type": "text", + "placeholders": {} + }, + "search": "Sök", + "@search": { + "type": "text", + "placeholders": {} + }, + "security": "Säkerhet", + "@security": { + "type": "text", + "placeholders": {} + }, + "seenByUser": "Sedd av {username}", + "@seenByUser": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "seenByUserAndCountOthers": "{count, plural, other{Sedd av {username} och {count} andra}}", + "@seenByUserAndCountOthers": { + "type": "text", + "placeholders": { + "username": {}, + "count": {} + } + }, + "seenByUserAndUser": "Sedd av {username} och {username2}", + "@seenByUserAndUser": { + "type": "text", + "placeholders": { + "username": {}, + "username2": {} + } + }, + "send": "Skicka", + "@send": { + "type": "text", + "placeholders": {} + }, + "sendAMessage": "Skicka ett meddelande", + "@sendAMessage": { + "type": "text", + "placeholders": {} + }, + "sendAudio": "Skicka ljud", + "@sendAudio": { + "type": "text", + "placeholders": {} + }, + "sendFile": "Skicka fil", + "@sendFile": { + "type": "text", + "placeholders": {} + }, + "sendImage": "Skicka bild", + "@sendImage": { + "type": "text", + "placeholders": {} + }, + "sendMessages": "Skickade meddelanden", + "@sendMessages": { + "type": "text", + "placeholders": {} + }, + "sendOriginal": "Skicka orginal", + "@sendOriginal": { + "type": "text", + "placeholders": {} + }, + "sendVideo": "Skicka video", + "@sendVideo": { + "type": "text", + "placeholders": {} + }, + "sentAFile": "📁 {username} skickade en fil", + "@sentAFile": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sentAnAudio": "🎤 {username} skickade ett ljudklipp", + "@sentAnAudio": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sentAPicture": "🖼️ {username} skickade en bild", + "@sentAPicture": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sentASticker": "😊 {username} skickade ett klistermärke", + "@sentASticker": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sentAVideo": "🎥 {username} skickade en video", + "@sentAVideo": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sentCallInformations": "{senderName} skickade samtalsinformation", + "@sentCallInformations": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "setCustomEmotes": "Ställ in anpassade dekaler", + "@setCustomEmotes": { + "type": "text", + "placeholders": {} + }, + "setGroupDescription": "Ställ in gruppbeskrivning", + "@setGroupDescription": { + "type": "text", + "placeholders": {} + }, + "setInvitationLink": "Ställ in inbjudningslänk", + "@setInvitationLink": { + "type": "text", + "placeholders": {} + }, + "setPermissionsLevel": "Ställ in behörighetsnivå", + "@setPermissionsLevel": { + "type": "text", + "placeholders": {} + }, + "setStatus": "Ställ in status", + "@setStatus": { + "type": "text", + "placeholders": {} + }, + "settings": "Inställningar", + "@settings": { + "type": "text", + "placeholders": {} + }, + "share": "Dela", + "@share": { + "type": "text", + "placeholders": {} + }, + "sharedTheLocation": "{username} delade sin position", + "@sharedTheLocation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "signUp": "Registrera", + "@signUp": { + "type": "text", + "placeholders": {} + }, + "skip": "Hoppa över", + "@skip": { + "type": "text", + "placeholders": {} + }, + "sourceCode": "Källkod", + "@sourceCode": { + "type": "text", + "placeholders": {} + }, + "startedACall": "{senderName} startade ett samtal", + "@startedACall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "status": "Status", + "@status": { + "type": "text", + "placeholders": {} + }, + "statusExampleMessage": "Hur mår du i dag?", + "@statusExampleMessage": { + "type": "text", + "placeholders": {} + }, + "submit": "Skicka in", + "@submit": { + "type": "text", + "placeholders": {} + }, + "systemTheme": "System", + "@systemTheme": { + "type": "text", + "placeholders": {} + }, + "theyDontMatch": "Dom Matchar Inte", + "@theyDontMatch": { + "type": "text", + "placeholders": {} + }, + "theyMatch": "Dom Matchar", + "@theyMatch": { + "type": "text", + "placeholders": {} + }, + "title": "FluffyChat", + "@title": { + "description": "Title for the application", + "type": "text", + "placeholders": {} + }, + "toggleFavorite": "Växla favorit", + "@toggleFavorite": { + "type": "text", + "placeholders": {} + }, + "toggleMuted": "Växla tystad", + "@toggleMuted": { + "type": "text", + "placeholders": {} + }, + "toggleUnread": "Markera läst/oläst", + "@toggleUnread": { + "type": "text", + "placeholders": {} + }, + "tooManyRequestsWarning": "För många förfrågningar. Vänligen försök senare!", + "@tooManyRequestsWarning": { + "type": "text", + "placeholders": {} + }, + "tryToSendAgain": "Försök att skicka igen", + "@tryToSendAgain": { + "type": "text", + "placeholders": {} + }, + "unavailable": "Upptagen", + "@unavailable": { + "type": "text", + "placeholders": {} + }, + "unbannedUser": "{username} avbannade {targetName}", + "@unbannedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "unblockDevice": "Avblockera enhet", + "@unblockDevice": { + "type": "text", + "placeholders": {} + }, + "unknownDevice": "Okänd enhet", + "@unknownDevice": { + "type": "text", + "placeholders": {} + }, + "unknownEncryptionAlgorithm": "Okänd krypteringsalgoritm", + "@unknownEncryptionAlgorithm": { + "type": "text", + "placeholders": {} + }, + "unknownEvent": "Okänd händelse '{type}'", + "@unknownEvent": { + "type": "text", + "placeholders": { + "type": {} + } + }, + "unmuteChat": "Slå på ljudet för chatten", + "@unmuteChat": { + "type": "text", + "placeholders": {} + }, + "unpin": "Avnåla", + "@unpin": { + "type": "text", + "placeholders": {} + }, + "unreadChats": "{unreadCount, plural, =1{en oläst chatt} other{{unreadCount} olästa chattar}}", + "@unreadChats": { + "type": "text", + "placeholders": { + "unreadCount": {} + } + }, + "userAndOthersAreTyping": "{username} och {count} andra skriver…", + "@userAndOthersAreTyping": { + "type": "text", + "placeholders": { + "username": {}, + "count": {} + } + }, + "userAndUserAreTyping": "{username} och {username2} skriver…", + "@userAndUserAreTyping": { + "type": "text", + "placeholders": { + "username": {}, + "username2": {} + } + }, + "userIsTyping": "{username} skriver…", + "@userIsTyping": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "userLeftTheChat": "🚪 {username} lämnade chatten", + "@userLeftTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "username": "Användarnamn", + "@username": { + "type": "text", + "placeholders": {} + }, + "userSentUnknownEvent": "{username} skickade en {type} händelse", + "@userSentUnknownEvent": { + "type": "text", + "placeholders": { + "username": {}, + "type": {} + } + }, + "verify": "Verifiera", + "@verify": { + "type": "text", + "placeholders": {} + }, + "verifyStart": "Starta verifiering", + "@verifyStart": { + "type": "text", + "placeholders": {} + }, + "verifySuccess": "Du har lyckats verifiera!", + "@verifySuccess": { + "type": "text", + "placeholders": {} + }, + "verifyTitle": "Verifiera andra konton", + "@verifyTitle": { + "type": "text", + "placeholders": {} + }, + "videoCall": "Videosamtal", + "@videoCall": { + "type": "text", + "placeholders": {} + }, + "visibilityOfTheChatHistory": "Chatt-historikens synlighet", + "@visibilityOfTheChatHistory": { + "type": "text", + "placeholders": {} + }, + "visibleForAllParticipants": "Synlig för alla deltagare", + "@visibleForAllParticipants": { + "type": "text", + "placeholders": {} + }, + "visibleForEveryone": "Synlig för alla", + "@visibleForEveryone": { + "type": "text", + "placeholders": {} + }, + "voiceMessage": "Röstmeddelande", + "@voiceMessage": { + "type": "text", + "placeholders": {} + }, + "waitingPartnerAcceptRequest": "Väntar på att deltagaren accepterar begäran…", + "@waitingPartnerAcceptRequest": { + "type": "text", + "placeholders": {} + }, + "waitingPartnerEmoji": "Väntar på att deltagaren accepterar emojien…", + "@waitingPartnerEmoji": { + "type": "text", + "placeholders": {} + }, + "waitingPartnerNumbers": "Väntar på att deltagaren accepterar nummer…", + "@waitingPartnerNumbers": { + "type": "text", + "placeholders": {} + }, + "wallpaper": "Bakgrund", + "@wallpaper": { + "type": "text", + "placeholders": {} + }, + "warning": "Varning!", + "@warning": { + "type": "text", + "placeholders": {} + }, + "weSentYouAnEmail": "Vi skickade dig ett e-postmeddelande", + "@weSentYouAnEmail": { + "type": "text", + "placeholders": {} + }, + "whoCanPerformWhichAction": "Vem kan utföra vilken åtgärd", + "@whoCanPerformWhichAction": { + "type": "text", + "placeholders": {} + }, + "whoIsAllowedToJoinThisGroup": "Vilka som är tilllåtna att ansluta till denna grupp", + "@whoIsAllowedToJoinThisGroup": { + "type": "text", + "placeholders": {} + }, + "whyDoYouWantToReportThis": "Varför vill du rapportera detta?", + "@whyDoYouWantToReportThis": { + "type": "text", + "placeholders": {} + }, + "withTheseAddressesRecoveryDescription": "Med dessa addresser kan du återställa ditt lösenord.", + "@withTheseAddressesRecoveryDescription": { + "type": "text", + "placeholders": {} + }, + "writeAMessage": "Skriv ett meddelande…", + "@writeAMessage": { + "type": "text", + "placeholders": {} + }, + "yes": "Ja", + "@yes": { + "type": "text", + "placeholders": {} + }, + "you": "Du", + "@you": { + "type": "text", + "placeholders": {} + }, + "youAreInvitedToThisChat": "Du är inbjuden till denna chatt", + "@youAreInvitedToThisChat": { + "type": "text", + "placeholders": {} + }, + "youAreNoLongerParticipatingInThisChat": "Du deltar inte längre i denna chatt", + "@youAreNoLongerParticipatingInThisChat": { + "type": "text", + "placeholders": {} + }, + "youCannotInviteYourself": "Du kan inte bjuda in dig själv", + "@youCannotInviteYourself": { + "type": "text", + "placeholders": {} + }, + "youHaveBeenBannedFromThisChat": "Du har blivit bannad från denna chatt", + "@youHaveBeenBannedFromThisChat": { + "type": "text", + "placeholders": {} + }, + "yourPublicKey": "Din publika nyckel", + "@yourPublicKey": { + "type": "text", + "placeholders": {} + }, + "commandHint_html": "Skicka HTML-formatted text", + "@commandHint_html": { + "type": "text", + "description": "Usage hint for the command /html" + }, + "commandHint_ban": "Bannlys användaren från detta rum", + "@commandHint_ban": { + "type": "text", + "description": "Usage hint for the command /ban" + }, + "clearArchive": "Rensa arkiv", + "@clearArchive": {}, + "chats": "Chatter", + "@chats": { + "type": "text", + "placeholders": {} + }, + "chatHasBeenAddedToThisSpace": "Chatt har lagts till i detta utrymme", + "@chatHasBeenAddedToThisSpace": {}, + "chatBackup": "Chatt backup", + "@chatBackup": { + "type": "text", + "placeholders": {} + }, + "changeYourAvatar": "Ändra din avatar", + "@changeYourAvatar": { + "type": "text", + "placeholders": {} + }, + "cantOpenUri": "Kan inte öppna URL {uri}", + "@cantOpenUri": { + "type": "text", + "placeholders": { + "uri": {} + } + }, + "blocked": "Blockerad", + "@blocked": { + "type": "text", + "placeholders": {} + }, + "badServerLoginTypesException": "Hemma servern stödjer följande inloggnings typer :\n {serverVersions}\nMen denna applikation stödjer enbart:\n{supportedVersions}", + "@badServerLoginTypesException": { + "type": "text", + "placeholders": { + "serverVersions": {}, + "supportedVersions": {} + } + }, + "autoplayImages": "Automatisk spela upp animerade klistermärken och emoji", + "@autoplayImages": { + "type": "text", + "placeholder": {} + }, + "allChats": "Alla chattar", + "@allChats": { + "type": "text", + "placeholders": {} + }, + "addToSpace": "Lägg till i utrymme", + "@addToSpace": {}, + "addEmail": "Lägg till e-post", + "@addEmail": { + "type": "text", + "placeholders": {} + }, + "commandHint_myroomavatar": "Sätt din bild för detta rum (by mxc-uri)", + "@commandHint_myroomavatar": { + "type": "text", + "description": "Usage hint for the command /myroomavatar" + }, + "commandHint_me": "Beskriv dig själv", + "@commandHint_me": { + "type": "text", + "description": "Usage hint for the command /me" + }, + "commandHint_leave": "Lämna detta rum", + "@commandHint_leave": { + "type": "text", + "description": "Usage hint for the command /leave" + }, + "commandHint_kick": "Ta bort användare från detta rum", + "@commandHint_kick": { + "type": "text", + "description": "Usage hint for the command /kick" + }, + "commandHint_join": "Gå med i rum", + "@commandHint_join": { + "type": "text", + "description": "Usage hint for the command /join" + }, + "commandHint_invite": "Bjud in användaren till detta rum", + "@commandHint_invite": { + "type": "text", + "description": "Usage hint for the command /invite" + }, + "locationPermissionDeniedNotice": "Plats åtkomst nekad. Var god godkän detta för att kunna dela din plats.", + "@locationPermissionDeniedNotice": { + "type": "text", + "placeholders": {} + }, + "locationDisabledNotice": "Platstjänster är inaktiverade. Var god aktivera dom för att kunna dela din plats.", + "@locationDisabledNotice": { + "type": "text", + "placeholders": {} + }, + "goToTheNewRoom": "Gå till det nya rummet", + "@goToTheNewRoom": { + "type": "text", + "placeholders": {} + }, + "fontSize": "Teckensnitt storlek", + "@fontSize": { + "type": "text", + "placeholders": {} + }, + "everythingReady": "Allt är klart!", + "@everythingReady": { + "type": "text", + "placeholders": {} + }, + "errorObtainingLocation": "Fel vid erhållande av plats: {error}", + "@errorObtainingLocation": { + "type": "text", + "placeholders": { + "error": {} + } + }, + "enterASpacepName": "Ange utrymmets namn", + "@enterASpacepName": {}, + "editRoomAliases": "Redigera rum alias", + "@editRoomAliases": { + "type": "text", + "placeholders": {} + }, + "createNewSpace": "Nytt utrymme", + "@createNewSpace": { + "type": "text", + "placeholders": {} + }, + "copyToClipboard": "Kopiera till urklipp", + "@copyToClipboard": { + "type": "text", + "placeholders": {} + }, + "commandMissing": "{command} är inte ett kommando.", + "@commandMissing": { + "type": "text", + "placeholders": { + "command": {} + }, + "description": "State that {command} is not a valid /command." + }, + "commandInvalid": "Felaktigt kommando", + "@commandInvalid": { + "type": "text" + }, + "commandHint_unban": "Tillåt användare i rummet", + "@commandHint_unban": { + "type": "text", + "description": "Usage hint for the command /unban" + }, + "commandHint_send": "Skicka text", + "@commandHint_send": { + "type": "text", + "description": "Usage hint for the command /send" + }, + "commandHint_react": "Skicka svar som reaktion", + "@commandHint_react": { + "type": "text", + "description": "Usage hint for the command /react" + }, + "commandHint_plain": "Skicka oformaterad text", + "@commandHint_plain": { + "type": "text", + "description": "Usage hint for the command /plain" + }, + "commandHint_op": "Sätt användarens kraft nivå ( standard: 50)", + "@commandHint_op": { + "type": "text", + "description": "Usage hint for the command /op" + }, + "commandHint_myroomnick": "Sätt ditt användarnamn för rummet", + "@commandHint_myroomnick": { + "type": "text", + "description": "Usage hint for the command /myroomnick" + }, + "noEncryptionForPublicRooms": "Du kan endast aktivera kryptering när rummet inte längre är publikt tillgängligt.", + "@noEncryptionForPublicRooms": { + "type": "text", + "placeholders": {} + }, + "loginWith": "Logga in med {brand}", + "@loginWith": { + "type": "text", + "placeholders": { + "brand": {} + } + }, + "noMatrixServer": "{server1} är inte en matrix server, använd {server2} istället?", + "@noMatrixServer": { + "type": "text", + "placeholders": { + "server1": {}, + "server2": {} + } + }, + "obtainingLocation": "Erhåller plats…", + "@obtainingLocation": { + "type": "text", + "placeholders": {} + }, + "pleaseChoose": "Var god välj", + "@pleaseChoose": { + "type": "text", + "placeholders": {} + }, + "people": "Människor", + "@people": { + "type": "text", + "placeholders": {} + }, + "or": "Eller", + "@or": { + "type": "text", + "placeholders": {} + }, + "openInMaps": "Öppna i karta", + "@openInMaps": { + "type": "text", + "placeholders": {} + }, + "oopsPushError": "Oj! Tyvärr uppstod ett fel vid upprättande av push notiser.", + "@oopsPushError": { + "type": "text", + "placeholders": {} + }, + "synchronizingPleaseWait": "Synkroniserar… Var god vänta.", + "@synchronizingPleaseWait": { + "type": "text", + "placeholders": {} + }, + "spaceName": "Utrymmes namn", + "@spaceName": { + "type": "text", + "placeholders": {} + }, + "spaceIsPublic": "Utrymme är publikt", + "@spaceIsPublic": { + "type": "text", + "placeholders": {} + }, + "showPassword": "Visa lösenord", + "@showPassword": { + "type": "text", + "placeholders": {} + }, + "shareLocation": "Dela plats", + "@shareLocation": { + "type": "text", + "placeholders": {} + }, + "setAsCanonicalAlias": "Sätt som primärt alias", + "@setAsCanonicalAlias": { + "type": "text", + "placeholders": {} + }, + "sendSticker": "Skicka klistermärke", + "@sendSticker": { + "type": "text", + "placeholders": {} + }, + "sendAsText": "Skicka som text", + "@sendAsText": { + "type": "text" + }, + "saveFile": "Spara fil", + "@saveFile": { + "type": "text", + "placeholders": {} + }, + "roomVersion": "Rum version", + "@roomVersion": { + "type": "text", + "placeholders": {} + }, + "removeYourAvatar": "Ta bort din avatar", + "@removeYourAvatar": { + "type": "text", + "placeholders": {} + }, + "register": "Registrera", + "@register": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourPin": "Ange din pin-kod", + "@pleaseEnterYourPin": { + "type": "text", + "placeholders": {} + }, + "wipeChatBackup": "Radera din chatt-backup för att skapa en ny återställningsnyckel?", + "@wipeChatBackup": { + "type": "text", + "placeholders": {} + }, + "verified": "Verifierad", + "@verified": { + "type": "text", + "placeholders": {} + }, + "transferFromAnotherDevice": "Överför till annan enhet", + "@transferFromAnotherDevice": { + "type": "text", + "placeholders": {} + }, + "shareYourInviteLink": "Dela din inbjudan", + "@shareYourInviteLink": {}, + "chatBackupDescription": "Din chatt backup är skyddad av en säkerhetsnyckel. Se till att du inte förlorar den.", + "@chatBackupDescription": { + "type": "text", + "placeholders": {} + }, + "commandHint_create": "Skapa en tom grupp-chatt\nAnvänd --no-encryption för att inaktivera kryptering", + "@commandHint_create": { + "type": "text", + "description": "Usage hint for the command /create" + }, + "commandHint_discardsession": "Kasta bort sessionen", + "@commandHint_discardsession": { + "type": "text", + "description": "Usage hint for the command /discardsession" + }, + "commandHint_dm": "Starta en direkt-chatt\nAnvänd --no-encryption för att inaktivera kryptering", + "@commandHint_dm": { + "type": "text", + "description": "Usage hint for the command /dm" + }, + "homeserver": "Hemserver", + "@homeserver": {}, + "oneClientLoggedOut": "En av dina klienter har loggats ut", + "@oneClientLoggedOut": {}, + "addAccount": "Lägg till konto", + "@addAccount": {}, + "editBundlesForAccount": "Lägg till paket för detta konto", + "@editBundlesForAccount": {}, + "addToBundle": "Utöka paket", + "@addToBundle": {}, + "bundleName": "Paketnamn", + "@bundleName": {}, + "serverRequiresEmail": "Servern behöver validera din e-postadress för registrering.", + "@serverRequiresEmail": {}, + "singlesignon": "Single Sign On", + "@singlesignon": { + "type": "text", + "placeholders": {} + }, + "unverified": "Ej verifierad", + "@unverified": {}, + "messageInfo": "Meddelandeinformation", + "@messageInfo": {}, + "messageType": "Meddelandetyp", + "@messageType": {}, + "time": "Tid", + "@time": {}, + "sender": "Avsändare", + "@sender": {}, + "removeFromSpace": "Ta bort från utrymme", + "@removeFromSpace": {}, + "addToSpaceDescription": "Välj ett utrymme som chatten skall läggas till i.", + "@addToSpaceDescription": {}, + "start": "Starta", + "@start": {}, + "iUnderstand": "Jag förstår", + "@iUnderstand": {}, + "yourStory": "Din berättelse", + "@yourStory": {}, + "openGallery": "Öppna galleri", + "@openGallery": {}, + "storyFrom": "Berättelse från {date}: \n{body}", + "@storyFrom": { + "type": "text", + "placeholders": { + "date": {}, + "body": {} + } + }, + "passwordsDoNotMatch": "Lösenorden stämmer inte överens!", + "@passwordsDoNotMatch": {}, + "repeatPassword": "Upprepa lösenord", + "@repeatPassword": {}, + "pleaseChooseAtLeastChars": "Vänligen ange minst {min} tecken.", + "@pleaseChooseAtLeastChars": { + "type": "text", + "placeholders": { + "min": {} + } + }, + "markAsRead": "Markera som läst", + "@markAsRead": {}, + "commandHint_clearcache": "Rensa cache", + "@commandHint_clearcache": { + "type": "text", + "description": "Usage hint for the command /clearcache" + }, + "openVideoCamera": "Aktivera kamera för video", + "@openVideoCamera": { + "type": "text", + "placeholders": {} + }, + "link": "Länk", + "@link": {}, + "publish": "Publicera", + "@publish": {}, + "unsubscribeStories": "Avprenumerera berättelser", + "@unsubscribeStories": {}, + "replyHasBeenSent": "Svar har skickats", + "@replyHasBeenSent": {}, + "videoWithSize": "Video ({size})", + "@videoWithSize": { + "type": "text", + "placeholders": { + "size": {} + } + }, + "whatIsGoingOn": "Vad händer?", + "@whatIsGoingOn": {}, + "addDescription": "Lägg till beskrivning", + "@addDescription": {}, + "reportUser": "Rapportera användare", + "@reportUser": {}, + "openChat": "Öppna Chatt", + "@openChat": {}, + "sendOnEnter": "Skicka med Enter", + "@sendOnEnter": {}, + "addToStory": "Addera till berättelse", + "@addToStory": {}, + "pleaseEnterValidEmail": "Vänligen ange en giltig e-postadress.", + "@pleaseEnterValidEmail": {}, + "scanQrCode": "Skanna QR-kod", + "@scanQrCode": {}, + "bubbleSize": "Storlek på bubbla", + "@bubbleSize": { + "type": "text", + "placeholders": {} + }, + "yourChatBackupHasBeenSetUp": "Din chatt-backup har konfigurerats.", + "@yourChatBackupHasBeenSetUp": {}, + "loginWithOneClick": "Logga in med ett klick", + "@loginWithOneClick": {}, + "removeFromBundle": "Ta bort från paket", + "@removeFromBundle": {}, + "enableMultiAccounts": "(BETA) Aktivera multi-konton på denna enhet", + "@enableMultiAccounts": {}, + "whoCanSeeMyStories": "Vem kan se mina berättelser?", + "@whoCanSeeMyStories": {}, + "whoCanSeeMyStoriesDesc": "Notera att användare kan se och kontakta varandra i din berättelse.", + "@whoCanSeeMyStoriesDesc": {}, + "thisUserHasNotPostedAnythingYet": "Den här användaren har inte lagt till något till deras berättelse än", + "@thisUserHasNotPostedAnythingYet": {}, + "storyPrivacyWarning": "Notera att användare kan se och kontakta varandra i din berättelse. Din berättelse är synlig i 24 timmar, men det finns ingen garanti för att berättelser raderas från alla enheter och servrar.", + "@storyPrivacyWarning": {}, + "emojis": "Uttryckssymboler", + "@emojis": {}, + "placeCall": "Ring", + "@placeCall": {}, + "voiceCall": "Röstsamtal", + "@voiceCall": {}, + "unsupportedAndroidVersion": "Inget stöd för denna version av Android", + "@unsupportedAndroidVersion": {}, + "videoCallsBetaWarning": "Videosamtal är för närvarande under testning. De kanske inte fungerar som det är tänkt eller på alla plattformar.", + "@videoCallsBetaWarning": {}, + "unsupportedAndroidVersionLong": "Denna funktion kräver en senare version av Android.", + "@unsupportedAndroidVersionLong": {}, + "dismiss": "Avfärda", + "@dismiss": {}, + "matrixWidgets": "Matrix widgetar", + "@matrixWidgets": {}, + "reactedWith": "{sender} reagerade med {reaction}", + "@reactedWith": { + "type": "text", + "placeholders": { + "sender": {}, + "reaction": {} + } + }, + "pinMessage": "Fäst i rum", + "@pinMessage": {}, + "confirmEventUnpin": "Är du säker på att händelsen inte längre skall vara fastnålad?", + "@confirmEventUnpin": {}, + "experimentalVideoCalls": "Experimentella videosamtal", + "@experimentalVideoCalls": {}, + "switchToAccount": "Byt till konto {number}", + "@switchToAccount": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "nextAccount": "Nästa konto", + "@nextAccount": {}, + "previousAccount": "Föregående konto", + "@previousAccount": {}, + "emailOrUsername": "Användarnamn eller e-postadress", + "@emailOrUsername": {}, + "addWidget": "Lägg till widget", + "@addWidget": {}, + "widgetVideo": "Video", + "@widgetVideo": {}, + "widgetEtherpad": "Anteckning", + "@widgetEtherpad": {}, + "widgetCustom": "Anpassad", + "@widgetCustom": {}, + "widgetName": "Namn", + "@widgetName": {}, + "widgetUrlError": "Detta är inte en giltig URL.", + "@widgetUrlError": {}, + "errorAddingWidget": "Ett fel uppstod när widgeten skulle läggas till.", + "@errorAddingWidget": {}, + "editWidgets": "Redigera widgetar", + "@editWidgets": {}, + "widgetJitsi": "Jitsi-möte", + "@widgetJitsi": {}, + "widgetNameError": "Vänligen ange ett visningsnamn.", + "@widgetNameError": {}, + "storeSecurlyOnThisDevice": "Lagra säkert på denna enhet", + "@storeSecurlyOnThisDevice": {}, + "youJoinedTheChat": "Du gick med i chatten", + "@youJoinedTheChat": {}, + "youAcceptedTheInvitation": "👍 Du accepterade inbjudan", + "@youAcceptedTheInvitation": {}, + "youKicked": "👞 Du sparkade ut {user}", + "@youKicked": { + "placeholders": { + "user": {} + } + }, + "hugContent": "{senderName} kramar dig", + "@hugContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "commandHint_markasgroup": "Märk som grupp", + "@commandHint_markasgroup": {}, + "recoveryKeyLost": "Borttappad återställningsnyckel?", + "@recoveryKeyLost": {}, + "indexedDbErrorTitle": "Problem med privat läge", + "@indexedDbErrorTitle": {}, + "youHaveWithdrawnTheInvitationFor": "Du har återkallat inbjudan till {user}", + "@youHaveWithdrawnTheInvitationFor": { + "placeholders": { + "user": {} + } + }, + "youUnbannedUser": "Du återkallade förbudet för {user}", + "@youUnbannedUser": { + "placeholders": { + "user": {} + } + }, + "unlockOldMessages": "Lås upp äldre meddelanden", + "@unlockOldMessages": {}, + "newSpace": "Nytt utrymme", + "@newSpace": {}, + "googlyEyesContent": "{senderName} skickar dig googly ögon", + "@googlyEyesContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "dehydrate": "Exportera sessionen och rensa enheten", + "@dehydrate": {}, + "dehydrateWarning": "Denna åtgärd kan inte ångras. Försäkra dig om att backupen är i säkert förvar.", + "@dehydrateWarning": {}, + "dehydrateTor": "TOR-användare: Exportera session", + "@dehydrateTor": {}, + "hydrateTor": "TOR-användare: Importera session från tidigare export", + "@hydrateTor": {}, + "hydrateTorLong": "Exporterade du sessionen när du senast använde TOR? Importera den enkelt och fortsätt chatta.", + "@hydrateTorLong": {}, + "recoveryKey": "Återställningsnyckel", + "@recoveryKey": {}, + "separateChatTypes": "Separata direktchattar och grupper", + "@separateChatTypes": { + "type": "text", + "placeholders": {} + }, + "showDirectChatsInSpaces": "Visa relaterade direktchattar i utrymmen", + "@showDirectChatsInSpaces": { + "type": "text", + "placeholders": {} + }, + "startFirstChat": "Starta din första chatt", + "@startFirstChat": {}, + "pleaseEnterRecoveryKeyDescription": "Ange din återställningsnyckel från en tidigare session för att låsa upp äldre meddelanden. Din återställningsnyckel är INTE ditt lösenord.", + "@pleaseEnterRecoveryKeyDescription": {}, + "encryptThisChat": "Kryptera denna chatt", + "@encryptThisChat": {}, + "enterInviteLinkOrMatrixId": "Ange länk för inbjudan eller Matrix-ID...", + "@enterInviteLinkOrMatrixId": {}, + "dehydrateTorLong": "TOR-användare rekommenderas att exportera sessionen innan fönstret stängs.", + "@dehydrateTorLong": {}, + "noBackupWarning": "Varning! Om du inte aktiverar säkerhetskopiering av chattar så tappar du åtkomst till krypterade meddelanden. Det är rekommenderat att du aktiverar säkerhetskopiering innan du loggar ut.", + "@noBackupWarning": {}, + "noOtherDevicesFound": "Inga andra enheter hittades", + "@noOtherDevicesFound": {}, + "endToEndEncryption": "Totalsträckskryptering", + "@endToEndEncryption": {}, + "disableEncryptionWarning": "Av säkerhetsskäl kan du inte stänga av kryptering i en chatt där det tidigare aktiverats.", + "@disableEncryptionWarning": {}, + "sorryThatsNotPossible": "Det där är inte möjligt", + "@sorryThatsNotPossible": {}, + "confirmMatrixId": "Bekräfta ditt Matrix-ID för att radera ditt konto.", + "@confirmMatrixId": {}, + "updateAvailable": "FluffyChat-uppdatering tillgänglig", + "@updateAvailable": {}, + "updateNow": "Påbörja uppdatering i bakgrunden", + "@updateNow": {}, + "supposedMxid": "Detta bör vara {mxid}", + "@supposedMxid": { + "type": "text", + "placeholders": { + "mxid": {} + } + }, + "pleaseEnterRecoveryKey": "Ange din återställningsnyckel:", + "@pleaseEnterRecoveryKey": {}, + "commandHint_markasdm": "Märk som rum för direktmeddelanden", + "@commandHint_markasdm": {}, + "noEmailWarning": "Utan en giltig e-postadress kommer du inte kunna återställa ditt lösenord. Om du inte vill ange en e-postadress, tryck på knappen igen för att fortsätta.", + "@noEmailWarning": {}, + "user": "Användare", + "@user": {}, + "indexedDbErrorLong": "Meddelandelagring är tyvärr inte aktiverat i privat läge som standard.\nGå till\n - about:config\n - sätt dom.indexedDB.privateBrowsing.enabled till true\nAnnars går det inte att använda FluffyChat.", + "@indexedDbErrorLong": {}, + "storeInSecureStorageDescription": "Lagra återställningsnyckeln på säker plats på denna enhet.", + "@storeInSecureStorageDescription": {}, + "storeInAppleKeyChain": "Lagra i Apples nyckelkedja (KeyChain)", + "@storeInAppleKeyChain": {}, + "foregroundServiceRunning": "Denna notifikation visas när förgrundstjänsten körs.", + "@foregroundServiceRunning": {}, + "custom": "Anpassad", + "@custom": {}, + "countFiles": "{count} filer", + "@countFiles": { + "placeholders": { + "count": {} + } + }, + "screenSharingTitle": "skärmdelning", + "@screenSharingTitle": {}, + "noKeyForThisMessage": "Detta kan hända om meddelandet skickades innan du loggade in på ditt konto i den här enheten.\n\nDet kan också vara så att avsändaren har blockerat din enhet eller att något gick fel med internetanslutningen.\n\nKan du läsa meddelandet i en annan session? I sådana fall kan du överföra meddelandet från den sessionen! Gå till Inställningar > Enhet och säkerställ att dina enheter har verifierat varandra. När du öppnar rummet nästa gång och båda sessionerna är i förgrunden, så kommer nycklarna att överföras automatiskt.\n\nVill du inte förlora nycklarna vid utloggning eller när du byter enhet? Säkerställ att du har aktiverat säkerhetskopiering för chatten i inställningarna.", + "@noKeyForThisMessage": {}, + "fileIsTooBigForServer": "Servern informerar om att filen är för stor för att skickas.", + "@fileIsTooBigForServer": {}, + "deviceKeys": "Enhetsnycklar:", + "@deviceKeys": {}, + "enterSpace": "Gå till utrymme", + "@enterSpace": {}, + "commandHint_googly": "Skicka några googly ögon", + "@commandHint_googly": {}, + "commandHint_cuddle": "Skicka en omfamning", + "@commandHint_cuddle": {}, + "commandHint_hug": "Skicka en kram", + "@commandHint_hug": {}, + "users": "Användare", + "@users": {}, + "cuddleContent": "{senderName} omfamnar dig", + "@cuddleContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "hydrate": "Återställ från säkerhetskopia", + "@hydrate": {}, + "screenSharingDetail": "Du delar din skärm i FluffyChat", + "@screenSharingDetail": {}, + "letsStart": "Lås oss börja", + "@letsStart": {}, + "youRejectedTheInvitation": "Du avvisade inbjudan", + "@youRejectedTheInvitation": {}, + "youBannedUser": "Du förbjöd {user}", + "@youBannedUser": { + "placeholders": { + "user": {} + } + }, + "youInvitedBy": "📩 Du har blivit inbjuden av {user}", + "@youInvitedBy": { + "placeholders": { + "user": {} + } + }, + "youInvitedUser": "📩 Du bjöd in {user}", + "@youInvitedUser": { + "placeholders": { + "user": {} + } + }, + "youKickedAndBanned": "🙅 Du sparkade ut och förbjöd {user}", + "@youKickedAndBanned": { + "placeholders": { + "user": {} + } + }, + "stories": "Berättelser", + "@stories": {}, + "saveKeyManuallyDescription": "Spara nyckeln manuellt genom att aktivera dela-funktionen eller urklippshanteraren på enheten.", + "@saveKeyManuallyDescription": {}, + "storeInAndroidKeystore": "Lagra i Androids nyckellagring (KeyStore)", + "@storeInAndroidKeystore": {}, + "callingPermissions": "Samtalsbehörighet", + "@callingPermissions": {}, + "callingAccount": "Samtalskonto", + "@callingAccount": {}, + "callingAccountDetails": "Tillåt FluffyChat att använda Androids ring-app.", + "@callingAccountDetails": {}, + "appearOnTop": "Visa ovanpå", + "@appearOnTop": {}, + "appearOnTopDetails": "Tillåt att appen visas ovanpå (behövs inte om du redan har FluffyChat konfigurerat som ett samtalskonto)", + "@appearOnTopDetails": {}, + "otherCallingPermissions": "Mikrofon, kamera och andra behörigheter för FluffyChat", + "@otherCallingPermissions": {}, + "whyIsThisMessageEncrypted": "Varför kan inte detta meddelande läsas?", + "@whyIsThisMessageEncrypted": {}, + "newGroup": "Ny grupp", + "@newGroup": {}, + "enterRoom": "Gå till rummet", + "@enterRoom": {}, + "allSpaces": "Alla utrymmen", + "@allSpaces": {}, + "numChats": "{number} chattar", + "@numChats": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "hideUnimportantStateEvents": "Göm oviktiga tillståndshändelser", + "@hideUnimportantStateEvents": {}, + "doNotShowAgain": "Visa inte igen", + "@doNotShowAgain": {}, + "wasDirectChatDisplayName": "Tom chatt (var {oldDisplayName})", + "@wasDirectChatDisplayName": { + "type": "text", + "placeholders": { + "oldDisplayName": {} + } + }, + "newSpaceDescription": "Utrymmen möjliggör konsolidering av chattar och att bygga privata eller offentliga gemenskaper.", + "@newSpaceDescription": {}, + "reopenChat": "Återöppna chatt", + "@reopenChat": {}, + "jumpToLastReadMessage": "Hoppa till det senast lästa meddelandet", + "@jumpToLastReadMessage": {}, + "readUpToHere": "Läs upp till hit", + "@readUpToHere": {}, + "fileHasBeenSavedAt": "Filen har sparats i {path}", + "@fileHasBeenSavedAt": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "discover": "", + "@discover": { + "type": "text", + "placeholders": {} + }, + "allRooms": "", + "@allRooms": { + "type": "text", + "placeholders": {} + }, + "reportErrorDescription": "", + "@reportErrorDescription": {}, + "setColorTheme": "", + "@setColorTheme": {}, + "banUserDescription": "", + "@banUserDescription": {}, + "requests": "", + "@requests": {}, + "removeDevicesDescription": "", + "@removeDevicesDescription": {}, + "tryAgain": "", + "@tryAgain": {}, + "unbanUserDescription": "", + "@unbanUserDescription": {}, + "todoLists": "", + "@todoLists": {}, + "messagesStyle": "", + "@messagesStyle": {}, + "chatDescription": "", + "@chatDescription": {}, + "editTodo": "", + "@editTodo": {}, + "pushNotificationsNotAvailable": "", + "@pushNotificationsNotAvailable": {}, + "invalidServerName": "", + "@invalidServerName": {}, + "chatPermissions": "", + "@chatPermissions": {}, + "signInWithPassword": "", + "@signInWithPassword": {}, + "pleaseAddATitle": "", + "@pleaseAddATitle": {}, + "makeAdminDescription": "", + "@makeAdminDescription": {}, + "setChatDescription": "", + "@setChatDescription": {}, + "importFromZipFile": "", + "@importFromZipFile": {}, + "redactedBy": "", + "@redactedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "signInWith": "", + "@signInWith": { + "type": "text", + "placeholders": { + "provider": {} + } + }, + "noTodosYet": "", + "@noTodosYet": {}, + "optionalRedactReason": "", + "@optionalRedactReason": {}, + "archiveRoomDescription": "", + "@archiveRoomDescription": {}, + "exportEmotePack": "", + "@exportEmotePack": {}, + "savedEmotePack": "", + "@savedEmotePack": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "inviteContactToGroupQuestion": "", + "@inviteContactToGroupQuestion": {}, + "redactedByBecause": "", + "@redactedByBecause": { + "type": "text", + "placeholders": { + "username": {}, + "reason": {} + } + }, + "importZipFile": "", + "@importZipFile": {}, + "anyoneCanKnock": "", + "@anyoneCanKnock": {}, + "redactMessageDescription": "", + "@redactMessageDescription": {}, + "invalidInput": "", + "@invalidInput": {}, + "todosUnencrypted": "", + "@todosUnencrypted": {}, + "report": "", + "@report": {}, + "addChatDescription": "", + "@addChatDescription": {}, + "hasKnocked": "", + "@hasKnocked": { + "placeholders": { + "user": {} + } + }, + "openLinkInBrowser": "", + "@openLinkInBrowser": {}, + "directChat": "", + "@directChat": {}, + "noOneCanJoin": "", + "@noOneCanJoin": {}, + "wrongPinEntered": "", + "@wrongPinEntered": { + "type": "text", + "placeholders": { + "seconds": {} + } + }, + "sendTypingNotifications": "", + "@sendTypingNotifications": {}, + "inviteGroupChat": "", + "@inviteGroupChat": {}, + "invitePrivateChat": "", + "@invitePrivateChat": {}, + "importEmojis": "", + "@importEmojis": {}, + "noChatDescriptionYet": "", + "@noChatDescriptionYet": {}, + "newTodo": "", + "@newTodo": {}, + "learnMore": "", + "@learnMore": {}, + "notAnImage": "", + "@notAnImage": {}, + "chatDescriptionHasBeenChanged": "", + "@chatDescriptionHasBeenChanged": {}, + "todoListChangedError": "", + "@todoListChangedError": {}, + "roomUpgradeDescription": "", + "@roomUpgradeDescription": {}, + "pleaseEnterANumber": "", + "@pleaseEnterANumber": {}, + "profileNotFound": "", + "@profileNotFound": {}, + "jump": "", + "@jump": {}, + "shareInviteLink": "", + "@shareInviteLink": {}, + "emoteKeyboardNoRecents": "", + "@emoteKeyboardNoRecents": { + "type": "text", + "placeholders": {} + }, + "setTheme": "", + "@setTheme": {}, + "replace": "", + "@replace": {}, + "pleaseTryAgainLaterOrChooseDifferentServer": "", + "@pleaseTryAgainLaterOrChooseDifferentServer": {}, + "createGroup": "", + "@createGroup": {}, + "kickUserDescription": "", + "@kickUserDescription": {}, + "importNow": "", + "@importNow": {}, + "invite": "", + "@invite": {}, + "continueWith": "", + "@continueWith": {} +} diff --git a/assets/l10n/intl_ta.arb b/assets/l10n/intl_ta.arb index 8befa5210..4f1ff4472 100644 --- a/assets/l10n/intl_ta.arb +++ b/assets/l10n/intl_ta.arb @@ -1,20 +1,2621 @@ { - "@@last_modified": "2021-08-14 12:41:09.826673", - "acceptedTheInvitation": "{username} அழைப்பை ஏற்றுக்கொண்டார்", - "@acceptedTheInvitation": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "accept": "ஏற்றுக்கொள்", - "@accept": { - "type": "text", - "placeholders": {} - }, - "about": "பற்றி", - "@about": { - "type": "text", - "placeholders": {} + "@@last_modified": "2021-08-14 12:41:09.826673", + "acceptedTheInvitation": "{username} அழைப்பை ஏற்றுக்கொண்டார்", + "@acceptedTheInvitation": { + "type": "text", + "placeholders": { + "username": {} } -} \ No newline at end of file + }, + "accept": "ஏற்றுக்கொள்", + "@accept": { + "type": "text", + "placeholders": {} + }, + "about": "பற்றி", + "@about": { + "type": "text", + "placeholders": {} + }, + "showPassword": "", + "@showPassword": { + "type": "text", + "placeholders": {} + }, + "hugContent": "", + "@hugContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "darkTheme": "", + "@darkTheme": { + "type": "text", + "placeholders": {} + }, + "passphraseOrKey": "", + "@passphraseOrKey": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourPassword": "", + "@pleaseEnterYourPassword": { + "type": "text", + "placeholders": {} + }, + "theyMatch": "", + "@theyMatch": { + "type": "text", + "placeholders": {} + }, + "connect": "", + "@connect": { + "type": "text", + "placeholders": {} + }, + "jumpToLastReadMessage": "", + "@jumpToLastReadMessage": {}, + "allRooms": "", + "@allRooms": { + "type": "text", + "placeholders": {} + }, + "obtainingLocation": "", + "@obtainingLocation": { + "type": "text", + "placeholders": {} + }, + "whoCanSeeMyStories": "", + "@whoCanSeeMyStories": {}, + "commandHint_cuddle": "", + "@commandHint_cuddle": {}, + "chats": "", + "@chats": { + "type": "text", + "placeholders": {} + }, + "widgetVideo": "", + "@widgetVideo": {}, + "dismiss": "", + "@dismiss": {}, + "unknownDevice": "", + "@unknownDevice": { + "type": "text", + "placeholders": {} + }, + "emoteShortcode": "", + "@emoteShortcode": { + "type": "text", + "placeholders": {} + }, + "noEncryptionForPublicRooms": "", + "@noEncryptionForPublicRooms": { + "type": "text", + "placeholders": {} + }, + "admin": "", + "@admin": { + "type": "text", + "placeholders": {} + }, + "reportErrorDescription": "", + "@reportErrorDescription": {}, + "directChats": "", + "@directChats": { + "type": "text", + "placeholders": {} + }, + "setPermissionsLevel": "", + "@setPermissionsLevel": { + "type": "text", + "placeholders": {} + }, + "inviteContactToGroup": "", + "@inviteContactToGroup": { + "type": "text", + "placeholders": { + "groupName": {} + } + }, + "addAccount": "", + "@addAccount": {}, + "close": "", + "@close": { + "type": "text", + "placeholders": {} + }, + "configureChat": "", + "@configureChat": { + "type": "text", + "placeholders": {} + }, + "seenByUserAndUser": "", + "@seenByUserAndUser": { + "type": "text", + "placeholders": { + "username": {}, + "username2": {} + } + }, + "chatHasBeenAddedToThisSpace": "", + "@chatHasBeenAddedToThisSpace": {}, + "reply": "", + "@reply": { + "type": "text", + "placeholders": {} + }, + "currentlyActive": "", + "@currentlyActive": { + "type": "text", + "placeholders": {} + }, + "removeYourAvatar": "", + "@removeYourAvatar": { + "type": "text", + "placeholders": {} + }, + "unsupportedAndroidVersion": "", + "@unsupportedAndroidVersion": {}, + "enterASpacepName": "", + "@enterASpacepName": {}, + "device": "", + "@device": { + "type": "text", + "placeholders": {} + }, + "blockDevice": "", + "@blockDevice": { + "type": "text", + "placeholders": {} + }, + "commandHint_html": "", + "@commandHint_html": { + "type": "text", + "description": "Usage hint for the command /html" + }, + "widgetJitsi": "", + "@widgetJitsi": {}, + "youAreNoLongerParticipatingInThisChat": "", + "@youAreNoLongerParticipatingInThisChat": { + "type": "text", + "placeholders": {} + }, + "encryption": "", + "@encryption": { + "type": "text", + "placeholders": {} + }, + "messageType": "", + "@messageType": {}, + "noEmailWarning": "", + "@noEmailWarning": {}, + "indexedDbErrorLong": "", + "@indexedDbErrorLong": {}, + "oneClientLoggedOut": "", + "@oneClientLoggedOut": {}, + "toggleMuted": "", + "@toggleMuted": { + "type": "text", + "placeholders": {} + }, + "kicked": "", + "@kicked": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "title": "", + "@title": { + "description": "Title for the application", + "type": "text", + "placeholders": {} + }, + "changeTheNameOfTheGroup": "", + "@changeTheNameOfTheGroup": { + "type": "text", + "placeholders": {} + }, + "changedTheChatAvatar": "", + "@changedTheChatAvatar": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "verifySuccess": "", + "@verifySuccess": { + "type": "text", + "placeholders": {} + }, + "sendFile": "", + "@sendFile": { + "type": "text", + "placeholders": {} + }, + "newVerificationRequest": "", + "@newVerificationRequest": { + "type": "text", + "placeholders": {} + }, + "startFirstChat": "", + "@startFirstChat": {}, + "callingAccount": "", + "@callingAccount": {}, + "requestPermission": "", + "@requestPermission": { + "type": "text", + "placeholders": {} + }, + "sentAPicture": "", + "@sentAPicture": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "invited": "", + "@invited": { + "type": "text", + "placeholders": {} + }, + "setColorTheme": "", + "@setColorTheme": {}, + "nextAccount": "", + "@nextAccount": {}, + "commandHint_create": "", + "@commandHint_create": { + "type": "text", + "description": "Usage hint for the command /create" + }, + "youAreInvitedToThisChat": "", + "@youAreInvitedToThisChat": { + "type": "text", + "placeholders": {} + }, + "singlesignon": "", + "@singlesignon": { + "type": "text", + "placeholders": {} + }, + "warning": "", + "@warning": { + "type": "text", + "placeholders": {} + }, + "password": "", + "@password": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterAMatrixIdentifier": "", + "@pleaseEnterAMatrixIdentifier": { + "type": "text", + "placeholders": {} + }, + "allSpaces": "", + "@allSpaces": {}, + "supposedMxid": "", + "@supposedMxid": { + "type": "text", + "placeholders": { + "mxid": {} + } + }, + "editDisplayname": "", + "@editDisplayname": { + "type": "text", + "placeholders": {} + }, + "user": "", + "@user": {}, + "roomVersion": "", + "@roomVersion": { + "type": "text", + "placeholders": {} + }, + "sentAFile": "", + "@sentAFile": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "videoCall": "", + "@videoCall": { + "type": "text", + "placeholders": {} + }, + "youAcceptedTheInvitation": "", + "@youAcceptedTheInvitation": {}, + "banFromChat": "", + "@banFromChat": { + "type": "text", + "placeholders": {} + }, + "noMatrixServer": "", + "@noMatrixServer": { + "type": "text", + "placeholders": { + "server1": {}, + "server2": {} + } + }, + "userAndOthersAreTyping": "", + "@userAndOthersAreTyping": { + "type": "text", + "placeholders": { + "username": {}, + "count": {} + } + }, + "youInvitedBy": "", + "@youInvitedBy": { + "placeholders": { + "user": {} + } + }, + "userIsTyping": "", + "@userIsTyping": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "openAppToReadMessages": "", + "@openAppToReadMessages": { + "type": "text", + "placeholders": {} + }, + "sentAVideo": "", + "@sentAVideo": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "banUserDescription": "", + "@banUserDescription": {}, + "inviteContact": "", + "@inviteContact": { + "type": "text", + "placeholders": {} + }, + "requests": "", + "@requests": {}, + "askSSSSSign": "", + "@askSSSSSign": { + "type": "text", + "placeholders": {} + }, + "widgetEtherpad": "", + "@widgetEtherpad": {}, + "waitingPartnerAcceptRequest": "", + "@waitingPartnerAcceptRequest": { + "type": "text", + "placeholders": {} + }, + "remove": "", + "@remove": { + "type": "text", + "placeholders": {} + }, + "writeAMessage": "", + "@writeAMessage": { + "type": "text", + "placeholders": {} + }, + "changeTheme": "", + "@changeTheme": { + "type": "text", + "placeholders": {} + }, + "stories": "", + "@stories": {}, + "id": "", + "@id": { + "type": "text", + "placeholders": {} + }, + "addToStory": "", + "@addToStory": {}, + "removeDevicesDescription": "", + "@removeDevicesDescription": {}, + "changedTheChatDescriptionTo": "", + "@changedTheChatDescriptionTo": { + "type": "text", + "placeholders": { + "username": {}, + "description": {} + } + }, + "countParticipants": "", + "@countParticipants": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "separateChatTypes": "", + "@separateChatTypes": { + "type": "text", + "placeholders": {} + }, + "tryAgain": "", + "@tryAgain": {}, + "areGuestsAllowedToJoin": "", + "@areGuestsAllowedToJoin": { + "type": "text", + "placeholders": {} + }, + "blocked": "", + "@blocked": { + "type": "text", + "placeholders": {} + }, + "youKickedAndBanned": "", + "@youKickedAndBanned": { + "placeholders": { + "user": {} + } + }, + "dateWithoutYear": "", + "@dateWithoutYear": { + "type": "text", + "placeholders": { + "month": {}, + "day": {} + } + }, + "showDirectChatsInSpaces": "", + "@showDirectChatsInSpaces": { + "type": "text", + "placeholders": {} + }, + "removeDevice": "", + "@removeDevice": { + "type": "text", + "placeholders": {} + }, + "youCannotInviteYourself": "", + "@youCannotInviteYourself": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterValidEmail": "", + "@pleaseEnterValidEmail": {}, + "unbanUserDescription": "", + "@unbanUserDescription": {}, + "todoLists": "", + "@todoLists": {}, + "userAndUserAreTyping": "", + "@userAndUserAreTyping": { + "type": "text", + "placeholders": { + "username": {}, + "username2": {} + } + }, + "pleaseClickOnLink": "", + "@pleaseClickOnLink": { + "type": "text", + "placeholders": {} + }, + "saveFile": "", + "@saveFile": { + "type": "text", + "placeholders": {} + }, + "sendOnEnter": "", + "@sendOnEnter": {}, + "seenByUserAndCountOthers": "", + "@seenByUserAndCountOthers": { + "type": "text", + "placeholders": { + "username": {}, + "count": {} + } + }, + "pickImage": "", + "@pickImage": { + "type": "text", + "placeholders": {} + }, + "answeredTheCall": "", + "@answeredTheCall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "youRejectedTheInvitation": "", + "@youRejectedTheInvitation": {}, + "otherCallingPermissions": "", + "@otherCallingPermissions": {}, + "messagesStyle": "", + "@messagesStyle": {}, + "couldNotDecryptMessage": "", + "@couldNotDecryptMessage": { + "type": "text", + "placeholders": { + "error": {} + } + }, + "invitedUsersOnly": "", + "@invitedUsersOnly": { + "type": "text", + "placeholders": {} + }, + "link": "", + "@link": {}, + "widgetUrlError": "", + "@widgetUrlError": {}, + "emailOrUsername": "", + "@emailOrUsername": {}, + "newSpaceDescription": "", + "@newSpaceDescription": {}, + "chatDescription": "", + "@chatDescription": {}, + "callingAccountDetails": "", + "@callingAccountDetails": {}, + "next": "", + "@next": { + "type": "text", + "placeholders": {} + }, + "pleaseFollowInstructionsOnWeb": "", + "@pleaseFollowInstructionsOnWeb": { + "type": "text", + "placeholders": {} + }, + "changedTheGuestAccessRules": "", + "@changedTheGuestAccessRules": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "pleaseChooseAtLeastChars": "", + "@pleaseChooseAtLeastChars": { + "type": "text", + "placeholders": { + "min": {} + } + }, + "dateWithYear": "", + "@dateWithYear": { + "type": "text", + "placeholders": { + "year": {}, + "month": {}, + "day": {} + } + }, + "editRoomAliases": "", + "@editRoomAliases": { + "type": "text", + "placeholders": {} + }, + "enterSpace": "", + "@enterSpace": {}, + "encryptThisChat": "", + "@encryptThisChat": {}, + "fileName": "", + "@fileName": { + "type": "text", + "placeholders": {} + }, + "unavailable": "", + "@unavailable": { + "type": "text", + "placeholders": {} + }, + "previousAccount": "", + "@previousAccount": {}, + "publicRooms": "", + "@publicRooms": { + "type": "text", + "placeholders": {} + }, + "fromTheInvitation": "", + "@fromTheInvitation": { + "type": "text", + "placeholders": {} + }, + "sendMessages": "", + "@sendMessages": { + "type": "text", + "placeholders": {} + }, + "incorrectPassphraseOrKey": "", + "@incorrectPassphraseOrKey": { + "type": "text", + "placeholders": {} + }, + "emoteWarnNeedToPick": "", + "@emoteWarnNeedToPick": { + "type": "text", + "placeholders": {} + }, + "reopenChat": "", + "@reopenChat": {}, + "pleaseEnterRecoveryKey": "", + "@pleaseEnterRecoveryKey": {}, + "create": "", + "@create": { + "type": "text", + "placeholders": {} + }, + "toggleFavorite": "", + "@toggleFavorite": { + "type": "text", + "placeholders": {} + }, + "no": "", + "@no": { + "type": "text", + "placeholders": {} + }, + "alias": "", + "@alias": { + "type": "text", + "placeholders": {} + }, + "widgetNameError": "", + "@widgetNameError": {}, + "inoffensive": "", + "@inoffensive": { + "type": "text", + "placeholders": {} + }, + "unpin": "", + "@unpin": { + "type": "text", + "placeholders": {} + }, + "addToBundle": "", + "@addToBundle": {}, + "reportMessage": "", + "@reportMessage": { + "type": "text", + "placeholders": {} + }, + "spaceIsPublic": "", + "@spaceIsPublic": { + "type": "text", + "placeholders": {} + }, + "addWidget": "", + "@addWidget": {}, + "all": "", + "@all": { + "type": "text", + "placeholders": {} + }, + "removeAllOtherDevices": "", + "@removeAllOtherDevices": { + "type": "text", + "placeholders": {} + }, + "unblockDevice": "", + "@unblockDevice": { + "type": "text", + "placeholders": {} + }, + "countFiles": "", + "@countFiles": { + "placeholders": { + "count": {} + } + }, + "noKeyForThisMessage": "", + "@noKeyForThisMessage": {}, + "enableEncryptionWarning": "", + "@enableEncryptionWarning": { + "type": "text", + "placeholders": {} + }, + "inviteText": "", + "@inviteText": { + "type": "text", + "placeholders": { + "username": {}, + "link": {} + } + }, + "shareLocation": "", + "@shareLocation": { + "type": "text", + "placeholders": {} + }, + "reason": "", + "@reason": { + "type": "text", + "placeholders": {} + }, + "commandHint_markasgroup": "", + "@commandHint_markasgroup": {}, + "editTodo": "", + "@editTodo": {}, + "errorObtainingLocation": "", + "@errorObtainingLocation": { + "type": "text", + "placeholders": { + "error": {} + } + }, + "hydrateTor": "", + "@hydrateTor": {}, + "pushNotificationsNotAvailable": "", + "@pushNotificationsNotAvailable": {}, + "passwordRecovery": "", + "@passwordRecovery": { + "type": "text", + "placeholders": {} + }, + "storeInAppleKeyChain": "", + "@storeInAppleKeyChain": {}, + "replaceRoomWithNewerVersion": "", + "@replaceRoomWithNewerVersion": { + "type": "text", + "placeholders": {} + }, + "hydrate": "", + "@hydrate": {}, + "invalidServerName": "", + "@invalidServerName": {}, + "chatPermissions": "", + "@chatPermissions": {}, + "voiceMessage": "", + "@voiceMessage": { + "type": "text", + "placeholders": {} + }, + "badServerLoginTypesException": "", + "@badServerLoginTypesException": { + "type": "text", + "placeholders": { + "serverVersions": {}, + "supportedVersions": {} + } + }, + "wipeChatBackup": "", + "@wipeChatBackup": { + "type": "text", + "placeholders": {} + }, + "cantOpenUri": "", + "@cantOpenUri": { + "type": "text", + "placeholders": { + "uri": {} + } + }, + "sender": "", + "@sender": {}, + "storeInAndroidKeystore": "", + "@storeInAndroidKeystore": {}, + "optionalGroupName": "", + "@optionalGroupName": { + "type": "text", + "placeholders": {} + }, + "hideRedactedEvents": "", + "@hideRedactedEvents": { + "type": "text", + "placeholders": {} + }, + "online": "", + "@online": { + "type": "text", + "placeholders": {} + }, + "signInWithPassword": "", + "@signInWithPassword": {}, + "pleaseAddATitle": "", + "@pleaseAddATitle": {}, + "updateNow": "", + "@updateNow": {}, + "ignoredUsers": "", + "@ignoredUsers": { + "type": "text", + "placeholders": {} + }, + "lastActiveAgo": "", + "@lastActiveAgo": { + "type": "text", + "placeholders": { + "localizedTimeShort": {} + } + }, + "changedTheGuestAccessRulesTo": "", + "@changedTheGuestAccessRulesTo": { + "type": "text", + "placeholders": { + "username": {}, + "rules": {} + } + }, + "weSentYouAnEmail": "", + "@weSentYouAnEmail": { + "type": "text", + "placeholders": {} + }, + "offensive": "", + "@offensive": { + "type": "text", + "placeholders": {} + }, + "needPantalaimonWarning": "", + "@needPantalaimonWarning": { + "type": "text", + "placeholders": {} + }, + "makeAdminDescription": "", + "@makeAdminDescription": {}, + "edit": "", + "@edit": { + "type": "text", + "placeholders": {} + }, + "loadMore": "", + "@loadMore": { + "type": "text", + "placeholders": {} + }, + "noEmotesFound": "", + "@noEmotesFound": { + "type": "text", + "placeholders": {} + }, + "synchronizingPleaseWait": "", + "@synchronizingPleaseWait": { + "type": "text", + "placeholders": {} + }, + "transferFromAnotherDevice": "", + "@transferFromAnotherDevice": { + "type": "text", + "placeholders": {} + }, + "passwordHasBeenChanged": "", + "@passwordHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "pushRules": "", + "@pushRules": { + "type": "text", + "placeholders": {} + }, + "goToTheNewRoom": "", + "@goToTheNewRoom": { + "type": "text", + "placeholders": {} + }, + "commandHint_clearcache": "", + "@commandHint_clearcache": { + "type": "text", + "description": "Usage hint for the command /clearcache" + }, + "loadingPleaseWait": "", + "@loadingPleaseWait": { + "type": "text", + "placeholders": {} + }, + "copy": "", + "@copy": { + "type": "text", + "placeholders": {} + }, + "saveKeyManuallyDescription": "", + "@saveKeyManuallyDescription": {}, + "none": "", + "@none": { + "type": "text", + "placeholders": {} + }, + "editBundlesForAccount": "", + "@editBundlesForAccount": {}, + "renderRichContent": "", + "@renderRichContent": { + "type": "text", + "placeholders": {} + }, + "enableEncryption": "", + "@enableEncryption": { + "type": "text", + "placeholders": {} + }, + "whyIsThisMessageEncrypted": "", + "@whyIsThisMessageEncrypted": {}, + "rejectedTheInvitation": "", + "@rejectedTheInvitation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "setChatDescription": "", + "@setChatDescription": {}, + "userLeftTheChat": "", + "@userLeftTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "spaceName": "", + "@spaceName": { + "type": "text", + "placeholders": {} + }, + "importFromZipFile": "", + "@importFromZipFile": {}, + "discover": "", + "@discover": { + "type": "text", + "placeholders": {} + }, + "toggleUnread": "", + "@toggleUnread": { + "type": "text", + "placeholders": {} + }, + "or": "", + "@or": { + "type": "text", + "placeholders": {} + }, + "dehydrateWarning": "", + "@dehydrateWarning": {}, + "sendOriginal": "", + "@sendOriginal": { + "type": "text", + "placeholders": {} + }, + "noOtherDevicesFound": "", + "@noOtherDevicesFound": {}, + "whoIsAllowedToJoinThisGroup": "", + "@whoIsAllowedToJoinThisGroup": { + "type": "text", + "placeholders": {} + }, + "emptyChat": "", + "@emptyChat": { + "type": "text", + "placeholders": {} + }, + "seenByUser": "", + "@seenByUser": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "yourChatBackupHasBeenSetUp": "", + "@yourChatBackupHasBeenSetUp": {}, + "addDescription": "", + "@addDescription": {}, + "chatBackup": "", + "@chatBackup": { + "type": "text", + "placeholders": {} + }, + "redactedBy": "", + "@redactedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "submit": "", + "@submit": { + "type": "text", + "placeholders": {} + }, + "videoCallsBetaWarning": "", + "@videoCallsBetaWarning": {}, + "unmuteChat": "", + "@unmuteChat": { + "type": "text", + "placeholders": {} + }, + "createdTheChat": "", + "@createdTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "redactedAnEvent": "", + "@redactedAnEvent": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "autoplayImages": "", + "@autoplayImages": { + "type": "text", + "placeholder": {} + }, + "storyPrivacyWarning": "", + "@storyPrivacyWarning": {}, + "compareEmojiMatch": "", + "@compareEmojiMatch": { + "type": "text", + "placeholders": {} + }, + "matrixWidgets": "", + "@matrixWidgets": {}, + "participant": "", + "@participant": { + "type": "text", + "placeholders": {} + }, + "logInTo": "", + "@logInTo": { + "type": "text", + "placeholders": { + "homeserver": {} + } + }, + "yes": "", + "@yes": { + "type": "text", + "placeholders": {} + }, + "containsDisplayName": "", + "@containsDisplayName": { + "type": "text", + "placeholders": {} + }, + "signInWith": "", + "@signInWith": { + "type": "text", + "placeholders": { + "provider": {} + } + }, + "username": "", + "@username": { + "type": "text", + "placeholders": {} + }, + "changedTheRoomAliases": "", + "@changedTheRoomAliases": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "updateAvailable": "", + "@updateAvailable": {}, + "fileIsTooBigForServer": "", + "@fileIsTooBigForServer": {}, + "homeserver": "", + "@homeserver": {}, + "help": "", + "@help": { + "type": "text", + "placeholders": {} + }, + "noTodosYet": "", + "@noTodosYet": {}, + "chatDetails": "", + "@chatDetails": { + "type": "text", + "placeholders": {} + }, + "people": "", + "@people": { + "type": "text", + "placeholders": {} + }, + "changedTheHistoryVisibilityTo": "", + "@changedTheHistoryVisibilityTo": { + "type": "text", + "placeholders": { + "username": {}, + "rules": {} + } + }, + "leftTheChat": "", + "@leftTheChat": { + "type": "text", + "placeholders": {} + }, + "verified": "", + "@verified": { + "type": "text", + "placeholders": {} + }, + "repeatPassword": "", + "@repeatPassword": {}, + "setStatus": "", + "@setStatus": { + "type": "text", + "placeholders": {} + }, + "groupWith": "", + "@groupWith": { + "type": "text", + "placeholders": { + "displayname": {} + } + }, + "callingPermissions": "", + "@callingPermissions": {}, + "delete": "", + "@delete": { + "type": "text", + "placeholders": {} + }, + "newMessageInFluffyChat": "", + "@newMessageInFluffyChat": { + "type": "text", + "placeholders": {} + }, + "readUpToHere": "", + "@readUpToHere": {}, + "start": "", + "@start": {}, + "bubbleSize": "", + "@bubbleSize": { + "type": "text", + "placeholders": {} + }, + "downloadFile": "", + "@downloadFile": { + "type": "text", + "placeholders": {} + }, + "deviceId": "", + "@deviceId": { + "type": "text", + "placeholders": {} + }, + "register": "", + "@register": { + "type": "text", + "placeholders": {} + }, + "unlockOldMessages": "", + "@unlockOldMessages": {}, + "identity": "", + "@identity": { + "type": "text", + "placeholders": {} + }, + "numChats": "", + "@numChats": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "changedTheJoinRulesTo": "", + "@changedTheJoinRulesTo": { + "type": "text", + "placeholders": { + "username": {}, + "joinRules": {} + } + }, + "ignore": "", + "@ignore": { + "type": "text", + "placeholders": {} + }, + "whatIsGoingOn": "", + "@whatIsGoingOn": {}, + "recording": "", + "@recording": { + "type": "text", + "placeholders": {} + }, + "changedTheChatPermissions": "", + "@changedTheChatPermissions": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changeWallpaper": "", + "@changeWallpaper": { + "type": "text", + "placeholders": {} + }, + "moderator": "", + "@moderator": { + "type": "text", + "placeholders": {} + }, + "optionalRedactReason": "", + "@optionalRedactReason": {}, + "waitingPartnerEmoji": "", + "@waitingPartnerEmoji": { + "type": "text", + "placeholders": {} + }, + "channelCorruptedDecryptError": "", + "@channelCorruptedDecryptError": { + "type": "text", + "placeholders": {} + }, + "tryToSendAgain": "", + "@tryToSendAgain": { + "type": "text", + "placeholders": {} + }, + "guestsCanJoin": "", + "@guestsCanJoin": { + "type": "text", + "placeholders": {} + }, + "copyToClipboard": "", + "@copyToClipboard": { + "type": "text", + "placeholders": {} + }, + "dehydrate": "", + "@dehydrate": {}, + "locationPermissionDeniedNotice": "", + "@locationPermissionDeniedNotice": { + "type": "text", + "placeholders": {} + }, + "send": "", + "@send": { + "type": "text", + "placeholders": {} + }, + "hasWithdrawnTheInvitationFor": "", + "@hasWithdrawnTheInvitationFor": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "visibleForAllParticipants": "", + "@visibleForAllParticipants": { + "type": "text", + "placeholders": {} + }, + "noRoomsFound": "", + "@noRoomsFound": { + "type": "text", + "placeholders": {} + }, + "banned": "", + "@banned": { + "type": "text", + "placeholders": {} + }, + "sendAsText": "", + "@sendAsText": { + "type": "text" + }, + "inviteForMe": "", + "@inviteForMe": { + "type": "text", + "placeholders": {} + }, + "archiveRoomDescription": "", + "@archiveRoomDescription": {}, + "exportEmotePack": "", + "@exportEmotePack": {}, + "changedTheChatNameTo": "", + "@changedTheChatNameTo": { + "type": "text", + "placeholders": { + "username": {}, + "chatname": {} + } + }, + "sendSticker": "", + "@sendSticker": { + "type": "text", + "placeholders": {} + }, + "account": "", + "@account": { + "type": "text", + "placeholders": {} + }, + "switchToAccount": "", + "@switchToAccount": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "commandInvalid": "", + "@commandInvalid": { + "type": "text" + }, + "setAsCanonicalAlias": "", + "@setAsCanonicalAlias": { + "type": "text", + "placeholders": {} + }, + "whyDoYouWantToReportThis": "", + "@whyDoYouWantToReportThis": { + "type": "text", + "placeholders": {} + }, + "locationDisabledNotice": "", + "@locationDisabledNotice": { + "type": "text", + "placeholders": {} + }, + "letsStart": "", + "@letsStart": {}, + "removedBy": "", + "@removedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheRoomInvitationLink": "", + "@changedTheRoomInvitationLink": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "newChat": "", + "@newChat": { + "type": "text", + "placeholders": {} + }, + "notifications": "", + "@notifications": { + "type": "text", + "placeholders": {} + }, + "commandHint_plain": "", + "@commandHint_plain": { + "type": "text", + "description": "Usage hint for the command /plain" + }, + "emoteSettings": "", + "@emoteSettings": { + "type": "text", + "placeholders": {} + }, + "experimentalVideoCalls": "", + "@experimentalVideoCalls": {}, + "savedEmotePack": "", + "@savedEmotePack": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "openCamera": "", + "@openCamera": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterRecoveryKeyDescription": "", + "@pleaseEnterRecoveryKeyDescription": {}, + "guestsAreForbidden": "", + "@guestsAreForbidden": { + "type": "text", + "placeholders": {} + }, + "mention": "", + "@mention": { + "type": "text", + "placeholders": {} + }, + "openInMaps": "", + "@openInMaps": { + "type": "text", + "placeholders": {} + }, + "withTheseAddressesRecoveryDescription": "", + "@withTheseAddressesRecoveryDescription": { + "type": "text", + "placeholders": {} + }, + "inviteContactToGroupQuestion": "", + "@inviteContactToGroupQuestion": {}, + "emoteExists": "", + "@emoteExists": { + "type": "text", + "placeholders": {} + }, + "redactedByBecause": "", + "@redactedByBecause": { + "type": "text", + "placeholders": { + "username": {}, + "reason": {} + } + }, + "isTyping": "", + "@isTyping": { + "type": "text", + "placeholders": {} + }, + "youHaveWithdrawnTheInvitationFor": "", + "@youHaveWithdrawnTheInvitationFor": { + "placeholders": { + "user": {} + } + }, + "chat": "", + "@chat": { + "type": "text", + "placeholders": {} + }, + "group": "", + "@group": { + "type": "text", + "placeholders": {} + }, + "leave": "", + "@leave": { + "type": "text", + "placeholders": {} + }, + "skip": "", + "@skip": { + "type": "text", + "placeholders": {} + }, + "appearOnTopDetails": "", + "@appearOnTopDetails": {}, + "roomHasBeenUpgraded": "", + "@roomHasBeenUpgraded": { + "type": "text", + "placeholders": {} + }, + "enterRoom": "", + "@enterRoom": {}, + "enableEmotesGlobally": "", + "@enableEmotesGlobally": { + "type": "text", + "placeholders": {} + }, + "areYouSure": "", + "@areYouSure": { + "type": "text", + "placeholders": {} + }, + "ignoreListDescription": "", + "@ignoreListDescription": { + "type": "text", + "placeholders": {} + }, + "pleaseChooseAPasscode": "", + "@pleaseChooseAPasscode": { + "type": "text", + "placeholders": {} + }, + "noPasswordRecoveryDescription": "", + "@noPasswordRecoveryDescription": { + "type": "text", + "placeholders": {} + }, + "changedTheProfileAvatar": "", + "@changedTheProfileAvatar": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "allChats": "", + "@allChats": { + "type": "text", + "placeholders": {} + }, + "reportUser": "", + "@reportUser": {}, + "commandHint_send": "", + "@commandHint_send": { + "type": "text", + "description": "Usage hint for the command /send" + }, + "onlineKeyBackupEnabled": "", + "@onlineKeyBackupEnabled": { + "type": "text", + "placeholders": {} + }, + "unbannedUser": "", + "@unbannedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "confirmEventUnpin": "", + "@confirmEventUnpin": {}, + "badServerVersionsException": "", + "@badServerVersionsException": { + "type": "text", + "placeholders": { + "serverVersions": {}, + "supportedVersions": {} + } + }, + "youInvitedUser": "", + "@youInvitedUser": { + "placeholders": { + "user": {} + } + }, + "kickedAndBanned": "", + "@kickedAndBanned": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "noConnectionToTheServer": "", + "@noConnectionToTheServer": { + "type": "text", + "placeholders": {} + }, + "fileHasBeenSavedAt": "", + "@fileHasBeenSavedAt": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "license": "", + "@license": { + "type": "text", + "placeholders": {} + }, + "addToSpace": "", + "@addToSpace": {}, + "importZipFile": "", + "@importZipFile": {}, + "anyoneCanKnock": "", + "@anyoneCanKnock": {}, + "commandMissing": "", + "@commandMissing": { + "type": "text", + "placeholders": { + "command": {} + }, + "description": "State that {command} is not a valid /command." + }, + "redactMessageDescription": "", + "@redactMessageDescription": {}, + "rejoin": "", + "@rejoin": { + "type": "text", + "placeholders": {} + }, + "recoveryKey": "", + "@recoveryKey": {}, + "redactMessage": "", + "@redactMessage": { + "type": "text", + "placeholders": {} + }, + "forward": "", + "@forward": { + "type": "text", + "placeholders": {} + }, + "commandHint_discardsession": "", + "@commandHint_discardsession": { + "type": "text", + "description": "Usage hint for the command /discardsession" + }, + "invalidInput": "", + "@invalidInput": {}, + "chooseAStrongPassword": "", + "@chooseAStrongPassword": { + "type": "text", + "placeholders": {} + }, + "hideUnknownEvents": "", + "@hideUnknownEvents": { + "type": "text", + "placeholders": {} + }, + "todosUnencrypted": "", + "@todosUnencrypted": {}, + "dehydrateTorLong": "", + "@dehydrateTorLong": {}, + "yourPublicKey": "", + "@yourPublicKey": { + "type": "text", + "placeholders": {} + }, + "tooManyRequestsWarning": "", + "@tooManyRequestsWarning": { + "type": "text", + "placeholders": {} + }, + "invitedUser": "", + "@invitedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "kickFromChat": "", + "@kickFromChat": { + "type": "text", + "placeholders": {} + }, + "commandHint_myroomnick": "", + "@commandHint_myroomnick": { + "type": "text", + "description": "Usage hint for the command /myroomnick" + }, + "offline": "", + "@offline": { + "type": "text", + "placeholders": {} + }, + "replyHasBeenSent": "", + "@replyHasBeenSent": {}, + "noPermission": "", + "@noPermission": { + "type": "text", + "placeholders": {} + }, + "doNotShowAgain": "", + "@doNotShowAgain": {}, + "activatedEndToEndEncryption": "", + "@activatedEndToEndEncryption": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "report": "", + "@report": {}, + "status": "", + "@status": { + "type": "text", + "placeholders": {} + }, + "deny": "", + "@deny": { + "type": "text", + "placeholders": {} + }, + "compareNumbersMatch": "", + "@compareNumbersMatch": { + "type": "text", + "placeholders": {} + }, + "groupIsPublic": "", + "@groupIsPublic": { + "type": "text", + "placeholders": {} + }, + "verifyStart": "", + "@verifyStart": { + "type": "text", + "placeholders": {} + }, + "yourStory": "", + "@yourStory": {}, + "memberChanges": "", + "@memberChanges": { + "type": "text", + "placeholders": {} + }, + "joinRoom": "", + "@joinRoom": { + "type": "text", + "placeholders": {} + }, + "ignoreUsername": "", + "@ignoreUsername": { + "type": "text", + "placeholders": {} + }, + "unverified": "", + "@unverified": {}, + "fluffychat": "", + "@fluffychat": { + "type": "text", + "placeholders": {} + }, + "howOffensiveIsThisContent": "", + "@howOffensiveIsThisContent": { + "type": "text", + "placeholders": {} + }, + "serverRequiresEmail": "", + "@serverRequiresEmail": {}, + "hideUnimportantStateEvents": "", + "@hideUnimportantStateEvents": {}, + "screenSharingTitle": "", + "@screenSharingTitle": {}, + "widgetCustom": "", + "@widgetCustom": {}, + "sentCallInformations": "", + "@sentCallInformations": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "addToSpaceDescription": "", + "@addToSpaceDescription": {}, + "googlyEyesContent": "", + "@googlyEyesContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "whoCanSeeMyStoriesDesc": "", + "@whoCanSeeMyStoriesDesc": {}, + "youBannedUser": "", + "@youBannedUser": { + "placeholders": { + "user": {} + } + }, + "theyDontMatch": "", + "@theyDontMatch": { + "type": "text", + "placeholders": {} + }, + "unsubscribeStories": "", + "@unsubscribeStories": {}, + "youHaveBeenBannedFromThisChat": "", + "@youHaveBeenBannedFromThisChat": { + "type": "text", + "placeholders": {} + }, + "displaynameHasBeenChanged": "", + "@displaynameHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "loginWithOneClick": "", + "@loginWithOneClick": {}, + "addChatDescription": "", + "@addChatDescription": {}, + "sentAnAudio": "", + "@sentAnAudio": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "editRoomAvatar": "", + "@editRoomAvatar": { + "type": "text", + "placeholders": {} + }, + "encrypted": "", + "@encrypted": { + "type": "text", + "placeholders": {} + }, + "commandHint_leave": "", + "@commandHint_leave": { + "type": "text", + "description": "Usage hint for the command /leave" + }, + "commandHint_myroomavatar": "", + "@commandHint_myroomavatar": { + "type": "text", + "description": "Usage hint for the command /myroomavatar" + }, + "cancel": "", + "@cancel": { + "type": "text", + "placeholders": {} + }, + "hasKnocked": "", + "@hasKnocked": { + "placeholders": { + "user": {} + } + }, + "publish": "", + "@publish": {}, + "openLinkInBrowser": "", + "@openLinkInBrowser": {}, + "clearArchive": "", + "@clearArchive": {}, + "appLock": "", + "@appLock": { + "type": "text", + "placeholders": {} + }, + "commandHint_react": "", + "@commandHint_react": { + "type": "text", + "description": "Usage hint for the command /react" + }, + "changedTheHistoryVisibility": "", + "@changedTheHistoryVisibility": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "commandHint_me": "", + "@commandHint_me": { + "type": "text", + "description": "Usage hint for the command /me" + }, + "pleaseEnterYourUsername": "", + "@pleaseEnterYourUsername": { + "type": "text", + "placeholders": {} + }, + "messageInfo": "", + "@messageInfo": {}, + "disableEncryptionWarning": "", + "@disableEncryptionWarning": {}, + "directChat": "", + "@directChat": {}, + "noOneCanJoin": "", + "@noOneCanJoin": {}, + "encryptionNotEnabled": "", + "@encryptionNotEnabled": { + "type": "text", + "placeholders": {} + }, + "wrongPinEntered": "", + "@wrongPinEntered": { + "type": "text", + "placeholders": { + "seconds": {} + } + }, + "sendTypingNotifications": "", + "@sendTypingNotifications": {}, + "lightTheme": "", + "@lightTheme": { + "type": "text", + "placeholders": {} + }, + "inviteGroupChat": "", + "@inviteGroupChat": {}, + "appearOnTop": "", + "@appearOnTop": {}, + "invitePrivateChat": "", + "@invitePrivateChat": {}, + "verifyTitle": "", + "@verifyTitle": { + "type": "text", + "placeholders": {} + }, + "foregroundServiceRunning": "", + "@foregroundServiceRunning": {}, + "enterAnEmailAddress": "", + "@enterAnEmailAddress": { + "type": "text", + "placeholders": {} + }, + "voiceCall": "", + "@voiceCall": {}, + "commandHint_kick": "", + "@commandHint_kick": { + "type": "text", + "description": "Usage hint for the command /kick" + }, + "copiedToClipboard": "", + "@copiedToClipboard": { + "type": "text", + "placeholders": {} + }, + "createNewSpace": "", + "@createNewSpace": { + "type": "text", + "placeholders": {} + }, + "commandHint_unban": "", + "@commandHint_unban": { + "type": "text", + "description": "Usage hint for the command /unban" + }, + "unknownEncryptionAlgorithm": "", + "@unknownEncryptionAlgorithm": { + "type": "text", + "placeholders": {} + }, + "commandHint_ban": "", + "@commandHint_ban": { + "type": "text", + "description": "Usage hint for the command /ban" + }, + "importEmojis": "", + "@importEmojis": {}, + "confirm": "", + "@confirm": { + "type": "text", + "placeholders": {} + }, + "wasDirectChatDisplayName": "", + "@wasDirectChatDisplayName": { + "type": "text", + "placeholders": { + "oldDisplayName": {} + } + }, + "noChatDescriptionYet": "", + "@noChatDescriptionYet": {}, + "defaultPermissionLevel": "", + "@defaultPermissionLevel": { + "type": "text", + "placeholders": {} + }, + "newTodo": "", + "@newTodo": {}, + "removeFromBundle": "", + "@removeFromBundle": {}, + "numUsersTyping": "", + "@numUsersTyping": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "fontSize": "", + "@fontSize": { + "type": "text", + "placeholders": {} + }, + "whoCanPerformWhichAction": "", + "@whoCanPerformWhichAction": { + "type": "text", + "placeholders": {} + }, + "confirmMatrixId": "", + "@confirmMatrixId": {}, + "learnMore": "", + "@learnMore": {}, + "iHaveClickedOnLink": "", + "@iHaveClickedOnLink": { + "type": "text", + "placeholders": {} + }, + "you": "", + "@you": { + "type": "text", + "placeholders": {} + }, + "notAnImage": "", + "@notAnImage": {}, + "users": "", + "@users": {}, + "openGallery": "", + "@openGallery": {}, + "chatDescriptionHasBeenChanged": "", + "@chatDescriptionHasBeenChanged": {}, + "search": "", + "@search": { + "type": "text", + "placeholders": {} + }, + "newGroup": "", + "@newGroup": {}, + "bundleName": "", + "@bundleName": {}, + "dehydrateTor": "", + "@dehydrateTor": {}, + "todoListChangedError": "", + "@todoListChangedError": {}, + "removeFromSpace": "", + "@removeFromSpace": {}, + "enterInviteLinkOrMatrixId": "", + "@enterInviteLinkOrMatrixId": {}, + "dateAndTimeOfDay": "", + "@dateAndTimeOfDay": { + "type": "text", + "placeholders": { + "date": {}, + "timeOfDay": {} + } + }, + "commandHint_op": "", + "@commandHint_op": { + "type": "text", + "description": "Usage hint for the command /op" + }, + "commandHint_join": "", + "@commandHint_join": { + "type": "text", + "description": "Usage hint for the command /join" + }, + "sourceCode": "", + "@sourceCode": { + "type": "text", + "placeholders": {} + }, + "enterAGroupName": "", + "@enterAGroupName": { + "type": "text", + "placeholders": {} + }, + "roomUpgradeDescription": "", + "@roomUpgradeDescription": {}, + "commandHint_invite": "", + "@commandHint_invite": { + "type": "text", + "description": "Usage hint for the command /invite" + }, + "userSentUnknownEvent": "", + "@userSentUnknownEvent": { + "type": "text", + "placeholders": { + "username": {}, + "type": {} + } + }, + "scanQrCode": "", + "@scanQrCode": {}, + "logout": "", + "@logout": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterANumber": "", + "@pleaseEnterANumber": {}, + "contactHasBeenInvitedToTheGroup": "", + "@contactHasBeenInvitedToTheGroup": { + "type": "text", + "placeholders": {} + }, + "youKicked": "", + "@youKicked": { + "placeholders": { + "user": {} + } + }, + "areYouSureYouWantToLogout": "", + "@areYouSureYouWantToLogout": { + "type": "text", + "placeholders": {} + }, + "changedTheJoinRules": "", + "@changedTheJoinRules": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "profileNotFound": "", + "@profileNotFound": {}, + "jump": "", + "@jump": {}, + "groups": "", + "@groups": { + "type": "text", + "placeholders": {} + }, + "reactedWith": "", + "@reactedWith": { + "type": "text", + "placeholders": { + "sender": {}, + "reaction": {} + } + }, + "bannedUser": "", + "@bannedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "sorryThatsNotPossible": "", + "@sorryThatsNotPossible": {}, + "storyFrom": "", + "@storyFrom": { + "type": "text", + "placeholders": { + "date": {}, + "body": {} + } + }, + "videoWithSize": "", + "@videoWithSize": { + "type": "text", + "placeholders": { + "size": {} + } + }, + "oopsSomethingWentWrong": "", + "@oopsSomethingWentWrong": { + "type": "text", + "placeholders": {} + }, + "loadCountMoreParticipants": "", + "@loadCountMoreParticipants": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "shareInviteLink": "", + "@shareInviteLink": {}, + "commandHint_markasdm": "", + "@commandHint_markasdm": {}, + "recoveryKeyLost": "", + "@recoveryKeyLost": {}, + "cuddleContent": "", + "@cuddleContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "askVerificationRequest": "", + "@askVerificationRequest": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "containsUserName": "", + "@containsUserName": { + "type": "text", + "placeholders": {} + }, + "messages": "", + "@messages": { + "type": "text", + "placeholders": {} + }, + "login": "", + "@login": { + "type": "text", + "placeholders": {} + }, + "deviceKeys": "", + "@deviceKeys": {}, + "waitingPartnerNumbers": "", + "@waitingPartnerNumbers": { + "type": "text", + "placeholders": {} + }, + "noGoogleServicesWarning": "", + "@noGoogleServicesWarning": { + "type": "text", + "placeholders": {} + }, + "everythingReady": "", + "@everythingReady": { + "type": "text", + "placeholders": {} + }, + "addEmail": "", + "@addEmail": { + "type": "text", + "placeholders": {} + }, + "emoteKeyboardNoRecents": "", + "@emoteKeyboardNoRecents": { + "type": "text", + "placeholders": {} + }, + "setCustomEmotes": "", + "@setCustomEmotes": { + "type": "text", + "placeholders": {} + }, + "startedACall": "", + "@startedACall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "emoteInvalid": "", + "@emoteInvalid": { + "type": "text", + "placeholders": {} + }, + "systemTheme": "", + "@systemTheme": { + "type": "text", + "placeholders": {} + }, + "messageWillBeRemovedWarning": "", + "@messageWillBeRemovedWarning": { + "type": "text", + "placeholders": {} + }, + "endToEndEncryption": "", + "@endToEndEncryption": {}, + "notificationsEnabledForThisAccount": "", + "@notificationsEnabledForThisAccount": { + "type": "text", + "placeholders": {} + }, + "deleteMessage": "", + "@deleteMessage": { + "type": "text", + "placeholders": {} + }, + "visibilityOfTheChatHistory": "", + "@visibilityOfTheChatHistory": { + "type": "text", + "placeholders": {} + }, + "settings": "", + "@settings": { + "type": "text", + "placeholders": {} + }, + "setTheme": "", + "@setTheme": {}, + "changeTheHomeserver": "", + "@changeTheHomeserver": { + "type": "text", + "placeholders": {} + }, + "youJoinedTheChat": "", + "@youJoinedTheChat": {}, + "wallpaper": "", + "@wallpaper": { + "type": "text", + "placeholders": {} + }, + "openVideoCamera": "", + "@openVideoCamera": { + "type": "text", + "placeholders": {} + }, + "play": "", + "@play": { + "type": "text", + "placeholders": { + "fileName": {} + } + }, + "chatBackupDescription": "", + "@chatBackupDescription": { + "type": "text", + "placeholders": {} + }, + "changeDeviceName": "", + "@changeDeviceName": { + "type": "text", + "placeholders": {} + }, + "lastSeenLongTimeAgo": "", + "@lastSeenLongTimeAgo": { + "type": "text", + "placeholders": {} + }, + "passwordForgotten": "", + "@passwordForgotten": { + "type": "text", + "placeholders": {} + }, + "statusExampleMessage": "", + "@statusExampleMessage": { + "type": "text", + "placeholders": {} + }, + "thisUserHasNotPostedAnythingYet": "", + "@thisUserHasNotPostedAnythingYet": {}, + "security": "", + "@security": { + "type": "text", + "placeholders": {} + }, + "markAsRead": "", + "@markAsRead": {}, + "sendAudio": "", + "@sendAudio": { + "type": "text", + "placeholders": {} + }, + "widgetName": "", + "@widgetName": {}, + "sentASticker": "", + "@sentASticker": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "errorAddingWidget": "", + "@errorAddingWidget": {}, + "commandHint_dm": "", + "@commandHint_dm": { + "type": "text", + "description": "Usage hint for the command /dm" + }, + "commandHint_hug": "", + "@commandHint_hug": {}, + "replace": "", + "@replace": {}, + "reject": "", + "@reject": { + "type": "text", + "placeholders": {} + }, + "editBlockedServers": "", + "@editBlockedServers": { + "type": "text", + "placeholders": {} + }, + "oopsPushError": "", + "@oopsPushError": { + "type": "text", + "placeholders": {} + }, + "youUnbannedUser": "", + "@youUnbannedUser": { + "placeholders": { + "user": {} + } + }, + "deactivateAccountWarning": "", + "@deactivateAccountWarning": { + "type": "text", + "placeholders": {} + }, + "archive": "", + "@archive": { + "type": "text", + "placeholders": {} + }, + "joinedTheChat": "", + "@joinedTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "visibleForEveryone": "", + "@visibleForEveryone": { + "type": "text", + "placeholders": {} + }, + "pleaseEnter4Digits": "", + "@pleaseEnter4Digits": { + "type": "text", + "placeholders": {} + }, + "newSpace": "", + "@newSpace": {}, + "changePassword": "", + "@changePassword": { + "type": "text", + "placeholders": {} + }, + "devices": "", + "@devices": { + "type": "text", + "placeholders": {} + }, + "unknownEvent": "", + "@unknownEvent": { + "type": "text", + "placeholders": { + "type": {} + } + }, + "emojis": "", + "@emojis": {}, + "signUp": "", + "@signUp": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourPin": "", + "@pleaseEnterYourPin": { + "type": "text", + "placeholders": {} + }, + "pleaseChoose": "", + "@pleaseChoose": { + "type": "text", + "placeholders": {} + }, + "share": "", + "@share": { + "type": "text", + "placeholders": {} + }, + "commandHint_googly": "", + "@commandHint_googly": {}, + "pleaseTryAgainLaterOrChooseDifferentServer": "", + "@pleaseTryAgainLaterOrChooseDifferentServer": {}, + "createGroup": "", + "@createGroup": {}, + "privacy": "", + "@privacy": { + "type": "text", + "placeholders": {} + }, + "changeYourAvatar": "", + "@changeYourAvatar": { + "type": "text", + "placeholders": {} + }, + "sendImage": "", + "@sendImage": { + "type": "text", + "placeholders": {} + }, + "hydrateTorLong": "", + "@hydrateTorLong": {}, + "time": "", + "@time": {}, + "enterYourHomeserver": "", + "@enterYourHomeserver": { + "type": "text", + "placeholders": {} + }, + "botMessages": "", + "@botMessages": { + "type": "text", + "placeholders": {} + }, + "contentHasBeenReported": "", + "@contentHasBeenReported": { + "type": "text", + "placeholders": {} + }, + "custom": "", + "@custom": {}, + "noBackupWarning": "", + "@noBackupWarning": {}, + "fromJoining": "", + "@fromJoining": { + "type": "text", + "placeholders": {} + }, + "verify": "", + "@verify": { + "type": "text", + "placeholders": {} + }, + "sendVideo": "", + "@sendVideo": { + "type": "text", + "placeholders": {} + }, + "editWidgets": "", + "@editWidgets": {}, + "storeInSecureStorageDescription": "", + "@storeInSecureStorageDescription": {}, + "openChat": "", + "@openChat": {}, + "kickUserDescription": "", + "@kickUserDescription": {}, + "sendAMessage": "", + "@sendAMessage": { + "type": "text", + "placeholders": {} + }, + "pin": "", + "@pin": { + "type": "text", + "placeholders": {} + }, + "importNow": "", + "@importNow": {}, + "deleteAccount": "", + "@deleteAccount": { + "type": "text", + "placeholders": {} + }, + "setInvitationLink": "", + "@setInvitationLink": { + "type": "text", + "placeholders": {} + }, + "pinMessage": "", + "@pinMessage": {}, + "muteChat": "", + "@muteChat": { + "type": "text", + "placeholders": {} + }, + "invite": "", + "@invite": {}, + "enableMultiAccounts": "", + "@enableMultiAccounts": {}, + "chooseAUsername": "", + "@chooseAUsername": { + "type": "text", + "placeholders": {} + }, + "anyoneCanJoin": "", + "@anyoneCanJoin": { + "type": "text", + "placeholders": {} + }, + "emotePacks": "", + "@emotePacks": { + "type": "text", + "placeholders": {} + }, + "makeSureTheIdentifierIsValid": "", + "@makeSureTheIdentifierIsValid": { + "type": "text", + "placeholders": {} + }, + "continueWith": "", + "@continueWith": {}, + "indexedDbErrorTitle": "", + "@indexedDbErrorTitle": {}, + "pleaseChooseAUsername": "", + "@pleaseChooseAUsername": { + "type": "text", + "placeholders": {} + }, + "endedTheCall": "", + "@endedTheCall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "unsupportedAndroidVersionLong": "", + "@unsupportedAndroidVersionLong": {}, + "storeSecurlyOnThisDevice": "", + "@storeSecurlyOnThisDevice": {}, + "ok": "", + "@ok": { + "type": "text", + "placeholders": {} + }, + "passwordsDoNotMatch": "", + "@passwordsDoNotMatch": {}, + "sharedTheLocation": "", + "@sharedTheLocation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "unbanFromChat": "", + "@unbanFromChat": { + "type": "text", + "placeholders": {} + }, + "iUnderstand": "", + "@iUnderstand": {}, + "screenSharingDetail": "", + "@screenSharingDetail": {}, + "changedTheDisplaynameTo": "", + "@changedTheDisplaynameTo": { + "type": "text", + "placeholders": { + "username": {}, + "displayname": {} + } + }, + "unreadChats": "", + "@unreadChats": { + "type": "text", + "placeholders": { + "unreadCount": {} + } + }, + "placeCall": "", + "@placeCall": {}, + "extremeOffensive": "", + "@extremeOffensive": { + "type": "text", + "placeholders": {} + } +} diff --git a/assets/l10n/intl_th.arb b/assets/l10n/intl_th.arb index 9e26dfeeb..eb7291df0 100644 --- a/assets/l10n/intl_th.arb +++ b/assets/l10n/intl_th.arb @@ -1 +1,2620 @@ -{} \ No newline at end of file +{ + "hugContent": "{senderName} กอดคุณ", + "@hugContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "commandHint_cuddle": "ส่งเคล้าเคลียให้", + "@commandHint_cuddle": {}, + "admin": "แอดมิน", + "@admin": { + "type": "text", + "placeholders": {} + }, + "supposedMxid": "อันนี้ควรเป็น {mxid}", + "@supposedMxid": { + "type": "text", + "placeholders": { + "mxid": {} + } + }, + "askSSSSSign": "เพื่อให้สามารถลงนามบุคคลอื่นได้ โปรดป้อนรหัสผ่านร้านค้าที่ปลอดภัยหรือรหัสกู้คืนของคุณ", + "@askSSSSSign": { + "type": "text", + "placeholders": {} + }, + "remove": "ลบออก", + "@remove": { + "type": "text", + "placeholders": {} + }, + "areGuestsAllowedToJoin": "ผู้ใช้ทั่วไปได้รับอนุญาตให้เข้าร่วมหรือไม่", + "@areGuestsAllowedToJoin": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterValidEmail": "กรุณาใส่อีเมล์ที่ถูกต้อง", + "@pleaseEnterValidEmail": {}, + "sendOnEnter": "ส่งเมื่อกด enter", + "@sendOnEnter": {}, + "answeredTheCall": "{senderName} รับสายแล้ว", + "@answeredTheCall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "pleaseChooseAtLeastChars": "กรุณาใส่รหัสอย่างน้อย {min} ตัว", + "@pleaseChooseAtLeastChars": { + "type": "text", + "placeholders": { + "min": {} + } + }, + "alias": "นามแฝง", + "@alias": { + "type": "text", + "placeholders": {} + }, + "all": "ทั้งหมด", + "@all": { + "type": "text", + "placeholders": {} + }, + "badServerLoginTypesException": "โฮมเซิร์ฟเวอร์รองรับประเภทการเข้าสู่ระบบ:\n{serverVersions}\nแต่แอปนี้รองรับเฉพาะ:\n{supportedVersions}", + "@badServerLoginTypesException": { + "type": "text", + "placeholders": { + "serverVersions": {}, + "supportedVersions": {} + } + }, + "updateNow": "เริ่มการอัปเดตในเบื้องหลัง", + "@updateNow": {}, + "edit": "แก้ไข", + "@edit": { + "type": "text", + "placeholders": {} + }, + "copy": "คัดลอก", + "@copy": { + "type": "text", + "placeholders": {} + }, + "importFromZipFile": "นำเข้าจากไฟล์ .zip", + "@importFromZipFile": {}, + "autoplayImages": "เล่นสติ๊กเกอร์และอิโมจิแบบเคลื่อนไหวโดยอัตโนมัติ", + "@autoplayImages": { + "type": "text", + "placeholder": {} + }, + "updateAvailable": "มีการอัปเดต FluffyChat แล้ว", + "@updateAvailable": {}, + "help": "ช่วยเหลือ", + "@help": { + "type": "text", + "placeholders": {} + }, + "chatDetails": "รายละเอียดแชท", + "@chatDetails": { + "type": "text", + "placeholders": {} + }, + "repeatPassword": "ใส่รหัสผ่านอีกรอบ", + "@repeatPassword": {}, + "delete": "ลบออก", + "@delete": { + "type": "text", + "placeholders": {} + }, + "acceptedTheInvitation": "👍 {username} ได้รับการชวนแล้ว", + "@acceptedTheInvitation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "send": "ส่ง", + "@send": { + "type": "text", + "placeholders": {} + }, + "exportEmotePack": "ส่งอิโมจิแพ็คออกเป็นไฟล์ .zip", + "@exportEmotePack": {}, + "account": "บัญชี", + "@account": { + "type": "text", + "placeholders": {} + }, + "savedEmotePack": "บันท฿กแพ็คอิโมจิไว้ที่ {path}!", + "@savedEmotePack": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "chat": "แชท", + "@chat": { + "type": "text", + "placeholders": {} + }, + "areYouSure": "คุณแน่ใจไหม?", + "@areYouSure": { + "type": "text", + "placeholders": {} + }, + "allChats": "แชททั้งหมด", + "@allChats": { + "type": "text", + "placeholders": {} + }, + "passwordsDoNotMatch": "รหัสผ่านของคุณไม่ตรงกัน", + "@passwordsDoNotMatch": {}, + "addToSpace": "เพิ่มไปที่ space", + "@addToSpace": {}, + "importZipFile": "นำเข้าไฟล์ .zip", + "@importZipFile": {}, + "about": "เกี่ยวกับ", + "@about": { + "type": "text", + "placeholders": {} + }, + "activatedEndToEndEncryption": "🔐 {username} เปิดใช้งาน end to end encryption", + "@activatedEndToEndEncryption": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "fluffychat": "FluffyChat", + "@fluffychat": { + "type": "text", + "placeholders": {} + }, + "googlyEyesContent": "{senderName} ส่งตากวนๆให้คุณ", + "@googlyEyesContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "addChatDescription": "เพิ่มคำอธิบายการแชท", + "@addChatDescription": {}, + "appLock": "ล็อคแอป", + "@appLock": { + "type": "text", + "placeholders": {} + }, + "sendTypingNotifications": "ส่งการแจ้งเตือนการพิมพ์", + "@sendTypingNotifications": {}, + "importEmojis": "นำเข้าอ๊โมจิ", + "@importEmojis": {}, + "confirmMatrixId": "กรุณายืนยัน Matrix ID ของคุณเพื่อลบบัญชีของคุณ", + "@confirmMatrixId": {}, + "notAnImage": "ไม่ใช่ไฟล์รูปภาพ", + "@notAnImage": {}, + "areYouSureYouWantToLogout": "คุณแน่ใจว่าคุณต้องการที่จะออกจากระบบ?", + "@areYouSureYouWantToLogout": { + "type": "text", + "placeholders": {} + }, + "cuddleContent": "{senderName} เคล้าเคลียคุณ", + "@cuddleContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "askVerificationRequest": "ยอมรับคำขอยืนยันนี้จาก {username} หรือไม่", + "@askVerificationRequest": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "addEmail": "เพิ่มอีเมล", + "@addEmail": { + "type": "text", + "placeholders": {} + }, + "commandHint_hug": "ส่งกอดให้", + "@commandHint_hug": {}, + "replace": "แทนที่", + "@replace": {}, + "archive": "คลังเก็บ", + "@archive": { + "type": "text", + "placeholders": {} + }, + "accept": "ยอมรับ", + "@accept": { + "type": "text", + "placeholders": {} + }, + "commandHint_googly": "ส่งสายตากวนๆ มาให้หน่อย", + "@commandHint_googly": {}, + "pin": "ปักหมุด", + "@pin": { + "type": "text", + "placeholders": {} + }, + "importNow": "นำเข้าเลย", + "@importNow": {}, + "anyoneCanJoin": "ใครๆ ก็สามารถเข้าร่วมได้", + "@anyoneCanJoin": { + "type": "text", + "placeholders": {} + }, + "showPassword": "", + "@showPassword": { + "type": "text", + "placeholders": {} + }, + "darkTheme": "", + "@darkTheme": { + "type": "text", + "placeholders": {} + }, + "passphraseOrKey": "", + "@passphraseOrKey": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourPassword": "", + "@pleaseEnterYourPassword": { + "type": "text", + "placeholders": {} + }, + "theyMatch": "", + "@theyMatch": { + "type": "text", + "placeholders": {} + }, + "connect": "", + "@connect": { + "type": "text", + "placeholders": {} + }, + "jumpToLastReadMessage": "", + "@jumpToLastReadMessage": {}, + "allRooms": "", + "@allRooms": { + "type": "text", + "placeholders": {} + }, + "obtainingLocation": "", + "@obtainingLocation": { + "type": "text", + "placeholders": {} + }, + "whoCanSeeMyStories": "", + "@whoCanSeeMyStories": {}, + "chats": "", + "@chats": { + "type": "text", + "placeholders": {} + }, + "widgetVideo": "", + "@widgetVideo": {}, + "dismiss": "", + "@dismiss": {}, + "unknownDevice": "", + "@unknownDevice": { + "type": "text", + "placeholders": {} + }, + "emoteShortcode": "", + "@emoteShortcode": { + "type": "text", + "placeholders": {} + }, + "noEncryptionForPublicRooms": "", + "@noEncryptionForPublicRooms": { + "type": "text", + "placeholders": {} + }, + "reportErrorDescription": "", + "@reportErrorDescription": {}, + "directChats": "", + "@directChats": { + "type": "text", + "placeholders": {} + }, + "setPermissionsLevel": "", + "@setPermissionsLevel": { + "type": "text", + "placeholders": {} + }, + "inviteContactToGroup": "", + "@inviteContactToGroup": { + "type": "text", + "placeholders": { + "groupName": {} + } + }, + "addAccount": "", + "@addAccount": {}, + "close": "", + "@close": { + "type": "text", + "placeholders": {} + }, + "configureChat": "", + "@configureChat": { + "type": "text", + "placeholders": {} + }, + "seenByUserAndUser": "", + "@seenByUserAndUser": { + "type": "text", + "placeholders": { + "username": {}, + "username2": {} + } + }, + "chatHasBeenAddedToThisSpace": "", + "@chatHasBeenAddedToThisSpace": {}, + "reply": "", + "@reply": { + "type": "text", + "placeholders": {} + }, + "currentlyActive": "", + "@currentlyActive": { + "type": "text", + "placeholders": {} + }, + "removeYourAvatar": "", + "@removeYourAvatar": { + "type": "text", + "placeholders": {} + }, + "unsupportedAndroidVersion": "", + "@unsupportedAndroidVersion": {}, + "enterASpacepName": "", + "@enterASpacepName": {}, + "device": "", + "@device": { + "type": "text", + "placeholders": {} + }, + "blockDevice": "", + "@blockDevice": { + "type": "text", + "placeholders": {} + }, + "commandHint_html": "", + "@commandHint_html": { + "type": "text", + "description": "Usage hint for the command /html" + }, + "widgetJitsi": "", + "@widgetJitsi": {}, + "youAreNoLongerParticipatingInThisChat": "", + "@youAreNoLongerParticipatingInThisChat": { + "type": "text", + "placeholders": {} + }, + "encryption": "", + "@encryption": { + "type": "text", + "placeholders": {} + }, + "messageType": "", + "@messageType": {}, + "noEmailWarning": "", + "@noEmailWarning": {}, + "indexedDbErrorLong": "", + "@indexedDbErrorLong": {}, + "oneClientLoggedOut": "", + "@oneClientLoggedOut": {}, + "toggleMuted": "", + "@toggleMuted": { + "type": "text", + "placeholders": {} + }, + "unsupportedAndroidVersionLong": "", + "@unsupportedAndroidVersionLong": {}, + "kicked": "", + "@kicked": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "title": "", + "@title": { + "description": "Title for the application", + "type": "text", + "placeholders": {} + }, + "changeTheNameOfTheGroup": "", + "@changeTheNameOfTheGroup": { + "type": "text", + "placeholders": {} + }, + "changedTheChatAvatar": "", + "@changedTheChatAvatar": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "verifySuccess": "", + "@verifySuccess": { + "type": "text", + "placeholders": {} + }, + "sendFile": "", + "@sendFile": { + "type": "text", + "placeholders": {} + }, + "newVerificationRequest": "", + "@newVerificationRequest": { + "type": "text", + "placeholders": {} + }, + "startFirstChat": "", + "@startFirstChat": {}, + "callingAccount": "", + "@callingAccount": {}, + "requestPermission": "", + "@requestPermission": { + "type": "text", + "placeholders": {} + }, + "sentAPicture": "", + "@sentAPicture": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "invited": "", + "@invited": { + "type": "text", + "placeholders": {} + }, + "changedTheDisplaynameTo": "", + "@changedTheDisplaynameTo": { + "type": "text", + "placeholders": { + "username": {}, + "displayname": {} + } + }, + "setColorTheme": "", + "@setColorTheme": {}, + "nextAccount": "", + "@nextAccount": {}, + "commandHint_create": "", + "@commandHint_create": { + "type": "text", + "description": "Usage hint for the command /create" + }, + "youAreInvitedToThisChat": "", + "@youAreInvitedToThisChat": { + "type": "text", + "placeholders": {} + }, + "singlesignon": "", + "@singlesignon": { + "type": "text", + "placeholders": {} + }, + "warning": "", + "@warning": { + "type": "text", + "placeholders": {} + }, + "password": "", + "@password": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterAMatrixIdentifier": "", + "@pleaseEnterAMatrixIdentifier": { + "type": "text", + "placeholders": {} + }, + "allSpaces": "", + "@allSpaces": {}, + "editDisplayname": "", + "@editDisplayname": { + "type": "text", + "placeholders": {} + }, + "user": "", + "@user": {}, + "roomVersion": "", + "@roomVersion": { + "type": "text", + "placeholders": {} + }, + "sentAFile": "", + "@sentAFile": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "videoCall": "", + "@videoCall": { + "type": "text", + "placeholders": {} + }, + "youAcceptedTheInvitation": "", + "@youAcceptedTheInvitation": {}, + "banFromChat": "", + "@banFromChat": { + "type": "text", + "placeholders": {} + }, + "noMatrixServer": "", + "@noMatrixServer": { + "type": "text", + "placeholders": { + "server1": {}, + "server2": {} + } + }, + "userAndOthersAreTyping": "", + "@userAndOthersAreTyping": { + "type": "text", + "placeholders": { + "username": {}, + "count": {} + } + }, + "youInvitedBy": "", + "@youInvitedBy": { + "placeholders": { + "user": {} + } + }, + "userIsTyping": "", + "@userIsTyping": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "openAppToReadMessages": "", + "@openAppToReadMessages": { + "type": "text", + "placeholders": {} + }, + "sentAVideo": "", + "@sentAVideo": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "banUserDescription": "", + "@banUserDescription": {}, + "inviteContact": "", + "@inviteContact": { + "type": "text", + "placeholders": {} + }, + "requests": "", + "@requests": {}, + "widgetEtherpad": "", + "@widgetEtherpad": {}, + "waitingPartnerAcceptRequest": "", + "@waitingPartnerAcceptRequest": { + "type": "text", + "placeholders": {} + }, + "writeAMessage": "", + "@writeAMessage": { + "type": "text", + "placeholders": {} + }, + "changeTheme": "", + "@changeTheme": { + "type": "text", + "placeholders": {} + }, + "stories": "", + "@stories": {}, + "id": "", + "@id": { + "type": "text", + "placeholders": {} + }, + "addToStory": "", + "@addToStory": {}, + "removeDevicesDescription": "", + "@removeDevicesDescription": {}, + "changedTheChatDescriptionTo": "", + "@changedTheChatDescriptionTo": { + "type": "text", + "placeholders": { + "username": {}, + "description": {} + } + }, + "countParticipants": "", + "@countParticipants": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "separateChatTypes": "", + "@separateChatTypes": { + "type": "text", + "placeholders": {} + }, + "tryAgain": "", + "@tryAgain": {}, + "blocked": "", + "@blocked": { + "type": "text", + "placeholders": {} + }, + "youKickedAndBanned": "", + "@youKickedAndBanned": { + "placeholders": { + "user": {} + } + }, + "dateWithoutYear": "", + "@dateWithoutYear": { + "type": "text", + "placeholders": { + "month": {}, + "day": {} + } + }, + "showDirectChatsInSpaces": "", + "@showDirectChatsInSpaces": { + "type": "text", + "placeholders": {} + }, + "removeDevice": "", + "@removeDevice": { + "type": "text", + "placeholders": {} + }, + "youCannotInviteYourself": "", + "@youCannotInviteYourself": { + "type": "text", + "placeholders": {} + }, + "unbanUserDescription": "", + "@unbanUserDescription": {}, + "todoLists": "", + "@todoLists": {}, + "userAndUserAreTyping": "", + "@userAndUserAreTyping": { + "type": "text", + "placeholders": { + "username": {}, + "username2": {} + } + }, + "pleaseClickOnLink": "", + "@pleaseClickOnLink": { + "type": "text", + "placeholders": {} + }, + "saveFile": "", + "@saveFile": { + "type": "text", + "placeholders": {} + }, + "seenByUserAndCountOthers": "", + "@seenByUserAndCountOthers": { + "type": "text", + "placeholders": { + "username": {}, + "count": {} + } + }, + "pickImage": "", + "@pickImage": { + "type": "text", + "placeholders": {} + }, + "youRejectedTheInvitation": "", + "@youRejectedTheInvitation": {}, + "otherCallingPermissions": "", + "@otherCallingPermissions": {}, + "messagesStyle": "", + "@messagesStyle": {}, + "couldNotDecryptMessage": "", + "@couldNotDecryptMessage": { + "type": "text", + "placeholders": { + "error": {} + } + }, + "invitedUsersOnly": "", + "@invitedUsersOnly": { + "type": "text", + "placeholders": {} + }, + "link": "", + "@link": {}, + "widgetUrlError": "", + "@widgetUrlError": {}, + "emailOrUsername": "", + "@emailOrUsername": {}, + "newSpaceDescription": "", + "@newSpaceDescription": {}, + "chatDescription": "", + "@chatDescription": {}, + "callingAccountDetails": "", + "@callingAccountDetails": {}, + "next": "", + "@next": { + "type": "text", + "placeholders": {} + }, + "pleaseFollowInstructionsOnWeb": "", + "@pleaseFollowInstructionsOnWeb": { + "type": "text", + "placeholders": {} + }, + "changedTheGuestAccessRules": "", + "@changedTheGuestAccessRules": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "dateWithYear": "", + "@dateWithYear": { + "type": "text", + "placeholders": { + "year": {}, + "month": {}, + "day": {} + } + }, + "editRoomAliases": "", + "@editRoomAliases": { + "type": "text", + "placeholders": {} + }, + "enterSpace": "", + "@enterSpace": {}, + "encryptThisChat": "", + "@encryptThisChat": {}, + "fileName": "", + "@fileName": { + "type": "text", + "placeholders": {} + }, + "unavailable": "", + "@unavailable": { + "type": "text", + "placeholders": {} + }, + "previousAccount": "", + "@previousAccount": {}, + "publicRooms": "", + "@publicRooms": { + "type": "text", + "placeholders": {} + }, + "fromTheInvitation": "", + "@fromTheInvitation": { + "type": "text", + "placeholders": {} + }, + "sendMessages": "", + "@sendMessages": { + "type": "text", + "placeholders": {} + }, + "incorrectPassphraseOrKey": "", + "@incorrectPassphraseOrKey": { + "type": "text", + "placeholders": {} + }, + "emoteWarnNeedToPick": "", + "@emoteWarnNeedToPick": { + "type": "text", + "placeholders": {} + }, + "reopenChat": "", + "@reopenChat": {}, + "pleaseEnterRecoveryKey": "", + "@pleaseEnterRecoveryKey": {}, + "create": "", + "@create": { + "type": "text", + "placeholders": {} + }, + "toggleFavorite": "", + "@toggleFavorite": { + "type": "text", + "placeholders": {} + }, + "no": "", + "@no": { + "type": "text", + "placeholders": {} + }, + "widgetNameError": "", + "@widgetNameError": {}, + "inoffensive": "", + "@inoffensive": { + "type": "text", + "placeholders": {} + }, + "unpin": "", + "@unpin": { + "type": "text", + "placeholders": {} + }, + "addToBundle": "", + "@addToBundle": {}, + "reportMessage": "", + "@reportMessage": { + "type": "text", + "placeholders": {} + }, + "spaceIsPublic": "", + "@spaceIsPublic": { + "type": "text", + "placeholders": {} + }, + "addWidget": "", + "@addWidget": {}, + "removeAllOtherDevices": "", + "@removeAllOtherDevices": { + "type": "text", + "placeholders": {} + }, + "unblockDevice": "", + "@unblockDevice": { + "type": "text", + "placeholders": {} + }, + "countFiles": "", + "@countFiles": { + "placeholders": { + "count": {} + } + }, + "noKeyForThisMessage": "", + "@noKeyForThisMessage": {}, + "enableEncryptionWarning": "", + "@enableEncryptionWarning": { + "type": "text", + "placeholders": {} + }, + "inviteText": "", + "@inviteText": { + "type": "text", + "placeholders": { + "username": {}, + "link": {} + } + }, + "shareLocation": "", + "@shareLocation": { + "type": "text", + "placeholders": {} + }, + "reason": "", + "@reason": { + "type": "text", + "placeholders": {} + }, + "commandHint_markasgroup": "", + "@commandHint_markasgroup": {}, + "editTodo": "", + "@editTodo": {}, + "errorObtainingLocation": "", + "@errorObtainingLocation": { + "type": "text", + "placeholders": { + "error": {} + } + }, + "hydrateTor": "", + "@hydrateTor": {}, + "pushNotificationsNotAvailable": "", + "@pushNotificationsNotAvailable": {}, + "passwordRecovery": "", + "@passwordRecovery": { + "type": "text", + "placeholders": {} + }, + "storeInAppleKeyChain": "", + "@storeInAppleKeyChain": {}, + "replaceRoomWithNewerVersion": "", + "@replaceRoomWithNewerVersion": { + "type": "text", + "placeholders": {} + }, + "hydrate": "", + "@hydrate": {}, + "invalidServerName": "", + "@invalidServerName": {}, + "chatPermissions": "", + "@chatPermissions": {}, + "voiceMessage": "", + "@voiceMessage": { + "type": "text", + "placeholders": {} + }, + "wipeChatBackup": "", + "@wipeChatBackup": { + "type": "text", + "placeholders": {} + }, + "cantOpenUri": "", + "@cantOpenUri": { + "type": "text", + "placeholders": { + "uri": {} + } + }, + "sender": "", + "@sender": {}, + "storeInAndroidKeystore": "", + "@storeInAndroidKeystore": {}, + "optionalGroupName": "", + "@optionalGroupName": { + "type": "text", + "placeholders": {} + }, + "hideRedactedEvents": "", + "@hideRedactedEvents": { + "type": "text", + "placeholders": {} + }, + "online": "", + "@online": { + "type": "text", + "placeholders": {} + }, + "signInWithPassword": "", + "@signInWithPassword": {}, + "pleaseAddATitle": "", + "@pleaseAddATitle": {}, + "ignoredUsers": "", + "@ignoredUsers": { + "type": "text", + "placeholders": {} + }, + "lastActiveAgo": "", + "@lastActiveAgo": { + "type": "text", + "placeholders": { + "localizedTimeShort": {} + } + }, + "changedTheGuestAccessRulesTo": "", + "@changedTheGuestAccessRulesTo": { + "type": "text", + "placeholders": { + "username": {}, + "rules": {} + } + }, + "weSentYouAnEmail": "", + "@weSentYouAnEmail": { + "type": "text", + "placeholders": {} + }, + "offensive": "", + "@offensive": { + "type": "text", + "placeholders": {} + }, + "needPantalaimonWarning": "", + "@needPantalaimonWarning": { + "type": "text", + "placeholders": {} + }, + "makeAdminDescription": "", + "@makeAdminDescription": {}, + "loadMore": "", + "@loadMore": { + "type": "text", + "placeholders": {} + }, + "noEmotesFound": "", + "@noEmotesFound": { + "type": "text", + "placeholders": {} + }, + "synchronizingPleaseWait": "", + "@synchronizingPleaseWait": { + "type": "text", + "placeholders": {} + }, + "transferFromAnotherDevice": "", + "@transferFromAnotherDevice": { + "type": "text", + "placeholders": {} + }, + "passwordHasBeenChanged": "", + "@passwordHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "pushRules": "", + "@pushRules": { + "type": "text", + "placeholders": {} + }, + "goToTheNewRoom": "", + "@goToTheNewRoom": { + "type": "text", + "placeholders": {} + }, + "commandHint_clearcache": "", + "@commandHint_clearcache": { + "type": "text", + "description": "Usage hint for the command /clearcache" + }, + "loadingPleaseWait": "", + "@loadingPleaseWait": { + "type": "text", + "placeholders": {} + }, + "saveKeyManuallyDescription": "", + "@saveKeyManuallyDescription": {}, + "none": "", + "@none": { + "type": "text", + "placeholders": {} + }, + "editBundlesForAccount": "", + "@editBundlesForAccount": {}, + "renderRichContent": "", + "@renderRichContent": { + "type": "text", + "placeholders": {} + }, + "enableEncryption": "", + "@enableEncryption": { + "type": "text", + "placeholders": {} + }, + "whyIsThisMessageEncrypted": "", + "@whyIsThisMessageEncrypted": {}, + "unreadChats": "", + "@unreadChats": { + "type": "text", + "placeholders": { + "unreadCount": {} + } + }, + "rejectedTheInvitation": "", + "@rejectedTheInvitation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "setChatDescription": "", + "@setChatDescription": {}, + "userLeftTheChat": "", + "@userLeftTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "spaceName": "", + "@spaceName": { + "type": "text", + "placeholders": {} + }, + "discover": "", + "@discover": { + "type": "text", + "placeholders": {} + }, + "toggleUnread": "", + "@toggleUnread": { + "type": "text", + "placeholders": {} + }, + "or": "", + "@or": { + "type": "text", + "placeholders": {} + }, + "dehydrateWarning": "", + "@dehydrateWarning": {}, + "sendOriginal": "", + "@sendOriginal": { + "type": "text", + "placeholders": {} + }, + "noOtherDevicesFound": "", + "@noOtherDevicesFound": {}, + "whoIsAllowedToJoinThisGroup": "", + "@whoIsAllowedToJoinThisGroup": { + "type": "text", + "placeholders": {} + }, + "emptyChat": "", + "@emptyChat": { + "type": "text", + "placeholders": {} + }, + "seenByUser": "", + "@seenByUser": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "storeSecurlyOnThisDevice": "", + "@storeSecurlyOnThisDevice": {}, + "yourChatBackupHasBeenSetUp": "", + "@yourChatBackupHasBeenSetUp": {}, + "addDescription": "", + "@addDescription": {}, + "chatBackup": "", + "@chatBackup": { + "type": "text", + "placeholders": {} + }, + "redactedBy": "", + "@redactedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "submit": "", + "@submit": { + "type": "text", + "placeholders": {} + }, + "videoCallsBetaWarning": "", + "@videoCallsBetaWarning": {}, + "unmuteChat": "", + "@unmuteChat": { + "type": "text", + "placeholders": {} + }, + "createdTheChat": "", + "@createdTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "redactedAnEvent": "", + "@redactedAnEvent": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "storyPrivacyWarning": "", + "@storyPrivacyWarning": {}, + "compareEmojiMatch": "", + "@compareEmojiMatch": { + "type": "text", + "placeholders": {} + }, + "matrixWidgets": "", + "@matrixWidgets": {}, + "participant": "", + "@participant": { + "type": "text", + "placeholders": {} + }, + "logInTo": "", + "@logInTo": { + "type": "text", + "placeholders": { + "homeserver": {} + } + }, + "yes": "", + "@yes": { + "type": "text", + "placeholders": {} + }, + "containsDisplayName": "", + "@containsDisplayName": { + "type": "text", + "placeholders": {} + }, + "signInWith": "", + "@signInWith": { + "type": "text", + "placeholders": { + "provider": {} + } + }, + "username": "", + "@username": { + "type": "text", + "placeholders": {} + }, + "changedTheRoomAliases": "", + "@changedTheRoomAliases": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "fileIsTooBigForServer": "", + "@fileIsTooBigForServer": {}, + "homeserver": "", + "@homeserver": {}, + "noTodosYet": "", + "@noTodosYet": {}, + "people": "", + "@people": { + "type": "text", + "placeholders": {} + }, + "changedTheHistoryVisibilityTo": "", + "@changedTheHistoryVisibilityTo": { + "type": "text", + "placeholders": { + "username": {}, + "rules": {} + } + }, + "leftTheChat": "", + "@leftTheChat": { + "type": "text", + "placeholders": {} + }, + "verified": "", + "@verified": { + "type": "text", + "placeholders": {} + }, + "setStatus": "", + "@setStatus": { + "type": "text", + "placeholders": {} + }, + "groupWith": "", + "@groupWith": { + "type": "text", + "placeholders": { + "displayname": {} + } + }, + "callingPermissions": "", + "@callingPermissions": {}, + "newMessageInFluffyChat": "", + "@newMessageInFluffyChat": { + "type": "text", + "placeholders": {} + }, + "readUpToHere": "", + "@readUpToHere": {}, + "start": "", + "@start": {}, + "bubbleSize": "", + "@bubbleSize": { + "type": "text", + "placeholders": {} + }, + "downloadFile": "", + "@downloadFile": { + "type": "text", + "placeholders": {} + }, + "deviceId": "", + "@deviceId": { + "type": "text", + "placeholders": {} + }, + "register": "", + "@register": { + "type": "text", + "placeholders": {} + }, + "unlockOldMessages": "", + "@unlockOldMessages": {}, + "identity": "", + "@identity": { + "type": "text", + "placeholders": {} + }, + "numChats": "", + "@numChats": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "changedTheJoinRulesTo": "", + "@changedTheJoinRulesTo": { + "type": "text", + "placeholders": { + "username": {}, + "joinRules": {} + } + }, + "ignore": "", + "@ignore": { + "type": "text", + "placeholders": {} + }, + "whatIsGoingOn": "", + "@whatIsGoingOn": {}, + "recording": "", + "@recording": { + "type": "text", + "placeholders": {} + }, + "changedTheChatPermissions": "", + "@changedTheChatPermissions": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changeWallpaper": "", + "@changeWallpaper": { + "type": "text", + "placeholders": {} + }, + "moderator": "", + "@moderator": { + "type": "text", + "placeholders": {} + }, + "optionalRedactReason": "", + "@optionalRedactReason": {}, + "waitingPartnerEmoji": "", + "@waitingPartnerEmoji": { + "type": "text", + "placeholders": {} + }, + "channelCorruptedDecryptError": "", + "@channelCorruptedDecryptError": { + "type": "text", + "placeholders": {} + }, + "tryToSendAgain": "", + "@tryToSendAgain": { + "type": "text", + "placeholders": {} + }, + "guestsCanJoin": "", + "@guestsCanJoin": { + "type": "text", + "placeholders": {} + }, + "ok": "", + "@ok": { + "type": "text", + "placeholders": {} + }, + "copyToClipboard": "", + "@copyToClipboard": { + "type": "text", + "placeholders": {} + }, + "dehydrate": "", + "@dehydrate": {}, + "locationPermissionDeniedNotice": "", + "@locationPermissionDeniedNotice": { + "type": "text", + "placeholders": {} + }, + "hasWithdrawnTheInvitationFor": "", + "@hasWithdrawnTheInvitationFor": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "visibleForAllParticipants": "", + "@visibleForAllParticipants": { + "type": "text", + "placeholders": {} + }, + "noRoomsFound": "", + "@noRoomsFound": { + "type": "text", + "placeholders": {} + }, + "banned": "", + "@banned": { + "type": "text", + "placeholders": {} + }, + "sendAsText": "", + "@sendAsText": { + "type": "text" + }, + "inviteForMe": "", + "@inviteForMe": { + "type": "text", + "placeholders": {} + }, + "archiveRoomDescription": "", + "@archiveRoomDescription": {}, + "changedTheChatNameTo": "", + "@changedTheChatNameTo": { + "type": "text", + "placeholders": { + "username": {}, + "chatname": {} + } + }, + "sendSticker": "", + "@sendSticker": { + "type": "text", + "placeholders": {} + }, + "switchToAccount": "", + "@switchToAccount": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "commandInvalid": "", + "@commandInvalid": { + "type": "text" + }, + "setAsCanonicalAlias": "", + "@setAsCanonicalAlias": { + "type": "text", + "placeholders": {} + }, + "whyDoYouWantToReportThis": "", + "@whyDoYouWantToReportThis": { + "type": "text", + "placeholders": {} + }, + "locationDisabledNotice": "", + "@locationDisabledNotice": { + "type": "text", + "placeholders": {} + }, + "letsStart": "", + "@letsStart": {}, + "placeCall": "", + "@placeCall": {}, + "removedBy": "", + "@removedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheRoomInvitationLink": "", + "@changedTheRoomInvitationLink": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "newChat": "", + "@newChat": { + "type": "text", + "placeholders": {} + }, + "notifications": "", + "@notifications": { + "type": "text", + "placeholders": {} + }, + "commandHint_plain": "", + "@commandHint_plain": { + "type": "text", + "description": "Usage hint for the command /plain" + }, + "emoteSettings": "", + "@emoteSettings": { + "type": "text", + "placeholders": {} + }, + "experimentalVideoCalls": "", + "@experimentalVideoCalls": {}, + "openCamera": "", + "@openCamera": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterRecoveryKeyDescription": "", + "@pleaseEnterRecoveryKeyDescription": {}, + "guestsAreForbidden": "", + "@guestsAreForbidden": { + "type": "text", + "placeholders": {} + }, + "mention": "", + "@mention": { + "type": "text", + "placeholders": {} + }, + "openInMaps": "", + "@openInMaps": { + "type": "text", + "placeholders": {} + }, + "withTheseAddressesRecoveryDescription": "", + "@withTheseAddressesRecoveryDescription": { + "type": "text", + "placeholders": {} + }, + "inviteContactToGroupQuestion": "", + "@inviteContactToGroupQuestion": {}, + "emoteExists": "", + "@emoteExists": { + "type": "text", + "placeholders": {} + }, + "redactedByBecause": "", + "@redactedByBecause": { + "type": "text", + "placeholders": { + "username": {}, + "reason": {} + } + }, + "isTyping": "", + "@isTyping": { + "type": "text", + "placeholders": {} + }, + "youHaveWithdrawnTheInvitationFor": "", + "@youHaveWithdrawnTheInvitationFor": { + "placeholders": { + "user": {} + } + }, + "group": "", + "@group": { + "type": "text", + "placeholders": {} + }, + "leave": "", + "@leave": { + "type": "text", + "placeholders": {} + }, + "skip": "", + "@skip": { + "type": "text", + "placeholders": {} + }, + "appearOnTopDetails": "", + "@appearOnTopDetails": {}, + "roomHasBeenUpgraded": "", + "@roomHasBeenUpgraded": { + "type": "text", + "placeholders": {} + }, + "enterRoom": "", + "@enterRoom": {}, + "enableEmotesGlobally": "", + "@enableEmotesGlobally": { + "type": "text", + "placeholders": {} + }, + "ignoreListDescription": "", + "@ignoreListDescription": { + "type": "text", + "placeholders": {} + }, + "pleaseChooseAPasscode": "", + "@pleaseChooseAPasscode": { + "type": "text", + "placeholders": {} + }, + "noPasswordRecoveryDescription": "", + "@noPasswordRecoveryDescription": { + "type": "text", + "placeholders": {} + }, + "changedTheProfileAvatar": "", + "@changedTheProfileAvatar": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "reportUser": "", + "@reportUser": {}, + "sharedTheLocation": "", + "@sharedTheLocation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "commandHint_send": "", + "@commandHint_send": { + "type": "text", + "description": "Usage hint for the command /send" + }, + "onlineKeyBackupEnabled": "", + "@onlineKeyBackupEnabled": { + "type": "text", + "placeholders": {} + }, + "unbannedUser": "", + "@unbannedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "confirmEventUnpin": "", + "@confirmEventUnpin": {}, + "badServerVersionsException": "", + "@badServerVersionsException": { + "type": "text", + "placeholders": { + "serverVersions": {}, + "supportedVersions": {} + } + }, + "youInvitedUser": "", + "@youInvitedUser": { + "placeholders": { + "user": {} + } + }, + "kickedAndBanned": "", + "@kickedAndBanned": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "noConnectionToTheServer": "", + "@noConnectionToTheServer": { + "type": "text", + "placeholders": {} + }, + "fileHasBeenSavedAt": "", + "@fileHasBeenSavedAt": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "license": "", + "@license": { + "type": "text", + "placeholders": {} + }, + "unbanFromChat": "", + "@unbanFromChat": { + "type": "text", + "placeholders": {} + }, + "anyoneCanKnock": "", + "@anyoneCanKnock": {}, + "commandMissing": "", + "@commandMissing": { + "type": "text", + "placeholders": { + "command": {} + }, + "description": "State that {command} is not a valid /command." + }, + "redactMessageDescription": "", + "@redactMessageDescription": {}, + "rejoin": "", + "@rejoin": { + "type": "text", + "placeholders": {} + }, + "recoveryKey": "", + "@recoveryKey": {}, + "redactMessage": "", + "@redactMessage": { + "type": "text", + "placeholders": {} + }, + "forward": "", + "@forward": { + "type": "text", + "placeholders": {} + }, + "commandHint_discardsession": "", + "@commandHint_discardsession": { + "type": "text", + "description": "Usage hint for the command /discardsession" + }, + "invalidInput": "", + "@invalidInput": {}, + "chooseAStrongPassword": "", + "@chooseAStrongPassword": { + "type": "text", + "placeholders": {} + }, + "hideUnknownEvents": "", + "@hideUnknownEvents": { + "type": "text", + "placeholders": {} + }, + "todosUnencrypted": "", + "@todosUnencrypted": {}, + "dehydrateTorLong": "", + "@dehydrateTorLong": {}, + "yourPublicKey": "", + "@yourPublicKey": { + "type": "text", + "placeholders": {} + }, + "tooManyRequestsWarning": "", + "@tooManyRequestsWarning": { + "type": "text", + "placeholders": {} + }, + "invitedUser": "", + "@invitedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "kickFromChat": "", + "@kickFromChat": { + "type": "text", + "placeholders": {} + }, + "commandHint_myroomnick": "", + "@commandHint_myroomnick": { + "type": "text", + "description": "Usage hint for the command /myroomnick" + }, + "offline": "", + "@offline": { + "type": "text", + "placeholders": {} + }, + "replyHasBeenSent": "", + "@replyHasBeenSent": {}, + "noPermission": "", + "@noPermission": { + "type": "text", + "placeholders": {} + }, + "doNotShowAgain": "", + "@doNotShowAgain": {}, + "report": "", + "@report": {}, + "status": "", + "@status": { + "type": "text", + "placeholders": {} + }, + "deny": "", + "@deny": { + "type": "text", + "placeholders": {} + }, + "compareNumbersMatch": "", + "@compareNumbersMatch": { + "type": "text", + "placeholders": {} + }, + "groupIsPublic": "", + "@groupIsPublic": { + "type": "text", + "placeholders": {} + }, + "verifyStart": "", + "@verifyStart": { + "type": "text", + "placeholders": {} + }, + "yourStory": "", + "@yourStory": {}, + "memberChanges": "", + "@memberChanges": { + "type": "text", + "placeholders": {} + }, + "joinRoom": "", + "@joinRoom": { + "type": "text", + "placeholders": {} + }, + "ignoreUsername": "", + "@ignoreUsername": { + "type": "text", + "placeholders": {} + }, + "unverified": "", + "@unverified": {}, + "howOffensiveIsThisContent": "", + "@howOffensiveIsThisContent": { + "type": "text", + "placeholders": {} + }, + "serverRequiresEmail": "", + "@serverRequiresEmail": {}, + "hideUnimportantStateEvents": "", + "@hideUnimportantStateEvents": {}, + "screenSharingTitle": "", + "@screenSharingTitle": {}, + "widgetCustom": "", + "@widgetCustom": {}, + "sentCallInformations": "", + "@sentCallInformations": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "addToSpaceDescription": "", + "@addToSpaceDescription": {}, + "whoCanSeeMyStoriesDesc": "", + "@whoCanSeeMyStoriesDesc": {}, + "youBannedUser": "", + "@youBannedUser": { + "placeholders": { + "user": {} + } + }, + "theyDontMatch": "", + "@theyDontMatch": { + "type": "text", + "placeholders": {} + }, + "unsubscribeStories": "", + "@unsubscribeStories": {}, + "youHaveBeenBannedFromThisChat": "", + "@youHaveBeenBannedFromThisChat": { + "type": "text", + "placeholders": {} + }, + "displaynameHasBeenChanged": "", + "@displaynameHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "loginWithOneClick": "", + "@loginWithOneClick": {}, + "sentAnAudio": "", + "@sentAnAudio": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "editRoomAvatar": "", + "@editRoomAvatar": { + "type": "text", + "placeholders": {} + }, + "encrypted": "", + "@encrypted": { + "type": "text", + "placeholders": {} + }, + "commandHint_leave": "", + "@commandHint_leave": { + "type": "text", + "description": "Usage hint for the command /leave" + }, + "commandHint_myroomavatar": "", + "@commandHint_myroomavatar": { + "type": "text", + "description": "Usage hint for the command /myroomavatar" + }, + "cancel": "", + "@cancel": { + "type": "text", + "placeholders": {} + }, + "hasKnocked": "", + "@hasKnocked": { + "placeholders": { + "user": {} + } + }, + "publish": "", + "@publish": {}, + "openLinkInBrowser": "", + "@openLinkInBrowser": {}, + "clearArchive": "", + "@clearArchive": {}, + "commandHint_react": "", + "@commandHint_react": { + "type": "text", + "description": "Usage hint for the command /react" + }, + "changedTheHistoryVisibility": "", + "@changedTheHistoryVisibility": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "commandHint_me": "", + "@commandHint_me": { + "type": "text", + "description": "Usage hint for the command /me" + }, + "pleaseEnterYourUsername": "", + "@pleaseEnterYourUsername": { + "type": "text", + "placeholders": {} + }, + "messageInfo": "", + "@messageInfo": {}, + "disableEncryptionWarning": "", + "@disableEncryptionWarning": {}, + "directChat": "", + "@directChat": {}, + "noOneCanJoin": "", + "@noOneCanJoin": {}, + "encryptionNotEnabled": "", + "@encryptionNotEnabled": { + "type": "text", + "placeholders": {} + }, + "wrongPinEntered": "", + "@wrongPinEntered": { + "type": "text", + "placeholders": { + "seconds": {} + } + }, + "lightTheme": "", + "@lightTheme": { + "type": "text", + "placeholders": {} + }, + "inviteGroupChat": "", + "@inviteGroupChat": {}, + "appearOnTop": "", + "@appearOnTop": {}, + "invitePrivateChat": "", + "@invitePrivateChat": {}, + "verifyTitle": "", + "@verifyTitle": { + "type": "text", + "placeholders": {} + }, + "foregroundServiceRunning": "", + "@foregroundServiceRunning": {}, + "enterAnEmailAddress": "", + "@enterAnEmailAddress": { + "type": "text", + "placeholders": {} + }, + "voiceCall": "", + "@voiceCall": {}, + "commandHint_kick": "", + "@commandHint_kick": { + "type": "text", + "description": "Usage hint for the command /kick" + }, + "copiedToClipboard": "", + "@copiedToClipboard": { + "type": "text", + "placeholders": {} + }, + "createNewSpace": "", + "@createNewSpace": { + "type": "text", + "placeholders": {} + }, + "commandHint_unban": "", + "@commandHint_unban": { + "type": "text", + "description": "Usage hint for the command /unban" + }, + "unknownEncryptionAlgorithm": "", + "@unknownEncryptionAlgorithm": { + "type": "text", + "placeholders": {} + }, + "commandHint_ban": "", + "@commandHint_ban": { + "type": "text", + "description": "Usage hint for the command /ban" + }, + "confirm": "", + "@confirm": { + "type": "text", + "placeholders": {} + }, + "wasDirectChatDisplayName": "", + "@wasDirectChatDisplayName": { + "type": "text", + "placeholders": { + "oldDisplayName": {} + } + }, + "noChatDescriptionYet": "", + "@noChatDescriptionYet": {}, + "defaultPermissionLevel": "", + "@defaultPermissionLevel": { + "type": "text", + "placeholders": {} + }, + "newTodo": "", + "@newTodo": {}, + "removeFromBundle": "", + "@removeFromBundle": {}, + "numUsersTyping": "", + "@numUsersTyping": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "fontSize": "", + "@fontSize": { + "type": "text", + "placeholders": {} + }, + "whoCanPerformWhichAction": "", + "@whoCanPerformWhichAction": { + "type": "text", + "placeholders": {} + }, + "learnMore": "", + "@learnMore": {}, + "iHaveClickedOnLink": "", + "@iHaveClickedOnLink": { + "type": "text", + "placeholders": {} + }, + "you": "", + "@you": { + "type": "text", + "placeholders": {} + }, + "users": "", + "@users": {}, + "openGallery": "", + "@openGallery": {}, + "chatDescriptionHasBeenChanged": "", + "@chatDescriptionHasBeenChanged": {}, + "search": "", + "@search": { + "type": "text", + "placeholders": {} + }, + "newGroup": "", + "@newGroup": {}, + "bundleName": "", + "@bundleName": {}, + "dehydrateTor": "", + "@dehydrateTor": {}, + "todoListChangedError": "", + "@todoListChangedError": {}, + "removeFromSpace": "", + "@removeFromSpace": {}, + "enterInviteLinkOrMatrixId": "", + "@enterInviteLinkOrMatrixId": {}, + "dateAndTimeOfDay": "", + "@dateAndTimeOfDay": { + "type": "text", + "placeholders": { + "date": {}, + "timeOfDay": {} + } + }, + "commandHint_op": "", + "@commandHint_op": { + "type": "text", + "description": "Usage hint for the command /op" + }, + "commandHint_join": "", + "@commandHint_join": { + "type": "text", + "description": "Usage hint for the command /join" + }, + "sourceCode": "", + "@sourceCode": { + "type": "text", + "placeholders": {} + }, + "enterAGroupName": "", + "@enterAGroupName": { + "type": "text", + "placeholders": {} + }, + "roomUpgradeDescription": "", + "@roomUpgradeDescription": {}, + "commandHint_invite": "", + "@commandHint_invite": { + "type": "text", + "description": "Usage hint for the command /invite" + }, + "userSentUnknownEvent": "", + "@userSentUnknownEvent": { + "type": "text", + "placeholders": { + "username": {}, + "type": {} + } + }, + "scanQrCode": "", + "@scanQrCode": {}, + "logout": "", + "@logout": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterANumber": "", + "@pleaseEnterANumber": {}, + "contactHasBeenInvitedToTheGroup": "", + "@contactHasBeenInvitedToTheGroup": { + "type": "text", + "placeholders": {} + }, + "youKicked": "", + "@youKicked": { + "placeholders": { + "user": {} + } + }, + "changedTheJoinRules": "", + "@changedTheJoinRules": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "profileNotFound": "", + "@profileNotFound": {}, + "jump": "", + "@jump": {}, + "groups": "", + "@groups": { + "type": "text", + "placeholders": {} + }, + "reactedWith": "", + "@reactedWith": { + "type": "text", + "placeholders": { + "sender": {}, + "reaction": {} + } + }, + "bannedUser": "", + "@bannedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "iUnderstand": "", + "@iUnderstand": {}, + "sorryThatsNotPossible": "", + "@sorryThatsNotPossible": {}, + "storyFrom": "", + "@storyFrom": { + "type": "text", + "placeholders": { + "date": {}, + "body": {} + } + }, + "videoWithSize": "", + "@videoWithSize": { + "type": "text", + "placeholders": { + "size": {} + } + }, + "oopsSomethingWentWrong": "", + "@oopsSomethingWentWrong": { + "type": "text", + "placeholders": {} + }, + "loadCountMoreParticipants": "", + "@loadCountMoreParticipants": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "shareInviteLink": "", + "@shareInviteLink": {}, + "commandHint_markasdm": "", + "@commandHint_markasdm": {}, + "recoveryKeyLost": "", + "@recoveryKeyLost": {}, + "containsUserName": "", + "@containsUserName": { + "type": "text", + "placeholders": {} + }, + "messages": "", + "@messages": { + "type": "text", + "placeholders": {} + }, + "login": "", + "@login": { + "type": "text", + "placeholders": {} + }, + "deviceKeys": "", + "@deviceKeys": {}, + "waitingPartnerNumbers": "", + "@waitingPartnerNumbers": { + "type": "text", + "placeholders": {} + }, + "noGoogleServicesWarning": "", + "@noGoogleServicesWarning": { + "type": "text", + "placeholders": {} + }, + "everythingReady": "", + "@everythingReady": { + "type": "text", + "placeholders": {} + }, + "emoteKeyboardNoRecents": "", + "@emoteKeyboardNoRecents": { + "type": "text", + "placeholders": {} + }, + "setCustomEmotes": "", + "@setCustomEmotes": { + "type": "text", + "placeholders": {} + }, + "startedACall": "", + "@startedACall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "emoteInvalid": "", + "@emoteInvalid": { + "type": "text", + "placeholders": {} + }, + "systemTheme": "", + "@systemTheme": { + "type": "text", + "placeholders": {} + }, + "messageWillBeRemovedWarning": "", + "@messageWillBeRemovedWarning": { + "type": "text", + "placeholders": {} + }, + "endToEndEncryption": "", + "@endToEndEncryption": {}, + "notificationsEnabledForThisAccount": "", + "@notificationsEnabledForThisAccount": { + "type": "text", + "placeholders": {} + }, + "deleteMessage": "", + "@deleteMessage": { + "type": "text", + "placeholders": {} + }, + "visibilityOfTheChatHistory": "", + "@visibilityOfTheChatHistory": { + "type": "text", + "placeholders": {} + }, + "settings": "", + "@settings": { + "type": "text", + "placeholders": {} + }, + "setTheme": "", + "@setTheme": {}, + "changeTheHomeserver": "", + "@changeTheHomeserver": { + "type": "text", + "placeholders": {} + }, + "youJoinedTheChat": "", + "@youJoinedTheChat": {}, + "wallpaper": "", + "@wallpaper": { + "type": "text", + "placeholders": {} + }, + "openVideoCamera": "", + "@openVideoCamera": { + "type": "text", + "placeholders": {} + }, + "play": "", + "@play": { + "type": "text", + "placeholders": { + "fileName": {} + } + }, + "chatBackupDescription": "", + "@chatBackupDescription": { + "type": "text", + "placeholders": {} + }, + "changeDeviceName": "", + "@changeDeviceName": { + "type": "text", + "placeholders": {} + }, + "lastSeenLongTimeAgo": "", + "@lastSeenLongTimeAgo": { + "type": "text", + "placeholders": {} + }, + "passwordForgotten": "", + "@passwordForgotten": { + "type": "text", + "placeholders": {} + }, + "statusExampleMessage": "", + "@statusExampleMessage": { + "type": "text", + "placeholders": {} + }, + "thisUserHasNotPostedAnythingYet": "", + "@thisUserHasNotPostedAnythingYet": {}, + "security": "", + "@security": { + "type": "text", + "placeholders": {} + }, + "markAsRead": "", + "@markAsRead": {}, + "sendAudio": "", + "@sendAudio": { + "type": "text", + "placeholders": {} + }, + "widgetName": "", + "@widgetName": {}, + "sentASticker": "", + "@sentASticker": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "errorAddingWidget": "", + "@errorAddingWidget": {}, + "commandHint_dm": "", + "@commandHint_dm": { + "type": "text", + "description": "Usage hint for the command /dm" + }, + "reject": "", + "@reject": { + "type": "text", + "placeholders": {} + }, + "extremeOffensive": "", + "@extremeOffensive": { + "type": "text", + "placeholders": {} + }, + "editBlockedServers": "", + "@editBlockedServers": { + "type": "text", + "placeholders": {} + }, + "oopsPushError": "", + "@oopsPushError": { + "type": "text", + "placeholders": {} + }, + "youUnbannedUser": "", + "@youUnbannedUser": { + "placeholders": { + "user": {} + } + }, + "deactivateAccountWarning": "", + "@deactivateAccountWarning": { + "type": "text", + "placeholders": {} + }, + "joinedTheChat": "", + "@joinedTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "visibleForEveryone": "", + "@visibleForEveryone": { + "type": "text", + "placeholders": {} + }, + "pleaseEnter4Digits": "", + "@pleaseEnter4Digits": { + "type": "text", + "placeholders": {} + }, + "newSpace": "", + "@newSpace": {}, + "changePassword": "", + "@changePassword": { + "type": "text", + "placeholders": {} + }, + "devices": "", + "@devices": { + "type": "text", + "placeholders": {} + }, + "unknownEvent": "", + "@unknownEvent": { + "type": "text", + "placeholders": { + "type": {} + } + }, + "emojis": "", + "@emojis": {}, + "signUp": "", + "@signUp": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourPin": "", + "@pleaseEnterYourPin": { + "type": "text", + "placeholders": {} + }, + "pleaseChoose": "", + "@pleaseChoose": { + "type": "text", + "placeholders": {} + }, + "share": "", + "@share": { + "type": "text", + "placeholders": {} + }, + "pleaseTryAgainLaterOrChooseDifferentServer": "", + "@pleaseTryAgainLaterOrChooseDifferentServer": {}, + "createGroup": "", + "@createGroup": {}, + "privacy": "", + "@privacy": { + "type": "text", + "placeholders": {} + }, + "changeYourAvatar": "", + "@changeYourAvatar": { + "type": "text", + "placeholders": {} + }, + "sendImage": "", + "@sendImage": { + "type": "text", + "placeholders": {} + }, + "hydrateTorLong": "", + "@hydrateTorLong": {}, + "time": "", + "@time": {}, + "enterYourHomeserver": "", + "@enterYourHomeserver": { + "type": "text", + "placeholders": {} + }, + "botMessages": "", + "@botMessages": { + "type": "text", + "placeholders": {} + }, + "contentHasBeenReported": "", + "@contentHasBeenReported": { + "type": "text", + "placeholders": {} + }, + "custom": "", + "@custom": {}, + "noBackupWarning": "", + "@noBackupWarning": {}, + "fromJoining": "", + "@fromJoining": { + "type": "text", + "placeholders": {} + }, + "verify": "", + "@verify": { + "type": "text", + "placeholders": {} + }, + "sendVideo": "", + "@sendVideo": { + "type": "text", + "placeholders": {} + }, + "editWidgets": "", + "@editWidgets": {}, + "storeInSecureStorageDescription": "", + "@storeInSecureStorageDescription": {}, + "openChat": "", + "@openChat": {}, + "kickUserDescription": "", + "@kickUserDescription": {}, + "sendAMessage": "", + "@sendAMessage": { + "type": "text", + "placeholders": {} + }, + "deleteAccount": "", + "@deleteAccount": { + "type": "text", + "placeholders": {} + }, + "setInvitationLink": "", + "@setInvitationLink": { + "type": "text", + "placeholders": {} + }, + "pinMessage": "", + "@pinMessage": {}, + "screenSharingDetail": "", + "@screenSharingDetail": {}, + "muteChat": "", + "@muteChat": { + "type": "text", + "placeholders": {} + }, + "invite": "", + "@invite": {}, + "enableMultiAccounts": "", + "@enableMultiAccounts": {}, + "chooseAUsername": "", + "@chooseAUsername": { + "type": "text", + "placeholders": {} + }, + "emotePacks": "", + "@emotePacks": { + "type": "text", + "placeholders": {} + }, + "makeSureTheIdentifierIsValid": "", + "@makeSureTheIdentifierIsValid": { + "type": "text", + "placeholders": {} + }, + "continueWith": "", + "@continueWith": {}, + "indexedDbErrorTitle": "", + "@indexedDbErrorTitle": {}, + "pleaseChooseAUsername": "", + "@pleaseChooseAUsername": { + "type": "text", + "placeholders": {} + }, + "endedTheCall": "", + "@endedTheCall": { + "type": "text", + "placeholders": { + "senderName": {} + } + } +} diff --git a/assets/l10n/intl_tr.arb b/assets/l10n/intl_tr.arb index 2d4dd11a7..3d2ecf6a4 100644 --- a/assets/l10n/intl_tr.arb +++ b/assets/l10n/intl_tr.arb @@ -2617,5 +2617,45 @@ "placeholders": { "seconds": {} } - } + }, + "banUserDescription": "", + "@banUserDescription": {}, + "removeDevicesDescription": "", + "@removeDevicesDescription": {}, + "unbanUserDescription": "", + "@unbanUserDescription": {}, + "todoLists": "", + "@todoLists": {}, + "editTodo": "", + "@editTodo": {}, + "pushNotificationsNotAvailable": "", + "@pushNotificationsNotAvailable": {}, + "pleaseAddATitle": "", + "@pleaseAddATitle": {}, + "makeAdminDescription": "", + "@makeAdminDescription": {}, + "noTodosYet": "", + "@noTodosYet": {}, + "archiveRoomDescription": "", + "@archiveRoomDescription": {}, + "todosUnencrypted": "", + "@todosUnencrypted": {}, + "hasKnocked": "", + "@hasKnocked": { + "placeholders": { + "user": {} + } + }, + "newTodo": "", + "@newTodo": {}, + "learnMore": "", + "@learnMore": {}, + "todoListChangedError": "", + "@todoListChangedError": {}, + "roomUpgradeDescription": "", + "@roomUpgradeDescription": {}, + "pleaseEnterANumber": "", + "@pleaseEnterANumber": {}, + "kickUserDescription": "", + "@kickUserDescription": {} } diff --git a/assets/l10n/intl_uk.arb b/assets/l10n/intl_uk.arb index dfac06603..b9f379f9d 100644 --- a/assets/l10n/intl_uk.arb +++ b/assets/l10n/intl_uk.arb @@ -736,7 +736,7 @@ "type": "text", "placeholders": {} }, - "noGoogleServicesWarning": "Схоже, на вашому телефоні немає служб Google. Це гарне рішення для вашої приватності! Щоб отримувати push-сповіщення у FluffyChat, ми радимо використовувати https://microg.org/ або https://unifiedpush.org/.", + "noGoogleServicesWarning": "Схоже, Firebase Cloud Messaging недоступна на вашому пристрої. Щоб отримувати push-сповіщення, радимо встановити ntfy. За допомогою ntfy або іншого постачальника Unified Push ви можете отримувати push-сповіщення у безпечний спосіб. Ви можете завантажити ntfy з PlayStore або з F-Droid.", "@noGoogleServicesWarning": { "type": "text", "placeholders": {} @@ -2619,5 +2619,45 @@ "placeholders": { "seconds": {} } - } + }, + "banUserDescription": "Користувача буде заблоковано в бесіді, і він не зможе знову увійти в неї, поки його не буде розблоковано.", + "@banUserDescription": {}, + "removeDevicesDescription": "Ви вийдете з цього пристрою і більше не зможете отримувати повідомлення.", + "@removeDevicesDescription": {}, + "unbanUserDescription": "Користувач зможе знову увійти в бесіду, якщо спробує.", + "@unbanUserDescription": {}, + "todoLists": "(Бета) Завдання", + "@todoLists": {}, + "editTodo": "Змінити завдання", + "@editTodo": {}, + "pushNotificationsNotAvailable": "Push-сповіщення недоступні", + "@pushNotificationsNotAvailable": {}, + "pleaseAddATitle": "Додайте заголовок", + "@pleaseAddATitle": {}, + "makeAdminDescription": "Після того, як ви зробите цього користувача адміністратором, ви, можливо, не зможете це скасувати, оскільки він матиме ті самі права, що й ви.", + "@makeAdminDescription": {}, + "noTodosYet": "До цієї бесіди ще не додано жодного завдання. Створіть своє перше завдання і почніть співпрацювати з іншими. 📝", + "@noTodosYet": {}, + "archiveRoomDescription": "Бесіду буде переміщено до архіву. Інші користувачі зможуть побачити, що ви вийшли з неї.", + "@archiveRoomDescription": {}, + "todosUnencrypted": "Зауважте, що завдання бачать усі учасники бесіди, і вони не захищені наскрізним шифруванням.", + "@todosUnencrypted": {}, + "hasKnocked": "{user} стукає до вас", + "@hasKnocked": { + "placeholders": { + "user": {} + } + }, + "newTodo": "Нове завдання", + "@newTodo": {}, + "learnMore": "Докладніше", + "@learnMore": {}, + "todoListChangedError": "Отакої... Список завдань було змінено, поки ви його редагували.", + "@todoListChangedError": {}, + "roomUpgradeDescription": "Після цього бесіду буде відтворено з новою версією кімнати. Усі учасники отримають сповіщення, що їм потрібно перейти до нової бесіди. Ви можете дізнатися більше про версії кімнат на https://spec.matrix.org/latest/rooms/", + "@roomUpgradeDescription": {}, + "pleaseEnterANumber": "Введіть число більше ніж 0", + "@pleaseEnterANumber": {}, + "kickUserDescription": "Користувача вигнали з бесіди, але не заблокували. До загальнодоступних бесід користувач може приєднатися будь-коли.", + "@kickUserDescription": {} } diff --git a/assets/l10n/intl_vi.arb b/assets/l10n/intl_vi.arb index 072271a81..b15308bdb 100644 --- a/assets/l10n/intl_vi.arb +++ b/assets/l10n/intl_vi.arb @@ -1,452 +1,2631 @@ { - "@@last_modified": "2021-08-14 12:41:09.781172", - "about": "Giới thiệu", - "@about": { - "type": "text", - "placeholders": {} - }, - "accept": "Đồng ý", - "@accept": { - "type": "text", - "placeholders": {} - }, - "acceptedTheInvitation": "{username} đã đồng ý lời mời", - "@acceptedTheInvitation": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "account": "Tài khoản", - "@account": { - "type": "text", - "placeholders": {} - }, - "activatedEndToEndEncryption": "{username} đã kích hoạt mã hóa đầu cuối 2 chiều", - "@activatedEndToEndEncryption": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "addGroupDescription": "Thêm mô tả cho nhóm", - "@addGroupDescription": { - "type": "text", - "placeholders": {} - }, - "admin": "Quản trị viên", - "@admin": { - "type": "text", - "placeholders": {} - }, - "alias": "bí danh", - "@alias": { - "type": "text", - "placeholders": {} - }, - "answeredTheCall": "{senderName} đã trả lời cuộc gọi", - "@answeredTheCall": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "anyoneCanJoin": "Mọi người đều có thể gia nhập", - "@anyoneCanJoin": { - "type": "text", - "placeholders": {} - }, - "archive": "Lưu trữ", - "@archive": { - "type": "text", - "placeholders": {} - }, - "areGuestsAllowedToJoin": "Khách vãng lai có được tham gia không", - "@areGuestsAllowedToJoin": { - "type": "text", - "placeholders": {} - }, - "areYouSure": "Bạn chắc chứ?", - "@areYouSure": { - "type": "text", - "placeholders": {} - }, - "blockDevice": "Thiết bị bị chặn", - "@blockDevice": { - "type": "text", - "placeholders": {} - }, - "verified": "Đã xác thực", - "@verified": { - "type": "text", - "placeholders": {} - }, - "transferFromAnotherDevice": "Chuyển từ thiết bị khác", - "@transferFromAnotherDevice": { - "type": "text", - "placeholders": {} - }, - "showPassword": "Hiển thị mật khẩu", - "@showPassword": { - "type": "text", - "placeholders": {} - }, - "pleaseFollowInstructionsOnWeb": "Vui lòng làm theo hướng dẫn trên trang web và bấm tiếp", - "@pleaseFollowInstructionsOnWeb": { - "type": "text", - "placeholders": {} - }, - "noEncryptionForPublicRooms": "Bạn chỉ có thể kích hoạt mã hoá khi phòng này không mở", - "@noEncryptionForPublicRooms": { - "type": "text", - "placeholders": {} - }, - "next": "Tiếp", - "@next": { - "type": "text", - "placeholders": {} - }, - "everythingReady": "Mọi thứ đã sẵn sàng!", - "@everythingReady": { - "type": "text", - "placeholders": {} - }, - "emoteSettings": "Cài đặt biểu tượng cảm xúc", - "@emoteSettings": { - "type": "text", - "placeholders": {} - }, - "editDisplayname": "Sửa tên hiển thị", - "@editDisplayname": { - "type": "text", - "placeholders": {} - }, - "downloadFile": "Tải ảnh xuống", - "@downloadFile": { - "type": "text", - "placeholders": {} - }, - "displaynameHasBeenChanged": "Tên hiển thị đã được thay đổi", - "@displaynameHasBeenChanged": { - "type": "text", - "placeholders": {} - }, - "devices": "Các thiết bị", - "@devices": { - "type": "text", - "placeholders": {} - }, - "deviceId": "Mã xác định thiết bị", - "@deviceId": { - "type": "text", - "placeholders": {} - }, - "device": "Thiết bị", - "@device": { - "type": "text", - "placeholders": {} - }, - "deny": "Từ chối", - "@deny": { - "type": "text", - "placeholders": {} - }, - "deleteMessage": "Xoá tin nhắn", - "@deleteMessage": { - "type": "text", - "placeholders": {} - }, - "deleteAccount": "Xoá tài khoản", - "@deleteAccount": { - "type": "text", - "placeholders": {} - }, - "delete": "Xoá", - "@delete": { - "type": "text", - "placeholders": {} - }, - "deactivateAccountWarning": "Việc này sẽ vô hiệu hoá tài khoản của bạn. Điều này không thể đảo ngược được! Bạn chắc là vẫn muốn tiếp tục chứ?", - "@deactivateAccountWarning": { - "type": "text", - "placeholders": {} - }, - "dateWithYear": "{day}/{month}/{year}", - "@dateWithYear": { - "type": "text", - "placeholders": { - "year": {}, - "month": {}, - "day": {} - } - }, - "dateWithoutYear": "{day}/{month}", - "@dateWithoutYear": { - "type": "text", - "placeholders": { - "month": {}, - "day": {} - } - }, - "dateAndTimeOfDay": "{date}, {timeOfDay}", - "@dateAndTimeOfDay": { - "type": "text", - "placeholders": { - "date": {}, - "timeOfDay": {} - } - }, - "currentlyActive": "Đang hoạt động", - "@currentlyActive": { - "type": "text", - "placeholders": {} - }, - "createNewGroup": "Tạo một nhóm mới", - "@createNewGroup": { - "type": "text", - "placeholders": {} - }, - "createdTheChat": "{username} đã tạo cuộc trò chuyện", - "@createdTheChat": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "create": "Tạo", - "@create": { - "type": "text", - "placeholders": {} - }, - "countParticipants": "{count} thành viên", - "@countParticipants": { - "type": "text", - "placeholders": { - "count": {} - } - }, - "couldNotDecryptMessage": "Không thể giải mã tin nhắn: {error}", - "@couldNotDecryptMessage": { - "type": "text", - "placeholders": { - "error": {} - } - }, - "copy": "Sao chép", - "@copy": { - "type": "text", - "placeholders": {} - }, - "contactHasBeenInvitedToTheGroup": "Liên hệ đã được mời vào nhóm", - "@contactHasBeenInvitedToTheGroup": { - "type": "text", - "placeholders": {} - }, - "connect": "Kết nối", - "@connect": { - "type": "text", - "placeholders": {} - }, - "confirm": "Xác nhận", - "@confirm": { - "type": "text", - "placeholders": {} - }, - "compareNumbersMatch": "So sánh và đảm bảo các số sau đây giống trên máy còn lại", - "@compareNumbersMatch": { - "type": "text", - "placeholders": {} - }, - "compareEmojiMatch": "So sánh và đảm bảo các biểu tượng cảm xúc sau đây giống với các biểu tượng trên máy còn lại", - "@compareEmojiMatch": { - "type": "text", - "placeholders": {} - }, - "close": "Đóng", - "@close": { - "type": "text", - "placeholders": {} - }, - "chooseAUsername": "Chọn tên người dùng", - "@chooseAUsername": { - "type": "text", - "placeholders": {} - }, - "chooseAStrongPassword": "Chọn một mật khẩu mạnh", - "@chooseAStrongPassword": { - "type": "text", - "placeholders": {} - }, - "chatDetails": "Chi tiết cuộc trò chuyện", - "@chatDetails": { - "type": "text", - "placeholders": {} - }, - "chatBackupDescription": "Bản sao lưu cuộc trò chuyện của bạn được bảo mật bằng một khoá bảo mật. Bạn đừng làm mất nó.", - "@chatBackupDescription": { - "type": "text", - "placeholders": {} - }, - "chatBackup": "Sao lưu cuộc trò chuyện", - "@chatBackup": { - "type": "text", - "placeholders": {} - }, - "chat": "Chat", - "@chat": { - "type": "text", - "placeholders": {} - }, - "changeWallpaper": "Thay hình nền", - "@changeWallpaper": { - "type": "text", - "placeholders": {} - }, - "changeTheNameOfTheGroup": "Thay đổi tên nhóm", - "@changeTheNameOfTheGroup": { - "type": "text", - "placeholders": {} - }, - "changeTheHomeserver": "Thay đổi máy chủ nhà", - "@changeTheHomeserver": { - "type": "text", - "placeholders": {} - }, - "changePassword": "Thay đổi mật khẩu", - "@changePassword": { - "type": "text", - "placeholders": {} - }, - "changedTheRoomInvitationLink": "{username} đã thay đổi đường dẫn mời", - "@changedTheRoomInvitationLink": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheRoomAliases": "{username} đã đổi địa chỉ phòng chat", - "@changedTheRoomAliases": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheProfileAvatar": "{username} đã thay đổi ảnh đại diện của mình", - "@changedTheProfileAvatar": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheGuestAccessRulesTo": "{username} đã thay đổi quy tắc truy cập đối với khách thành: {rules}", - "@changedTheGuestAccessRulesTo": { - "type": "text", - "placeholders": { - "username": {}, - "rules": {} - } - }, - "changedTheGuestAccessRules": "{username} đã thay đổi quy tắc truy cập đối với khách", - "@changedTheGuestAccessRules": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheChatPermissions": "{username} đã thay đổi quyền trong phòng chat", - "@changedTheChatPermissions": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheChatNameTo": "{username} đã thay đổi tên phòng chat thành: '{chatname}'", - "@changedTheChatNameTo": { - "type": "text", - "placeholders": { - "username": {}, - "chatname": {} - } - }, - "changedTheChatDescriptionTo": "{username} đã thay đổi mô tả phòng chat thành: '{description}'", - "@changedTheChatDescriptionTo": { - "type": "text", - "placeholders": { - "username": {}, - "description": {} - } - }, - "changedTheChatAvatar": "{username} đã thay đổi ảnh phòng chat", - "@changedTheChatAvatar": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changeDeviceName": "Thay đổi tên thiết bị", - "@changeDeviceName": { - "type": "text", - "placeholders": {} - }, - "cancel": "Hủy", - "@cancel": { - "type": "text", - "placeholders": {} - }, - "blocked": "Đã chặn", - "@blocked": { - "type": "text", - "placeholders": {} - }, - "bannedUser": "{username} đã cấm {targetName}", - "@bannedUser": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "banned": "Đã bị cấm", - "@banned": { - "type": "text", - "placeholders": {} - }, - "banFromChat": "Cấm khỏi cuộc trò chuyện", - "@banFromChat": { - "type": "text", - "placeholders": {} - }, - "badServerVersionsException": "Máy chủ nhà hỗ trợ Spec phiên bản:\n{serverVerions}\nNhưng ứng dụng này chỉ hỗ trợ {supportedVersions}", - "@badServerVersionsException": { - "type": "text", - "placeholders": { - "serverVersions": {}, - "supportedVersions": {} - } - }, - "badServerLoginTypesException": "Máy chủ nhà hỗ trợ kiểu đăng nhập:\n{serverVersions}\nNhưng ứng dụng này chỉ hỗ trợ:\n{supportedVersions}", - "@badServerLoginTypesException": { - "type": "text", - "placeholders": { - "serverVersions": {}, - "supportedVersions": {} - } - }, - "askVerificationRequest": "Bạn có đồng ý yêu cầu chứng thực từ {username} không?", - "@askVerificationRequest": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "areYouSureYouWantToLogout": "Bạn có chắc bạn muốn đăng xuất không?", - "@areYouSureYouWantToLogout": { - "type": "text", - "placeholders": {} - }, - "addEmail": "Thêm email", - "@addEmail": { - "type": "text", - "placeholders": {} + "@@last_modified": "2021-08-14 12:41:09.781172", + "about": "Giới thiệu", + "@about": { + "type": "text", + "placeholders": {} + }, + "accept": "Đồng ý", + "@accept": { + "type": "text", + "placeholders": {} + }, + "acceptedTheInvitation": "{username} đã đồng ý lời mời", + "@acceptedTheInvitation": { + "type": "text", + "placeholders": { + "username": {} } -} \ No newline at end of file + }, + "account": "Tài khoản", + "@account": { + "type": "text", + "placeholders": {} + }, + "activatedEndToEndEncryption": "{username} đã kích hoạt mã hóa đầu cuối 2 chiều", + "@activatedEndToEndEncryption": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "addGroupDescription": "Thêm mô tả cho nhóm", + "@addGroupDescription": { + "type": "text", + "placeholders": {} + }, + "admin": "Quản trị viên", + "@admin": { + "type": "text", + "placeholders": {} + }, + "alias": "bí danh", + "@alias": { + "type": "text", + "placeholders": {} + }, + "answeredTheCall": "{senderName} đã trả lời cuộc gọi", + "@answeredTheCall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "anyoneCanJoin": "Mọi người đều có thể gia nhập", + "@anyoneCanJoin": { + "type": "text", + "placeholders": {} + }, + "archive": "Lưu trữ", + "@archive": { + "type": "text", + "placeholders": {} + }, + "areGuestsAllowedToJoin": "Khách vãng lai có được tham gia không", + "@areGuestsAllowedToJoin": { + "type": "text", + "placeholders": {} + }, + "areYouSure": "Bạn chắc chứ?", + "@areYouSure": { + "type": "text", + "placeholders": {} + }, + "blockDevice": "Thiết bị bị chặn", + "@blockDevice": { + "type": "text", + "placeholders": {} + }, + "verified": "Đã xác thực", + "@verified": { + "type": "text", + "placeholders": {} + }, + "transferFromAnotherDevice": "Chuyển từ thiết bị khác", + "@transferFromAnotherDevice": { + "type": "text", + "placeholders": {} + }, + "showPassword": "Hiển thị mật khẩu", + "@showPassword": { + "type": "text", + "placeholders": {} + }, + "pleaseFollowInstructionsOnWeb": "Vui lòng làm theo hướng dẫn trên trang web và bấm tiếp", + "@pleaseFollowInstructionsOnWeb": { + "type": "text", + "placeholders": {} + }, + "noEncryptionForPublicRooms": "Bạn chỉ có thể kích hoạt mã hoá khi phòng này không mở", + "@noEncryptionForPublicRooms": { + "type": "text", + "placeholders": {} + }, + "next": "Tiếp", + "@next": { + "type": "text", + "placeholders": {} + }, + "everythingReady": "Mọi thứ đã sẵn sàng!", + "@everythingReady": { + "type": "text", + "placeholders": {} + }, + "emoteSettings": "Cài đặt biểu tượng cảm xúc", + "@emoteSettings": { + "type": "text", + "placeholders": {} + }, + "editDisplayname": "Sửa tên hiển thị", + "@editDisplayname": { + "type": "text", + "placeholders": {} + }, + "downloadFile": "Tải ảnh xuống", + "@downloadFile": { + "type": "text", + "placeholders": {} + }, + "displaynameHasBeenChanged": "Tên hiển thị đã được thay đổi", + "@displaynameHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "devices": "Các thiết bị", + "@devices": { + "type": "text", + "placeholders": {} + }, + "deviceId": "Mã xác định thiết bị", + "@deviceId": { + "type": "text", + "placeholders": {} + }, + "device": "Thiết bị", + "@device": { + "type": "text", + "placeholders": {} + }, + "deny": "Từ chối", + "@deny": { + "type": "text", + "placeholders": {} + }, + "deleteMessage": "Xoá tin nhắn", + "@deleteMessage": { + "type": "text", + "placeholders": {} + }, + "deleteAccount": "Xoá tài khoản", + "@deleteAccount": { + "type": "text", + "placeholders": {} + }, + "delete": "Xoá", + "@delete": { + "type": "text", + "placeholders": {} + }, + "deactivateAccountWarning": "Việc này sẽ vô hiệu hoá tài khoản của bạn. Điều này không thể đảo ngược được! Bạn chắc là vẫn muốn tiếp tục chứ?", + "@deactivateAccountWarning": { + "type": "text", + "placeholders": {} + }, + "dateWithYear": "{day}/{month}/{year}", + "@dateWithYear": { + "type": "text", + "placeholders": { + "year": {}, + "month": {}, + "day": {} + } + }, + "dateWithoutYear": "{day}/{month}", + "@dateWithoutYear": { + "type": "text", + "placeholders": { + "month": {}, + "day": {} + } + }, + "dateAndTimeOfDay": "{date}, {timeOfDay}", + "@dateAndTimeOfDay": { + "type": "text", + "placeholders": { + "date": {}, + "timeOfDay": {} + } + }, + "currentlyActive": "Đang hoạt động", + "@currentlyActive": { + "type": "text", + "placeholders": {} + }, + "createNewGroup": "Tạo một nhóm mới", + "@createNewGroup": { + "type": "text", + "placeholders": {} + }, + "createdTheChat": "{username} đã tạo cuộc trò chuyện", + "@createdTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "create": "Tạo", + "@create": { + "type": "text", + "placeholders": {} + }, + "countParticipants": "{count} thành viên", + "@countParticipants": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "couldNotDecryptMessage": "Không thể giải mã tin nhắn: {error}", + "@couldNotDecryptMessage": { + "type": "text", + "placeholders": { + "error": {} + } + }, + "copy": "Sao chép", + "@copy": { + "type": "text", + "placeholders": {} + }, + "contactHasBeenInvitedToTheGroup": "Liên hệ đã được mời vào nhóm", + "@contactHasBeenInvitedToTheGroup": { + "type": "text", + "placeholders": {} + }, + "connect": "Kết nối", + "@connect": { + "type": "text", + "placeholders": {} + }, + "confirm": "Xác nhận", + "@confirm": { + "type": "text", + "placeholders": {} + }, + "compareNumbersMatch": "So sánh và đảm bảo các số sau đây giống trên máy còn lại", + "@compareNumbersMatch": { + "type": "text", + "placeholders": {} + }, + "compareEmojiMatch": "So sánh và đảm bảo các biểu tượng cảm xúc sau đây giống với các biểu tượng trên máy còn lại", + "@compareEmojiMatch": { + "type": "text", + "placeholders": {} + }, + "close": "Đóng", + "@close": { + "type": "text", + "placeholders": {} + }, + "chooseAUsername": "Chọn tên người dùng", + "@chooseAUsername": { + "type": "text", + "placeholders": {} + }, + "chooseAStrongPassword": "Chọn một mật khẩu mạnh", + "@chooseAStrongPassword": { + "type": "text", + "placeholders": {} + }, + "chatDetails": "Chi tiết cuộc trò chuyện", + "@chatDetails": { + "type": "text", + "placeholders": {} + }, + "chatBackupDescription": "Bản sao lưu cuộc trò chuyện của bạn được bảo mật bằng một khoá bảo mật. Bạn đừng làm mất nó.", + "@chatBackupDescription": { + "type": "text", + "placeholders": {} + }, + "chatBackup": "Sao lưu cuộc trò chuyện", + "@chatBackup": { + "type": "text", + "placeholders": {} + }, + "chat": "Chat", + "@chat": { + "type": "text", + "placeholders": {} + }, + "changeWallpaper": "Thay hình nền", + "@changeWallpaper": { + "type": "text", + "placeholders": {} + }, + "changeTheNameOfTheGroup": "Thay đổi tên nhóm", + "@changeTheNameOfTheGroup": { + "type": "text", + "placeholders": {} + }, + "changeTheHomeserver": "Thay đổi máy chủ nhà", + "@changeTheHomeserver": { + "type": "text", + "placeholders": {} + }, + "changePassword": "Thay đổi mật khẩu", + "@changePassword": { + "type": "text", + "placeholders": {} + }, + "changedTheRoomInvitationLink": "{username} đã thay đổi đường dẫn mời", + "@changedTheRoomInvitationLink": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheRoomAliases": "{username} đã đổi địa chỉ phòng chat", + "@changedTheRoomAliases": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheProfileAvatar": "{username} đã thay đổi ảnh đại diện của mình", + "@changedTheProfileAvatar": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheGuestAccessRulesTo": "{username} đã thay đổi quy tắc truy cập đối với khách thành: {rules}", + "@changedTheGuestAccessRulesTo": { + "type": "text", + "placeholders": { + "username": {}, + "rules": {} + } + }, + "changedTheGuestAccessRules": "{username} đã thay đổi quy tắc truy cập đối với khách", + "@changedTheGuestAccessRules": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheChatPermissions": "{username} đã thay đổi quyền trong phòng chat", + "@changedTheChatPermissions": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheChatNameTo": "{username} đã thay đổi tên phòng chat thành: '{chatname}'", + "@changedTheChatNameTo": { + "type": "text", + "placeholders": { + "username": {}, + "chatname": {} + } + }, + "changedTheChatDescriptionTo": "{username} đã thay đổi mô tả phòng chat thành: '{description}'", + "@changedTheChatDescriptionTo": { + "type": "text", + "placeholders": { + "username": {}, + "description": {} + } + }, + "changedTheChatAvatar": "{username} đã thay đổi ảnh phòng chat", + "@changedTheChatAvatar": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changeDeviceName": "Thay đổi tên thiết bị", + "@changeDeviceName": { + "type": "text", + "placeholders": {} + }, + "cancel": "Hủy", + "@cancel": { + "type": "text", + "placeholders": {} + }, + "blocked": "Đã chặn", + "@blocked": { + "type": "text", + "placeholders": {} + }, + "bannedUser": "{username} đã cấm {targetName}", + "@bannedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "banned": "Đã bị cấm", + "@banned": { + "type": "text", + "placeholders": {} + }, + "banFromChat": "Cấm khỏi cuộc trò chuyện", + "@banFromChat": { + "type": "text", + "placeholders": {} + }, + "badServerVersionsException": "Máy chủ nhà hỗ trợ Spec phiên bản:\n{serverVerions}\nNhưng ứng dụng này chỉ hỗ trợ {supportedVersions}", + "@badServerVersionsException": { + "type": "text", + "placeholders": { + "serverVersions": {}, + "supportedVersions": {} + } + }, + "badServerLoginTypesException": "Máy chủ nhà hỗ trợ kiểu đăng nhập:\n{serverVersions}\nNhưng ứng dụng này chỉ hỗ trợ:\n{supportedVersions}", + "@badServerLoginTypesException": { + "type": "text", + "placeholders": { + "serverVersions": {}, + "supportedVersions": {} + } + }, + "askVerificationRequest": "Bạn có đồng ý yêu cầu chứng thực từ {username} không?", + "@askVerificationRequest": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "areYouSureYouWantToLogout": "Bạn có chắc bạn muốn đăng xuất không?", + "@areYouSureYouWantToLogout": { + "type": "text", + "placeholders": {} + }, + "addEmail": "Thêm email", + "@addEmail": { + "type": "text", + "placeholders": {} + }, + "unsupportedAndroidVersionLong": "", + "@unsupportedAndroidVersionLong": {}, + "storeSecurlyOnThisDevice": "", + "@storeSecurlyOnThisDevice": {}, + "ok": "", + "@ok": { + "type": "text", + "placeholders": {} + }, + "passwordsDoNotMatch": "", + "@passwordsDoNotMatch": {}, + "sharedTheLocation": "", + "@sharedTheLocation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "unbanFromChat": "", + "@unbanFromChat": { + "type": "text", + "placeholders": {} + }, + "iUnderstand": "", + "@iUnderstand": {}, + "screenSharingDetail": "", + "@screenSharingDetail": {}, + "hugContent": "", + "@hugContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "darkTheme": "", + "@darkTheme": { + "type": "text", + "placeholders": {} + }, + "passphraseOrKey": "", + "@passphraseOrKey": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourPassword": "", + "@pleaseEnterYourPassword": { + "type": "text", + "placeholders": {} + }, + "theyMatch": "", + "@theyMatch": { + "type": "text", + "placeholders": {} + }, + "jumpToLastReadMessage": "", + "@jumpToLastReadMessage": {}, + "allRooms": "", + "@allRooms": { + "type": "text", + "placeholders": {} + }, + "obtainingLocation": "", + "@obtainingLocation": { + "type": "text", + "placeholders": {} + }, + "whoCanSeeMyStories": "", + "@whoCanSeeMyStories": {}, + "commandHint_cuddle": "", + "@commandHint_cuddle": {}, + "chats": "", + "@chats": { + "type": "text", + "placeholders": {} + }, + "widgetVideo": "", + "@widgetVideo": {}, + "dismiss": "", + "@dismiss": {}, + "unknownDevice": "", + "@unknownDevice": { + "type": "text", + "placeholders": {} + }, + "emoteShortcode": "", + "@emoteShortcode": { + "type": "text", + "placeholders": {} + }, + "reportErrorDescription": "", + "@reportErrorDescription": {}, + "directChats": "", + "@directChats": { + "type": "text", + "placeholders": {} + }, + "setPermissionsLevel": "", + "@setPermissionsLevel": { + "type": "text", + "placeholders": {} + }, + "inviteContactToGroup": "", + "@inviteContactToGroup": { + "type": "text", + "placeholders": { + "groupName": {} + } + }, + "addAccount": "", + "@addAccount": {}, + "configureChat": "", + "@configureChat": { + "type": "text", + "placeholders": {} + }, + "seenByUserAndUser": "", + "@seenByUserAndUser": { + "type": "text", + "placeholders": { + "username": {}, + "username2": {} + } + }, + "chatHasBeenAddedToThisSpace": "", + "@chatHasBeenAddedToThisSpace": {}, + "reply": "", + "@reply": { + "type": "text", + "placeholders": {} + }, + "removeYourAvatar": "", + "@removeYourAvatar": { + "type": "text", + "placeholders": {} + }, + "unsupportedAndroidVersion": "", + "@unsupportedAndroidVersion": {}, + "enterASpacepName": "", + "@enterASpacepName": {}, + "commandHint_html": "", + "@commandHint_html": { + "type": "text", + "description": "Usage hint for the command /html" + }, + "widgetJitsi": "", + "@widgetJitsi": {}, + "youAreNoLongerParticipatingInThisChat": "", + "@youAreNoLongerParticipatingInThisChat": { + "type": "text", + "placeholders": {} + }, + "encryption": "", + "@encryption": { + "type": "text", + "placeholders": {} + }, + "messageType": "", + "@messageType": {}, + "noEmailWarning": "", + "@noEmailWarning": {}, + "indexedDbErrorLong": "", + "@indexedDbErrorLong": {}, + "oneClientLoggedOut": "", + "@oneClientLoggedOut": {}, + "toggleMuted": "", + "@toggleMuted": { + "type": "text", + "placeholders": {} + }, + "kicked": "", + "@kicked": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "title": "", + "@title": { + "description": "Title for the application", + "type": "text", + "placeholders": {} + }, + "verifySuccess": "", + "@verifySuccess": { + "type": "text", + "placeholders": {} + }, + "sendFile": "", + "@sendFile": { + "type": "text", + "placeholders": {} + }, + "newVerificationRequest": "", + "@newVerificationRequest": { + "type": "text", + "placeholders": {} + }, + "startFirstChat": "", + "@startFirstChat": {}, + "callingAccount": "", + "@callingAccount": {}, + "requestPermission": "", + "@requestPermission": { + "type": "text", + "placeholders": {} + }, + "sentAPicture": "", + "@sentAPicture": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "invited": "", + "@invited": { + "type": "text", + "placeholders": {} + }, + "setColorTheme": "", + "@setColorTheme": {}, + "nextAccount": "", + "@nextAccount": {}, + "commandHint_create": "", + "@commandHint_create": { + "type": "text", + "description": "Usage hint for the command /create" + }, + "youAreInvitedToThisChat": "", + "@youAreInvitedToThisChat": { + "type": "text", + "placeholders": {} + }, + "singlesignon": "", + "@singlesignon": { + "type": "text", + "placeholders": {} + }, + "warning": "", + "@warning": { + "type": "text", + "placeholders": {} + }, + "password": "", + "@password": { + "type": "text", + "placeholders": {} + }, + "allSpaces": "", + "@allSpaces": {}, + "supposedMxid": "", + "@supposedMxid": { + "type": "text", + "placeholders": { + "mxid": {} + } + }, + "user": "", + "@user": {}, + "roomVersion": "", + "@roomVersion": { + "type": "text", + "placeholders": {} + }, + "sentAFile": "", + "@sentAFile": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "videoCall": "", + "@videoCall": { + "type": "text", + "placeholders": {} + }, + "youAcceptedTheInvitation": "", + "@youAcceptedTheInvitation": {}, + "noMatrixServer": "", + "@noMatrixServer": { + "type": "text", + "placeholders": { + "server1": {}, + "server2": {} + } + }, + "youInvitedBy": "", + "@youInvitedBy": { + "placeholders": { + "user": {} + } + }, + "openAppToReadMessages": "", + "@openAppToReadMessages": { + "type": "text", + "placeholders": {} + }, + "sentAVideo": "", + "@sentAVideo": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "banUserDescription": "", + "@banUserDescription": {}, + "inviteContact": "", + "@inviteContact": { + "type": "text", + "placeholders": {} + }, + "requests": "", + "@requests": {}, + "askSSSSSign": "", + "@askSSSSSign": { + "type": "text", + "placeholders": {} + }, + "widgetEtherpad": "", + "@widgetEtherpad": {}, + "remove": "", + "@remove": { + "type": "text", + "placeholders": {} + }, + "changeTheme": "", + "@changeTheme": { + "type": "text", + "placeholders": {} + }, + "stories": "", + "@stories": {}, + "id": "", + "@id": { + "type": "text", + "placeholders": {} + }, + "addToStory": "", + "@addToStory": {}, + "removeDevicesDescription": "", + "@removeDevicesDescription": {}, + "separateChatTypes": "", + "@separateChatTypes": { + "type": "text", + "placeholders": {} + }, + "tryAgain": "", + "@tryAgain": {}, + "youKickedAndBanned": "", + "@youKickedAndBanned": { + "placeholders": { + "user": {} + } + }, + "showDirectChatsInSpaces": "", + "@showDirectChatsInSpaces": { + "type": "text", + "placeholders": {} + }, + "removeDevice": "", + "@removeDevice": { + "type": "text", + "placeholders": {} + }, + "youCannotInviteYourself": "", + "@youCannotInviteYourself": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterValidEmail": "", + "@pleaseEnterValidEmail": {}, + "unbanUserDescription": "", + "@unbanUserDescription": {}, + "todoLists": "", + "@todoLists": {}, + "pleaseClickOnLink": "", + "@pleaseClickOnLink": { + "type": "text", + "placeholders": {} + }, + "saveFile": "", + "@saveFile": { + "type": "text", + "placeholders": {} + }, + "sendOnEnter": "", + "@sendOnEnter": {}, + "seenByUserAndCountOthers": "", + "@seenByUserAndCountOthers": { + "type": "text", + "placeholders": { + "username": {}, + "count": {} + } + }, + "youRejectedTheInvitation": "", + "@youRejectedTheInvitation": {}, + "otherCallingPermissions": "", + "@otherCallingPermissions": {}, + "messagesStyle": "", + "@messagesStyle": {}, + "invitedUsersOnly": "", + "@invitedUsersOnly": { + "type": "text", + "placeholders": {} + }, + "link": "", + "@link": {}, + "widgetUrlError": "", + "@widgetUrlError": {}, + "emailOrUsername": "", + "@emailOrUsername": {}, + "newSpaceDescription": "", + "@newSpaceDescription": {}, + "chatDescription": "", + "@chatDescription": {}, + "callingAccountDetails": "", + "@callingAccountDetails": {}, + "pleaseChooseAtLeastChars": "", + "@pleaseChooseAtLeastChars": { + "type": "text", + "placeholders": { + "min": {} + } + }, + "editRoomAliases": "", + "@editRoomAliases": { + "type": "text", + "placeholders": {} + }, + "enterSpace": "", + "@enterSpace": {}, + "encryptThisChat": "", + "@encryptThisChat": {}, + "unavailable": "", + "@unavailable": { + "type": "text", + "placeholders": {} + }, + "previousAccount": "", + "@previousAccount": {}, + "publicRooms": "", + "@publicRooms": { + "type": "text", + "placeholders": {} + }, + "fromTheInvitation": "", + "@fromTheInvitation": { + "type": "text", + "placeholders": {} + }, + "sendMessages": "", + "@sendMessages": { + "type": "text", + "placeholders": {} + }, + "incorrectPassphraseOrKey": "", + "@incorrectPassphraseOrKey": { + "type": "text", + "placeholders": {} + }, + "emoteWarnNeedToPick": "", + "@emoteWarnNeedToPick": { + "type": "text", + "placeholders": {} + }, + "reopenChat": "", + "@reopenChat": {}, + "pleaseEnterRecoveryKey": "", + "@pleaseEnterRecoveryKey": {}, + "toggleFavorite": "", + "@toggleFavorite": { + "type": "text", + "placeholders": {} + }, + "no": "", + "@no": { + "type": "text", + "placeholders": {} + }, + "widgetNameError": "", + "@widgetNameError": {}, + "inoffensive": "", + "@inoffensive": { + "type": "text", + "placeholders": {} + }, + "unpin": "", + "@unpin": { + "type": "text", + "placeholders": {} + }, + "addToBundle": "", + "@addToBundle": {}, + "reportMessage": "", + "@reportMessage": { + "type": "text", + "placeholders": {} + }, + "spaceIsPublic": "", + "@spaceIsPublic": { + "type": "text", + "placeholders": {} + }, + "addWidget": "", + "@addWidget": {}, + "all": "", + "@all": { + "type": "text", + "placeholders": {} + }, + "removeAllOtherDevices": "", + "@removeAllOtherDevices": { + "type": "text", + "placeholders": {} + }, + "unblockDevice": "", + "@unblockDevice": { + "type": "text", + "placeholders": {} + }, + "countFiles": "", + "@countFiles": { + "placeholders": { + "count": {} + } + }, + "noKeyForThisMessage": "", + "@noKeyForThisMessage": {}, + "enableEncryptionWarning": "", + "@enableEncryptionWarning": { + "type": "text", + "placeholders": {} + }, + "inviteText": "", + "@inviteText": { + "type": "text", + "placeholders": { + "username": {}, + "link": {} + } + }, + "shareLocation": "", + "@shareLocation": { + "type": "text", + "placeholders": {} + }, + "reason": "", + "@reason": { + "type": "text", + "placeholders": {} + }, + "commandHint_markasgroup": "", + "@commandHint_markasgroup": {}, + "editTodo": "", + "@editTodo": {}, + "errorObtainingLocation": "", + "@errorObtainingLocation": { + "type": "text", + "placeholders": { + "error": {} + } + }, + "hydrateTor": "", + "@hydrateTor": {}, + "pushNotificationsNotAvailable": "", + "@pushNotificationsNotAvailable": {}, + "passwordRecovery": "", + "@passwordRecovery": { + "type": "text", + "placeholders": {} + }, + "storeInAppleKeyChain": "", + "@storeInAppleKeyChain": {}, + "replaceRoomWithNewerVersion": "", + "@replaceRoomWithNewerVersion": { + "type": "text", + "placeholders": {} + }, + "hydrate": "", + "@hydrate": {}, + "invalidServerName": "", + "@invalidServerName": {}, + "chatPermissions": "", + "@chatPermissions": {}, + "voiceMessage": "", + "@voiceMessage": { + "type": "text", + "placeholders": {} + }, + "wipeChatBackup": "", + "@wipeChatBackup": { + "type": "text", + "placeholders": {} + }, + "cantOpenUri": "", + "@cantOpenUri": { + "type": "text", + "placeholders": { + "uri": {} + } + }, + "sender": "", + "@sender": {}, + "storeInAndroidKeystore": "", + "@storeInAndroidKeystore": {}, + "optionalGroupName": "", + "@optionalGroupName": { + "type": "text", + "placeholders": {} + }, + "hideRedactedEvents": "", + "@hideRedactedEvents": { + "type": "text", + "placeholders": {} + }, + "online": "", + "@online": { + "type": "text", + "placeholders": {} + }, + "signInWithPassword": "", + "@signInWithPassword": {}, + "pleaseAddATitle": "", + "@pleaseAddATitle": {}, + "updateNow": "", + "@updateNow": {}, + "ignoredUsers": "", + "@ignoredUsers": { + "type": "text", + "placeholders": {} + }, + "lastActiveAgo": "", + "@lastActiveAgo": { + "type": "text", + "placeholders": { + "localizedTimeShort": {} + } + }, + "weSentYouAnEmail": "", + "@weSentYouAnEmail": { + "type": "text", + "placeholders": {} + }, + "offensive": "", + "@offensive": { + "type": "text", + "placeholders": {} + }, + "needPantalaimonWarning": "", + "@needPantalaimonWarning": { + "type": "text", + "placeholders": {} + }, + "makeAdminDescription": "", + "@makeAdminDescription": {}, + "edit": "", + "@edit": { + "type": "text", + "placeholders": {} + }, + "noEmotesFound": "", + "@noEmotesFound": { + "type": "text", + "placeholders": {} + }, + "synchronizingPleaseWait": "", + "@synchronizingPleaseWait": { + "type": "text", + "placeholders": {} + }, + "pushRules": "", + "@pushRules": { + "type": "text", + "placeholders": {} + }, + "goToTheNewRoom": "", + "@goToTheNewRoom": { + "type": "text", + "placeholders": {} + }, + "commandHint_clearcache": "", + "@commandHint_clearcache": { + "type": "text", + "description": "Usage hint for the command /clearcache" + }, + "saveKeyManuallyDescription": "", + "@saveKeyManuallyDescription": {}, + "none": "", + "@none": { + "type": "text", + "placeholders": {} + }, + "editBundlesForAccount": "", + "@editBundlesForAccount": {}, + "renderRichContent": "", + "@renderRichContent": { + "type": "text", + "placeholders": {} + }, + "enableEncryption": "", + "@enableEncryption": { + "type": "text", + "placeholders": {} + }, + "whyIsThisMessageEncrypted": "", + "@whyIsThisMessageEncrypted": {}, + "rejectedTheInvitation": "", + "@rejectedTheInvitation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "setChatDescription": "", + "@setChatDescription": {}, + "userLeftTheChat": "", + "@userLeftTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "spaceName": "", + "@spaceName": { + "type": "text", + "placeholders": {} + }, + "importFromZipFile": "", + "@importFromZipFile": {}, + "discover": "", + "@discover": { + "type": "text", + "placeholders": {} + }, + "toggleUnread": "", + "@toggleUnread": { + "type": "text", + "placeholders": {} + }, + "or": "", + "@or": { + "type": "text", + "placeholders": {} + }, + "dehydrateWarning": "", + "@dehydrateWarning": {}, + "sendOriginal": "", + "@sendOriginal": { + "type": "text", + "placeholders": {} + }, + "noOtherDevicesFound": "", + "@noOtherDevicesFound": {}, + "whoIsAllowedToJoinThisGroup": "", + "@whoIsAllowedToJoinThisGroup": { + "type": "text", + "placeholders": {} + }, + "emptyChat": "", + "@emptyChat": { + "type": "text", + "placeholders": {} + }, + "seenByUser": "", + "@seenByUser": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "yourChatBackupHasBeenSetUp": "", + "@yourChatBackupHasBeenSetUp": {}, + "addDescription": "", + "@addDescription": {}, + "redactedBy": "", + "@redactedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "submit": "", + "@submit": { + "type": "text", + "placeholders": {} + }, + "videoCallsBetaWarning": "", + "@videoCallsBetaWarning": {}, + "unmuteChat": "", + "@unmuteChat": { + "type": "text", + "placeholders": {} + }, + "redactedAnEvent": "", + "@redactedAnEvent": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "autoplayImages": "", + "@autoplayImages": { + "type": "text", + "placeholder": {} + }, + "storyPrivacyWarning": "", + "@storyPrivacyWarning": {}, + "matrixWidgets": "", + "@matrixWidgets": {}, + "participant": "", + "@participant": { + "type": "text", + "placeholders": {} + }, + "logInTo": "", + "@logInTo": { + "type": "text", + "placeholders": { + "homeserver": {} + } + }, + "yes": "", + "@yes": { + "type": "text", + "placeholders": {} + }, + "containsDisplayName": "", + "@containsDisplayName": { + "type": "text", + "placeholders": {} + }, + "signInWith": "", + "@signInWith": { + "type": "text", + "placeholders": { + "provider": {} + } + }, + "username": "", + "@username": { + "type": "text", + "placeholders": {} + }, + "updateAvailable": "", + "@updateAvailable": {}, + "fileIsTooBigForServer": "", + "@fileIsTooBigForServer": {}, + "homeserver": "", + "@homeserver": {}, + "help": "", + "@help": { + "type": "text", + "placeholders": {} + }, + "noTodosYet": "", + "@noTodosYet": {}, + "people": "", + "@people": { + "type": "text", + "placeholders": {} + }, + "changedTheHistoryVisibilityTo": "", + "@changedTheHistoryVisibilityTo": { + "type": "text", + "placeholders": { + "username": {}, + "rules": {} + } + }, + "leftTheChat": "", + "@leftTheChat": { + "type": "text", + "placeholders": {} + }, + "repeatPassword": "", + "@repeatPassword": {}, + "setStatus": "", + "@setStatus": { + "type": "text", + "placeholders": {} + }, + "groupWith": "", + "@groupWith": { + "type": "text", + "placeholders": { + "displayname": {} + } + }, + "callingPermissions": "", + "@callingPermissions": {}, + "newMessageInFluffyChat": "", + "@newMessageInFluffyChat": { + "type": "text", + "placeholders": {} + }, + "readUpToHere": "", + "@readUpToHere": {}, + "start": "", + "@start": {}, + "bubbleSize": "", + "@bubbleSize": { + "type": "text", + "placeholders": {} + }, + "register": "", + "@register": { + "type": "text", + "placeholders": {} + }, + "unlockOldMessages": "", + "@unlockOldMessages": {}, + "identity": "", + "@identity": { + "type": "text", + "placeholders": {} + }, + "numChats": "", + "@numChats": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "changedTheJoinRulesTo": "", + "@changedTheJoinRulesTo": { + "type": "text", + "placeholders": { + "username": {}, + "joinRules": {} + } + }, + "ignore": "", + "@ignore": { + "type": "text", + "placeholders": {} + }, + "whatIsGoingOn": "", + "@whatIsGoingOn": {}, + "recording": "", + "@recording": { + "type": "text", + "placeholders": {} + }, + "moderator": "", + "@moderator": { + "type": "text", + "placeholders": {} + }, + "optionalRedactReason": "", + "@optionalRedactReason": {}, + "channelCorruptedDecryptError": "", + "@channelCorruptedDecryptError": { + "type": "text", + "placeholders": {} + }, + "tryToSendAgain": "", + "@tryToSendAgain": { + "type": "text", + "placeholders": {} + }, + "guestsCanJoin": "", + "@guestsCanJoin": { + "type": "text", + "placeholders": {} + }, + "copyToClipboard": "", + "@copyToClipboard": { + "type": "text", + "placeholders": {} + }, + "dehydrate": "", + "@dehydrate": {}, + "locationPermissionDeniedNotice": "", + "@locationPermissionDeniedNotice": { + "type": "text", + "placeholders": {} + }, + "send": "", + "@send": { + "type": "text", + "placeholders": {} + }, + "hasWithdrawnTheInvitationFor": "", + "@hasWithdrawnTheInvitationFor": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "visibleForAllParticipants": "", + "@visibleForAllParticipants": { + "type": "text", + "placeholders": {} + }, + "sendAsText": "", + "@sendAsText": { + "type": "text" + }, + "inviteForMe": "", + "@inviteForMe": { + "type": "text", + "placeholders": {} + }, + "archiveRoomDescription": "", + "@archiveRoomDescription": {}, + "exportEmotePack": "", + "@exportEmotePack": {}, + "sendSticker": "", + "@sendSticker": { + "type": "text", + "placeholders": {} + }, + "switchToAccount": "", + "@switchToAccount": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "commandInvalid": "", + "@commandInvalid": { + "type": "text" + }, + "setAsCanonicalAlias": "", + "@setAsCanonicalAlias": { + "type": "text", + "placeholders": {} + }, + "whyDoYouWantToReportThis": "", + "@whyDoYouWantToReportThis": { + "type": "text", + "placeholders": {} + }, + "locationDisabledNotice": "", + "@locationDisabledNotice": { + "type": "text", + "placeholders": {} + }, + "letsStart": "", + "@letsStart": {}, + "removedBy": "", + "@removedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "newChat": "", + "@newChat": { + "type": "text", + "placeholders": {} + }, + "notifications": "", + "@notifications": { + "type": "text", + "placeholders": {} + }, + "commandHint_plain": "", + "@commandHint_plain": { + "type": "text", + "description": "Usage hint for the command /plain" + }, + "experimentalVideoCalls": "", + "@experimentalVideoCalls": {}, + "savedEmotePack": "", + "@savedEmotePack": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "openCamera": "", + "@openCamera": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterRecoveryKeyDescription": "", + "@pleaseEnterRecoveryKeyDescription": {}, + "guestsAreForbidden": "", + "@guestsAreForbidden": { + "type": "text", + "placeholders": {} + }, + "mention": "", + "@mention": { + "type": "text", + "placeholders": {} + }, + "openInMaps": "", + "@openInMaps": { + "type": "text", + "placeholders": {} + }, + "inviteContactToGroupQuestion": "", + "@inviteContactToGroupQuestion": {}, + "emoteExists": "", + "@emoteExists": { + "type": "text", + "placeholders": {} + }, + "redactedByBecause": "", + "@redactedByBecause": { + "type": "text", + "placeholders": { + "username": {}, + "reason": {} + } + }, + "youHaveWithdrawnTheInvitationFor": "", + "@youHaveWithdrawnTheInvitationFor": { + "placeholders": { + "user": {} + } + }, + "group": "", + "@group": { + "type": "text", + "placeholders": {} + }, + "leave": "", + "@leave": { + "type": "text", + "placeholders": {} + }, + "skip": "", + "@skip": { + "type": "text", + "placeholders": {} + }, + "appearOnTopDetails": "", + "@appearOnTopDetails": {}, + "roomHasBeenUpgraded": "", + "@roomHasBeenUpgraded": { + "type": "text", + "placeholders": {} + }, + "enterRoom": "", + "@enterRoom": {}, + "enableEmotesGlobally": "", + "@enableEmotesGlobally": { + "type": "text", + "placeholders": {} + }, + "ignoreListDescription": "", + "@ignoreListDescription": { + "type": "text", + "placeholders": {} + }, + "pleaseChooseAPasscode": "", + "@pleaseChooseAPasscode": { + "type": "text", + "placeholders": {} + }, + "allChats": "", + "@allChats": { + "type": "text", + "placeholders": {} + }, + "reportUser": "", + "@reportUser": {}, + "commandHint_send": "", + "@commandHint_send": { + "type": "text", + "description": "Usage hint for the command /send" + }, + "unbannedUser": "", + "@unbannedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "confirmEventUnpin": "", + "@confirmEventUnpin": {}, + "youInvitedUser": "", + "@youInvitedUser": { + "placeholders": { + "user": {} + } + }, + "kickedAndBanned": "", + "@kickedAndBanned": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "noConnectionToTheServer": "", + "@noConnectionToTheServer": { + "type": "text", + "placeholders": {} + }, + "fileHasBeenSavedAt": "", + "@fileHasBeenSavedAt": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "license": "", + "@license": { + "type": "text", + "placeholders": {} + }, + "addToSpace": "", + "@addToSpace": {}, + "importZipFile": "", + "@importZipFile": {}, + "anyoneCanKnock": "", + "@anyoneCanKnock": {}, + "commandMissing": "", + "@commandMissing": { + "type": "text", + "placeholders": { + "command": {} + }, + "description": "State that {command} is not a valid /command." + }, + "redactMessageDescription": "", + "@redactMessageDescription": {}, + "rejoin": "", + "@rejoin": { + "type": "text", + "placeholders": {} + }, + "recoveryKey": "", + "@recoveryKey": {}, + "redactMessage": "", + "@redactMessage": { + "type": "text", + "placeholders": {} + }, + "forward": "", + "@forward": { + "type": "text", + "placeholders": {} + }, + "commandHint_discardsession": "", + "@commandHint_discardsession": { + "type": "text", + "description": "Usage hint for the command /discardsession" + }, + "invalidInput": "", + "@invalidInput": {}, + "hideUnknownEvents": "", + "@hideUnknownEvents": { + "type": "text", + "placeholders": {} + }, + "todosUnencrypted": "", + "@todosUnencrypted": {}, + "dehydrateTorLong": "", + "@dehydrateTorLong": {}, + "yourPublicKey": "", + "@yourPublicKey": { + "type": "text", + "placeholders": {} + }, + "tooManyRequestsWarning": "", + "@tooManyRequestsWarning": { + "type": "text", + "placeholders": {} + }, + "invitedUser": "", + "@invitedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "kickFromChat": "", + "@kickFromChat": { + "type": "text", + "placeholders": {} + }, + "commandHint_myroomnick": "", + "@commandHint_myroomnick": { + "type": "text", + "description": "Usage hint for the command /myroomnick" + }, + "offline": "", + "@offline": { + "type": "text", + "placeholders": {} + }, + "replyHasBeenSent": "", + "@replyHasBeenSent": {}, + "noPermission": "", + "@noPermission": { + "type": "text", + "placeholders": {} + }, + "doNotShowAgain": "", + "@doNotShowAgain": {}, + "report": "", + "@report": {}, + "status": "", + "@status": { + "type": "text", + "placeholders": {} + }, + "verifyStart": "", + "@verifyStart": { + "type": "text", + "placeholders": {} + }, + "yourStory": "", + "@yourStory": {}, + "memberChanges": "", + "@memberChanges": { + "type": "text", + "placeholders": {} + }, + "joinRoom": "", + "@joinRoom": { + "type": "text", + "placeholders": {} + }, + "ignoreUsername": "", + "@ignoreUsername": { + "type": "text", + "placeholders": {} + }, + "unverified": "", + "@unverified": {}, + "fluffychat": "", + "@fluffychat": { + "type": "text", + "placeholders": {} + }, + "howOffensiveIsThisContent": "", + "@howOffensiveIsThisContent": { + "type": "text", + "placeholders": {} + }, + "serverRequiresEmail": "", + "@serverRequiresEmail": {}, + "hideUnimportantStateEvents": "", + "@hideUnimportantStateEvents": {}, + "screenSharingTitle": "", + "@screenSharingTitle": {}, + "widgetCustom": "", + "@widgetCustom": {}, + "addToSpaceDescription": "", + "@addToSpaceDescription": {}, + "googlyEyesContent": "", + "@googlyEyesContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "whoCanSeeMyStoriesDesc": "", + "@whoCanSeeMyStoriesDesc": {}, + "youBannedUser": "", + "@youBannedUser": { + "placeholders": { + "user": {} + } + }, + "theyDontMatch": "", + "@theyDontMatch": { + "type": "text", + "placeholders": {} + }, + "unsubscribeStories": "", + "@unsubscribeStories": {}, + "youHaveBeenBannedFromThisChat": "", + "@youHaveBeenBannedFromThisChat": { + "type": "text", + "placeholders": {} + }, + "loginWithOneClick": "", + "@loginWithOneClick": {}, + "addChatDescription": "", + "@addChatDescription": {}, + "sentAnAudio": "", + "@sentAnAudio": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "editRoomAvatar": "", + "@editRoomAvatar": { + "type": "text", + "placeholders": {} + }, + "encrypted": "", + "@encrypted": { + "type": "text", + "placeholders": {} + }, + "commandHint_leave": "", + "@commandHint_leave": { + "type": "text", + "description": "Usage hint for the command /leave" + }, + "commandHint_myroomavatar": "", + "@commandHint_myroomavatar": { + "type": "text", + "description": "Usage hint for the command /myroomavatar" + }, + "hasKnocked": "", + "@hasKnocked": { + "placeholders": { + "user": {} + } + }, + "publish": "", + "@publish": {}, + "openLinkInBrowser": "", + "@openLinkInBrowser": {}, + "clearArchive": "", + "@clearArchive": {}, + "appLock": "", + "@appLock": { + "type": "text", + "placeholders": {} + }, + "commandHint_react": "", + "@commandHint_react": { + "type": "text", + "description": "Usage hint for the command /react" + }, + "changedTheHistoryVisibility": "", + "@changedTheHistoryVisibility": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "commandHint_me": "", + "@commandHint_me": { + "type": "text", + "description": "Usage hint for the command /me" + }, + "pleaseEnterYourUsername": "", + "@pleaseEnterYourUsername": { + "type": "text", + "placeholders": {} + }, + "messageInfo": "", + "@messageInfo": {}, + "disableEncryptionWarning": "", + "@disableEncryptionWarning": {}, + "directChat": "", + "@directChat": {}, + "noOneCanJoin": "", + "@noOneCanJoin": {}, + "wrongPinEntered": "", + "@wrongPinEntered": { + "type": "text", + "placeholders": { + "seconds": {} + } + }, + "sendTypingNotifications": "", + "@sendTypingNotifications": {}, + "lightTheme": "", + "@lightTheme": { + "type": "text", + "placeholders": {} + }, + "inviteGroupChat": "", + "@inviteGroupChat": {}, + "appearOnTop": "", + "@appearOnTop": {}, + "invitePrivateChat": "", + "@invitePrivateChat": {}, + "verifyTitle": "", + "@verifyTitle": { + "type": "text", + "placeholders": {} + }, + "foregroundServiceRunning": "", + "@foregroundServiceRunning": {}, + "enterAnEmailAddress": "", + "@enterAnEmailAddress": { + "type": "text", + "placeholders": {} + }, + "voiceCall": "", + "@voiceCall": {}, + "commandHint_kick": "", + "@commandHint_kick": { + "type": "text", + "description": "Usage hint for the command /kick" + }, + "copiedToClipboard": "", + "@copiedToClipboard": { + "type": "text", + "placeholders": {} + }, + "createNewSpace": "", + "@createNewSpace": { + "type": "text", + "placeholders": {} + }, + "commandHint_unban": "", + "@commandHint_unban": { + "type": "text", + "description": "Usage hint for the command /unban" + }, + "unknownEncryptionAlgorithm": "", + "@unknownEncryptionAlgorithm": { + "type": "text", + "placeholders": {} + }, + "commandHint_ban": "", + "@commandHint_ban": { + "type": "text", + "description": "Usage hint for the command /ban" + }, + "importEmojis": "", + "@importEmojis": {}, + "wasDirectChatDisplayName": "", + "@wasDirectChatDisplayName": { + "type": "text", + "placeholders": { + "oldDisplayName": {} + } + }, + "noChatDescriptionYet": "", + "@noChatDescriptionYet": {}, + "defaultPermissionLevel": "", + "@defaultPermissionLevel": { + "type": "text", + "placeholders": {} + }, + "newTodo": "", + "@newTodo": {}, + "removeFromBundle": "", + "@removeFromBundle": {}, + "numUsersTyping": "", + "@numUsersTyping": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "fontSize": "", + "@fontSize": { + "type": "text", + "placeholders": {} + }, + "whoCanPerformWhichAction": "", + "@whoCanPerformWhichAction": { + "type": "text", + "placeholders": {} + }, + "confirmMatrixId": "", + "@confirmMatrixId": {}, + "learnMore": "", + "@learnMore": {}, + "iHaveClickedOnLink": "", + "@iHaveClickedOnLink": { + "type": "text", + "placeholders": {} + }, + "you": "", + "@you": { + "type": "text", + "placeholders": {} + }, + "notAnImage": "", + "@notAnImage": {}, + "users": "", + "@users": {}, + "openGallery": "", + "@openGallery": {}, + "chatDescriptionHasBeenChanged": "", + "@chatDescriptionHasBeenChanged": {}, + "search": "", + "@search": { + "type": "text", + "placeholders": {} + }, + "newGroup": "", + "@newGroup": {}, + "bundleName": "", + "@bundleName": {}, + "dehydrateTor": "", + "@dehydrateTor": {}, + "todoListChangedError": "", + "@todoListChangedError": {}, + "removeFromSpace": "", + "@removeFromSpace": {}, + "enterInviteLinkOrMatrixId": "", + "@enterInviteLinkOrMatrixId": {}, + "commandHint_op": "", + "@commandHint_op": { + "type": "text", + "description": "Usage hint for the command /op" + }, + "commandHint_join": "", + "@commandHint_join": { + "type": "text", + "description": "Usage hint for the command /join" + }, + "sourceCode": "", + "@sourceCode": { + "type": "text", + "placeholders": {} + }, + "enterAGroupName": "", + "@enterAGroupName": { + "type": "text", + "placeholders": {} + }, + "roomUpgradeDescription": "", + "@roomUpgradeDescription": {}, + "commandHint_invite": "", + "@commandHint_invite": { + "type": "text", + "description": "Usage hint for the command /invite" + }, + "userSentUnknownEvent": "", + "@userSentUnknownEvent": { + "type": "text", + "placeholders": { + "username": {}, + "type": {} + } + }, + "scanQrCode": "", + "@scanQrCode": {}, + "pleaseEnterANumber": "", + "@pleaseEnterANumber": {}, + "youKicked": "", + "@youKicked": { + "placeholders": { + "user": {} + } + }, + "changedTheJoinRules": "", + "@changedTheJoinRules": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "profileNotFound": "", + "@profileNotFound": {}, + "jump": "", + "@jump": {}, + "groups": "", + "@groups": { + "type": "text", + "placeholders": {} + }, + "reactedWith": "", + "@reactedWith": { + "type": "text", + "placeholders": { + "sender": {}, + "reaction": {} + } + }, + "sorryThatsNotPossible": "", + "@sorryThatsNotPossible": {}, + "storyFrom": "", + "@storyFrom": { + "type": "text", + "placeholders": { + "date": {}, + "body": {} + } + }, + "videoWithSize": "", + "@videoWithSize": { + "type": "text", + "placeholders": { + "size": {} + } + }, + "loadCountMoreParticipants": "", + "@loadCountMoreParticipants": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "shareInviteLink": "", + "@shareInviteLink": {}, + "commandHint_markasdm": "", + "@commandHint_markasdm": {}, + "recoveryKeyLost": "", + "@recoveryKeyLost": {}, + "cuddleContent": "", + "@cuddleContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "messages": "", + "@messages": { + "type": "text", + "placeholders": {} + }, + "deviceKeys": "", + "@deviceKeys": {}, + "emoteKeyboardNoRecents": "", + "@emoteKeyboardNoRecents": { + "type": "text", + "placeholders": {} + }, + "setCustomEmotes": "", + "@setCustomEmotes": { + "type": "text", + "placeholders": {} + }, + "startedACall": "", + "@startedACall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "emoteInvalid": "", + "@emoteInvalid": { + "type": "text", + "placeholders": {} + }, + "systemTheme": "", + "@systemTheme": { + "type": "text", + "placeholders": {} + }, + "endToEndEncryption": "", + "@endToEndEncryption": {}, + "notificationsEnabledForThisAccount": "", + "@notificationsEnabledForThisAccount": { + "type": "text", + "placeholders": {} + }, + "visibilityOfTheChatHistory": "", + "@visibilityOfTheChatHistory": { + "type": "text", + "placeholders": {} + }, + "settings": "", + "@settings": { + "type": "text", + "placeholders": {} + }, + "setTheme": "", + "@setTheme": {}, + "youJoinedTheChat": "", + "@youJoinedTheChat": {}, + "wallpaper": "", + "@wallpaper": { + "type": "text", + "placeholders": {} + }, + "openVideoCamera": "", + "@openVideoCamera": { + "type": "text", + "placeholders": {} + }, + "play": "", + "@play": { + "type": "text", + "placeholders": { + "fileName": {} + } + }, + "lastSeenLongTimeAgo": "", + "@lastSeenLongTimeAgo": { + "type": "text", + "placeholders": {} + }, + "statusExampleMessage": "", + "@statusExampleMessage": { + "type": "text", + "placeholders": {} + }, + "thisUserHasNotPostedAnythingYet": "", + "@thisUserHasNotPostedAnythingYet": {}, + "security": "", + "@security": { + "type": "text", + "placeholders": {} + }, + "markAsRead": "", + "@markAsRead": {}, + "sendAudio": "", + "@sendAudio": { + "type": "text", + "placeholders": {} + }, + "widgetName": "", + "@widgetName": {}, + "sentASticker": "", + "@sentASticker": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "errorAddingWidget": "", + "@errorAddingWidget": {}, + "commandHint_dm": "", + "@commandHint_dm": { + "type": "text", + "description": "Usage hint for the command /dm" + }, + "commandHint_hug": "", + "@commandHint_hug": {}, + "replace": "", + "@replace": {}, + "reject": "", + "@reject": { + "type": "text", + "placeholders": {} + }, + "editBlockedServers": "", + "@editBlockedServers": { + "type": "text", + "placeholders": {} + }, + "oopsPushError": "", + "@oopsPushError": { + "type": "text", + "placeholders": {} + }, + "youUnbannedUser": "", + "@youUnbannedUser": { + "placeholders": { + "user": {} + } + }, + "joinedTheChat": "", + "@joinedTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "visibleForEveryone": "", + "@visibleForEveryone": { + "type": "text", + "placeholders": {} + }, + "pleaseEnter4Digits": "", + "@pleaseEnter4Digits": { + "type": "text", + "placeholders": {} + }, + "newSpace": "", + "@newSpace": {}, + "unknownEvent": "", + "@unknownEvent": { + "type": "text", + "placeholders": { + "type": {} + } + }, + "emojis": "", + "@emojis": {}, + "signUp": "", + "@signUp": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourPin": "", + "@pleaseEnterYourPin": { + "type": "text", + "placeholders": {} + }, + "pleaseChoose": "", + "@pleaseChoose": { + "type": "text", + "placeholders": {} + }, + "share": "", + "@share": { + "type": "text", + "placeholders": {} + }, + "commandHint_googly": "", + "@commandHint_googly": {}, + "pleaseTryAgainLaterOrChooseDifferentServer": "", + "@pleaseTryAgainLaterOrChooseDifferentServer": {}, + "createGroup": "", + "@createGroup": {}, + "privacy": "", + "@privacy": { + "type": "text", + "placeholders": {} + }, + "changeYourAvatar": "", + "@changeYourAvatar": { + "type": "text", + "placeholders": {} + }, + "sendImage": "", + "@sendImage": { + "type": "text", + "placeholders": {} + }, + "hydrateTorLong": "", + "@hydrateTorLong": {}, + "time": "", + "@time": {}, + "enterYourHomeserver": "", + "@enterYourHomeserver": { + "type": "text", + "placeholders": {} + }, + "botMessages": "", + "@botMessages": { + "type": "text", + "placeholders": {} + }, + "contentHasBeenReported": "", + "@contentHasBeenReported": { + "type": "text", + "placeholders": {} + }, + "custom": "", + "@custom": {}, + "noBackupWarning": "", + "@noBackupWarning": {}, + "fromJoining": "", + "@fromJoining": { + "type": "text", + "placeholders": {} + }, + "verify": "", + "@verify": { + "type": "text", + "placeholders": {} + }, + "sendVideo": "", + "@sendVideo": { + "type": "text", + "placeholders": {} + }, + "editWidgets": "", + "@editWidgets": {}, + "storeInSecureStorageDescription": "", + "@storeInSecureStorageDescription": {}, + "openChat": "", + "@openChat": {}, + "kickUserDescription": "", + "@kickUserDescription": {}, + "sendAMessage": "", + "@sendAMessage": { + "type": "text", + "placeholders": {} + }, + "pin": "", + "@pin": { + "type": "text", + "placeholders": {} + }, + "importNow": "", + "@importNow": {}, + "setInvitationLink": "", + "@setInvitationLink": { + "type": "text", + "placeholders": {} + }, + "pinMessage": "", + "@pinMessage": {}, + "muteChat": "", + "@muteChat": { + "type": "text", + "placeholders": {} + }, + "invite": "", + "@invite": {}, + "enableMultiAccounts": "", + "@enableMultiAccounts": {}, + "emotePacks": "", + "@emotePacks": { + "type": "text", + "placeholders": {} + }, + "makeSureTheIdentifierIsValid": "", + "@makeSureTheIdentifierIsValid": { + "type": "text", + "placeholders": {} + }, + "continueWith": "", + "@continueWith": {}, + "indexedDbErrorTitle": "", + "@indexedDbErrorTitle": {}, + "pleaseChooseAUsername": "", + "@pleaseChooseAUsername": { + "type": "text", + "placeholders": {} + }, + "endedTheCall": "", + "@endedTheCall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "changedTheDisplaynameTo": "", + "@changedTheDisplaynameTo": { + "type": "text", + "placeholders": { + "username": {}, + "displayname": {} + } + }, + "unreadChats": "", + "@unreadChats": { + "type": "text", + "placeholders": { + "unreadCount": {} + } + }, + "pleaseEnterAMatrixIdentifier": "", + "@pleaseEnterAMatrixIdentifier": { + "type": "text", + "placeholders": {} + }, + "userAndOthersAreTyping": "", + "@userAndOthersAreTyping": { + "type": "text", + "placeholders": { + "username": {}, + "count": {} + } + }, + "userIsTyping": "", + "@userIsTyping": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "waitingPartnerAcceptRequest": "", + "@waitingPartnerAcceptRequest": { + "type": "text", + "placeholders": {} + }, + "writeAMessage": "", + "@writeAMessage": { + "type": "text", + "placeholders": {} + }, + "userAndUserAreTyping": "", + "@userAndUserAreTyping": { + "type": "text", + "placeholders": { + "username": {}, + "username2": {} + } + }, + "pickImage": "", + "@pickImage": { + "type": "text", + "placeholders": {} + }, + "fileName": "", + "@fileName": { + "type": "text", + "placeholders": {} + }, + "loadMore": "", + "@loadMore": { + "type": "text", + "placeholders": {} + }, + "passwordHasBeenChanged": "", + "@passwordHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "loadingPleaseWait": "", + "@loadingPleaseWait": { + "type": "text", + "placeholders": {} + }, + "waitingPartnerEmoji": "", + "@waitingPartnerEmoji": { + "type": "text", + "placeholders": {} + }, + "noRoomsFound": "", + "@noRoomsFound": { + "type": "text", + "placeholders": {} + }, + "withTheseAddressesRecoveryDescription": "", + "@withTheseAddressesRecoveryDescription": { + "type": "text", + "placeholders": {} + }, + "isTyping": "", + "@isTyping": { + "type": "text", + "placeholders": {} + }, + "noPasswordRecoveryDescription": "", + "@noPasswordRecoveryDescription": { + "type": "text", + "placeholders": {} + }, + "onlineKeyBackupEnabled": "", + "@onlineKeyBackupEnabled": { + "type": "text", + "placeholders": {} + }, + "groupIsPublic": "", + "@groupIsPublic": { + "type": "text", + "placeholders": {} + }, + "sentCallInformations": "", + "@sentCallInformations": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "encryptionNotEnabled": "", + "@encryptionNotEnabled": { + "type": "text", + "placeholders": {} + }, + "logout": "", + "@logout": { + "type": "text", + "placeholders": {} + }, + "oopsSomethingWentWrong": "", + "@oopsSomethingWentWrong": { + "type": "text", + "placeholders": {} + }, + "containsUserName": "", + "@containsUserName": { + "type": "text", + "placeholders": {} + }, + "login": "", + "@login": { + "type": "text", + "placeholders": {} + }, + "waitingPartnerNumbers": "", + "@waitingPartnerNumbers": { + "type": "text", + "placeholders": {} + }, + "messageWillBeRemovedWarning": "", + "@messageWillBeRemovedWarning": { + "type": "text", + "placeholders": {} + }, + "passwordForgotten": "", + "@passwordForgotten": { + "type": "text", + "placeholders": {} + }, + "placeCall": "", + "@placeCall": {}, + "noGoogleServicesWarning": "", + "@noGoogleServicesWarning": { + "type": "text", + "placeholders": {} + }, + "extremeOffensive": "", + "@extremeOffensive": { + "type": "text", + "placeholders": {} + } +} diff --git a/assets/l10n/intl_zh.arb b/assets/l10n/intl_zh.arb index 586a5c9ff..676ca3aa6 100644 --- a/assets/l10n/intl_zh.arb +++ b/assets/l10n/intl_zh.arb @@ -1123,7 +1123,7 @@ "type": "text", "placeholders": {} }, - "noGoogleServicesWarning": "看起来你手机上没有谷歌服务框架。这对保护你的隐私而言是个好决定!要接收 FluffyChat 的推送通知,推荐你使用 https://microg.org/ 或 https://unifiedpush.org/。", + "noGoogleServicesWarning": "看起来你手机上没有 Firebase Cloud Messaging。如果仍希望接收 FluffyChat 的推送通知,推荐安装 ntfy。借助 ntfy 或另一个 Unified Push 程序,你可以以一种数据安全的方式接收推送通知。你可以从 PlayStore 或 F-Droid 商店下载 ntfy。", "@noGoogleServicesWarning": { "type": "text", "placeholders": {} @@ -2617,5 +2617,45 @@ "placeholders": { "seconds": {} } - } + }, + "hasKnocked": "{user} 请求了加入聊天室的邀请", + "@hasKnocked": { + "placeholders": { + "user": {} + } + }, + "pleaseEnterANumber": "请输入大于 0 的数", + "@pleaseEnterANumber": {}, + "banUserDescription": "", + "@banUserDescription": {}, + "removeDevicesDescription": "", + "@removeDevicesDescription": {}, + "unbanUserDescription": "", + "@unbanUserDescription": {}, + "todoLists": "", + "@todoLists": {}, + "editTodo": "", + "@editTodo": {}, + "pushNotificationsNotAvailable": "", + "@pushNotificationsNotAvailable": {}, + "pleaseAddATitle": "", + "@pleaseAddATitle": {}, + "makeAdminDescription": "", + "@makeAdminDescription": {}, + "noTodosYet": "", + "@noTodosYet": {}, + "archiveRoomDescription": "", + "@archiveRoomDescription": {}, + "todosUnencrypted": "", + "@todosUnencrypted": {}, + "newTodo": "", + "@newTodo": {}, + "learnMore": "", + "@learnMore": {}, + "todoListChangedError": "", + "@todoListChangedError": {}, + "roomUpgradeDescription": "", + "@roomUpgradeDescription": {}, + "kickUserDescription": "", + "@kickUserDescription": {} } diff --git a/assets/l10n/intl_zh_Hant.arb b/assets/l10n/intl_zh_Hant.arb index 7cadeeb3d..5bfc25f37 100644 --- a/assets/l10n/intl_zh_Hant.arb +++ b/assets/l10n/intl_zh_Hant.arb @@ -1,1919 +1,2651 @@ { - "@@last_modified": "2021-08-14 12:41:09.708353", - "about": "關於", - "@about": { - "type": "text", - "placeholders": {} - }, - "accept": "接受", - "@accept": { - "type": "text", - "placeholders": {} - }, - "acceptedTheInvitation": "{username}已接受邀請", - "@acceptedTheInvitation": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "account": "帳號", - "@account": { - "type": "text", - "placeholders": {} - }, - "activatedEndToEndEncryption": "{username}已啟用點對點加密", - "@activatedEndToEndEncryption": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "addEmail": "新增電子郵件", - "@addEmail": { - "type": "text", - "placeholders": {} - }, - "addGroupDescription": "新增一個群組描述", - "@addGroupDescription": { - "type": "text", - "placeholders": {} - }, - "admin": "管理員", - "@admin": { - "type": "text", - "placeholders": {} - }, - "alias": "別稱", - "@alias": { - "type": "text", - "placeholders": {} - }, - "all": "全部", - "@all": { - "type": "text", - "placeholders": {} - }, - "answeredTheCall": "已開始與{senderName}通話", - "@answeredTheCall": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "anyoneCanJoin": "任何人可以加入", - "@anyoneCanJoin": { - "type": "text", - "placeholders": {} - }, - "appLock": "密碼鎖定", - "@appLock": { - "type": "text", - "placeholders": {} - }, - "archive": "封存", - "@archive": { - "type": "text", - "placeholders": {} - }, - "areGuestsAllowedToJoin": "是否允許訪客加入", - "@areGuestsAllowedToJoin": { - "type": "text", - "placeholders": {} - }, - "areYouSure": "您確定嗎?", - "@areYouSure": { - "type": "text", - "placeholders": {} - }, - "areYouSureYouWantToLogout": "您確定要登出嗎?", - "@areYouSureYouWantToLogout": { - "type": "text", - "placeholders": {} - }, - "askSSSSSign": "請輸入您安全儲存的密碼短語或恢復金鑰,以向對方簽名。", - "@askSSSSSign": { - "type": "text", - "placeholders": {} - }, - "askVerificationRequest": "是否接受來自{username}的驗證申請?", - "@askVerificationRequest": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "badServerLoginTypesException": "目前伺服器支援的登入類型:\n{serverVersions}\n但本應用程式僅支援:\n{supportedVersions}", - "@badServerLoginTypesException": { - "type": "text", - "placeholders": { - "serverVersions": {}, - "supportedVersions": {} - } - }, - "badServerVersionsException": "目前伺服器支援的Spec版本:\n{serverVersions}\n但本應用程式僅支援{supportedVersions}", - "@badServerVersionsException": { - "type": "text", - "placeholders": { - "serverVersions": {}, - "supportedVersions": {} - } - }, - "banFromChat": "已從聊天室中封禁", - "@banFromChat": { - "type": "text", - "placeholders": {} - }, - "banned": "已被封禁", - "@banned": { - "type": "text", - "placeholders": {} - }, - "bannedUser": "{username}封禁了{targetName}", - "@bannedUser": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "blockDevice": "封鎖裝置", - "@blockDevice": { - "type": "text", - "placeholders": {} - }, - "blocked": "已封鎖", - "@blocked": { - "type": "text", - "placeholders": {} - }, - "botMessages": "機器人訊息", - "@botMessages": { - "type": "text", - "placeholders": {} - }, - "cancel": "取消", - "@cancel": { - "type": "text", - "placeholders": {} - }, - "changeDeviceName": "變更裝置名稱", - "@changeDeviceName": { - "type": "text", - "placeholders": {} - }, - "changedTheChatAvatar": "{username}變更了對話頭貼", - "@changedTheChatAvatar": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheChatDescriptionTo": "{username}變更了對話介紹為:「{description}」", - "@changedTheChatDescriptionTo": { - "type": "text", - "placeholders": { - "username": {}, - "description": {} - } - }, - "changedTheChatNameTo": "{username}變更了暱稱為:「{chatname}」", - "@changedTheChatNameTo": { - "type": "text", - "placeholders": { - "username": {}, - "chatname": {} - } - }, - "changedTheChatPermissions": "{username}變更了對話權限", - "@changedTheChatPermissions": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheDisplaynameTo": "{username} 變更了顯示名稱為:「{displayname}」", - "@changedTheDisplaynameTo": { - "type": "text", - "placeholders": { - "username": {}, - "displayname": {} - } - }, - "changedTheGuestAccessRules": "{username}變更了訪客訪問規則", - "@changedTheGuestAccessRules": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheGuestAccessRulesTo": "{username}變更了訪客訪問規則為:{rules}", - "@changedTheGuestAccessRulesTo": { - "type": "text", - "placeholders": { - "username": {}, - "rules": {} - } - }, - "changedTheHistoryVisibility": "{username}變更了歷史記錄觀察狀態", - "@changedTheHistoryVisibility": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheHistoryVisibilityTo": "{username}變更了歷史紀錄觀察狀態到:{rules}", - "@changedTheHistoryVisibilityTo": { - "type": "text", - "placeholders": { - "username": {}, - "rules": {} - } - }, - "changedTheJoinRules": "{username}變更了加入的規則", - "@changedTheJoinRules": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheJoinRulesTo": "{username}變更了加入的規則為:{joinRules}", - "@changedTheJoinRulesTo": { - "type": "text", - "placeholders": { - "username": {}, - "joinRules": {} - } - }, - "changedTheProfileAvatar": "{username}變更了頭貼", - "@changedTheProfileAvatar": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheRoomAliases": "{username}變更了聊天室名", - "@changedTheRoomAliases": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheRoomInvitationLink": "{username}變更了邀請連結", - "@changedTheRoomInvitationLink": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changePassword": "變更密碼", - "@changePassword": { - "type": "text", - "placeholders": {} - }, - "changeTheHomeserver": "變更主機位址", - "@changeTheHomeserver": { - "type": "text", - "placeholders": {} - }, - "changeTheme": "變更主題", - "@changeTheme": { - "type": "text", - "placeholders": {} - }, - "changeTheNameOfTheGroup": "變更了群組名稱", - "@changeTheNameOfTheGroup": { - "type": "text", - "placeholders": {} - }, - "changeWallpaper": "變更聊天背景", - "@changeWallpaper": { - "type": "text", - "placeholders": {} - }, - "channelCorruptedDecryptError": "加密已被破壞", - "@channelCorruptedDecryptError": { - "type": "text", - "placeholders": {} - }, - "chat": "聊天", - "@chat": { - "type": "text", - "placeholders": {} - }, - "chatBackup": "備份聊天室", - "@chatBackup": { - "type": "text", - "placeholders": {} - }, - "chatBackupDescription": "您的聊天記錄備份已被安全金鑰鑰加密。請您確保不會弄丟它。", - "@chatBackupDescription": { - "type": "text", - "placeholders": {} - }, - "chatDetails": "對話詳細", - "@chatDetails": { - "type": "text", - "placeholders": {} - }, - "chooseAStrongPassword": "輸入一個較強的密碼", - "@chooseAStrongPassword": { - "type": "text", - "placeholders": {} - }, - "chooseAUsername": "輸入您的使用者名稱", - "@chooseAUsername": { - "type": "text", - "placeholders": {} - }, - "close": "關閉", - "@close": { - "type": "text", - "placeholders": {} - }, - "compareEmojiMatch": "對比並確認這些表情符合其他那些裝置:", - "@compareEmojiMatch": { - "type": "text", - "placeholders": {} - }, - "compareNumbersMatch": "比較以下數字,確保它們和另一個裝置上的相同:", - "@compareNumbersMatch": { - "type": "text", - "placeholders": {} - }, - "configureChat": "設定聊天室", - "@configureChat": { - "type": "text", - "placeholders": {} - }, - "confirm": "確認", - "@confirm": { - "type": "text", - "placeholders": {} - }, - "connect": "連接", - "@connect": { - "type": "text", - "placeholders": {} - }, - "contactHasBeenInvitedToTheGroup": "聯絡人已被邀請至群組", - "@contactHasBeenInvitedToTheGroup": { - "type": "text", - "placeholders": {} - }, - "containsDisplayName": "包含顯示名稱", - "@containsDisplayName": { - "type": "text", - "placeholders": {} - }, - "containsUserName": "包含使用者名稱", - "@containsUserName": { - "type": "text", - "placeholders": {} - }, - "contentHasBeenReported": "此內容已被回報給伺服器管理員們", - "@contentHasBeenReported": { - "type": "text", - "placeholders": {} - }, - "copiedToClipboard": "已複製到剪貼簿", - "@copiedToClipboard": { - "type": "text", - "placeholders": {} - }, - "copy": "複製", - "@copy": { - "type": "text", - "placeholders": {} - }, - "copyToClipboard": "複製到剪貼簿", - "@copyToClipboard": { - "type": "text", - "placeholders": {} - }, - "couldNotDecryptMessage": "不能解密訊息:{error}", - "@couldNotDecryptMessage": { - "type": "text", - "placeholders": { - "error": {} - } - }, - "countParticipants": "{count}個參與者", - "@countParticipants": { - "type": "text", - "placeholders": { - "count": {} - } - }, - "create": "建立", - "@create": { - "type": "text", - "placeholders": {} - }, - "createdTheChat": "{username}建立了聊天室", - "@createdTheChat": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "createNewGroup": "建立新群組", - "@createNewGroup": { - "type": "text", - "placeholders": {} - }, - "currentlyActive": "目前活躍", - "@currentlyActive": { - "type": "text", - "placeholders": {} - }, - "darkTheme": "夜間模式", - "@darkTheme": { - "type": "text", - "placeholders": {} - }, - "dateAndTimeOfDay": "{date}, {timeOfDay}", - "@dateAndTimeOfDay": { - "type": "text", - "placeholders": { - "date": {}, - "timeOfDay": {} - } - }, - "dateWithoutYear": "{month}-{day}", - "@dateWithoutYear": { - "type": "text", - "placeholders": { - "month": {}, - "day": {} - } - }, - "dateWithYear": "{year}-{month}-{day}", - "@dateWithYear": { - "type": "text", - "placeholders": { - "year": {}, - "month": {}, - "day": {} - } - }, - "deactivateAccountWarning": "這將停用您的帳號。這個決定是不能挽回的!您確定嗎?", - "@deactivateAccountWarning": { - "type": "text", - "placeholders": {} - }, - "defaultPermissionLevel": "預設權限等級", - "@defaultPermissionLevel": { - "type": "text", - "placeholders": {} - }, - "delete": "刪除", - "@delete": { - "type": "text", - "placeholders": {} - }, - "deleteAccount": "刪除帳號", - "@deleteAccount": { - "type": "text", - "placeholders": {} - }, - "deleteMessage": "刪除訊息", - "@deleteMessage": { - "type": "text", - "placeholders": {} - }, - "deny": "否認", - "@deny": { - "type": "text", - "placeholders": {} - }, - "device": "裝置", - "@device": { - "type": "text", - "placeholders": {} - }, - "deviceId": "裝置ID", - "@deviceId": { - "type": "text", - "placeholders": {} - }, - "devices": "裝置", - "@devices": { - "type": "text", - "placeholders": {} - }, - "directChats": "直接傳訊", - "@directChats": { - "type": "text", - "placeholders": {} - }, - "displaynameHasBeenChanged": "顯示名稱已被變更", - "@displaynameHasBeenChanged": { - "type": "text", - "placeholders": {} - }, - "downloadFile": "下載文件", - "@downloadFile": { - "type": "text", - "placeholders": {} - }, - "edit": "編輯", - "@edit": { - "type": "text", - "placeholders": {} - }, - "editBlockedServers": "編輯被封鎖的伺服器", - "@editBlockedServers": { - "type": "text", - "placeholders": {} - }, - "editChatPermissions": "編輯聊天室權限", - "@editChatPermissions": { - "type": "text", - "placeholders": {} - }, - "editDisplayname": "編輯顯示名稱", - "@editDisplayname": { - "type": "text", - "placeholders": {} - }, - "editRoomAvatar": "編輯聊天室頭貼", - "@editRoomAvatar": { - "type": "text", - "placeholders": {} - }, - "emoteExists": "表情已存在!", - "@emoteExists": { - "type": "text", - "placeholders": {} - }, - "emoteInvalid": "無效的表情快捷鍵!", - "@emoteInvalid": { - "type": "text", - "placeholders": {} - }, - "emotePacks": "聊天室的表情符號", - "@emotePacks": { - "type": "text", - "placeholders": {} - }, - "emoteSettings": "表情設定", - "@emoteSettings": { - "type": "text", - "placeholders": {} - }, - "emoteShortcode": "表情快捷鍵", - "@emoteShortcode": { - "type": "text", - "placeholders": {} - }, - "emoteWarnNeedToPick": "您需要選取一個表情快捷鍵和一張圖片!", - "@emoteWarnNeedToPick": { - "type": "text", - "placeholders": {} - }, - "emptyChat": "空的聊天室", - "@emptyChat": { - "type": "text", - "placeholders": {} - }, - "enableEmotesGlobally": "在全域啟用表情符號", - "@enableEmotesGlobally": { - "type": "text", - "placeholders": {} - }, - "enableEncryption": "啟用加密", - "@enableEncryption": { - "type": "text", - "placeholders": {} - }, - "enableEncryptionWarning": "您將不能再停用加密,確定嗎?", - "@enableEncryptionWarning": { - "type": "text", - "placeholders": {} - }, - "encrypted": "加密的", - "@encrypted": { - "type": "text", - "placeholders": {} - }, - "encryption": "加密", - "@encryption": { - "type": "text", - "placeholders": {} - }, - "encryptionNotEnabled": "加密未啟用", - "@encryptionNotEnabled": { - "type": "text", - "placeholders": {} - }, - "endedTheCall": "{senderName}結束了通話", - "@endedTheCall": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "enterAGroupName": "輸入群組名稱", - "@enterAGroupName": { - "type": "text", - "placeholders": {} - }, - "enterAnEmailAddress": "輸入一個電子郵件位址", - "@enterAnEmailAddress": { - "type": "text", - "placeholders": {} - }, - "enterYourHomeserver": "輸入伺服器位址", - "@enterYourHomeserver": { - "type": "text", - "placeholders": {} - }, - "everythingReady": "一切就緒!", - "@everythingReady": { - "type": "text", - "placeholders": {} - }, - "extremeOffensive": "極端令人反感", - "@extremeOffensive": { - "type": "text", - "placeholders": {} - }, - "fileName": "檔案名稱", - "@fileName": { - "type": "text", - "placeholders": {} - }, - "fluffychat": "FluffyChat", - "@fluffychat": { - "type": "text", - "placeholders": {} - }, - "fontSize": "字體大小", - "@fontSize": { - "type": "text", - "placeholders": {} - }, - "forward": "轉發", - "@forward": { - "type": "text", - "placeholders": {} - }, - "fromJoining": "自加入起", - "@fromJoining": { - "type": "text", - "placeholders": {} - }, - "fromTheInvitation": "自邀請起", - "@fromTheInvitation": { - "type": "text", - "placeholders": {} - }, - "group": "群組", - "@group": { - "type": "text", - "placeholders": {} - }, - "groupDescription": "群組描述", - "@groupDescription": { - "type": "text", - "placeholders": {} - }, - "groupDescriptionHasBeenChanged": "群組描述已被變更", - "@groupDescriptionHasBeenChanged": { - "type": "text", - "placeholders": {} - }, - "groupIsPublic": "群組是公開的", - "@groupIsPublic": { - "type": "text", - "placeholders": {} - }, - "groups": "群組", - "@groups": { - "type": "text", - "placeholders": {} - }, - "groupWith": "名稱為{displayname}的群組", - "@groupWith": { - "type": "text", - "placeholders": { - "displayname": {} - } - }, - "guestsAreForbidden": "訪客已被禁止", - "@guestsAreForbidden": { - "type": "text", - "placeholders": {} - }, - "guestsCanJoin": "訪客可以加入", - "@guestsCanJoin": { - "type": "text", - "placeholders": {} - }, - "hasWithdrawnTheInvitationFor": "{username}收回了對{targetName}的邀請", - "@hasWithdrawnTheInvitationFor": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "help": "幫助", - "@help": { - "type": "text", - "placeholders": {} - }, - "hideRedactedEvents": "隱藏編輯過的事件", - "@hideRedactedEvents": { - "type": "text", - "placeholders": {} - }, - "hideUnknownEvents": "隱藏未知事件", - "@hideUnknownEvents": { - "type": "text", - "placeholders": {} - }, - "howOffensiveIsThisContent": "這個內容有多令人反感?", - "@howOffensiveIsThisContent": { - "type": "text", - "placeholders": {} - }, - "id": "ID", - "@id": { - "type": "text", - "placeholders": {} - }, - "identity": "身份", - "@identity": { - "type": "text", - "placeholders": {} - }, - "ignore": "無視", - "@ignore": { - "type": "text", - "placeholders": {} - }, - "ignoredUsers": "已無視的使用者", - "@ignoredUsers": { - "type": "text", - "placeholders": {} - }, - "ignoreListDescription": "您可以無視打擾您的使用者。您將不會再收到來自無視列表中使用者的任何消息或聊天室邀請。", - "@ignoreListDescription": { - "type": "text", - "placeholders": {} - }, - "ignoreUsername": "無視使用者名稱", - "@ignoreUsername": { - "type": "text", - "placeholders": {} - }, - "iHaveClickedOnLink": "我已經點擊了網址", - "@iHaveClickedOnLink": { - "type": "text", - "placeholders": {} - }, - "incorrectPassphraseOrKey": "錯誤的密碼短語或恢復金鑰", - "@incorrectPassphraseOrKey": { - "type": "text", - "placeholders": {} - }, - "inoffensive": "不令人反感", - "@inoffensive": { - "type": "text", - "placeholders": {} - }, - "inviteContact": "邀請聯絡人", - "@inviteContact": { - "type": "text", - "placeholders": {} - }, - "inviteContactToGroup": "邀請聯絡人到{groupName}", - "@inviteContactToGroup": { - "type": "text", - "placeholders": { - "groupName": {} - } - }, - "invited": "已邀請", - "@invited": { - "type": "text", - "placeholders": {} - }, - "invitedUser": "{username}邀請了{targetName}", - "@invitedUser": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "invitedUsersOnly": "只有被邀請的使用者", - "@invitedUsersOnly": { - "type": "text", - "placeholders": {} - }, - "inviteForMe": "來自我的邀請", - "@inviteForMe": { - "type": "text", - "placeholders": {} - }, - "inviteText": "{username}邀請您使用FluffyChat\n1. 安裝FluffyChat:https://fluffychat.im\n2. 登入或註冊\n3. 打開該邀請網址:{link}", - "@inviteText": { - "type": "text", - "placeholders": { - "username": {}, - "link": {} - } - }, - "isTyping": "正在輸入...…", - "@isTyping": { - "type": "text", - "placeholders": {} - }, - "joinedTheChat": "{username}加入了聊天室", - "@joinedTheChat": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "joinRoom": "加入聊天室", - "@joinRoom": { - "type": "text", - "placeholders": {} - }, - "kicked": "{username}踢了{targetName}", - "@kicked": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "kickedAndBanned": "{username}踢了{targetName}並將其封禁", - "@kickedAndBanned": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "kickFromChat": "從聊天室踢出", - "@kickFromChat": { - "type": "text", - "placeholders": {} - }, - "lastActiveAgo": "最後活動時間:{localizedTimeShort}", - "@lastActiveAgo": { - "type": "text", - "placeholders": { - "localizedTimeShort": {} - } - }, - "lastSeenLongTimeAgo": "很長一段時間沒有上線了", - "@lastSeenLongTimeAgo": { - "type": "text", - "placeholders": {} - }, - "leave": "離開", - "@leave": { - "type": "text", - "placeholders": {} - }, - "leftTheChat": "離開了聊天室", - "@leftTheChat": { - "type": "text", - "placeholders": {} - }, - "license": "授權", - "@license": { - "type": "text", - "placeholders": {} - }, - "lightTheme": "日間模式", - "@lightTheme": { - "type": "text", - "placeholders": {} - }, - "loadCountMoreParticipants": "載入{count}個更多的參與者", - "@loadCountMoreParticipants": { - "type": "text", - "placeholders": { - "count": {} - } - }, - "loadingPleaseWait": "載入中… 請稍候。", - "@loadingPleaseWait": { - "type": "text", - "placeholders": {} - }, - "loadMore": "載入更多…", - "@loadMore": { - "type": "text", - "placeholders": {} - }, - "login": "登入", - "@login": { - "type": "text", - "placeholders": {} - }, - "logInTo": "登入{homeserver}", - "@logInTo": { - "type": "text", - "placeholders": { - "homeserver": {} - } - }, - "logout": "登出", - "@logout": { - "type": "text", - "placeholders": {} - }, - "makeSureTheIdentifierIsValid": "確保識別碼正確", - "@makeSureTheIdentifierIsValid": { - "type": "text", - "placeholders": {} - }, - "memberChanges": "變更成員", - "@memberChanges": { - "type": "text", - "placeholders": {} - }, - "mention": "提及", - "@mention": { - "type": "text", - "placeholders": {} - }, - "messages": "訊息", - "@messages": { - "type": "text", - "placeholders": {} - }, - "messageWillBeRemovedWarning": "將移除所有參與者的訊息", - "@messageWillBeRemovedWarning": { - "type": "text", - "placeholders": {} - }, - "moderator": "版主", - "@moderator": { - "type": "text", - "placeholders": {} - }, - "muteChat": "將該聊天室靜音", - "@muteChat": { - "type": "text", - "placeholders": {} - }, - "needPantalaimonWarning": "請注意您需要Pantalaimon才能使用點對點加密功能。", - "@needPantalaimonWarning": { - "type": "text", - "placeholders": {} - }, - "newChat": "新聊天室", - "@newChat": { - "type": "text", - "placeholders": {} - }, - "newMessageInFluffyChat": "來自 FluffyChat 的新訊息", - "@newMessageInFluffyChat": { - "type": "text", - "placeholders": {} - }, - "newVerificationRequest": "新的驗證請求!", - "@newVerificationRequest": { - "type": "text", - "placeholders": {} - }, - "next": "下一個", - "@next": { - "type": "text", - "placeholders": {} - }, - "no": "否", - "@no": { - "type": "text", - "placeholders": {} - }, - "noConnectionToTheServer": "無法連接到伺服器", - "@noConnectionToTheServer": { - "type": "text", - "placeholders": {} - }, - "noEmotesFound": "表情符號不存在。😕", - "@noEmotesFound": { - "type": "text", - "placeholders": {} - }, - "noEncryptionForPublicRooms": "您只能在這個聊天室不再被允許公開訪問後,才能啟用加密。", - "@noEncryptionForPublicRooms": { - "type": "text", - "placeholders": {} - }, - "noGoogleServicesWarning": "看起來您手機上沒有Google服務框架。這對於保護您的隱私而言是個好決定!但為了收到FluffyChat的推播通知,我們推薦您使用 https://microg.org/ 或 https://unifiedpush.org/。", - "@noGoogleServicesWarning": { - "type": "text", - "placeholders": {} - }, - "none": "無", - "@none": { - "type": "text", - "placeholders": {} - }, - "noPasswordRecoveryDescription": "您尚未新增恢復密碼的方法。", - "@noPasswordRecoveryDescription": { - "type": "text", - "placeholders": {} - }, - "noPermission": "沒有權限", - "@noPermission": { - "type": "text", - "placeholders": {} - }, - "noRoomsFound": "找不到聊天室…", - "@noRoomsFound": { - "type": "text", - "placeholders": {} - }, - "notifications": "通知", - "@notifications": { - "type": "text", - "placeholders": {} - }, - "notificationsEnabledForThisAccount": "已為此帳號啟用通知", - "@notificationsEnabledForThisAccount": { - "type": "text", - "placeholders": {} - }, - "numUsersTyping": "{count}個人正在輸入…", - "@numUsersTyping": { - "type": "text", - "placeholders": { - "count": {} - } - }, - "offensive": "令人反感", - "@offensive": { - "type": "text", - "placeholders": {} - }, - "offline": "離線", - "@offline": { - "type": "text", - "placeholders": {} - }, - "ok": "OK", - "@ok": { - "type": "text", - "placeholders": {} - }, - "online": "線上", - "@online": { - "type": "text", - "placeholders": {} - }, - "onlineKeyBackupEnabled": "線上金鑰備份已啟用", - "@onlineKeyBackupEnabled": { - "type": "text", - "placeholders": {} - }, - "oopsSomethingWentWrong": "哎呀!出了一點差錯…", - "@oopsSomethingWentWrong": { - "type": "text", - "placeholders": {} - }, - "openAppToReadMessages": "打開應用程式以讀取訊息", - "@openAppToReadMessages": { - "type": "text", - "placeholders": {} - }, - "openCamera": "開啟相機", - "@openCamera": { - "type": "text", - "placeholders": {} - }, - "optionalGroupName": "(可選)群組名稱", - "@optionalGroupName": { - "type": "text", - "placeholders": {} - }, - "participant": "參與者", - "@participant": { - "type": "text", - "placeholders": {} - }, - "passphraseOrKey": "密碼短語或恢復金鑰", - "@passphraseOrKey": { - "type": "text", - "placeholders": {} - }, - "password": "密碼", - "@password": { - "type": "text", - "placeholders": {} - }, - "passwordForgotten": "忘記密碼", - "@passwordForgotten": { - "type": "text", - "placeholders": {} - }, - "passwordHasBeenChanged": "密碼已被變更", - "@passwordHasBeenChanged": { - "type": "text", - "placeholders": {} - }, - "passwordRecovery": "恢復密碼", - "@passwordRecovery": { - "type": "text", - "placeholders": {} - }, - "pickImage": "選擇圖片", - "@pickImage": { - "type": "text", - "placeholders": {} - }, - "pin": "釘選", - "@pin": { - "type": "text", - "placeholders": {} - }, - "play": "播放{fileName}", - "@play": { - "type": "text", - "placeholders": { - "fileName": {} - } - }, - "pleaseChooseAPasscode": "請選擇一個密碼", - "@pleaseChooseAPasscode": { - "type": "text", - "placeholders": {} - }, - "pleaseChooseAUsername": "請選擇使用者名稱", - "@pleaseChooseAUsername": { - "type": "text", - "placeholders": {} - }, - "pleaseClickOnLink": "請點擊電子郵件中的網址,然後繼續。", - "@pleaseClickOnLink": { - "type": "text", - "placeholders": {} - }, - "pleaseEnter4Digits": "請輸入4位數字,或留空以停用密碼鎖定。", - "@pleaseEnter4Digits": { - "type": "text", - "placeholders": {} - }, - "pleaseEnterAMatrixIdentifier": "請輸入Matrix ID。", - "@pleaseEnterAMatrixIdentifier": { - "type": "text", - "placeholders": {} - }, - "pleaseEnterYourPassword": "請輸入您的密碼", - "@pleaseEnterYourPassword": { - "type": "text", - "placeholders": {} - }, - "pleaseEnterYourUsername": "請輸入您的使用者名稱", - "@pleaseEnterYourUsername": { - "type": "text", - "placeholders": {} - }, - "pleaseFollowInstructionsOnWeb": "請按照網站上的說明進行操作,然後點擊下一步。", - "@pleaseFollowInstructionsOnWeb": { - "type": "text", - "placeholders": {} - }, - "privacy": "隱私", - "@privacy": { - "type": "text", - "placeholders": {} - }, - "publicRooms": "公開的聊天室", - "@publicRooms": { - "type": "text", - "placeholders": {} - }, - "pushRules": "推播規則", - "@pushRules": { - "type": "text", - "placeholders": {} - }, - "reason": "原因", - "@reason": { - "type": "text", - "placeholders": {} - }, - "recording": "錄音中", - "@recording": { - "type": "text", - "placeholders": {} - }, - "redactedAnEvent": "{username}編輯了一個事件", - "@redactedAnEvent": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "redactMessage": "重新編輯訊息", - "@redactMessage": { - "type": "text", - "placeholders": {} - }, - "reject": "拒絕", - "@reject": { - "type": "text", - "placeholders": {} - }, - "rejectedTheInvitation": "{username}拒絕了邀請", - "@rejectedTheInvitation": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "rejoin": "重新加入", - "@rejoin": { - "type": "text", - "placeholders": {} - }, - "remove": "移除", - "@remove": { - "type": "text", - "placeholders": {} - }, - "removeAllOtherDevices": "移除所有其他裝置", - "@removeAllOtherDevices": { - "type": "text", - "placeholders": {} - }, - "removedBy": "被{username}移除", - "@removedBy": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "removeDevice": "移除裝置", - "@removeDevice": { - "type": "text", - "placeholders": {} - }, - "unbanFromChat": "解禁聊天", - "@unbanFromChat": { - "type": "text", - "placeholders": {} - }, - "renderRichContent": "繪製圖文訊息內容", - "@renderRichContent": { - "type": "text", - "placeholders": {} - }, - "replaceRoomWithNewerVersion": "用較新的版本取代聊天室", - "@replaceRoomWithNewerVersion": { - "type": "text", - "placeholders": {} - }, - "reply": "回覆", - "@reply": { - "type": "text", - "placeholders": {} - }, - "reportMessage": "檢舉訊息", - "@reportMessage": { - "type": "text", - "placeholders": {} - }, - "requestPermission": "請求權限", - "@requestPermission": { - "type": "text", - "placeholders": {} - }, - "roomHasBeenUpgraded": "聊天室已更新", - "@roomHasBeenUpgraded": { - "type": "text", - "placeholders": {} - }, - "search": "搜尋", - "@search": { - "type": "text", - "placeholders": {} - }, - "security": "安全", - "@security": { - "type": "text", - "placeholders": {} - }, - "seenByUser": "{username}已讀", - "@seenByUser": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "seenByUserAndCountOthers": "{count, plural, other{{username}和其他{count}個人已讀}}", - "@seenByUserAndCountOthers": { - "type": "text", - "placeholders": { - "username": {}, - "count": {} - } - }, - "seenByUserAndUser": "{username}和{username2}已讀", - "@seenByUserAndUser": { - "type": "text", - "placeholders": { - "username": {}, - "username2": {} - } - }, - "send": "傳送", - "@send": { - "type": "text", - "placeholders": {} - }, - "sendAMessage": "傳送訊息", - "@sendAMessage": { - "type": "text", - "placeholders": {} - }, - "sendAudio": "傳送音訊", - "@sendAudio": { - "type": "text", - "placeholders": {} - }, - "sendFile": "傳送文件", - "@sendFile": { - "type": "text", - "placeholders": {} - }, - "sendImage": "傳送圖片", - "@sendImage": { - "type": "text", - "placeholders": {} - }, - "sendMessages": "傳送訊息", - "@sendMessages": { - "type": "text", - "placeholders": {} - }, - "sendOriginal": "傳送原始內容", - "@sendOriginal": { - "type": "text", - "placeholders": {} - }, - "sendVideo": "傳送影片", - "@sendVideo": { - "type": "text", - "placeholders": {} - }, - "sentAFile": "{username}傳送了一個文件", - "@sentAFile": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sentAnAudio": "{username}傳送了一個音訊", - "@sentAnAudio": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sentAPicture": "{username}傳送了一張圖片", - "@sentAPicture": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sentASticker": "{username} 傳送了貼圖", - "@sentASticker": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sentAVideo": "{username} 傳送了影片", - "@sentAVideo": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sentCallInformations": "{senderName} 傳送了通話資訊", - "@sentCallInformations": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "setCustomEmotes": "自訂表情符號", - "@setCustomEmotes": { - "type": "text", - "placeholders": {} - }, - "setGroupDescription": "設定群組描述", - "@setGroupDescription": { - "type": "text", - "placeholders": {} - }, - "setInvitationLink": "設定邀請連結", - "@setInvitationLink": { - "type": "text", - "placeholders": {} - }, - "setPermissionsLevel": "設定權限級別", - "@setPermissionsLevel": { - "type": "text", - "placeholders": {} - }, - "setStatus": "設定狀態", - "@setStatus": { - "type": "text", - "placeholders": {} - }, - "settings": "設定", - "@settings": { - "type": "text", - "placeholders": {} - }, - "share": "分享", - "@share": { - "type": "text", - "placeholders": {} - }, - "sharedTheLocation": "{username} 分享了位置", - "@sharedTheLocation": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "showPassword": "顯示密碼", - "@showPassword": { - "type": "text", - "placeholders": {} - }, - "signUp": "註冊", - "@signUp": { - "type": "text", - "placeholders": {} - }, - "skip": "跳過", - "@skip": { - "type": "text", - "placeholders": {} - }, - "sourceCode": "原始碼", - "@sourceCode": { - "type": "text", - "placeholders": {} - }, - "startedACall": "{senderName}開始了通話", - "@startedACall": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "status": "狀態", - "@status": { - "type": "text", - "placeholders": {} - }, - "statusExampleMessage": "今天過得如何?", - "@statusExampleMessage": { - "type": "text", - "placeholders": {} - }, - "submit": "送出", - "@submit": { - "type": "text", - "placeholders": {} - }, - "systemTheme": "自動", - "@systemTheme": { - "type": "text", - "placeholders": {} - }, - "theyDontMatch": "它們不相符", - "@theyDontMatch": { - "type": "text", - "placeholders": {} - }, - "theyMatch": "它們相符", - "@theyMatch": { - "type": "text", - "placeholders": {} - }, - "title": "FluffyChat", - "@title": { - "description": "Title for the application", - "type": "text", - "placeholders": {} - }, - "toggleFavorite": "切換收藏夾", - "@toggleFavorite": { - "type": "text", - "placeholders": {} - }, - "toggleMuted": "切換靜音", - "@toggleMuted": { - "type": "text", - "placeholders": {} - }, - "toggleUnread": "標記為已讀/未讀", - "@toggleUnread": { - "type": "text", - "placeholders": {} - }, - "tooManyRequestsWarning": "太多請求了。請稍候再試!", - "@tooManyRequestsWarning": { - "type": "text", - "placeholders": {} - }, - "transferFromAnotherDevice": "從其他裝置傳輸", - "@transferFromAnotherDevice": { - "type": "text", - "placeholders": {} - }, - "tryToSendAgain": "再次嘗試傳送", - "@tryToSendAgain": { - "type": "text", - "placeholders": {} - }, - "unavailable": "無法取得", - "@unavailable": { - "type": "text", - "placeholders": {} - }, - "unbannedUser": "{username}解除封禁了{targetName}", - "@unbannedUser": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "unblockDevice": "解除鎖定裝置", - "@unblockDevice": { - "type": "text", - "placeholders": {} - }, - "unknownDevice": "未知裝置", - "@unknownDevice": { - "type": "text", - "placeholders": {} - }, - "unknownEncryptionAlgorithm": "未知的加密演算法", - "@unknownEncryptionAlgorithm": { - "type": "text", - "placeholders": {} - }, - "unknownEvent": "未知事件「{type}」", - "@unknownEvent": { - "type": "text", - "placeholders": { - "type": {} - } - }, - "unmuteChat": "取消靜音聊天室", - "@unmuteChat": { - "type": "text", - "placeholders": {} - }, - "unpin": "取消釘選", - "@unpin": { - "type": "text", - "placeholders": {} - }, - "unreadChats": "{unreadCount, plural, =1{1 unread chat} other{{unreadCount} 個未讀聊天室}}", - "@unreadChats": { - "type": "text", - "placeholders": { - "unreadCount": {} - } - }, - "userAndOthersAreTyping": "{username}和其他{count}個人正在輸入…", - "@userAndOthersAreTyping": { - "type": "text", - "placeholders": { - "username": {}, - "count": {} - } - }, - "userAndUserAreTyping": "{username}和{username2}正在輸入…", - "@userAndUserAreTyping": { - "type": "text", - "placeholders": { - "username": {}, - "username2": {} - } - }, - "userIsTyping": "{username}正在輸入…", - "@userIsTyping": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "userLeftTheChat": "{username}離開了聊天室", - "@userLeftTheChat": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "username": "使用者名稱", - "@username": { - "type": "text", - "placeholders": {} - }, - "userSentUnknownEvent": "{username}傳送了一個{type}事件", - "@userSentUnknownEvent": { - "type": "text", - "placeholders": { - "username": {}, - "type": {} - } - }, - "verified": "已驗證", - "@verified": { - "type": "text", - "placeholders": {} - }, - "verify": "驗證", - "@verify": { - "type": "text", - "placeholders": {} - }, - "verifyStart": "開始驗證", - "@verifyStart": { - "type": "text", - "placeholders": {} - }, - "verifySuccess": "您成功驗證了!", - "@verifySuccess": { - "type": "text", - "placeholders": {} - }, - "verifyTitle": "正在驗證其他帳號", - "@verifyTitle": { - "type": "text", - "placeholders": {} - }, - "videoCall": "視訊通話", - "@videoCall": { - "type": "text", - "placeholders": {} - }, - "visibilityOfTheChatHistory": "聊天記錄的可見性", - "@visibilityOfTheChatHistory": { - "type": "text", - "placeholders": {} - }, - "visibleForAllParticipants": "對所有參與者可見", - "@visibleForAllParticipants": { - "type": "text", - "placeholders": {} - }, - "visibleForEveryone": "對所有人可見", - "@visibleForEveryone": { - "type": "text", - "placeholders": {} - }, - "voiceMessage": "語音訊息", - "@voiceMessage": { - "type": "text", - "placeholders": {} - }, - "waitingPartnerAcceptRequest": "正在等待夥伴接受請求…", - "@waitingPartnerAcceptRequest": { - "type": "text", - "placeholders": {} - }, - "waitingPartnerEmoji": "正在等待夥伴接受表情符號…", - "@waitingPartnerEmoji": { - "type": "text", - "placeholders": {} - }, - "waitingPartnerNumbers": "正在等待夥伴接受數字…", - "@waitingPartnerNumbers": { - "type": "text", - "placeholders": {} - }, - "wallpaper": "桌布", - "@wallpaper": { - "type": "text", - "placeholders": {} - }, - "warning": "警告!", - "@warning": { - "type": "text", - "placeholders": {} - }, - "weSentYouAnEmail": "我們向您傳送了一封電子郵件", - "@weSentYouAnEmail": { - "type": "text", - "placeholders": {} - }, - "whoCanPerformWhichAction": "誰可以執行這個動作", - "@whoCanPerformWhichAction": { - "type": "text", - "placeholders": {} - }, - "whoIsAllowedToJoinThisGroup": "誰可以加入這個群組", - "@whoIsAllowedToJoinThisGroup": { - "type": "text", - "placeholders": {} - }, - "whyDoYouWantToReportThis": "您檢舉的原因是什麼?", - "@whyDoYouWantToReportThis": { - "type": "text", - "placeholders": {} - }, - "wipeChatBackup": "要清除您的聊天記錄備份以建立新的安全金鑰嗎?", - "@wipeChatBackup": { - "type": "text", - "placeholders": {} - }, - "withTheseAddressesRecoveryDescription": "有了這些位址,您就可以恢復密碼。", - "@withTheseAddressesRecoveryDescription": { - "type": "text", - "placeholders": {} - }, - "writeAMessage": "輸入訊息…", - "@writeAMessage": { - "type": "text", - "placeholders": {} - }, - "yes": "是", - "@yes": { - "type": "text", - "placeholders": {} - }, - "you": "您", - "@you": { - "type": "text", - "placeholders": {} - }, - "youAreInvitedToThisChat": "有人邀請您加入這個聊天室", - "@youAreInvitedToThisChat": { - "type": "text", - "placeholders": {} - }, - "youAreNoLongerParticipatingInThisChat": "您不再參與這個聊天室了", - "@youAreNoLongerParticipatingInThisChat": { - "type": "text", - "placeholders": {} - }, - "youCannotInviteYourself": "您不能邀請您自己", - "@youCannotInviteYourself": { - "type": "text", - "placeholders": {} - }, - "youHaveBeenBannedFromThisChat": "您已經被這個聊天室封禁", - "@youHaveBeenBannedFromThisChat": { - "type": "text", - "placeholders": {} - }, - "yourPublicKey": "您的公鑰", - "@yourPublicKey": { - "type": "text", - "placeholders": {} - }, - "people": "人", - "@people": { - "type": "text", - "placeholders": {} - }, - "chats": "聊天室", - "@chats": { - "type": "text", - "placeholders": {} - }, - "allChats": "所有會話", - "@allChats": { - "type": "text", - "placeholders": {} - }, - "commandHint_ban": "在此聊天室封禁該使用者", - "@commandHint_ban": { - "type": "text", - "description": "Usage hint for the command /ban" - }, - "commandHint_clearcache": "清除快取", - "@commandHint_clearcache": { - "type": "text", - "description": "Usage hint for the command /clearcache" - }, - "commandHint_create": "建立一個空的群聊\n使用 --no-encryption 選項來禁用加密", - "@commandHint_create": { - "type": "text", - "description": "Usage hint for the command /create" - }, - "commandHint_discardsession": "丟棄工作階段", - "@commandHint_discardsession": { - "type": "text", - "description": "Usage hint for the command /discardsession" - }, - "commandHint_dm": "啟動一對一聊天\n使用 --no-encryption 選項來禁用加密", - "@commandHint_dm": { - "type": "text", - "description": "Usage hint for the command /dm" - }, - "commandHint_invite": "邀請該使用者加入此聊天室", - "@commandHint_invite": { - "type": "text", - "description": "Usage hint for the command /invite" - }, - "commandHint_join": "加入此聊天室", - "@commandHint_join": { - "type": "text", - "description": "Usage hint for the command /join" - }, - "commandHint_kick": "將這個使用者移出此聊天室", - "@commandHint_kick": { - "type": "text", - "description": "Usage hint for the command /kick" - }, - "commandHint_leave": "退出此聊天室", - "@commandHint_leave": { - "type": "text", - "description": "Usage hint for the command /leave" - }, - "commandHint_myroomnick": "設定您的聊天室暱稱", - "@commandHint_myroomnick": { - "type": "text", - "description": "Usage hint for the command /myroomnick" - }, - "editRoomAliases": "編輯聊天室名", - "@editRoomAliases": { - "type": "text", - "placeholders": {} - }, - "roomVersion": "聊天室的版本", - "@roomVersion": { - "type": "text", - "placeholders": {} - }, - "addToSpace": "加入空間", - "@addToSpace": {}, - "cantOpenUri": "無法打開URI {uri}", - "@cantOpenUri": { - "type": "text", - "placeholders": { - "uri": {} - } - }, - "repeatPassword": "再次輸入密碼", - "@repeatPassword": {}, - "yourChatBackupHasBeenSetUp": "您的聊天記錄備份已設定。", - "@yourChatBackupHasBeenSetUp": {}, - "pleaseChooseAtLeastChars": "請至少輸入 {min} 个字元。", - "@pleaseChooseAtLeastChars": { - "type": "text", - "placeholders": { - "min": {} - } - }, - "goToTheNewRoom": "前往新聊天室", - "@goToTheNewRoom": { - "type": "text", - "placeholders": {} - }, - "commandHint_myroomavatar": "設置您的聊天室頭貼(通過 mxc-uri)", - "@commandHint_myroomavatar": { - "type": "text", - "description": "Usage hint for the command /myroomavatar" - }, - "commandHint_unban": "在此聊天室解封該使用者", - "@commandHint_unban": { - "type": "text", - "description": "Usage hint for the command /unban" - }, - "passwordsDoNotMatch": "密碼不匹配!", - "@passwordsDoNotMatch": {}, - "pleaseEnterValidEmail": "請輸入一個有效的電子郵件地址。", - "@pleaseEnterValidEmail": {}, - "autoplayImages": "自動播放動態貼圖和表情", - "@autoplayImages": { - "type": "text", - "placeholder": {} - }, - "sendOnEnter": "按 Enter 鍵發送", - "@sendOnEnter": {}, - "changeYourAvatar": "更改您的大頭貼", - "@changeYourAvatar": { - "type": "text", - "placeholders": {} - }, - "chatHasBeenAddedToThisSpace": "聊天室已添加到此空間", - "@chatHasBeenAddedToThisSpace": {}, - "clearArchive": "清除存檔", - "@clearArchive": {} -} \ No newline at end of file + "@@last_modified": "2021-08-14 12:41:09.708353", + "about": "關於", + "@about": { + "type": "text", + "placeholders": {} + }, + "accept": "接受", + "@accept": { + "type": "text", + "placeholders": {} + }, + "acceptedTheInvitation": "{username}已接受邀請", + "@acceptedTheInvitation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "account": "帳號", + "@account": { + "type": "text", + "placeholders": {} + }, + "activatedEndToEndEncryption": "{username}已啟用點對點加密", + "@activatedEndToEndEncryption": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "addEmail": "新增電子郵件", + "@addEmail": { + "type": "text", + "placeholders": {} + }, + "addGroupDescription": "新增一個群組描述", + "@addGroupDescription": { + "type": "text", + "placeholders": {} + }, + "admin": "管理員", + "@admin": { + "type": "text", + "placeholders": {} + }, + "alias": "別稱", + "@alias": { + "type": "text", + "placeholders": {} + }, + "all": "全部", + "@all": { + "type": "text", + "placeholders": {} + }, + "answeredTheCall": "已開始與{senderName}通話", + "@answeredTheCall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "anyoneCanJoin": "任何人可以加入", + "@anyoneCanJoin": { + "type": "text", + "placeholders": {} + }, + "appLock": "密碼鎖定", + "@appLock": { + "type": "text", + "placeholders": {} + }, + "archive": "封存", + "@archive": { + "type": "text", + "placeholders": {} + }, + "areGuestsAllowedToJoin": "是否允許訪客加入", + "@areGuestsAllowedToJoin": { + "type": "text", + "placeholders": {} + }, + "areYouSure": "您確定嗎?", + "@areYouSure": { + "type": "text", + "placeholders": {} + }, + "areYouSureYouWantToLogout": "您確定要登出嗎?", + "@areYouSureYouWantToLogout": { + "type": "text", + "placeholders": {} + }, + "askSSSSSign": "請輸入您安全儲存的密碼短語或恢復金鑰,以向對方簽名。", + "@askSSSSSign": { + "type": "text", + "placeholders": {} + }, + "askVerificationRequest": "是否接受來自{username}的驗證申請?", + "@askVerificationRequest": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "badServerLoginTypesException": "目前伺服器支援的登入類型:\n{serverVersions}\n但本應用程式僅支援:\n{supportedVersions}", + "@badServerLoginTypesException": { + "type": "text", + "placeholders": { + "serverVersions": {}, + "supportedVersions": {} + } + }, + "badServerVersionsException": "目前伺服器支援的Spec版本:\n{serverVersions}\n但本應用程式僅支援{supportedVersions}", + "@badServerVersionsException": { + "type": "text", + "placeholders": { + "serverVersions": {}, + "supportedVersions": {} + } + }, + "banFromChat": "已從聊天室中封禁", + "@banFromChat": { + "type": "text", + "placeholders": {} + }, + "banned": "已被封禁", + "@banned": { + "type": "text", + "placeholders": {} + }, + "bannedUser": "{username}封禁了{targetName}", + "@bannedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "blockDevice": "封鎖裝置", + "@blockDevice": { + "type": "text", + "placeholders": {} + }, + "blocked": "已封鎖", + "@blocked": { + "type": "text", + "placeholders": {} + }, + "botMessages": "機器人訊息", + "@botMessages": { + "type": "text", + "placeholders": {} + }, + "cancel": "取消", + "@cancel": { + "type": "text", + "placeholders": {} + }, + "changeDeviceName": "變更裝置名稱", + "@changeDeviceName": { + "type": "text", + "placeholders": {} + }, + "changedTheChatAvatar": "{username}變更了對話頭貼", + "@changedTheChatAvatar": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheChatDescriptionTo": "{username}變更了對話介紹為:「{description}」", + "@changedTheChatDescriptionTo": { + "type": "text", + "placeholders": { + "username": {}, + "description": {} + } + }, + "changedTheChatNameTo": "{username}變更了暱稱為:「{chatname}」", + "@changedTheChatNameTo": { + "type": "text", + "placeholders": { + "username": {}, + "chatname": {} + } + }, + "changedTheChatPermissions": "{username}變更了對話權限", + "@changedTheChatPermissions": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheDisplaynameTo": "{username} 變更了顯示名稱為:「{displayname}」", + "@changedTheDisplaynameTo": { + "type": "text", + "placeholders": { + "username": {}, + "displayname": {} + } + }, + "changedTheGuestAccessRules": "{username}變更了訪客訪問規則", + "@changedTheGuestAccessRules": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheGuestAccessRulesTo": "{username}變更了訪客訪問規則為:{rules}", + "@changedTheGuestAccessRulesTo": { + "type": "text", + "placeholders": { + "username": {}, + "rules": {} + } + }, + "changedTheHistoryVisibility": "{username}變更了歷史記錄觀察狀態", + "@changedTheHistoryVisibility": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheHistoryVisibilityTo": "{username}變更了歷史紀錄觀察狀態到:{rules}", + "@changedTheHistoryVisibilityTo": { + "type": "text", + "placeholders": { + "username": {}, + "rules": {} + } + }, + "changedTheJoinRules": "{username}變更了加入的規則", + "@changedTheJoinRules": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheJoinRulesTo": "{username}變更了加入的規則為:{joinRules}", + "@changedTheJoinRulesTo": { + "type": "text", + "placeholders": { + "username": {}, + "joinRules": {} + } + }, + "changedTheProfileAvatar": "{username}變更了頭貼", + "@changedTheProfileAvatar": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheRoomAliases": "{username}變更了聊天室名", + "@changedTheRoomAliases": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheRoomInvitationLink": "{username}變更了邀請連結", + "@changedTheRoomInvitationLink": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changePassword": "變更密碼", + "@changePassword": { + "type": "text", + "placeholders": {} + }, + "changeTheHomeserver": "變更主機位址", + "@changeTheHomeserver": { + "type": "text", + "placeholders": {} + }, + "changeTheme": "變更主題", + "@changeTheme": { + "type": "text", + "placeholders": {} + }, + "changeTheNameOfTheGroup": "變更了群組名稱", + "@changeTheNameOfTheGroup": { + "type": "text", + "placeholders": {} + }, + "changeWallpaper": "變更聊天背景", + "@changeWallpaper": { + "type": "text", + "placeholders": {} + }, + "channelCorruptedDecryptError": "加密已被破壞", + "@channelCorruptedDecryptError": { + "type": "text", + "placeholders": {} + }, + "chat": "聊天", + "@chat": { + "type": "text", + "placeholders": {} + }, + "chatBackup": "備份聊天室", + "@chatBackup": { + "type": "text", + "placeholders": {} + }, + "chatBackupDescription": "您的聊天記錄備份已被安全金鑰鑰加密。請您確保不會弄丟它。", + "@chatBackupDescription": { + "type": "text", + "placeholders": {} + }, + "chatDetails": "對話詳細", + "@chatDetails": { + "type": "text", + "placeholders": {} + }, + "chooseAStrongPassword": "輸入一個較強的密碼", + "@chooseAStrongPassword": { + "type": "text", + "placeholders": {} + }, + "chooseAUsername": "輸入您的使用者名稱", + "@chooseAUsername": { + "type": "text", + "placeholders": {} + }, + "close": "關閉", + "@close": { + "type": "text", + "placeholders": {} + }, + "compareEmojiMatch": "對比並確認這些表情符合其他那些裝置:", + "@compareEmojiMatch": { + "type": "text", + "placeholders": {} + }, + "compareNumbersMatch": "比較以下數字,確保它們和另一個裝置上的相同:", + "@compareNumbersMatch": { + "type": "text", + "placeholders": {} + }, + "configureChat": "設定聊天室", + "@configureChat": { + "type": "text", + "placeholders": {} + }, + "confirm": "確認", + "@confirm": { + "type": "text", + "placeholders": {} + }, + "connect": "連接", + "@connect": { + "type": "text", + "placeholders": {} + }, + "contactHasBeenInvitedToTheGroup": "聯絡人已被邀請至群組", + "@contactHasBeenInvitedToTheGroup": { + "type": "text", + "placeholders": {} + }, + "containsDisplayName": "包含顯示名稱", + "@containsDisplayName": { + "type": "text", + "placeholders": {} + }, + "containsUserName": "包含使用者名稱", + "@containsUserName": { + "type": "text", + "placeholders": {} + }, + "contentHasBeenReported": "此內容已被回報給伺服器管理員們", + "@contentHasBeenReported": { + "type": "text", + "placeholders": {} + }, + "copiedToClipboard": "已複製到剪貼簿", + "@copiedToClipboard": { + "type": "text", + "placeholders": {} + }, + "copy": "複製", + "@copy": { + "type": "text", + "placeholders": {} + }, + "copyToClipboard": "複製到剪貼簿", + "@copyToClipboard": { + "type": "text", + "placeholders": {} + }, + "couldNotDecryptMessage": "不能解密訊息:{error}", + "@couldNotDecryptMessage": { + "type": "text", + "placeholders": { + "error": {} + } + }, + "countParticipants": "{count}個參與者", + "@countParticipants": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "create": "建立", + "@create": { + "type": "text", + "placeholders": {} + }, + "createdTheChat": "{username}建立了聊天室", + "@createdTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "createNewGroup": "建立新群組", + "@createNewGroup": { + "type": "text", + "placeholders": {} + }, + "currentlyActive": "目前活躍", + "@currentlyActive": { + "type": "text", + "placeholders": {} + }, + "darkTheme": "夜間模式", + "@darkTheme": { + "type": "text", + "placeholders": {} + }, + "dateAndTimeOfDay": "{date}, {timeOfDay}", + "@dateAndTimeOfDay": { + "type": "text", + "placeholders": { + "date": {}, + "timeOfDay": {} + } + }, + "dateWithoutYear": "{month}-{day}", + "@dateWithoutYear": { + "type": "text", + "placeholders": { + "month": {}, + "day": {} + } + }, + "dateWithYear": "{year}-{month}-{day}", + "@dateWithYear": { + "type": "text", + "placeholders": { + "year": {}, + "month": {}, + "day": {} + } + }, + "deactivateAccountWarning": "這將停用您的帳號。這個決定是不能挽回的!您確定嗎?", + "@deactivateAccountWarning": { + "type": "text", + "placeholders": {} + }, + "defaultPermissionLevel": "預設權限等級", + "@defaultPermissionLevel": { + "type": "text", + "placeholders": {} + }, + "delete": "刪除", + "@delete": { + "type": "text", + "placeholders": {} + }, + "deleteAccount": "刪除帳號", + "@deleteAccount": { + "type": "text", + "placeholders": {} + }, + "deleteMessage": "刪除訊息", + "@deleteMessage": { + "type": "text", + "placeholders": {} + }, + "deny": "否認", + "@deny": { + "type": "text", + "placeholders": {} + }, + "device": "裝置", + "@device": { + "type": "text", + "placeholders": {} + }, + "deviceId": "裝置ID", + "@deviceId": { + "type": "text", + "placeholders": {} + }, + "devices": "裝置", + "@devices": { + "type": "text", + "placeholders": {} + }, + "directChats": "直接傳訊", + "@directChats": { + "type": "text", + "placeholders": {} + }, + "displaynameHasBeenChanged": "顯示名稱已被變更", + "@displaynameHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "downloadFile": "下載文件", + "@downloadFile": { + "type": "text", + "placeholders": {} + }, + "edit": "編輯", + "@edit": { + "type": "text", + "placeholders": {} + }, + "editBlockedServers": "編輯被封鎖的伺服器", + "@editBlockedServers": { + "type": "text", + "placeholders": {} + }, + "editChatPermissions": "編輯聊天室權限", + "@editChatPermissions": { + "type": "text", + "placeholders": {} + }, + "editDisplayname": "編輯顯示名稱", + "@editDisplayname": { + "type": "text", + "placeholders": {} + }, + "editRoomAvatar": "編輯聊天室頭貼", + "@editRoomAvatar": { + "type": "text", + "placeholders": {} + }, + "emoteExists": "表情已存在!", + "@emoteExists": { + "type": "text", + "placeholders": {} + }, + "emoteInvalid": "無效的表情快捷鍵!", + "@emoteInvalid": { + "type": "text", + "placeholders": {} + }, + "emotePacks": "聊天室的表情符號", + "@emotePacks": { + "type": "text", + "placeholders": {} + }, + "emoteSettings": "表情設定", + "@emoteSettings": { + "type": "text", + "placeholders": {} + }, + "emoteShortcode": "表情快捷鍵", + "@emoteShortcode": { + "type": "text", + "placeholders": {} + }, + "emoteWarnNeedToPick": "您需要選取一個表情快捷鍵和一張圖片!", + "@emoteWarnNeedToPick": { + "type": "text", + "placeholders": {} + }, + "emptyChat": "空的聊天室", + "@emptyChat": { + "type": "text", + "placeholders": {} + }, + "enableEmotesGlobally": "在全域啟用表情符號", + "@enableEmotesGlobally": { + "type": "text", + "placeholders": {} + }, + "enableEncryption": "啟用加密", + "@enableEncryption": { + "type": "text", + "placeholders": {} + }, + "enableEncryptionWarning": "您將不能再停用加密,確定嗎?", + "@enableEncryptionWarning": { + "type": "text", + "placeholders": {} + }, + "encrypted": "加密的", + "@encrypted": { + "type": "text", + "placeholders": {} + }, + "encryption": "加密", + "@encryption": { + "type": "text", + "placeholders": {} + }, + "encryptionNotEnabled": "加密未啟用", + "@encryptionNotEnabled": { + "type": "text", + "placeholders": {} + }, + "endedTheCall": "{senderName}結束了通話", + "@endedTheCall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "enterAGroupName": "輸入群組名稱", + "@enterAGroupName": { + "type": "text", + "placeholders": {} + }, + "enterAnEmailAddress": "輸入一個電子郵件位址", + "@enterAnEmailAddress": { + "type": "text", + "placeholders": {} + }, + "enterYourHomeserver": "輸入伺服器位址", + "@enterYourHomeserver": { + "type": "text", + "placeholders": {} + }, + "everythingReady": "一切就緒!", + "@everythingReady": { + "type": "text", + "placeholders": {} + }, + "extremeOffensive": "極端令人反感", + "@extremeOffensive": { + "type": "text", + "placeholders": {} + }, + "fileName": "檔案名稱", + "@fileName": { + "type": "text", + "placeholders": {} + }, + "fluffychat": "FluffyChat", + "@fluffychat": { + "type": "text", + "placeholders": {} + }, + "fontSize": "字體大小", + "@fontSize": { + "type": "text", + "placeholders": {} + }, + "forward": "轉發", + "@forward": { + "type": "text", + "placeholders": {} + }, + "fromJoining": "自加入起", + "@fromJoining": { + "type": "text", + "placeholders": {} + }, + "fromTheInvitation": "自邀請起", + "@fromTheInvitation": { + "type": "text", + "placeholders": {} + }, + "group": "群組", + "@group": { + "type": "text", + "placeholders": {} + }, + "groupDescription": "群組描述", + "@groupDescription": { + "type": "text", + "placeholders": {} + }, + "groupDescriptionHasBeenChanged": "群組描述已被變更", + "@groupDescriptionHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "groupIsPublic": "群組是公開的", + "@groupIsPublic": { + "type": "text", + "placeholders": {} + }, + "groups": "群組", + "@groups": { + "type": "text", + "placeholders": {} + }, + "groupWith": "名稱為{displayname}的群組", + "@groupWith": { + "type": "text", + "placeholders": { + "displayname": {} + } + }, + "guestsAreForbidden": "訪客已被禁止", + "@guestsAreForbidden": { + "type": "text", + "placeholders": {} + }, + "guestsCanJoin": "訪客可以加入", + "@guestsCanJoin": { + "type": "text", + "placeholders": {} + }, + "hasWithdrawnTheInvitationFor": "{username}收回了對{targetName}的邀請", + "@hasWithdrawnTheInvitationFor": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "help": "幫助", + "@help": { + "type": "text", + "placeholders": {} + }, + "hideRedactedEvents": "隱藏編輯過的事件", + "@hideRedactedEvents": { + "type": "text", + "placeholders": {} + }, + "hideUnknownEvents": "隱藏未知事件", + "@hideUnknownEvents": { + "type": "text", + "placeholders": {} + }, + "howOffensiveIsThisContent": "這個內容有多令人反感?", + "@howOffensiveIsThisContent": { + "type": "text", + "placeholders": {} + }, + "id": "ID", + "@id": { + "type": "text", + "placeholders": {} + }, + "identity": "身份", + "@identity": { + "type": "text", + "placeholders": {} + }, + "ignore": "無視", + "@ignore": { + "type": "text", + "placeholders": {} + }, + "ignoredUsers": "已無視的使用者", + "@ignoredUsers": { + "type": "text", + "placeholders": {} + }, + "ignoreListDescription": "您可以無視打擾您的使用者。您將不會再收到來自無視列表中使用者的任何消息或聊天室邀請。", + "@ignoreListDescription": { + "type": "text", + "placeholders": {} + }, + "ignoreUsername": "無視使用者名稱", + "@ignoreUsername": { + "type": "text", + "placeholders": {} + }, + "iHaveClickedOnLink": "我已經點擊了網址", + "@iHaveClickedOnLink": { + "type": "text", + "placeholders": {} + }, + "incorrectPassphraseOrKey": "錯誤的密碼短語或恢復金鑰", + "@incorrectPassphraseOrKey": { + "type": "text", + "placeholders": {} + }, + "inoffensive": "不令人反感", + "@inoffensive": { + "type": "text", + "placeholders": {} + }, + "inviteContact": "邀請聯絡人", + "@inviteContact": { + "type": "text", + "placeholders": {} + }, + "inviteContactToGroup": "邀請聯絡人到{groupName}", + "@inviteContactToGroup": { + "type": "text", + "placeholders": { + "groupName": {} + } + }, + "invited": "已邀請", + "@invited": { + "type": "text", + "placeholders": {} + }, + "invitedUser": "{username}邀請了{targetName}", + "@invitedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "invitedUsersOnly": "只有被邀請的使用者", + "@invitedUsersOnly": { + "type": "text", + "placeholders": {} + }, + "inviteForMe": "來自我的邀請", + "@inviteForMe": { + "type": "text", + "placeholders": {} + }, + "inviteText": "{username}邀請您使用FluffyChat\n1. 安裝FluffyChat:https://fluffychat.im\n2. 登入或註冊\n3. 打開該邀請網址:{link}", + "@inviteText": { + "type": "text", + "placeholders": { + "username": {}, + "link": {} + } + }, + "isTyping": "正在輸入...…", + "@isTyping": { + "type": "text", + "placeholders": {} + }, + "joinedTheChat": "{username}加入了聊天室", + "@joinedTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "joinRoom": "加入聊天室", + "@joinRoom": { + "type": "text", + "placeholders": {} + }, + "kicked": "{username}踢了{targetName}", + "@kicked": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "kickedAndBanned": "{username}踢了{targetName}並將其封禁", + "@kickedAndBanned": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "kickFromChat": "從聊天室踢出", + "@kickFromChat": { + "type": "text", + "placeholders": {} + }, + "lastActiveAgo": "最後活動時間:{localizedTimeShort}", + "@lastActiveAgo": { + "type": "text", + "placeholders": { + "localizedTimeShort": {} + } + }, + "lastSeenLongTimeAgo": "很長一段時間沒有上線了", + "@lastSeenLongTimeAgo": { + "type": "text", + "placeholders": {} + }, + "leave": "離開", + "@leave": { + "type": "text", + "placeholders": {} + }, + "leftTheChat": "離開了聊天室", + "@leftTheChat": { + "type": "text", + "placeholders": {} + }, + "license": "授權", + "@license": { + "type": "text", + "placeholders": {} + }, + "lightTheme": "日間模式", + "@lightTheme": { + "type": "text", + "placeholders": {} + }, + "loadCountMoreParticipants": "載入{count}個更多的參與者", + "@loadCountMoreParticipants": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "loadingPleaseWait": "載入中… 請稍候。", + "@loadingPleaseWait": { + "type": "text", + "placeholders": {} + }, + "loadMore": "載入更多…", + "@loadMore": { + "type": "text", + "placeholders": {} + }, + "login": "登入", + "@login": { + "type": "text", + "placeholders": {} + }, + "logInTo": "登入{homeserver}", + "@logInTo": { + "type": "text", + "placeholders": { + "homeserver": {} + } + }, + "logout": "登出", + "@logout": { + "type": "text", + "placeholders": {} + }, + "makeSureTheIdentifierIsValid": "確保識別碼正確", + "@makeSureTheIdentifierIsValid": { + "type": "text", + "placeholders": {} + }, + "memberChanges": "變更成員", + "@memberChanges": { + "type": "text", + "placeholders": {} + }, + "mention": "提及", + "@mention": { + "type": "text", + "placeholders": {} + }, + "messages": "訊息", + "@messages": { + "type": "text", + "placeholders": {} + }, + "messageWillBeRemovedWarning": "將移除所有參與者的訊息", + "@messageWillBeRemovedWarning": { + "type": "text", + "placeholders": {} + }, + "moderator": "版主", + "@moderator": { + "type": "text", + "placeholders": {} + }, + "muteChat": "將該聊天室靜音", + "@muteChat": { + "type": "text", + "placeholders": {} + }, + "needPantalaimonWarning": "請注意您需要Pantalaimon才能使用點對點加密功能。", + "@needPantalaimonWarning": { + "type": "text", + "placeholders": {} + }, + "newChat": "新聊天室", + "@newChat": { + "type": "text", + "placeholders": {} + }, + "newMessageInFluffyChat": "來自 FluffyChat 的新訊息", + "@newMessageInFluffyChat": { + "type": "text", + "placeholders": {} + }, + "newVerificationRequest": "新的驗證請求!", + "@newVerificationRequest": { + "type": "text", + "placeholders": {} + }, + "next": "下一個", + "@next": { + "type": "text", + "placeholders": {} + }, + "no": "否", + "@no": { + "type": "text", + "placeholders": {} + }, + "noConnectionToTheServer": "無法連接到伺服器", + "@noConnectionToTheServer": { + "type": "text", + "placeholders": {} + }, + "noEmotesFound": "表情符號不存在。😕", + "@noEmotesFound": { + "type": "text", + "placeholders": {} + }, + "noEncryptionForPublicRooms": "您只能在這個聊天室不再被允許公開訪問後,才能啟用加密。", + "@noEncryptionForPublicRooms": { + "type": "text", + "placeholders": {} + }, + "noGoogleServicesWarning": "看起來您手機上沒有Google服務框架。這對於保護您的隱私而言是個好決定!但為了收到FluffyChat的推播通知,我們推薦您使用 https://microg.org/ 或 https://unifiedpush.org/。", + "@noGoogleServicesWarning": { + "type": "text", + "placeholders": {} + }, + "none": "無", + "@none": { + "type": "text", + "placeholders": {} + }, + "noPasswordRecoveryDescription": "您尚未新增恢復密碼的方法。", + "@noPasswordRecoveryDescription": { + "type": "text", + "placeholders": {} + }, + "noPermission": "沒有權限", + "@noPermission": { + "type": "text", + "placeholders": {} + }, + "noRoomsFound": "找不到聊天室…", + "@noRoomsFound": { + "type": "text", + "placeholders": {} + }, + "notifications": "通知", + "@notifications": { + "type": "text", + "placeholders": {} + }, + "notificationsEnabledForThisAccount": "已為此帳號啟用通知", + "@notificationsEnabledForThisAccount": { + "type": "text", + "placeholders": {} + }, + "numUsersTyping": "{count}個人正在輸入…", + "@numUsersTyping": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "offensive": "令人反感", + "@offensive": { + "type": "text", + "placeholders": {} + }, + "offline": "離線", + "@offline": { + "type": "text", + "placeholders": {} + }, + "ok": "OK", + "@ok": { + "type": "text", + "placeholders": {} + }, + "online": "線上", + "@online": { + "type": "text", + "placeholders": {} + }, + "onlineKeyBackupEnabled": "線上金鑰備份已啟用", + "@onlineKeyBackupEnabled": { + "type": "text", + "placeholders": {} + }, + "oopsSomethingWentWrong": "哎呀!出了一點差錯…", + "@oopsSomethingWentWrong": { + "type": "text", + "placeholders": {} + }, + "openAppToReadMessages": "打開應用程式以讀取訊息", + "@openAppToReadMessages": { + "type": "text", + "placeholders": {} + }, + "openCamera": "開啟相機", + "@openCamera": { + "type": "text", + "placeholders": {} + }, + "optionalGroupName": "(可選)群組名稱", + "@optionalGroupName": { + "type": "text", + "placeholders": {} + }, + "participant": "參與者", + "@participant": { + "type": "text", + "placeholders": {} + }, + "passphraseOrKey": "密碼短語或恢復金鑰", + "@passphraseOrKey": { + "type": "text", + "placeholders": {} + }, + "password": "密碼", + "@password": { + "type": "text", + "placeholders": {} + }, + "passwordForgotten": "忘記密碼", + "@passwordForgotten": { + "type": "text", + "placeholders": {} + }, + "passwordHasBeenChanged": "密碼已被變更", + "@passwordHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "passwordRecovery": "恢復密碼", + "@passwordRecovery": { + "type": "text", + "placeholders": {} + }, + "pickImage": "選擇圖片", + "@pickImage": { + "type": "text", + "placeholders": {} + }, + "pin": "釘選", + "@pin": { + "type": "text", + "placeholders": {} + }, + "play": "播放{fileName}", + "@play": { + "type": "text", + "placeholders": { + "fileName": {} + } + }, + "pleaseChooseAPasscode": "請選擇一個密碼", + "@pleaseChooseAPasscode": { + "type": "text", + "placeholders": {} + }, + "pleaseChooseAUsername": "請選擇使用者名稱", + "@pleaseChooseAUsername": { + "type": "text", + "placeholders": {} + }, + "pleaseClickOnLink": "請點擊電子郵件中的網址,然後繼續。", + "@pleaseClickOnLink": { + "type": "text", + "placeholders": {} + }, + "pleaseEnter4Digits": "請輸入4位數字,或留空以停用密碼鎖定。", + "@pleaseEnter4Digits": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterAMatrixIdentifier": "請輸入Matrix ID。", + "@pleaseEnterAMatrixIdentifier": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourPassword": "請輸入您的密碼", + "@pleaseEnterYourPassword": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourUsername": "請輸入您的使用者名稱", + "@pleaseEnterYourUsername": { + "type": "text", + "placeholders": {} + }, + "pleaseFollowInstructionsOnWeb": "請按照網站上的說明進行操作,然後點擊下一步。", + "@pleaseFollowInstructionsOnWeb": { + "type": "text", + "placeholders": {} + }, + "privacy": "隱私", + "@privacy": { + "type": "text", + "placeholders": {} + }, + "publicRooms": "公開的聊天室", + "@publicRooms": { + "type": "text", + "placeholders": {} + }, + "pushRules": "推播規則", + "@pushRules": { + "type": "text", + "placeholders": {} + }, + "reason": "原因", + "@reason": { + "type": "text", + "placeholders": {} + }, + "recording": "錄音中", + "@recording": { + "type": "text", + "placeholders": {} + }, + "redactedAnEvent": "{username}編輯了一個事件", + "@redactedAnEvent": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "redactMessage": "重新編輯訊息", + "@redactMessage": { + "type": "text", + "placeholders": {} + }, + "reject": "拒絕", + "@reject": { + "type": "text", + "placeholders": {} + }, + "rejectedTheInvitation": "{username}拒絕了邀請", + "@rejectedTheInvitation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "rejoin": "重新加入", + "@rejoin": { + "type": "text", + "placeholders": {} + }, + "remove": "移除", + "@remove": { + "type": "text", + "placeholders": {} + }, + "removeAllOtherDevices": "移除所有其他裝置", + "@removeAllOtherDevices": { + "type": "text", + "placeholders": {} + }, + "removedBy": "被{username}移除", + "@removedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "removeDevice": "移除裝置", + "@removeDevice": { + "type": "text", + "placeholders": {} + }, + "unbanFromChat": "解禁聊天", + "@unbanFromChat": { + "type": "text", + "placeholders": {} + }, + "renderRichContent": "繪製圖文訊息內容", + "@renderRichContent": { + "type": "text", + "placeholders": {} + }, + "replaceRoomWithNewerVersion": "用較新的版本取代聊天室", + "@replaceRoomWithNewerVersion": { + "type": "text", + "placeholders": {} + }, + "reply": "回覆", + "@reply": { + "type": "text", + "placeholders": {} + }, + "reportMessage": "檢舉訊息", + "@reportMessage": { + "type": "text", + "placeholders": {} + }, + "requestPermission": "請求權限", + "@requestPermission": { + "type": "text", + "placeholders": {} + }, + "roomHasBeenUpgraded": "聊天室已更新", + "@roomHasBeenUpgraded": { + "type": "text", + "placeholders": {} + }, + "search": "搜尋", + "@search": { + "type": "text", + "placeholders": {} + }, + "security": "安全", + "@security": { + "type": "text", + "placeholders": {} + }, + "seenByUser": "{username}已讀", + "@seenByUser": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "seenByUserAndCountOthers": "{count, plural, other{{username}和其他{count}個人已讀}}", + "@seenByUserAndCountOthers": { + "type": "text", + "placeholders": { + "username": {}, + "count": {} + } + }, + "seenByUserAndUser": "{username}和{username2}已讀", + "@seenByUserAndUser": { + "type": "text", + "placeholders": { + "username": {}, + "username2": {} + } + }, + "send": "傳送", + "@send": { + "type": "text", + "placeholders": {} + }, + "sendAMessage": "傳送訊息", + "@sendAMessage": { + "type": "text", + "placeholders": {} + }, + "sendAudio": "傳送音訊", + "@sendAudio": { + "type": "text", + "placeholders": {} + }, + "sendFile": "傳送文件", + "@sendFile": { + "type": "text", + "placeholders": {} + }, + "sendImage": "傳送圖片", + "@sendImage": { + "type": "text", + "placeholders": {} + }, + "sendMessages": "傳送訊息", + "@sendMessages": { + "type": "text", + "placeholders": {} + }, + "sendOriginal": "傳送原始內容", + "@sendOriginal": { + "type": "text", + "placeholders": {} + }, + "sendVideo": "傳送影片", + "@sendVideo": { + "type": "text", + "placeholders": {} + }, + "sentAFile": "{username}傳送了一個文件", + "@sentAFile": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sentAnAudio": "{username}傳送了一個音訊", + "@sentAnAudio": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sentAPicture": "{username}傳送了一張圖片", + "@sentAPicture": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sentASticker": "{username} 傳送了貼圖", + "@sentASticker": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sentAVideo": "{username} 傳送了影片", + "@sentAVideo": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sentCallInformations": "{senderName} 傳送了通話資訊", + "@sentCallInformations": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "setCustomEmotes": "自訂表情符號", + "@setCustomEmotes": { + "type": "text", + "placeholders": {} + }, + "setGroupDescription": "設定群組描述", + "@setGroupDescription": { + "type": "text", + "placeholders": {} + }, + "setInvitationLink": "設定邀請連結", + "@setInvitationLink": { + "type": "text", + "placeholders": {} + }, + "setPermissionsLevel": "設定權限級別", + "@setPermissionsLevel": { + "type": "text", + "placeholders": {} + }, + "setStatus": "設定狀態", + "@setStatus": { + "type": "text", + "placeholders": {} + }, + "settings": "設定", + "@settings": { + "type": "text", + "placeholders": {} + }, + "share": "分享", + "@share": { + "type": "text", + "placeholders": {} + }, + "sharedTheLocation": "{username} 分享了位置", + "@sharedTheLocation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "showPassword": "顯示密碼", + "@showPassword": { + "type": "text", + "placeholders": {} + }, + "signUp": "註冊", + "@signUp": { + "type": "text", + "placeholders": {} + }, + "skip": "跳過", + "@skip": { + "type": "text", + "placeholders": {} + }, + "sourceCode": "原始碼", + "@sourceCode": { + "type": "text", + "placeholders": {} + }, + "startedACall": "{senderName}開始了通話", + "@startedACall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "status": "狀態", + "@status": { + "type": "text", + "placeholders": {} + }, + "statusExampleMessage": "今天過得如何?", + "@statusExampleMessage": { + "type": "text", + "placeholders": {} + }, + "submit": "送出", + "@submit": { + "type": "text", + "placeholders": {} + }, + "systemTheme": "自動", + "@systemTheme": { + "type": "text", + "placeholders": {} + }, + "theyDontMatch": "它們不相符", + "@theyDontMatch": { + "type": "text", + "placeholders": {} + }, + "theyMatch": "它們相符", + "@theyMatch": { + "type": "text", + "placeholders": {} + }, + "title": "FluffyChat", + "@title": { + "description": "Title for the application", + "type": "text", + "placeholders": {} + }, + "toggleFavorite": "切換收藏夾", + "@toggleFavorite": { + "type": "text", + "placeholders": {} + }, + "toggleMuted": "切換靜音", + "@toggleMuted": { + "type": "text", + "placeholders": {} + }, + "toggleUnread": "標記為已讀/未讀", + "@toggleUnread": { + "type": "text", + "placeholders": {} + }, + "tooManyRequestsWarning": "太多請求了。請稍候再試!", + "@tooManyRequestsWarning": { + "type": "text", + "placeholders": {} + }, + "transferFromAnotherDevice": "從其他裝置傳輸", + "@transferFromAnotherDevice": { + "type": "text", + "placeholders": {} + }, + "tryToSendAgain": "再次嘗試傳送", + "@tryToSendAgain": { + "type": "text", + "placeholders": {} + }, + "unavailable": "無法取得", + "@unavailable": { + "type": "text", + "placeholders": {} + }, + "unbannedUser": "{username}解除封禁了{targetName}", + "@unbannedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "unblockDevice": "解除鎖定裝置", + "@unblockDevice": { + "type": "text", + "placeholders": {} + }, + "unknownDevice": "未知裝置", + "@unknownDevice": { + "type": "text", + "placeholders": {} + }, + "unknownEncryptionAlgorithm": "未知的加密演算法", + "@unknownEncryptionAlgorithm": { + "type": "text", + "placeholders": {} + }, + "unknownEvent": "未知事件「{type}」", + "@unknownEvent": { + "type": "text", + "placeholders": { + "type": {} + } + }, + "unmuteChat": "取消靜音聊天室", + "@unmuteChat": { + "type": "text", + "placeholders": {} + }, + "unpin": "取消釘選", + "@unpin": { + "type": "text", + "placeholders": {} + }, + "unreadChats": "{unreadCount, plural, =1{1 unread chat} other{{unreadCount} 個未讀聊天室}}", + "@unreadChats": { + "type": "text", + "placeholders": { + "unreadCount": {} + } + }, + "userAndOthersAreTyping": "{username}和其他{count}個人正在輸入…", + "@userAndOthersAreTyping": { + "type": "text", + "placeholders": { + "username": {}, + "count": {} + } + }, + "userAndUserAreTyping": "{username}和{username2}正在輸入…", + "@userAndUserAreTyping": { + "type": "text", + "placeholders": { + "username": {}, + "username2": {} + } + }, + "userIsTyping": "{username}正在輸入…", + "@userIsTyping": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "userLeftTheChat": "{username}離開了聊天室", + "@userLeftTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "username": "使用者名稱", + "@username": { + "type": "text", + "placeholders": {} + }, + "userSentUnknownEvent": "{username}傳送了一個{type}事件", + "@userSentUnknownEvent": { + "type": "text", + "placeholders": { + "username": {}, + "type": {} + } + }, + "verified": "已驗證", + "@verified": { + "type": "text", + "placeholders": {} + }, + "verify": "驗證", + "@verify": { + "type": "text", + "placeholders": {} + }, + "verifyStart": "開始驗證", + "@verifyStart": { + "type": "text", + "placeholders": {} + }, + "verifySuccess": "您成功驗證了!", + "@verifySuccess": { + "type": "text", + "placeholders": {} + }, + "verifyTitle": "正在驗證其他帳號", + "@verifyTitle": { + "type": "text", + "placeholders": {} + }, + "videoCall": "視訊通話", + "@videoCall": { + "type": "text", + "placeholders": {} + }, + "visibilityOfTheChatHistory": "聊天記錄的可見性", + "@visibilityOfTheChatHistory": { + "type": "text", + "placeholders": {} + }, + "visibleForAllParticipants": "對所有參與者可見", + "@visibleForAllParticipants": { + "type": "text", + "placeholders": {} + }, + "visibleForEveryone": "對所有人可見", + "@visibleForEveryone": { + "type": "text", + "placeholders": {} + }, + "voiceMessage": "語音訊息", + "@voiceMessage": { + "type": "text", + "placeholders": {} + }, + "waitingPartnerAcceptRequest": "正在等待夥伴接受請求…", + "@waitingPartnerAcceptRequest": { + "type": "text", + "placeholders": {} + }, + "waitingPartnerEmoji": "正在等待夥伴接受表情符號…", + "@waitingPartnerEmoji": { + "type": "text", + "placeholders": {} + }, + "waitingPartnerNumbers": "正在等待夥伴接受數字…", + "@waitingPartnerNumbers": { + "type": "text", + "placeholders": {} + }, + "wallpaper": "桌布", + "@wallpaper": { + "type": "text", + "placeholders": {} + }, + "warning": "警告!", + "@warning": { + "type": "text", + "placeholders": {} + }, + "weSentYouAnEmail": "我們向您傳送了一封電子郵件", + "@weSentYouAnEmail": { + "type": "text", + "placeholders": {} + }, + "whoCanPerformWhichAction": "誰可以執行這個動作", + "@whoCanPerformWhichAction": { + "type": "text", + "placeholders": {} + }, + "whoIsAllowedToJoinThisGroup": "誰可以加入這個群組", + "@whoIsAllowedToJoinThisGroup": { + "type": "text", + "placeholders": {} + }, + "whyDoYouWantToReportThis": "您檢舉的原因是什麼?", + "@whyDoYouWantToReportThis": { + "type": "text", + "placeholders": {} + }, + "wipeChatBackup": "要清除您的聊天記錄備份以建立新的安全金鑰嗎?", + "@wipeChatBackup": { + "type": "text", + "placeholders": {} + }, + "withTheseAddressesRecoveryDescription": "有了這些位址,您就可以恢復密碼。", + "@withTheseAddressesRecoveryDescription": { + "type": "text", + "placeholders": {} + }, + "writeAMessage": "輸入訊息…", + "@writeAMessage": { + "type": "text", + "placeholders": {} + }, + "yes": "是", + "@yes": { + "type": "text", + "placeholders": {} + }, + "you": "您", + "@you": { + "type": "text", + "placeholders": {} + }, + "youAreInvitedToThisChat": "有人邀請您加入這個聊天室", + "@youAreInvitedToThisChat": { + "type": "text", + "placeholders": {} + }, + "youAreNoLongerParticipatingInThisChat": "您不再參與這個聊天室了", + "@youAreNoLongerParticipatingInThisChat": { + "type": "text", + "placeholders": {} + }, + "youCannotInviteYourself": "您不能邀請您自己", + "@youCannotInviteYourself": { + "type": "text", + "placeholders": {} + }, + "youHaveBeenBannedFromThisChat": "您已經被這個聊天室封禁", + "@youHaveBeenBannedFromThisChat": { + "type": "text", + "placeholders": {} + }, + "yourPublicKey": "您的公鑰", + "@yourPublicKey": { + "type": "text", + "placeholders": {} + }, + "people": "人", + "@people": { + "type": "text", + "placeholders": {} + }, + "chats": "聊天室", + "@chats": { + "type": "text", + "placeholders": {} + }, + "allChats": "所有會話", + "@allChats": { + "type": "text", + "placeholders": {} + }, + "commandHint_ban": "在此聊天室封禁該使用者", + "@commandHint_ban": { + "type": "text", + "description": "Usage hint for the command /ban" + }, + "commandHint_clearcache": "清除快取", + "@commandHint_clearcache": { + "type": "text", + "description": "Usage hint for the command /clearcache" + }, + "commandHint_create": "建立一個空的群聊\n使用 --no-encryption 選項來禁用加密", + "@commandHint_create": { + "type": "text", + "description": "Usage hint for the command /create" + }, + "commandHint_discardsession": "丟棄工作階段", + "@commandHint_discardsession": { + "type": "text", + "description": "Usage hint for the command /discardsession" + }, + "commandHint_dm": "啟動一對一聊天\n使用 --no-encryption 選項來禁用加密", + "@commandHint_dm": { + "type": "text", + "description": "Usage hint for the command /dm" + }, + "commandHint_invite": "邀請該使用者加入此聊天室", + "@commandHint_invite": { + "type": "text", + "description": "Usage hint for the command /invite" + }, + "commandHint_join": "加入此聊天室", + "@commandHint_join": { + "type": "text", + "description": "Usage hint for the command /join" + }, + "commandHint_kick": "將這個使用者移出此聊天室", + "@commandHint_kick": { + "type": "text", + "description": "Usage hint for the command /kick" + }, + "commandHint_leave": "退出此聊天室", + "@commandHint_leave": { + "type": "text", + "description": "Usage hint for the command /leave" + }, + "commandHint_myroomnick": "設定您的聊天室暱稱", + "@commandHint_myroomnick": { + "type": "text", + "description": "Usage hint for the command /myroomnick" + }, + "editRoomAliases": "編輯聊天室名", + "@editRoomAliases": { + "type": "text", + "placeholders": {} + }, + "roomVersion": "聊天室的版本", + "@roomVersion": { + "type": "text", + "placeholders": {} + }, + "addToSpace": "加入空間", + "@addToSpace": {}, + "cantOpenUri": "無法打開URI {uri}", + "@cantOpenUri": { + "type": "text", + "placeholders": { + "uri": {} + } + }, + "repeatPassword": "再次輸入密碼", + "@repeatPassword": {}, + "yourChatBackupHasBeenSetUp": "您的聊天記錄備份已設定。", + "@yourChatBackupHasBeenSetUp": {}, + "pleaseChooseAtLeastChars": "請至少輸入 {min} 个字元。", + "@pleaseChooseAtLeastChars": { + "type": "text", + "placeholders": { + "min": {} + } + }, + "goToTheNewRoom": "前往新聊天室", + "@goToTheNewRoom": { + "type": "text", + "placeholders": {} + }, + "commandHint_myroomavatar": "設置您的聊天室頭貼(通過 mxc-uri)", + "@commandHint_myroomavatar": { + "type": "text", + "description": "Usage hint for the command /myroomavatar" + }, + "commandHint_unban": "在此聊天室解封該使用者", + "@commandHint_unban": { + "type": "text", + "description": "Usage hint for the command /unban" + }, + "passwordsDoNotMatch": "密碼不匹配!", + "@passwordsDoNotMatch": {}, + "pleaseEnterValidEmail": "請輸入一個有效的電子郵件地址。", + "@pleaseEnterValidEmail": {}, + "autoplayImages": "自動播放動態貼圖和表情", + "@autoplayImages": { + "type": "text", + "placeholder": {} + }, + "sendOnEnter": "按 Enter 鍵發送", + "@sendOnEnter": {}, + "changeYourAvatar": "更改您的大頭貼", + "@changeYourAvatar": { + "type": "text", + "placeholders": {} + }, + "chatHasBeenAddedToThisSpace": "聊天室已添加到此空間", + "@chatHasBeenAddedToThisSpace": {}, + "clearArchive": "清除存檔", + "@clearArchive": {}, + "discover": "", + "@discover": { + "type": "text", + "placeholders": {} + }, + "hugContent": "", + "@hugContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "jumpToLastReadMessage": "", + "@jumpToLastReadMessage": {}, + "allRooms": "", + "@allRooms": { + "type": "text", + "placeholders": {} + }, + "obtainingLocation": "", + "@obtainingLocation": { + "type": "text", + "placeholders": {} + }, + "whoCanSeeMyStories": "", + "@whoCanSeeMyStories": {}, + "commandHint_cuddle": "", + "@commandHint_cuddle": {}, + "widgetVideo": "", + "@widgetVideo": {}, + "dismiss": "", + "@dismiss": {}, + "reportErrorDescription": "", + "@reportErrorDescription": {}, + "addAccount": "", + "@addAccount": {}, + "removeYourAvatar": "", + "@removeYourAvatar": { + "type": "text", + "placeholders": {} + }, + "unsupportedAndroidVersion": "", + "@unsupportedAndroidVersion": {}, + "enterASpacepName": "", + "@enterASpacepName": {}, + "commandHint_html": "", + "@commandHint_html": { + "type": "text", + "description": "Usage hint for the command /html" + }, + "widgetJitsi": "", + "@widgetJitsi": {}, + "messageType": "", + "@messageType": {}, + "noEmailWarning": "", + "@noEmailWarning": {}, + "indexedDbErrorLong": "", + "@indexedDbErrorLong": {}, + "oneClientLoggedOut": "", + "@oneClientLoggedOut": {}, + "startFirstChat": "", + "@startFirstChat": {}, + "callingAccount": "", + "@callingAccount": {}, + "setColorTheme": "", + "@setColorTheme": {}, + "nextAccount": "", + "@nextAccount": {}, + "singlesignon": "", + "@singlesignon": { + "type": "text", + "placeholders": {} + }, + "allSpaces": "", + "@allSpaces": {}, + "supposedMxid": "", + "@supposedMxid": { + "type": "text", + "placeholders": { + "mxid": {} + } + }, + "user": "", + "@user": {}, + "youAcceptedTheInvitation": "", + "@youAcceptedTheInvitation": {}, + "noMatrixServer": "", + "@noMatrixServer": { + "type": "text", + "placeholders": { + "server1": {}, + "server2": {} + } + }, + "youInvitedBy": "", + "@youInvitedBy": { + "placeholders": { + "user": {} + } + }, + "banUserDescription": "", + "@banUserDescription": {}, + "requests": "", + "@requests": {}, + "widgetEtherpad": "", + "@widgetEtherpad": {}, + "stories": "", + "@stories": {}, + "addToStory": "", + "@addToStory": {}, + "removeDevicesDescription": "", + "@removeDevicesDescription": {}, + "separateChatTypes": "", + "@separateChatTypes": { + "type": "text", + "placeholders": {} + }, + "tryAgain": "", + "@tryAgain": {}, + "youKickedAndBanned": "", + "@youKickedAndBanned": { + "placeholders": { + "user": {} + } + }, + "showDirectChatsInSpaces": "", + "@showDirectChatsInSpaces": { + "type": "text", + "placeholders": {} + }, + "unbanUserDescription": "", + "@unbanUserDescription": {}, + "todoLists": "", + "@todoLists": {}, + "saveFile": "", + "@saveFile": { + "type": "text", + "placeholders": {} + }, + "youRejectedTheInvitation": "", + "@youRejectedTheInvitation": {}, + "otherCallingPermissions": "", + "@otherCallingPermissions": {}, + "messagesStyle": "", + "@messagesStyle": {}, + "link": "", + "@link": {}, + "widgetUrlError": "", + "@widgetUrlError": {}, + "emailOrUsername": "", + "@emailOrUsername": {}, + "newSpaceDescription": "", + "@newSpaceDescription": {}, + "chatDescription": "", + "@chatDescription": {}, + "callingAccountDetails": "", + "@callingAccountDetails": {}, + "enterSpace": "", + "@enterSpace": {}, + "encryptThisChat": "", + "@encryptThisChat": {}, + "previousAccount": "", + "@previousAccount": {}, + "reopenChat": "", + "@reopenChat": {}, + "pleaseEnterRecoveryKey": "", + "@pleaseEnterRecoveryKey": {}, + "widgetNameError": "", + "@widgetNameError": {}, + "addToBundle": "", + "@addToBundle": {}, + "spaceIsPublic": "", + "@spaceIsPublic": { + "type": "text", + "placeholders": {} + }, + "addWidget": "", + "@addWidget": {}, + "countFiles": "", + "@countFiles": { + "placeholders": { + "count": {} + } + }, + "noKeyForThisMessage": "", + "@noKeyForThisMessage": {}, + "shareLocation": "", + "@shareLocation": { + "type": "text", + "placeholders": {} + }, + "commandHint_markasgroup": "", + "@commandHint_markasgroup": {}, + "editTodo": "", + "@editTodo": {}, + "errorObtainingLocation": "", + "@errorObtainingLocation": { + "type": "text", + "placeholders": { + "error": {} + } + }, + "hydrateTor": "", + "@hydrateTor": {}, + "pushNotificationsNotAvailable": "", + "@pushNotificationsNotAvailable": {}, + "storeInAppleKeyChain": "", + "@storeInAppleKeyChain": {}, + "hydrate": "", + "@hydrate": {}, + "invalidServerName": "", + "@invalidServerName": {}, + "chatPermissions": "", + "@chatPermissions": {}, + "sender": "", + "@sender": {}, + "storeInAndroidKeystore": "", + "@storeInAndroidKeystore": {}, + "signInWithPassword": "", + "@signInWithPassword": {}, + "pleaseAddATitle": "", + "@pleaseAddATitle": {}, + "updateNow": "", + "@updateNow": {}, + "makeAdminDescription": "", + "@makeAdminDescription": {}, + "synchronizingPleaseWait": "", + "@synchronizingPleaseWait": { + "type": "text", + "placeholders": {} + }, + "saveKeyManuallyDescription": "", + "@saveKeyManuallyDescription": {}, + "editBundlesForAccount": "", + "@editBundlesForAccount": {}, + "whyIsThisMessageEncrypted": "", + "@whyIsThisMessageEncrypted": {}, + "setChatDescription": "", + "@setChatDescription": {}, + "spaceName": "", + "@spaceName": { + "type": "text", + "placeholders": {} + }, + "importFromZipFile": "", + "@importFromZipFile": {}, + "or": "", + "@or": { + "type": "text", + "placeholders": {} + }, + "dehydrateWarning": "", + "@dehydrateWarning": {}, + "noOtherDevicesFound": "", + "@noOtherDevicesFound": {}, + "addDescription": "", + "@addDescription": {}, + "redactedBy": "", + "@redactedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "videoCallsBetaWarning": "", + "@videoCallsBetaWarning": {}, + "storyPrivacyWarning": "", + "@storyPrivacyWarning": {}, + "matrixWidgets": "", + "@matrixWidgets": {}, + "signInWith": "", + "@signInWith": { + "type": "text", + "placeholders": { + "provider": {} + } + }, + "updateAvailable": "", + "@updateAvailable": {}, + "fileIsTooBigForServer": "", + "@fileIsTooBigForServer": {}, + "homeserver": "", + "@homeserver": {}, + "noTodosYet": "", + "@noTodosYet": {}, + "callingPermissions": "", + "@callingPermissions": {}, + "readUpToHere": "", + "@readUpToHere": {}, + "start": "", + "@start": {}, + "bubbleSize": "", + "@bubbleSize": { + "type": "text", + "placeholders": {} + }, + "register": "", + "@register": { + "type": "text", + "placeholders": {} + }, + "unlockOldMessages": "", + "@unlockOldMessages": {}, + "numChats": "", + "@numChats": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "whatIsGoingOn": "", + "@whatIsGoingOn": {}, + "optionalRedactReason": "", + "@optionalRedactReason": {}, + "dehydrate": "", + "@dehydrate": {}, + "locationPermissionDeniedNotice": "", + "@locationPermissionDeniedNotice": { + "type": "text", + "placeholders": {} + }, + "sendAsText": "", + "@sendAsText": { + "type": "text" + }, + "archiveRoomDescription": "", + "@archiveRoomDescription": {}, + "exportEmotePack": "", + "@exportEmotePack": {}, + "sendSticker": "", + "@sendSticker": { + "type": "text", + "placeholders": {} + }, + "switchToAccount": "", + "@switchToAccount": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "commandInvalid": "", + "@commandInvalid": { + "type": "text" + }, + "setAsCanonicalAlias": "", + "@setAsCanonicalAlias": { + "type": "text", + "placeholders": {} + }, + "locationDisabledNotice": "", + "@locationDisabledNotice": { + "type": "text", + "placeholders": {} + }, + "letsStart": "", + "@letsStart": {}, + "commandHint_plain": "", + "@commandHint_plain": { + "type": "text", + "description": "Usage hint for the command /plain" + }, + "experimentalVideoCalls": "", + "@experimentalVideoCalls": {}, + "savedEmotePack": "", + "@savedEmotePack": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "pleaseEnterRecoveryKeyDescription": "", + "@pleaseEnterRecoveryKeyDescription": {}, + "openInMaps": "", + "@openInMaps": { + "type": "text", + "placeholders": {} + }, + "inviteContactToGroupQuestion": "", + "@inviteContactToGroupQuestion": {}, + "redactedByBecause": "", + "@redactedByBecause": { + "type": "text", + "placeholders": { + "username": {}, + "reason": {} + } + }, + "youHaveWithdrawnTheInvitationFor": "", + "@youHaveWithdrawnTheInvitationFor": { + "placeholders": { + "user": {} + } + }, + "appearOnTopDetails": "", + "@appearOnTopDetails": {}, + "enterRoom": "", + "@enterRoom": {}, + "reportUser": "", + "@reportUser": {}, + "commandHint_send": "", + "@commandHint_send": { + "type": "text", + "description": "Usage hint for the command /send" + }, + "confirmEventUnpin": "", + "@confirmEventUnpin": {}, + "youInvitedUser": "", + "@youInvitedUser": { + "placeholders": { + "user": {} + } + }, + "fileHasBeenSavedAt": "", + "@fileHasBeenSavedAt": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "importZipFile": "", + "@importZipFile": {}, + "anyoneCanKnock": "", + "@anyoneCanKnock": {}, + "commandMissing": "", + "@commandMissing": { + "type": "text", + "placeholders": { + "command": {} + }, + "description": "State that {command} is not a valid /command." + }, + "redactMessageDescription": "", + "@redactMessageDescription": {}, + "recoveryKey": "", + "@recoveryKey": {}, + "invalidInput": "", + "@invalidInput": {}, + "todosUnencrypted": "", + "@todosUnencrypted": {}, + "dehydrateTorLong": "", + "@dehydrateTorLong": {}, + "replyHasBeenSent": "", + "@replyHasBeenSent": {}, + "doNotShowAgain": "", + "@doNotShowAgain": {}, + "report": "", + "@report": {}, + "yourStory": "", + "@yourStory": {}, + "unverified": "", + "@unverified": {}, + "serverRequiresEmail": "", + "@serverRequiresEmail": {}, + "hideUnimportantStateEvents": "", + "@hideUnimportantStateEvents": {}, + "screenSharingTitle": "", + "@screenSharingTitle": {}, + "widgetCustom": "", + "@widgetCustom": {}, + "addToSpaceDescription": "", + "@addToSpaceDescription": {}, + "googlyEyesContent": "", + "@googlyEyesContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "whoCanSeeMyStoriesDesc": "", + "@whoCanSeeMyStoriesDesc": {}, + "youBannedUser": "", + "@youBannedUser": { + "placeholders": { + "user": {} + } + }, + "unsubscribeStories": "", + "@unsubscribeStories": {}, + "loginWithOneClick": "", + "@loginWithOneClick": {}, + "addChatDescription": "", + "@addChatDescription": {}, + "hasKnocked": "", + "@hasKnocked": { + "placeholders": { + "user": {} + } + }, + "publish": "", + "@publish": {}, + "openLinkInBrowser": "", + "@openLinkInBrowser": {}, + "commandHint_react": "", + "@commandHint_react": { + "type": "text", + "description": "Usage hint for the command /react" + }, + "commandHint_me": "", + "@commandHint_me": { + "type": "text", + "description": "Usage hint for the command /me" + }, + "messageInfo": "", + "@messageInfo": {}, + "disableEncryptionWarning": "", + "@disableEncryptionWarning": {}, + "directChat": "", + "@directChat": {}, + "noOneCanJoin": "", + "@noOneCanJoin": {}, + "wrongPinEntered": "", + "@wrongPinEntered": { + "type": "text", + "placeholders": { + "seconds": {} + } + }, + "sendTypingNotifications": "", + "@sendTypingNotifications": {}, + "inviteGroupChat": "", + "@inviteGroupChat": {}, + "appearOnTop": "", + "@appearOnTop": {}, + "invitePrivateChat": "", + "@invitePrivateChat": {}, + "foregroundServiceRunning": "", + "@foregroundServiceRunning": {}, + "voiceCall": "", + "@voiceCall": {}, + "createNewSpace": "", + "@createNewSpace": { + "type": "text", + "placeholders": {} + }, + "importEmojis": "", + "@importEmojis": {}, + "wasDirectChatDisplayName": "", + "@wasDirectChatDisplayName": { + "type": "text", + "placeholders": { + "oldDisplayName": {} + } + }, + "noChatDescriptionYet": "", + "@noChatDescriptionYet": {}, + "newTodo": "", + "@newTodo": {}, + "removeFromBundle": "", + "@removeFromBundle": {}, + "confirmMatrixId": "", + "@confirmMatrixId": {}, + "learnMore": "", + "@learnMore": {}, + "notAnImage": "", + "@notAnImage": {}, + "users": "", + "@users": {}, + "openGallery": "", + "@openGallery": {}, + "chatDescriptionHasBeenChanged": "", + "@chatDescriptionHasBeenChanged": {}, + "newGroup": "", + "@newGroup": {}, + "bundleName": "", + "@bundleName": {}, + "dehydrateTor": "", + "@dehydrateTor": {}, + "todoListChangedError": "", + "@todoListChangedError": {}, + "removeFromSpace": "", + "@removeFromSpace": {}, + "enterInviteLinkOrMatrixId": "", + "@enterInviteLinkOrMatrixId": {}, + "commandHint_op": "", + "@commandHint_op": { + "type": "text", + "description": "Usage hint for the command /op" + }, + "roomUpgradeDescription": "", + "@roomUpgradeDescription": {}, + "scanQrCode": "", + "@scanQrCode": {}, + "pleaseEnterANumber": "", + "@pleaseEnterANumber": {}, + "youKicked": "", + "@youKicked": { + "placeholders": { + "user": {} + } + }, + "profileNotFound": "", + "@profileNotFound": {}, + "jump": "", + "@jump": {}, + "reactedWith": "", + "@reactedWith": { + "type": "text", + "placeholders": { + "sender": {}, + "reaction": {} + } + }, + "sorryThatsNotPossible": "", + "@sorryThatsNotPossible": {}, + "storyFrom": "", + "@storyFrom": { + "type": "text", + "placeholders": { + "date": {}, + "body": {} + } + }, + "videoWithSize": "", + "@videoWithSize": { + "type": "text", + "placeholders": { + "size": {} + } + }, + "shareInviteLink": "", + "@shareInviteLink": {}, + "commandHint_markasdm": "", + "@commandHint_markasdm": {}, + "recoveryKeyLost": "", + "@recoveryKeyLost": {}, + "cuddleContent": "", + "@cuddleContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "deviceKeys": "", + "@deviceKeys": {}, + "emoteKeyboardNoRecents": "", + "@emoteKeyboardNoRecents": { + "type": "text", + "placeholders": {} + }, + "endToEndEncryption": "", + "@endToEndEncryption": {}, + "setTheme": "", + "@setTheme": {}, + "youJoinedTheChat": "", + "@youJoinedTheChat": {}, + "openVideoCamera": "", + "@openVideoCamera": { + "type": "text", + "placeholders": {} + }, + "thisUserHasNotPostedAnythingYet": "", + "@thisUserHasNotPostedAnythingYet": {}, + "markAsRead": "", + "@markAsRead": {}, + "widgetName": "", + "@widgetName": {}, + "errorAddingWidget": "", + "@errorAddingWidget": {}, + "commandHint_hug": "", + "@commandHint_hug": {}, + "replace": "", + "@replace": {}, + "oopsPushError": "", + "@oopsPushError": { + "type": "text", + "placeholders": {} + }, + "youUnbannedUser": "", + "@youUnbannedUser": { + "placeholders": { + "user": {} + } + }, + "newSpace": "", + "@newSpace": {}, + "emojis": "", + "@emojis": {}, + "pleaseEnterYourPin": "", + "@pleaseEnterYourPin": { + "type": "text", + "placeholders": {} + }, + "pleaseChoose": "", + "@pleaseChoose": { + "type": "text", + "placeholders": {} + }, + "commandHint_googly": "", + "@commandHint_googly": {}, + "pleaseTryAgainLaterOrChooseDifferentServer": "", + "@pleaseTryAgainLaterOrChooseDifferentServer": {}, + "createGroup": "", + "@createGroup": {}, + "hydrateTorLong": "", + "@hydrateTorLong": {}, + "time": "", + "@time": {}, + "custom": "", + "@custom": {}, + "noBackupWarning": "", + "@noBackupWarning": {}, + "editWidgets": "", + "@editWidgets": {}, + "storeInSecureStorageDescription": "", + "@storeInSecureStorageDescription": {}, + "openChat": "", + "@openChat": {}, + "kickUserDescription": "", + "@kickUserDescription": {}, + "importNow": "", + "@importNow": {}, + "pinMessage": "", + "@pinMessage": {}, + "invite": "", + "@invite": {}, + "enableMultiAccounts": "", + "@enableMultiAccounts": {}, + "continueWith": "", + "@continueWith": {}, + "indexedDbErrorTitle": "", + "@indexedDbErrorTitle": {}, + "unsupportedAndroidVersionLong": "", + "@unsupportedAndroidVersionLong": {}, + "storeSecurlyOnThisDevice": "", + "@storeSecurlyOnThisDevice": {}, + "iUnderstand": "", + "@iUnderstand": {}, + "screenSharingDetail": "", + "@screenSharingDetail": {}, + "placeCall": "", + "@placeCall": {} +} diff --git a/assets/login_wallpaper.png b/assets/login_wallpaper.png index 2ca9db9ca..2301f7ffd 100644 Binary files a/assets/login_wallpaper.png and b/assets/login_wallpaper.png differ diff --git a/assets/pangea/apple.svg b/assets/pangea/apple.svg new file mode 100644 index 000000000..133f976ba --- /dev/null +++ b/assets/pangea/apple.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/assets/pangea/bot_faces/addled.png b/assets/pangea/bot_faces/addled.png new file mode 100644 index 000000000..bc65a3c0b Binary files /dev/null and b/assets/pangea/bot_faces/addled.png differ diff --git a/assets/pangea/bot_faces/down.png b/assets/pangea/bot_faces/down.png new file mode 100644 index 000000000..99bd22bad Binary files /dev/null and b/assets/pangea/bot_faces/down.png differ diff --git a/assets/pangea/bot_faces/left.png b/assets/pangea/bot_faces/left.png new file mode 100644 index 000000000..dbf2b486f Binary files /dev/null and b/assets/pangea/bot_faces/left.png differ diff --git a/assets/pangea/bot_faces/right.png b/assets/pangea/bot_faces/right.png new file mode 100644 index 000000000..c6283d710 Binary files /dev/null and b/assets/pangea/bot_faces/right.png differ diff --git a/assets/pangea/bot_faces/shocked.png b/assets/pangea/bot_faces/shocked.png new file mode 100644 index 000000000..b0a302a35 Binary files /dev/null and b/assets/pangea/bot_faces/shocked.png differ diff --git a/assets/pangea/bot_faces/surprised.png b/assets/pangea/bot_faces/surprised.png new file mode 100644 index 000000000..760279019 Binary files /dev/null and b/assets/pangea/bot_faces/surprised.png differ diff --git a/assets/pangea/google.svg b/assets/pangea/google.svg new file mode 100644 index 000000000..a504470e1 --- /dev/null +++ b/assets/pangea/google.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/pangea/logo.png b/assets/pangea/logo.png new file mode 100644 index 000000000..96781ee7f Binary files /dev/null and b/assets/pangea/logo.png differ diff --git a/assets/pangea/pangea_logo.svg b/assets/pangea/pangea_logo.svg new file mode 100644 index 000000000..f1169b6b1 --- /dev/null +++ b/assets/pangea/pangea_logo.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/sounds/WoodenBeaver_stereo_message-new-instant.ogg b/assets/sounds/WoodenBeaver_stereo_message-new-instant.ogg new file mode 100644 index 000000000..3950f4903 Binary files /dev/null and b/assets/sounds/WoodenBeaver_stereo_message-new-instant.ogg differ diff --git a/assets/start_chat.png b/assets/start_chat.png new file mode 100644 index 000000000..bb9dd5524 Binary files /dev/null and b/assets/start_chat.png differ diff --git a/config.sample.json b/config.sample.json index ff37ec238..03ac42a6a 100644 --- a/config.sample.json +++ b/config.sample.json @@ -1,9 +1,9 @@ { - "application_name": "FluffyChat", + "application_name": "PangeaChat", "application_welcome_message": null, - "default_homeserver": "matrix.org", - "web_base_url": "https://fluffychat.im/web", - "privacy_url": "https://fluffychat.im/en/privacy.html", + "default_homeserver": "matrix.pangea.chat", + "web_base_url": "https://web.pangea.chat", + "privacy_url": "https://pangea.chat/privacy", "render_html": false, "hide_redacted_events": false, "hide_unknown_events": false diff --git a/docs/en/privacy.html b/docs/en/privacy.html new file mode 100644 index 000000000..6651972a1 --- /dev/null +++ b/docs/en/privacy.html @@ -0,0 +1,9 @@ + + + + + + +

Please follow this link.

+ + \ No newline at end of file diff --git a/docs/how_to_fork.md b/docs/how_to_fork.md new file mode 100644 index 000000000..2452c13fd --- /dev/null +++ b/docs/how_to_fork.md @@ -0,0 +1,39 @@ +# How to create your own FluffyChat fork + +## 1. License +FluffyChat is licensed under AGPL. Read the license +(https://gitlab.com/ChristianPauly/fluffychat-flutter/-/blob/main/LICENSE) and +make sure that your fork is open source under the same license and that you +fulfill all requirements. Maybe you should consider contacting a lawyer **before** +you publish your fork. + +## 2. Disable end-to-end encryption! +Due to US export regulations you are not allowed to publish your app in +a store or anywhere on a US server before you have removed everything regarding +the encryption or fulfill the regulations. + +Learn more: +https://www.bis.doc.gov/index.php/policy-guidance/encryption + +If you need help from us with using E2EE in your fork read more below under the +topic "**Official Support**". + +## 3. Stay up to date! +FluffyChat contains security related stuff. If we find a security bug, we will +try to fix it as soon as possible and ship it with a new version. But this +means that your fork is out of date and a security risk. You can't be awake +24 hours a day so you must decide how you protect your users by chosing one +of the following methods: + +1. Make your fork as minimal as possible and enable repository mirroring. Set +up a CI which publishes new versions automatically if FluffyChat publishes a +bug fix. +2. Never sleep and pay a big team where one guy at least is never sleeping. +3. Contact [famedly.com](https://famedly.com) to buy official support. + +## 4. Official Support +FluffyChat is free as in free speech and not free beer! Please contact +my company [famedly.com](https://famedly.com) for offers and official support +and take in mind that it costs a lot of work and time to maintain FluffyChat +or the Famedly Matrix SDK. So we can't give you support for free. So please +expect around 1$ per month per user of your fork. diff --git a/docs/index.html b/docs/index.html index edfb771d0..cbd27caa5 100644 --- a/docs/index.html +++ b/docs/index.html @@ -94,16 +94,16 @@ code - Privacy + href="https://github.com/krille-chan/fluffychat/blob/main/PRIVACY.md">Privacy - Changelog + href="https://github.com/krille-chan/fluffychat/blob/main/CHANGELOG.md">Changelog - Translations - FluffyChat F-Droid + href="https://github.com/krille-chan/fluffychat/blob/main/docs/fdroid_repo.md">FluffyChat F-Droid repository - - \ No newline at end of file + diff --git a/docs/tailwind.css b/docs/tailwind.css new file mode 100644 index 000000000..a4b94aea8 --- /dev/null +++ b/docs/tailwind.css @@ -0,0 +1 @@ +/*! tailwindcss v3.0.19 | MIT License | https://tailwindcss.com*/*,:after,:before{box-sizing:border-box;border:0 solid #e5e7eb}:after,:before{--tw-content:""}html{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:initial}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button;background-color:initial;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:initial}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input:-ms-input-placeholder,textarea:-ms-input-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]{display:none}*,:after,:before{--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#3b82f680;--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}.relative{position:relative}.mx-auto{margin-left:auto;margin-right:auto}.my-4{margin-top:1rem;margin-bottom:1rem}.mb-8{margin-bottom:2rem}.mb-2{margin-bottom:.5rem}.inline-block{display:inline-block}.inline{display:inline}.flex{display:flex}.h-screen{height:100vh}.h-8{height:2rem}.h-10{height:2.5rem}.h-6{height:1.5rem}.max-h-12{max-height:3rem}.w-full{width:100%}.w-1\/2{width:50%}.w-10{width:2.5rem}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.content-center{align-content:center}.items-center{align-items:center}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.overflow-y-hidden{overflow-y:hidden}.bg-cover{background-size:cover}.bg-right{background-position:100%}.fill-current{fill:currentColor}.p-6{padding:1.5rem}.p-2{padding:.5rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.pb-14{padding-bottom:3.5rem}.pr-2{padding-right:.5rem}.pt-8{padding-top:2rem}.pb-4{padding-bottom:1rem}.pb-24{padding-bottom:6rem}.pt-16{padding-top:4rem}.pb-6{padding-bottom:1.5rem}.text-center{text-align:center}.text-2xl{font-size:1.5rem;line-height:2rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-base{font-size:1rem;line-height:1.5rem}.text-sm{font-size:.875rem;line-height:1.25rem}.font-bold{font-weight:700}.leading-normal{line-height:1.5}.leading-tight{line-height:1.25}.tracking-normal{letter-spacing:0}.text-gray-900{--tw-text-opacity:1;color:rgb(17 24 39/var(--tw-text-opacity))}.text-indigo-600{--tw-text-opacity:1;color:rgb(79 70 229/var(--tw-text-opacity))}.text-blue-300{--tw-text-opacity:1;color:rgb(147 197 253/var(--tw-text-opacity))}.text-purple-800{--tw-text-opacity:1;color:rgb(107 33 168/var(--tw-text-opacity))}.text-blue-700{--tw-text-opacity:1;color:rgb(29 78 216/var(--tw-text-opacity))}.text-gray-500{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity))}.underline{-webkit-text-decoration-line:underline;text-decoration-line:underline}.no-underline{-webkit-text-decoration-line:none;text-decoration-line:none}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.ease-in{transition-timing-function:cubic-bezier(.4,0,1,1)}.ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)}@-webkit-keyframes bounce{0%,to{transform:translateY(-25%);-webkit-animation-timing-function:cubic-bezier(.8,0,1,1);animation-timing-function:cubic-bezier(.8,0,1,1)}50%{transform:none;-webkit-animation-timing-function:cubic-bezier(0,0,.2,1);animation-timing-function:cubic-bezier(0,0,.2,1)}}@keyframes bounce{0%,to{transform:translateY(-25%);-webkit-animation-timing-function:cubic-bezier(.8,0,1,1);animation-timing-function:cubic-bezier(.8,0,1,1)}50%{transform:none;-webkit-animation-timing-function:cubic-bezier(0,0,.2,1);animation-timing-function:cubic-bezier(0,0,.2,1)}}.hover\:animate-bounce:hover{-webkit-animation:bounce 1s infinite;animation:bounce 1s infinite}.hover\:text-indigo-800:hover{--tw-text-opacity:1;color:rgb(55 48 163/var(--tw-text-opacity))}.hover\:text-blue-700:hover{--tw-text-opacity:1;color:rgb(29 78 216/var(--tw-text-opacity))}.hover\:text-purple-800:hover{--tw-text-opacity:1;color:rgb(107 33 168/var(--tw-text-opacity))}.hover\:no-underline:hover{-webkit-text-decoration-line:none;text-decoration-line:none}@media (min-width:768px){.md\:h-auto{height:auto}.md\:flex-row{flex-direction:row}.md\:justify-start{justify-content:flex-start}.md\:p-4{padding:1rem}.md\:text-left{text-align:left}.md\:text-5xl{font-size:3rem;line-height:1}.md\:text-2xl{font-size:1.5rem;line-height:2rem}}@media (min-width:1024px){.lg\:items-start{align-items:flex-start}.lg\:pb-0{padding-bottom:0}.lg\:text-4xl{font-size:2.25rem;line-height:2.5rem}}@media (min-width:1280px){.xl\:w-2\/5{width:40%}.xl\:w-3\/5{width:60%}} \ No newline at end of file diff --git a/fastlane b/fastlane deleted file mode 120000 index 94746b0d7..000000000 --- a/fastlane +++ /dev/null @@ -1 +0,0 @@ -./android/fastlane \ No newline at end of file diff --git a/fonts/Inconsolata/Inconsolata-Black.ttf b/fonts/Inconsolata/Inconsolata-Black.ttf new file mode 100644 index 000000000..ab78d8552 Binary files /dev/null and b/fonts/Inconsolata/Inconsolata-Black.ttf differ diff --git a/fonts/Inconsolata/Inconsolata-Bold.ttf b/fonts/Inconsolata/Inconsolata-Bold.ttf new file mode 100644 index 000000000..57aa66cc0 Binary files /dev/null and b/fonts/Inconsolata/Inconsolata-Bold.ttf differ diff --git a/fonts/Inconsolata/Inconsolata-ExtraBold.ttf b/fonts/Inconsolata/Inconsolata-ExtraBold.ttf new file mode 100644 index 000000000..12b733fad Binary files /dev/null and b/fonts/Inconsolata/Inconsolata-ExtraBold.ttf differ diff --git a/fonts/Inconsolata/Inconsolata-ExtraLight.ttf b/fonts/Inconsolata/Inconsolata-ExtraLight.ttf new file mode 100644 index 000000000..3492bb202 Binary files /dev/null and b/fonts/Inconsolata/Inconsolata-ExtraLight.ttf differ diff --git a/fonts/Inconsolata/Inconsolata-Light.ttf b/fonts/Inconsolata/Inconsolata-Light.ttf new file mode 100644 index 000000000..b313b1c95 Binary files /dev/null and b/fonts/Inconsolata/Inconsolata-Light.ttf differ diff --git a/fonts/Inconsolata/Inconsolata-Medium.ttf b/fonts/Inconsolata/Inconsolata-Medium.ttf new file mode 100644 index 000000000..d6ad05e84 Binary files /dev/null and b/fonts/Inconsolata/Inconsolata-Medium.ttf differ diff --git a/fonts/Inconsolata/Inconsolata-Regular.ttf b/fonts/Inconsolata/Inconsolata-Regular.ttf new file mode 100644 index 000000000..0d879bf3a Binary files /dev/null and b/fonts/Inconsolata/Inconsolata-Regular.ttf differ diff --git a/fonts/Inconsolata/Inconsolata-SemiBold.ttf b/fonts/Inconsolata/Inconsolata-SemiBold.ttf new file mode 100644 index 000000000..71ba4f997 Binary files /dev/null and b/fonts/Inconsolata/Inconsolata-SemiBold.ttf differ diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 40710f60c..e5c2d6a2b 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -475,7 +475,7 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = 4NXF6Z997G; + DEVELOPMENT_TEAM = PJ8L5H7L7H; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -491,7 +491,7 @@ "$(PROJECT_DIR)/Flutter", ); MARKETING_VERSION = 0.32.1; - PRODUCT_BUNDLE_IDENTIFIER = im.fluffychat.app; + PRODUCT_BUNDLE_IDENTIFIER = com.talktolearn.chat; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; @@ -615,7 +615,7 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = 4NXF6Z997G; + DEVELOPMENT_TEAM = PJ8L5H7L7H; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -631,7 +631,7 @@ "$(PROJECT_DIR)/Flutter", ); MARKETING_VERSION = 0.32.1; - PRODUCT_BUNDLE_IDENTIFIER = im.fluffychat.app; + PRODUCT_BUNDLE_IDENTIFIER = com.talktolearn.chat; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; @@ -649,7 +649,7 @@ CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = 4NXF6Z997G; + DEVELOPMENT_TEAM = PJ8L5H7L7H; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", @@ -665,7 +665,7 @@ "$(PROJECT_DIR)/Flutter", ); MARKETING_VERSION = 0.32.1; - PRODUCT_BUNDLE_IDENTIFIER = im.fluffychat.app; + PRODUCT_BUNDLE_IDENTIFIER = com.talktolearn.chat; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; @@ -685,7 +685,7 @@ CODE_SIGN_ENTITLEMENTS = "FluffyChat Share/FluffyChat Share.entitlements"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = 4NXF6Z997G; + DEVELOPMENT_TEAM = PJ8L5H7L7H; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = "FluffyChat Share/Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 14.4; @@ -697,7 +697,7 @@ MARKETING_VERSION = 1.0.0; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; - PRODUCT_BUNDLE_IDENTIFIER = "im.fluffychat.app.FluffyChat-Share"; + PRODUCT_BUNDLE_IDENTIFIER = com.talktolearn.chat.FluffyChatShare; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; @@ -719,7 +719,7 @@ CODE_SIGN_ENTITLEMENTS = "FluffyChat Share/FluffyChat Share.entitlements"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = 4NXF6Z997G; + DEVELOPMENT_TEAM = PJ8L5H7L7H; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = "FluffyChat Share/Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 14.4; @@ -730,7 +730,7 @@ ); MARKETING_VERSION = 1.0.0; MTL_FAST_MATH = YES; - PRODUCT_BUNDLE_IDENTIFIER = "im.fluffychat.app.FluffyChat-Share"; + PRODUCT_BUNDLE_IDENTIFIER = com.talktolearn.chat.FluffyChatShare; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; SWIFT_VERSION = 5.0; @@ -750,7 +750,7 @@ CODE_SIGN_ENTITLEMENTS = "FluffyChat Share/FluffyChat Share.entitlements"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; - DEVELOPMENT_TEAM = 4NXF6Z997G; + DEVELOPMENT_TEAM = PJ8L5H7L7H; GCC_C_LANGUAGE_STANDARD = gnu11; INFOPLIST_FILE = "FluffyChat Share/Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 14.4; @@ -761,7 +761,7 @@ ); MARKETING_VERSION = 1.0.0; MTL_FAST_MATH = YES; - PRODUCT_BUNDLE_IDENTIFIER = "im.fluffychat.app.FluffyChat-Share"; + PRODUCT_BUNDLE_IDENTIFIER = com.talktolearn.chat.FluffyChatShare; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; SWIFT_VERSION = 5.0; diff --git a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index 3db53b6e1..b52b2e698 100644 --- a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -1,6 +1,6 @@ CLIENT_ID - 865731724731-ofdr7e6m04murgb1bvchlj9oaos0q5i3.apps.googleusercontent.com + 545984292675-f5p76l3h9sibsonrct7a8l9ca3c69at0.apps.googleusercontent.com REVERSED_CLIENT_ID - com.googleusercontent.apps.865731724731-ofdr7e6m04murgb1bvchlj9oaos0q5i3 + com.googleusercontent.apps.545984292675-f5p76l3h9sibsonrct7a8l9ca3c69at0 API_KEY - AIzaSyA8ZUBcuny0HjPwF2Q2fvDyQTC5dG2VHlE + AIzaSyCl8QZd9_PnaqJY2zLHCwlsmSWdq7hnH-U GCM_SENDER_ID - 865731724731 + 545984292675 PLIST_VERSION 1 BUNDLE_ID - im.fluffychat.app + com.talktolearn.chat PROJECT_ID - fluffychat-ef3e8 + pangea-chat-936ee STORAGE_BUCKET - fluffychat-ef3e8.appspot.com + pangea-chat-936ee.appspot.com IS_ADS_ENABLED IS_ANALYTICS_ENABLED @@ -29,6 +29,6 @@ IS_SIGNIN_ENABLED GOOGLE_APP_ID - 1:865731724731:ios:79fd983ce46cb40c64309e + 1:545984292675:ios:1226406ecc36e056b931f6 \ No newline at end of file diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index f53992f99..546e02616 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -9,7 +9,7 @@ CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleDisplayName - FluffyChat + Pangea Chat CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier @@ -17,7 +17,7 @@ CFBundleInfoDictionaryVersion 6.0 CFBundleName - fluffychat + pangeachat CFBundlePackageType APPL CFBundleShortVersionString @@ -52,27 +52,29 @@ NSBluetoothPeripheralUsageDescription Play audio and voice messages on bluetooth devices NSCalendarsUsageDescription - Share calendar dates with your contacts in FluffyChat. + Share calendar dates with your contacts in Pangea Chat. NSCameraUsageDescription - Open the camera and take a picture to share them with your contacts on FluffyChat. + Open the camera and take a picture to share them with your contacts on Pangea Chat. NSContactsUsageDescription - Share contacts with your contacts in FluffyChat. + Share contacts with your contacts in Pangea Chat. NSFaceIDUsageDescription - FluffyChat uses an app lock for an additional security level + Pangea Chat uses an app lock for an additional security level NSLocationAlwaysUsageDescription - Share your location with your contacts in FluffyChat. + Share your location with your contacts in Pangea Chat. NSLocationWhenInUseUsageDescription - Share your location with your contacts in FluffyChat. + Share your location with your contacts in Pangea Chat. NSLocationAlwaysAndWhenInUseUsageDescription - Share your location with your contacts in FluffyChat. + Share your location with your contacts in Pangea Chat. NSMicrophoneUsageDescription - Record voice message and share them with your contacts on FluffyChat. + Record voice message and share them with your contacts on Pangea Chat. NSMotionUsageDescription - Share motions with your contacts in FluffyChat. + Share motions with your contacts in Pangea Chat. NSPhotoLibraryUsageDescription - Open photos from your gallery and share them with your contacts on FluffyChat. + Open photos from your gallery and share them with your contacts on Pangea Chat. NSSpeechRecognitionUsageDescription - Share data with your contacts in FluffyChat. + Share data with your contacts in Pangea Chat. + UIApplicationSupportsIndirectInputEvents + UIBackgroundModes audio diff --git a/ios/Runner/Runner.entitlements b/ios/Runner/Runner.entitlements index 84071122d..44b27ed8e 100644 --- a/ios/Runner/Runner.entitlements +++ b/ios/Runner/Runner.entitlements @@ -9,8 +9,10 @@ applinks:example.com com.apple.security.application-groups - + + + diff --git a/l10n.yaml b/l10n.yaml index a714613ee..bb2dd7632 100644 --- a/l10n.yaml +++ b/l10n.yaml @@ -3,3 +3,4 @@ template-arb-file: intl_en.arb output-localization-file: l10n.dart output-class: L10n preferred-supported-locales: ["en"] +untranslated-messages-file: needed-translations.txt diff --git a/lib/config/app_config.dart b/lib/config/app_config.dart index f078fdf08..b3c85c116 100644 --- a/lib/config/app_config.dart +++ b/lib/config/app_config.dart @@ -2,12 +2,20 @@ import 'dart:ui'; import 'package:matrix/matrix.dart'; +import 'package:fluffychat/pangea/config/environment.dart'; + abstract class AppConfig { - static String _applicationName = 'FluffyChat'; + // #Pangea + // static String _applicationName = 'FluffyChat'; + static String _applicationName = 'Pangea Chat'; + // #Pangea static String get applicationName => _applicationName; static String? _applicationWelcomeMessage; static String? get applicationWelcomeMessage => _applicationWelcomeMessage; - static String _defaultHomeserver = 'matrix.org'; + // #Pangea + // static String _defaultHomeserver = 'matrix.org'; + static String _defaultHomeserver = Environment.synapsURL; + // #Pangea static String get defaultHomeserver => _defaultHomeserver; static double fontSizeFactor = 1; static const Color chatColor = primaryColor; @@ -15,24 +23,39 @@ abstract class AppConfig { static const double messageFontSize = 15.75; static const bool allowOtherHomeservers = true; static const bool enableRegistration = true; - static const Color primaryColor = Color(0xFF5625BA); - static const Color primaryColorLight = Color(0xFFCCBDEA); + // #Pangea + // static const Color primaryColor = Color(0xFF5625BA); + // static const Color primaryColorLight = Color(0xFFCCBDEA); + static const Color primaryColor = Color(0xFF8560E0); + static const Color primaryColorLight = Color(0xFFDBC9FF); static const Color secondaryColor = Color(0xFF41a2bc); - static String _privacyUrl = - 'https://github.com/krille-chan/fluffychat/blob/main/PRIVACY.md'; + static const Color activeToggleColor = Color(0xFF33D057); + // static String _privacyUrl = + // 'https://gitlab.com/famedly/fluffychat/-/blob/main/PRIVACY.md'; + static String _privacyUrl = "https://www.pangeachat.com/privacy"; + //Pangea# static String get privacyUrl => _privacyUrl; static const String enablePushTutorial = 'https://github.com/krille-chan/fluffychat/wiki/Push-Notifications-without-Google-Services'; static const String encryptionTutorial = 'https://github.com/krille-chan/fluffychat/wiki/How-to-use-end-to-end-encryption-in-FluffyChat'; + static const String startChatTutorial = + 'https://github.com/krille-chan/fluffychat/wiki/How-to-Find-Users-in-FluffyChat'; static const String appId = 'im.fluffychat.FluffyChat'; - static const String appOpenUrlScheme = 'im.fluffychat'; + // #Pangea + // static const String appOpenUrlScheme = 'im.fluffychat'; + static const String appOpenUrlScheme = 'matrix.pangea.chat'; static String _webBaseUrl = 'https://fluffychat.im/web'; + // Pangea# static String get webBaseUrl => _webBaseUrl; - static const String sourceCodeUrl = - 'https://github.com/krille-chan/fluffychat'; - static const String supportUrl = - 'https://github.com/krille-chan/fluffychat/issues'; + //#Pangea + static const String sourceCodeUrl = 'https://gitlab.com/famedly/fluffychat'; + // static const String supportUrl = + // 'https://gitlab.com/famedly/fluffychat/issues'; + static const String supportUrl = 'https://www.pangeachat.com/faqs'; + static const String termsOfServiceUrl = + 'https://www.pangeachat.com/terms-of-service'; + //Pangea# static final Uri newIssueUrl = Uri( scheme: 'https', host: 'github.com', @@ -41,35 +64,65 @@ abstract class AppConfig { static const bool enableSentry = true; static const String sentryDns = 'https://8591d0d863b646feb4f3dda7e5dcab38@o256755.ingest.sentry.io/5243143'; - static bool renderHtml = true; + //#Pangea + static bool renderHtml = false; + // static bool renderHtml = true; + //Pangea# static bool hideRedactedEvents = false; static bool hideUnknownEvents = true; static bool hideUnimportantStateEvents = true; - static bool showDirectChatsInSpaces = true; static bool separateChatTypes = false; static bool autoplayImages = true; static bool sendTypingNotifications = true; - static bool sendOnEnter = false; + //#Pangea + static bool sendOnEnter = true; + // static bool sendOnEnter = false; + //Pangea# static bool experimentalVoip = false; static const bool hideTypingUsernames = false; static const bool hideAllStateEvents = false; static const String inviteLinkPrefix = 'https://matrix.to/#/'; static const String deepLinkPrefix = 'im.fluffychat://chat/'; static const String schemePrefix = 'matrix:'; - static const String pushNotificationsChannelId = 'fluffychat_push'; - static const String pushNotificationsChannelName = 'FluffyChat push channel'; + // #Pangea + // static const String pushNotificationsChannelId = 'fluffychat_push'; + // static const String pushNotificationsChannelName = 'FluffyChat push channel'; + // static const String pushNotificationsChannelDescription = + // 'Push notifications for FluffyChat'; + // static const String pushNotificationsAppId = 'chat.fluffy.fluffychat'; + // static const String pushNotificationsGatewayUrl = + // 'https://push.fluffychat.im/_matrix/push/v1/notify'; + // static const String pushNotificationsPusherFormat = 'event_id_only'; + static const String pushNotificationsChannelId = 'pangeachat_push'; + static const String pushNotificationsChannelName = 'Pangea Chat push channel'; static const String pushNotificationsChannelDescription = - 'Push notifications for FluffyChat'; - static const String pushNotificationsAppId = 'chat.fluffy.fluffychat'; + 'Push notifications for Pangea Chat'; + static const String pushNotificationsAppId = 'com.talktolearn.chat'; static const String pushNotificationsGatewayUrl = - 'https://push.fluffychat.im/_matrix/push/v1/notify'; - static const String pushNotificationsPusherFormat = 'event_id_only'; + 'https://sygnal.pangea.chat/_matrix/push/v1/notify'; + static const String? pushNotificationsPusherFormat = null; + // Pangea# static const String emojiFontName = 'Noto Emoji'; static const String emojiFontUrl = 'https://github.com/googlefonts/noto-emoji/'; static const double borderRadius = 16.0; static const double columnWidth = 360.0; + // #Pangea + static String googlePlayMangementUrl = + "https://play.google.com/store/account/subscriptions"; + static String googlePlayHistoryUrl = + "https://play.google.com/store/account/orderhistory"; + static String googlePlayPaymentMethodUrl = + "https://play.google.com/store/paymentmethods"; + static String appleMangementUrl = + "https://apps.apple.com/account/subscriptions"; + static String stripePerMonth = + "https://buy.stripe.com/test_bIY6ssd8z5Uz8ec8ww"; + static String iosPromoCode = + "https://apps.apple.com/redeem?ctx=offercodes&id=1445118630&code="; + // Pangea# + static void loadFromJson(Map json) { if (json['chat_color'] != null) { try { @@ -97,7 +150,11 @@ abstract class AppConfig { _privacyUrl = json['web_base_url']; } if (json['render_html'] is bool) { - renderHtml = json['render_html']; + // #Pangea + // this is interfering with our PangeaRichText functionality, removing it for now + renderHtml = false; + // renderHtml = json['render_html']; + // Pangea# } if (json['hide_redacted_events'] is bool) { hideRedactedEvents = json['hide_redacted_events']; diff --git a/lib/config/firebase_options.dart b/lib/config/firebase_options.dart new file mode 100644 index 000000000..a66f312bc --- /dev/null +++ b/lib/config/firebase_options.dart @@ -0,0 +1,93 @@ +// File generated by FlutterFire CLI. +// ignore_for_file: lines_longer_than_80_chars, avoid_classes_with_only_static_members + +import 'package:firebase_core/firebase_core.dart' show FirebaseOptions; + +import 'package:flutter/foundation.dart' + show defaultTargetPlatform, kIsWeb, TargetPlatform; + +/// Default [FirebaseOptions] for use with your Firebase apps. +/// +/// Example: +/// ```dart +/// import 'firebase_options.dart'; +/// // ... +/// await Firebase.initializeApp( +/// options: DefaultFirebaseOptions.currentPlatform, +/// ); +/// ``` +class DefaultFirebaseOptions { + static FirebaseOptions get currentPlatform { + if (kIsWeb) { + return web; + } + switch (defaultTargetPlatform) { + case TargetPlatform.android: + return android; + case TargetPlatform.iOS: + return ios; + case TargetPlatform.macOS: + return macos; + case TargetPlatform.windows: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for windows - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + case TargetPlatform.linux: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for linux - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + default: + throw UnsupportedError( + 'DefaultFirebaseOptions are not supported for this platform.', + ); + } + } + + static const FirebaseOptions web = FirebaseOptions( + apiKey: 'AIzaSyAXK_jobz9YjNmiS1leA-vbGd_a8W-TCGI', + appId: '1:545984292675:web:80f3babc12328eddb931f6', + messagingSenderId: '545984292675', + projectId: 'pangea-chat-936ee', + authDomain: 'pangea-chat-936ee.firebaseapp.com', + databaseURL: 'https://pangea-chat-936ee-default-rtdb.firebaseio.com', + storageBucket: 'pangea-chat-936ee.appspot.com', + measurementId: 'G-FKP13VDEBX', + ); + + static const FirebaseOptions android = FirebaseOptions( + apiKey: 'AIzaSyAyWBbl83WXzbVr6txyCmlUsZhpWomQfdg', + appId: '1:545984292675:android:d808acce7a80c20bb931f6', + messagingSenderId: '545984292675', + projectId: 'pangea-chat-936ee', + databaseURL: 'https://pangea-chat-936ee-default-rtdb.firebaseio.com', + storageBucket: 'pangea-chat-936ee.appspot.com', + androidClientId: + '545984292675-2amsnoan1mt6lec1fld1a7eagu6gej7o.apps.googleusercontent.com', + ); + + static const FirebaseOptions ios = FirebaseOptions( + apiKey: 'AIzaSyCl8QZd9_PnaqJY2zLHCwlsmSWdq7hnH-U', + appId: '1:545984292675:ios:1226406ecc36e056b931f6', + messagingSenderId: '545984292675', + projectId: 'pangea-chat-936ee', + databaseURL: 'https://pangea-chat-936ee-default-rtdb.firebaseio.com', + storageBucket: 'pangea-chat-936ee.appspot.com', + iosClientId: + '545984292675-f5p76l3h9sibsonrct7a8l9ca3c69at0.apps.googleusercontent.com', + iosBundleId: 'com.talktolearn.chat', + ); + + static const FirebaseOptions macos = FirebaseOptions( + apiKey: 'AIzaSyCl8QZd9_PnaqJY2zLHCwlsmSWdq7hnH-U', + appId: '1:545984292675:ios:1226406ecc36e056b931f6', + messagingSenderId: '545984292675', + projectId: 'pangea-chat-936ee', + databaseURL: 'https://pangea-chat-936ee-default-rtdb.firebaseio.com', + storageBucket: 'pangea-chat-936ee.appspot.com', + iosClientId: + '545984292675-f5p76l3h9sibsonrct7a8l9ca3c69at0.apps.googleusercontent.com', + iosBundleId: 'com.talktolearn.chat', + ); +} diff --git a/lib/config/routes.dart b/lib/config/routes.dart index 2386fb3c9..ff2b0b55e 100644 --- a/lib/config/routes.dart +++ b/lib/config/routes.dart @@ -5,11 +5,9 @@ import 'package:flutter/cupertino.dart'; import 'package:go_router/go_router.dart'; import 'package:fluffychat/config/themes.dart'; -import 'package:fluffychat/pages/add_story/add_story.dart'; import 'package:fluffychat/pages/archive/archive.dart'; import 'package:fluffychat/pages/chat/chat.dart'; import 'package:fluffychat/pages/chat_details/chat_details.dart'; -import 'package:fluffychat/pages/chat_encryption_settings/chat_encryption_settings.dart'; import 'package:fluffychat/pages/chat_list/chat_list.dart'; import 'package:fluffychat/pages/chat_members/chat_members.dart'; import 'package:fluffychat/pages/chat_permissions_settings/chat_permissions_settings.dart'; @@ -30,24 +28,43 @@ import 'package:fluffychat/pages/settings_notifications/settings_notifications.d import 'package:fluffychat/pages/settings_security/settings_security.dart'; import 'package:fluffychat/pages/settings_stories/settings_stories.dart'; import 'package:fluffychat/pages/settings_style/settings_style.dart'; -import 'package:fluffychat/pages/story/story_page.dart'; +import 'package:fluffychat/pangea/guard/p_vguard.dart'; +import 'package:fluffychat/pangea/pages/analytics/student_analytics/student_analytics.dart'; +import 'package:fluffychat/pangea/pages/class_settings/class_settings_page.dart'; +import 'package:fluffychat/pangea/pages/exchange/add_exchange_to_class.dart'; +import 'package:fluffychat/pangea/pages/find_partner/find_partner.dart'; +import 'package:fluffychat/pangea/pages/p_user_age/p_user_age.dart'; +import 'package:fluffychat/pangea/pages/settings_learning/settings_learning.dart'; +import 'package:fluffychat/pangea/pages/settings_subscription/settings_subscription.dart'; +import 'package:fluffychat/pangea/pages/sign_up/signup.dart'; +import 'package:fluffychat/pangea/widgets/class/join_with_link.dart'; import 'package:fluffychat/widgets/layouts/empty_page.dart'; import 'package:fluffychat/widgets/layouts/two_column_layout.dart'; import 'package:fluffychat/widgets/log_view.dart'; import 'package:fluffychat/widgets/matrix.dart'; +import '../pangea/pages/analytics/class_analytics/class_analytics.dart'; +import '../pangea/pages/analytics/class_list/class_list.dart'; abstract class AppRoutes { static FutureOr loggedInRedirect( BuildContext context, GoRouterState state, - ) => - Matrix.of(context).client.isLogged() ? '/rooms' : null; + ) { + // #Pangea + // Matrix.of(context).client.isLogged() ? '/rooms' : null; + return PAuthGaurd.loggedInRedirect(context, state); + // Pangea# + } static FutureOr loggedOutRedirect( BuildContext context, GoRouterState state, - ) => - Matrix.of(context).client.isLogged() ? null : '/home'; + ) { + // #Pangea + // Matrix.of(context).client.isLogged() ? null : '/home'; + return PAuthGaurd.loggedOutRedirect(context, state); + // Pangea# + } AppRoutes(); @@ -73,6 +90,16 @@ abstract class AppRoutes { ), redirect: loggedInRedirect, ), + // #Pangea + GoRoute( + path: 'signup', + pageBuilder: (context, state) => defaultPageBuilder( + context, + const SignupPage(), + ), + redirect: loggedInRedirect, + ), + // Pangea# ], ), GoRoute( @@ -100,6 +127,26 @@ abstract class AppRoutes { : child, ), routes: [ + // #Pangea + GoRoute( + path: '/spaces/:roomid', + pageBuilder: (context, state) => defaultPageBuilder( + context, + ChatDetails( + roomId: state.pathParameters['roomid']!, + ), + ), + redirect: loggedOutRedirect, + ), + GoRoute( + path: '/join_with_link', + pageBuilder: (context, state) => defaultPageBuilder( + context, + const JoinClassWithLink(), + ), + redirect: loggedOutRedirect, + ), + // Pangea# GoRoute( path: '/rooms', redirect: loggedOutRedirect, @@ -112,32 +159,68 @@ abstract class AppRoutes { ), ), routes: [ + // #Pangea GoRoute( - path: 'stories/create', + path: 'user_age', pageBuilder: (context, state) => defaultPageBuilder( context, - const AddStoryPage(), + const PUserAge(), ), redirect: loggedOutRedirect, ), GoRoute( - path: 'stories/:roomid', + path: 'mylearning', pageBuilder: (context, state) => defaultPageBuilder( context, - const StoryPage(), + const StudentAnalyticsPage(), + ), + redirect: loggedOutRedirect, + ), + GoRoute( + path: 'analytics', + pageBuilder: (context, state) => defaultPageBuilder( + context, + const AnalyticsClassList(), ), redirect: loggedOutRedirect, routes: [ GoRoute( - path: 'share', + path: ':classid', + redirect: loggedOutRedirect, pageBuilder: (context, state) => defaultPageBuilder( context, - const AddStoryPage(), + const ClassAnalyticsPage(), ), - redirect: loggedOutRedirect, ), ], ), + // GoRoute( + // path: 'stories/create', + // pageBuilder: (context, state) => defaultPageBuilder( + // context, + // const AddStoryPage(), + // ), + // redirect: loggedOutRedirect, + // ), + // GoRoute( + // path: 'stories/:roomid', + // pageBuilder: (context, state) => defaultPageBuilder( + // context, + // const StoryPage(), + // ), + // redirect: loggedOutRedirect, + // routes: [ + // GoRoute( + // path: 'share', + // pageBuilder: (context, state) => defaultPageBuilder( + // context, + // const AddStoryPage(), + // ), + // redirect: loggedOutRedirect, + // ), + // ], + // ), + // Pangea# GoRoute( path: 'archive', pageBuilder: (context, state) => defaultPageBuilder( @@ -167,7 +250,10 @@ abstract class AppRoutes { redirect: loggedOutRedirect, ), GoRoute( - path: 'newgroup', + // #Pangea + // path: 'newgroup', + path: 'newgroup/:spaceid', + // Pangea# pageBuilder: (context, state) => defaultPageBuilder( context, const NewGroup(), @@ -182,6 +268,32 @@ abstract class AppRoutes { ), redirect: loggedOutRedirect, ), + // #Pangea + GoRoute( + path: 'newspace/:newexchange', + pageBuilder: (context, state) => defaultPageBuilder( + context, + const NewSpace(), + ), + redirect: loggedOutRedirect, + ), + GoRoute( + path: 'join_exchange/:exchangeid', + pageBuilder: (context, state) => defaultPageBuilder( + context, + const AddExchangeToClass(), + ), + redirect: loggedOutRedirect, + ), + GoRoute( + path: 'partner', + pageBuilder: (context, state) => defaultPageBuilder( + context, + const FindPartner(), + ), + redirect: loggedOutRedirect, + ), + // Pangea# ShellRoute( pageBuilder: (context, state, child) => defaultPageBuilder( context, @@ -244,24 +356,26 @@ abstract class AppRoutes { ], redirect: loggedOutRedirect, ), - GoRoute( - path: 'addaccount', - redirect: loggedOutRedirect, - pageBuilder: (context, state) => defaultPageBuilder( - context, - const HomeserverPicker(), - ), - routes: [ - GoRoute( - path: 'login', - pageBuilder: (context, state) => defaultPageBuilder( - context, - const Login(), - ), - redirect: loggedOutRedirect, - ), - ], - ), + // #Pangea + // GoRoute( + // path: 'addaccount', + // redirect: loggedOutRedirect, + // pageBuilder: (context, state) => defaultPageBuilder( + // context, + // const HomeserverPicker(), + // ), + // routes: [ + // GoRoute( + // path: 'login', + // pageBuilder: (context, state) => defaultPageBuilder( + // context, + // const Login(), + // ), + // redirect: loggedOutRedirect, + // ), + // ], + // ), + // Pangea# GoRoute( path: 'security', redirect: loggedOutRedirect, @@ -296,6 +410,24 @@ abstract class AppRoutes { ), ], ), + // #Pangea + GoRoute( + path: 'learning', + pageBuilder: (context, state) => defaultPageBuilder( + context, + const SettingsLearning(), + ), + redirect: loggedOutRedirect, + ), + GoRoute( + path: 'subscription', + pageBuilder: (context, state) => defaultPageBuilder( + context, + const SubscriptionManagement(), + ), + redirect: loggedOutRedirect, + ), + // Pangea# ], redirect: loggedOutRedirect, ), @@ -309,14 +441,16 @@ abstract class AppRoutes { ), redirect: loggedOutRedirect, routes: [ - GoRoute( - path: 'encryption', - pageBuilder: (context, state) => defaultPageBuilder( - context, - const ChatEncryptionSettings(), - ), - redirect: loggedOutRedirect, - ), + // #Pangea + // GoRoute( + // path: 'encryption', + // pageBuilder: (context, state) => defaultPageBuilder( + // context, + // const ChatEncryptionSettings(), + // ), + // redirect: loggedOutRedirect, + // ), + // Pangea# GoRoute( path: 'invite', pageBuilder: (context, state) => defaultPageBuilder( @@ -354,6 +488,16 @@ abstract class AppRoutes { ), redirect: loggedOutRedirect, ), + // #Pangea + GoRoute( + path: 'class_settings', + pageBuilder: (context, state) => defaultPageBuilder( + context, + const ClassSettingsPage(), + ), + redirect: loggedOutRedirect, + ), + // Pangea# GoRoute( path: 'invite', pageBuilder: (context, state) => defaultPageBuilder( @@ -391,6 +535,19 @@ abstract class AppRoutes { ], redirect: loggedOutRedirect, ), + // #Pangea + // GoRoute( + // path: 'tasks', + // pageBuilder: (context, state) => defaultPageBuilder( + // context, + // TasksPage( + // room: Matrix.of(context) + // .client + // .getRoomById(state.pathParameters['roomid']!)!, + // ), + // ), + // ), + // Pangea# ], ), ], diff --git a/lib/config/setting_keys.dart b/lib/config/setting_keys.dart index 14bc6da3c..e7ef76596 100644 --- a/lib/config/setting_keys.dart +++ b/lib/config/setting_keys.dart @@ -5,8 +5,6 @@ abstract class SettingKeys { static const String hideUnknownEvents = 'chat.fluffy.hideUnknownEvents'; static const String hideUnimportantStateEvents = 'chat.fluffy.hideUnimportantStateEvents'; - static const String showDirectChatsInSpaces = - 'chat.fluffy.showDirectChatsInSpaces'; static const String separateChatTypes = 'chat.fluffy.separateChatTypes'; static const String sentry = 'sentry'; static const String theme = 'theme'; diff --git a/lib/config/themes.dart b/lib/config/themes.dart index f03c74d4f..4615eae9c 100644 --- a/lib/config/themes.dart +++ b/lib/config/themes.dart @@ -1,3 +1,4 @@ +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -140,6 +141,11 @@ abstract class FluffyThemes { ), ), ), + // #Pangea + cupertinoOverrideTheme: const CupertinoThemeData( + textTheme: CupertinoTextThemeData(), + ), + // Pangea# ); } } diff --git a/lib/main.dart b/lib/main.dart index 1adfa077c..f2123f915 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,12 +1,20 @@ import 'package:flutter/material.dart'; import 'package:collection/collection.dart'; +import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; +import 'package:get_storage/get_storage.dart'; import 'package:matrix/matrix.dart'; +import 'package:shared_preferences/shared_preferences.dart'; import 'package:fluffychat/config/app_config.dart'; +import 'package:fluffychat/pangea/config/environment.dart'; +import 'package:fluffychat/pangea/controllers/language_list_controller.dart'; +import 'package:fluffychat/pangea/utils/error_handler.dart'; +import 'package:fluffychat/pangea/utils/firebase_analytics.dart'; import 'package:fluffychat/utils/client_manager.dart'; import 'package:fluffychat/utils/platform_infos.dart'; +import 'package:fluffychat/widgets/error_widget.dart'; import 'config/setting_keys.dart'; import 'utils/background_push.dart'; import 'widgets/fluffy_chat_app.dart'; @@ -14,24 +22,47 @@ import 'widgets/fluffy_chat_app.dart'; void main() async { Logs().i('Welcome to ${AppConfig.applicationName} <3'); + // #Pangea + await dotenv.load(fileName: Environment.fileName); + + await Future.wait([ + ErrorHandler.initialize(), + PangeaLanguage.initialize(), + GoogleAnalytics.initialize(), + ]); + + /// + /// PangeaLanguage must be initialized before the runApp + /// Then where ever you need language functions simply call PangeaLanguage pangeaLanguage = PangeaLanguage() + /// pangeaLanguage.getList or whatever function you need + /// + await GetStorage.init(); + // Pangea# + // Our background push shared isolate accesses flutter-internal things very early in the startup proccess // To make sure that the parts of flutter needed are started up already, we need to ensure that the // widget bindings are initialized already. WidgetsFlutterBinding.ensureInitialized(); Logs().nativeColors = !PlatformInfos.isIOS; - final clients = await ClientManager.getClients(); + final store = await SharedPreferences.getInstance(); + final clients = await ClientManager.getClients(store: store); // If the app starts in detached mode, we assume that it is in // background fetch mode for processing push notifications. This is // currently only supported on Android. if (PlatformInfos.isAndroid && AppLifecycleState.detached == WidgetsBinding.instance.lifecycleState) { + // Do not send online presences when app is in background fetch mode. + for (final client in clients) { + client.syncPresence = PresenceType.offline; + } + // In the background fetch mode we do not want to waste ressources with // starting the Flutter engine but process incoming push notifications. BackgroundPush.clientOnly(clients.first); // To start the flutter engine afterwards we add an custom observer. - WidgetsBinding.instance.addObserver(AppStarter(clients)); + WidgetsBinding.instance.addObserver(AppStarter(clients, store)); Logs().i( '${AppConfig.applicationName} started in background-fetch mode. No GUI will be created unless the app is no longer detached.', ); @@ -42,11 +73,11 @@ void main() async { Logs().i( '${AppConfig.applicationName} started in foreground mode. Rendering GUI...', ); - await startGui(clients); + await startGui(clients, store); } /// Fetch the pincode for the applock and start the flutter engine. -Future startGui(List clients) async { +Future startGui(List clients, SharedPreferences store) async { // Fetch the pin for the applock if existing for mobile applications. String? pin; if (PlatformInfos.isMobile) { @@ -63,16 +94,18 @@ Future startGui(List clients) async { await firstClient?.roomsLoading; await firstClient?.accountDataLoading; - runApp(FluffyChatApp(clients: clients, pincode: pin)); + ErrorWidget.builder = (details) => FluffyChatErrorWidget(details); + runApp(FluffyChatApp(clients: clients, pincode: pin, store: store)); } /// Watches the lifecycle changes to start the application when it /// is no longer detached. class AppStarter with WidgetsBindingObserver { final List clients; + final SharedPreferences store; bool guiStarted = false; - AppStarter(this.clients); + AppStarter(this.clients, this.store); @override void didChangeAppLifecycleState(AppLifecycleState state) { @@ -82,7 +115,11 @@ class AppStarter with WidgetsBindingObserver { Logs().i( '${AppConfig.applicationName} switches from the detached background-fetch mode to ${state.name} mode. Rendering GUI...', ); - startGui(clients); + // Switching to foreground mode needs to reenable send online sync presence. + for (final client in clients) { + client.syncPresence = PresenceType.online; + } + startGui(clients, store); // We must make sure that the GUI is only started once. guiStarted = true; } diff --git a/lib/pages/add_story/add_story.dart b/lib/pages/add_story/add_story.dart index 323d103b4..6f96fdf64 100644 --- a/lib/pages/add_story/add_story.dart +++ b/lib/pages/add_story/add_story.dart @@ -22,7 +22,7 @@ import 'package:fluffychat/widgets/matrix.dart'; import '../../utils/matrix_sdk_extensions/client_stories_extension.dart'; class AddStoryPage extends StatefulWidget { - const AddStoryPage({Key? key}) : super(key: key); + const AddStoryPage({super.key}); @override AddStoryController createState() => AddStoryController(); diff --git a/lib/pages/add_story/add_story_view.dart b/lib/pages/add_story/add_story_view.dart index 12f7dad26..ea828aadf 100644 --- a/lib/pages/add_story/add_story_view.dart +++ b/lib/pages/add_story/add_story_view.dart @@ -8,7 +8,7 @@ import 'add_story.dart'; class AddStoryView extends StatelessWidget { final AddStoryController controller; - const AddStoryView(this.controller, {Key? key}) : super(key: key); + const AddStoryView(this.controller, {super.key}); @override Widget build(BuildContext context) { diff --git a/lib/pages/add_story/invite_story_page.dart b/lib/pages/add_story/invite_story_page.dart index c28af4416..c62a0b815 100644 --- a/lib/pages/add_story/invite_story_page.dart +++ b/lib/pages/add_story/invite_story_page.dart @@ -14,8 +14,8 @@ class InviteStoryPage extends StatefulWidget { final Room? storiesRoom; const InviteStoryPage({ required this.storiesRoom, - Key? key, - }) : super(key: key); + super.key, + }); @override InviteStoryPageState createState() => InviteStoryPageState(); diff --git a/lib/pages/archive/archive.dart b/lib/pages/archive/archive.dart index 823fe8362..a3c35c347 100644 --- a/lib/pages/archive/archive.dart +++ b/lib/pages/archive/archive.dart @@ -9,24 +9,36 @@ import 'package:fluffychat/pages/archive/archive_view.dart'; import 'package:fluffychat/widgets/matrix.dart'; class Archive extends StatefulWidget { - const Archive({Key? key}) : super(key: key); + const Archive({super.key}); @override ArchiveController createState() => ArchiveController(); } class ArchiveController extends State { - List? archive; + List archive = []; Future> getArchive(BuildContext context) async { - final archive = this.archive; - if (archive != null) return archive; - return this.archive = await Matrix.of(context).client.loadArchive(); + if (archive.isNotEmpty) return archive; + return archive = await Matrix.of(context).client.loadArchive(); + } + + void forgetRoomAction(int i) async { + await showFutureLoadingDialog( + context: context, + future: () async { + Logs().v('Forget room ${archive.last.getLocalizedDisplayname()}'); + await archive[i].forget(); + archive.removeAt(i); + }, + ); + setState(() {}); } void forgetAllAction() async { final archive = this.archive; - if (archive == null) return; + final client = Matrix.of(context).client; + if (archive.isEmpty) return; if (await showOkCancelAlertDialog( useRootNavigator: false, context: context, @@ -48,6 +60,7 @@ class ArchiveController extends State { } }, ); + client.clearArchivesFromCache(); setState(() {}); } diff --git a/lib/pages/archive/archive_view.dart b/lib/pages/archive/archive_view.dart index d0df690b8..fc5c3e250 100644 --- a/lib/pages/archive/archive_view.dart +++ b/lib/pages/archive/archive_view.dart @@ -10,11 +10,10 @@ import 'package:fluffychat/widgets/layouts/max_width_body.dart'; class ArchiveView extends StatelessWidget { final ArchiveController controller; - const ArchiveView(this.controller, {Key? key}) : super(key: key); + const ArchiveView(this.controller, {super.key}); @override Widget build(BuildContext context) { - var archive = controller.archive; return FutureBuilder>( future: controller.getArchive(context), builder: (BuildContext context, snapshot) => Scaffold( @@ -50,16 +49,16 @@ class ArchiveView extends StatelessWidget { child: CircularProgressIndicator.adaptive(strokeWidth: 2), ); } else { - archive = snapshot.data; - if (archive == null || archive!.isEmpty) { + if (controller.archive.isEmpty) { return const Center( child: Icon(Icons.archive_outlined, size: 80), ); } return ListView.builder( - itemCount: archive!.length, + itemCount: controller.archive.length, itemBuilder: (BuildContext context, int i) => ChatListItem( - archive![i], + controller.archive[i], + onForget: () => controller.forgetRoomAction(i), ), ); } diff --git a/lib/pages/bootstrap/bootstrap_dialog.dart b/lib/pages/bootstrap/bootstrap_dialog.dart index 20128b069..8a227cb03 100644 --- a/lib/pages/bootstrap/bootstrap_dialog.dart +++ b/lib/pages/bootstrap/bootstrap_dialog.dart @@ -18,10 +18,10 @@ class BootstrapDialog extends StatefulWidget { final bool wipe; final Client client; const BootstrapDialog({ - Key? key, + super.key, this.wipe = false, required this.client, - }) : super(key: key); + }); Future show(BuildContext context) => showAdaptiveBottomSheet( context: context, diff --git a/lib/pages/chat/add_widget_tile.dart b/lib/pages/chat/add_widget_tile.dart index 89ad8976d..11e3cce5d 100644 --- a/lib/pages/chat/add_widget_tile.dart +++ b/lib/pages/chat/add_widget_tile.dart @@ -8,7 +8,7 @@ import 'package:fluffychat/pages/chat/add_widget_tile_view.dart'; class AddWidgetTile extends StatefulWidget { final Room room; - const AddWidgetTile({Key? key, required this.room}) : super(key: key); + const AddWidgetTile({super.key, required this.room}); @override State createState() => AddWidgetTileState(); diff --git a/lib/pages/chat/add_widget_tile_view.dart b/lib/pages/chat/add_widget_tile_view.dart index 7ce441e84..d7ac53ef2 100644 --- a/lib/pages/chat/add_widget_tile_view.dart +++ b/lib/pages/chat/add_widget_tile_view.dart @@ -8,8 +8,7 @@ import 'package:fluffychat/pages/chat/add_widget_tile.dart'; class AddWidgetTileView extends StatelessWidget { final AddWidgetTileState controller; - const AddWidgetTileView({Key? key, required this.controller}) - : super(key: key); + const AddWidgetTileView({super.key, required this.controller}); @override Widget build(BuildContext context) { diff --git a/lib/pages/chat/chat.dart b/lib/pages/chat/chat.dart index e17226fae..bfadb1f16 100644 --- a/lib/pages/chat/chat.dart +++ b/lib/pages/chat/chat.dart @@ -1,6 +1,8 @@ import 'dart:async'; +import 'dart:developer'; import 'dart:io'; +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/scheduler.dart'; import 'package:flutter/services.dart'; @@ -25,6 +27,19 @@ import 'package:fluffychat/pages/chat/chat_view.dart'; import 'package:fluffychat/pages/chat/event_info_dialog.dart'; import 'package:fluffychat/pages/chat/recording_dialog.dart'; import 'package:fluffychat/pages/chat_details/chat_details.dart'; +import 'package:fluffychat/pangea/choreographer/controllers/choreographer.dart'; +import 'package:fluffychat/pangea/controllers/pangea_controller.dart'; +import 'package:fluffychat/pangea/enum/use_type.dart'; +import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart'; +import 'package:fluffychat/pangea/models/choreo_record.dart'; +import 'package:fluffychat/pangea/models/class_model.dart'; +import 'package:fluffychat/pangea/models/message_data_models.dart'; +import 'package:fluffychat/pangea/models/student_analytics_summary_model.dart'; +import 'package:fluffychat/pangea/utils/error_handler.dart'; +import 'package:fluffychat/pangea/utils/firebase_analytics.dart'; +import 'package:fluffychat/pangea/utils/instructions.dart'; +import 'package:fluffychat/pangea/utils/report_message.dart'; +import 'package:fluffychat/pangea/widgets/igc/pangea_text_controller.dart'; import 'package:fluffychat/utils/adaptive_bottom_sheet.dart'; import 'package:fluffychat/utils/error_reporter.dart'; import 'package:fluffychat/utils/matrix_sdk_extensions/event_extension.dart'; @@ -43,9 +58,9 @@ class ChatPage extends StatelessWidget { final String roomId; const ChatPage({ - Key? key, + super.key, required this.roomId, - }) : super(key: key); + }); @override Widget build(BuildContext context) { @@ -95,15 +110,19 @@ class ChatPageWithRoom extends StatefulWidget { final Room room; const ChatPageWithRoom({ - Key? key, + super.key, required this.room, - }) : super(key: key); + }); @override ChatController createState() => ChatController(); } class ChatController extends State { + // #Pangea + final PangeaController pangeaController = MatrixState.pangeaController; + late Choreographer choreographer = Choreographer(pangeaController, this); + // Pangea# Room get room => sendingClient.getRoomById(roomId) ?? widget.room; late Client sendingClient; @@ -148,10 +167,12 @@ class ChatController extends State { ).detectFileType, ); } + // #Pangea + if (matrixFiles.isEmpty) return; + // Pangea# - await showDialog( + await showAdaptiveDialog( context: context, - useRootNavigator: false, builder: (c) => SendFileDialog( files: matrixFiles, room: room, @@ -210,7 +231,10 @@ class ChatController extends State { .firstWhere((s) => s.rooms?.leave?.containsKey(room.id) ?? false); await room.leave(); await waitForSync; - return await client.startDirectChat(userId); + //#Pangea + // return await client.startDirectChat(userId); + return await client.startDirectChat(userId, enableEncryption: false); + //Pangea# }, ); final roomId = success.result; @@ -229,7 +253,10 @@ class ChatController extends State { EmojiPickerType emojiPickerType = EmojiPickerType.keyboard; - void requestHistory() async { + // #Pangea + // void requestHistory() async { + Future requestHistory() async { + // #Pangea if (!timeline!.canRequestHistory) return; Logs().v('Requesting history...'); try { @@ -276,9 +303,19 @@ class ChatController extends State { if (timeline?.allowNewEvent == false || scrollController.position.pixels > 0 && _scrolledUp == false) { setState(() => _scrolledUp = true); - } else if (scrollController.position.pixels == 0 && _scrolledUp == true) { + } else if (scrollController.position.pixels <= 0 && _scrolledUp == true) { setState(() => _scrolledUp = false); } + + if (scrollController.position.pixels == 0 || + scrollController.position.pixels == 64) { + requestFuture(); + } else if (scrollController.position.pixels == + scrollController.position.maxScrollExtent || + scrollController.position.pixels + 64 == + scrollController.position.maxScrollExtent) { + requestHistory(); + } } void _loadDraft() async { @@ -290,6 +327,10 @@ class ChatController extends State { } } + // #Pangea + bool showPermissionsError = false; + // #Pangea + @override void initState() { scrollController.addListener(_updateScrollController); @@ -297,6 +338,47 @@ class ChatController extends State { _loadDraft(); super.initState(); sendingClient = Matrix.of(context).client; + // #Pangea + if (!mounted) return; + Future.delayed(const Duration(seconds: 1), () async { + if (!mounted) return; + debugPrint( + "chat.dart l1 ${pangeaController.languageController.activeL1Code(roomID: roomId)}", + ); + debugPrint( + "chat.dart l2 ${pangeaController.languageController.activeL2Code(roomID: roomId)}", + ); + if (mounted) { + pangeaController.languageController.showDialogOnEmptyLanguage( + context, + () => Future.delayed( + Duration.zero, + () => setState( + () {}, + ), + ), + ); + } + await Matrix.of(context).client.roomsLoading; + choreographer.setRoomId(roomId); + choreographer.messageOptions.resetSelectedDisplayLang(); + choreographer.stateListener.stream.listen((event) { + debugPrint("chat.dart choreo event $event"); + setState(() {}); + }); + showPermissionsError = !pangeaController.permissionsController + .isToolEnabled(ToolSetting.interactiveTranslator, room) || + !pangeaController.permissionsController + .isToolEnabled(ToolSetting.interactiveGrammar, room); + }); + + Future.delayed( + const Duration(seconds: 5), + () { + if (mounted) setState(() => showPermissionsError = false); + }, + ); + // Pangea# _tryLoadTimeline(); } @@ -351,6 +433,27 @@ class ChatController extends State { onUpdate: updateView, eventContextId: eventContextId, ); + // #Pangea + List? messageEvents = + timeline?.events.where((x) => x.type == 'm.room.message').toList(); + if (messageEvents != null && messageEvents.length < 10) { + int prevNumEvents = timeline!.events.length; + await requestHistory(); + messageEvents = + timeline?.events.where((x) => x.type == 'm.room.message').toList(); + int numRequests = 0; + while (timeline!.events.length > prevNumEvents && + messageEvents!.length < 10 && + numRequests <= 5) { + prevNumEvents = timeline!.events.length; + await requestHistory(); + messageEvents = timeline?.events + .where((x) => x.type == 'm.room.message') + .toList(); + numRequests++; + } + } + // #Pangea } catch (e, s) { Logs().w('Unable to load timeline on event ID $eventContextId', e, s); if (!mounted) return; @@ -408,10 +511,17 @@ class ChatController extends State { timeline?.cancelSubscriptions(); timeline = null; inputFocus.removeListener(_inputFocusListener); + //#Pangea + choreographer.stateListener.close(); + choreographer.dispose(); + //Pangea# super.dispose(); } - TextEditingController sendController = TextEditingController(); + // #Pangea + // TextEditingController sendController = TextEditingController(); + PangeaTextController get sendController => choreographer.textController; + // #Pangea void setSendingClient(Client c) { // first cancel typing with the old sending client @@ -439,7 +549,20 @@ class ChatController extends State { Matrix.of(context).setActiveClient(c); }); - Future send() async { + // #Pangea + // Future send() async { + // Original send function gets the tx id within the matrix lib, + // but for choero, the tx id is generated before the message send. + // Also, adding PangeaMessageData + Future send({ + PangeaRepresentation? originalSent, + PangeaRepresentation? originalWritten, + PangeaMessageTokens? tokensSent, + PangeaMessageTokens? tokensWritten, + ChoreoRecord? choreo, + UseType? useType, + }) async { + // Pangea# if (sendController.text.trim().isEmpty) return; _storeInputTimeoutTimer?.cancel(); final prefs = await SharedPreferences.getInstance(); @@ -452,7 +575,6 @@ class ChatController extends State { final l10n = L10n.of(context)!; final dialogResult = await showOkCancelAlertDialog( context: context, - useRootNavigator: false, title: l10n.commandInvalid, message: l10n.commandMissing(commandMatch[0]!), okLabel: l10n.sendAsText, @@ -463,12 +585,70 @@ class ChatController extends State { } // ignore: unawaited_futures - room.sendTextEvent( + // #Pangea + // room.sendTextEvent( + // sendController.text, + // inReplyTo: replyEvent, + // editEventId: editEvent?.eventId, + // parseCommands: parseCommands, + // ); + room + .pangeaSendTextEvent( sendController.text, inReplyTo: replyEvent, editEventId: editEvent?.eventId, parseCommands: parseCommands, + originalSent: originalSent, + originalWritten: originalWritten, + tokensSent: tokensSent, + tokensWritten: tokensWritten, + choreo: choreo, + useType: useType, + ) + //#Pangea + .then( + (String? msgEventId) { + GoogleAnalytics.sendMessage( + room.id, + room.classCode, + useType ?? UseType.un, + ); + + if (msgEventId == null) { + ErrorHandler.logError( + e: Exception('msgEventId is null'), + s: StackTrace.current, + ); + return; + } + + pangeaController.myAnalytics.handleMessage( + room, + RecentMessageRecord( + eventId: msgEventId, + chatId: room.id, + useType: useType ?? UseType.un, + time: DateTime.now(), + ), + ); + + if (choreo != null && + tokensSent != null && + originalSent?.langCode == + pangeaController.languageController + .activeL2Code(roomID: room.id)) { + pangeaController.myAnalytics.saveConstructsMixed( + [ + // ...choreo.toVocabUse(tokensSent.tokens, room.id, msgEventId), + ...choreo.toGrammarConstructUse(msgEventId, room.id), + ], + originalSent!.langCode, + ); + } + }, + onError: (err, stack) => ErrorHandler.logError(e: err, s: stack), ); + // Pangea# sendController.value = TextEditingValue( text: pendingText, selection: const TextSelection.collapsed(offset: 0), @@ -485,14 +665,13 @@ class ChatController extends State { void sendFileAction() async { final result = await AppLock.of(context).pauseWhile( FilePicker.platform.pickFiles( - allowMultiple: true, + allowMultiple: false, withData: true, ), ); if (result == null || result.files.isEmpty) return; - await showDialog( + await showAdaptiveDialog( context: context, - useRootNavigator: false, builder: (c) => SendFileDialog( files: result.files .map( @@ -508,9 +687,8 @@ class ChatController extends State { } void sendImageFromClipBoard(Uint8List? image) async { - await showDialog( + await showAdaptiveDialog( context: context, - useRootNavigator: false, builder: (c) => SendFileDialog( files: [ MatrixFile( @@ -524,19 +702,17 @@ class ChatController extends State { } void sendImageAction() async { - //AppLock.of(context).pauseWhile(); final result = await AppLock.of(context).pauseWhile( FilePicker.platform.pickFiles( type: FileType.image, withData: true, - allowMultiple: true, + allowMultiple: false, ), ); if (result == null || result.files.isEmpty) return; - await showDialog( + await showAdaptiveDialog( context: context, - useRootNavigator: false, builder: (c) => SendFileDialog( files: result.files .map( @@ -557,9 +733,8 @@ class ChatController extends State { final file = await ImagePicker().pickImage(source: ImageSource.camera); if (file == null) return; final bytes = await file.readAsBytes(); - await showDialog( + await showAdaptiveDialog( context: context, - useRootNavigator: false, builder: (c) => SendFileDialog( files: [ MatrixImageFile( @@ -575,12 +750,14 @@ class ChatController extends State { void openVideoCameraAction() async { // Make sure the textfield is unfocused before opening the camera FocusScope.of(context).requestFocus(FocusNode()); - final file = await ImagePicker().pickVideo(source: ImageSource.camera); + final file = await ImagePicker().pickVideo( + source: ImageSource.camera, + maxDuration: const Duration(minutes: 1), + ); if (file == null) return; final bytes = await file.readAsBytes(); - await showDialog( + await showAdaptiveDialog( context: context, - useRootNavigator: false, builder: (c) => SendFileDialog( files: [ MatrixVideoFile( @@ -629,7 +806,6 @@ class ChatController extends State { if (await Record().hasPermission() == false) return; final result = await showDialog( context: context, - useRootNavigator: false, barrierDismissible: false, builder: (c) => const RecordingDialog(), ); @@ -669,6 +845,11 @@ class ChatController extends State { } void emojiPickerAction() { + // #Pangea + if (choreographer.itController.isOpen) { + return; + } + // Pangea# if (showEmojiPicker) { inputFocus.requestFocus(); } else { @@ -686,9 +867,8 @@ class ChatController extends State { } void sendLocationAction() async { - await showDialog( + await showAdaptiveDialog( context: context, - useRootNavigator: false, builder: (c) => SendLocationDialog(room: room), ); } @@ -743,7 +923,6 @@ class ChatController extends State { ); if (score == null) return; final reason = await showTextInputDialog( - useRootNavigator: false, context: context, title: L10n.of(context)!.whyDoYouWantToReportThis, okLabel: L10n.of(context)!.ok, @@ -751,16 +930,36 @@ class ChatController extends State { textFields: [DialogTextField(hintText: L10n.of(context)!.reason)], ); if (reason == null || reason.single.isEmpty) return; - final result = await showFutureLoadingDialog( - context: context, - future: () => Matrix.of(context).client.reportContent( - event.roomId!, - event.eventId, - reason: reason.single, - score: score, + // #Pangea + try { + await reportMessage( + context, + roomId, + reason.single, + event.senderId, + event.content['body'].toString(), + ); + } catch (err) { + ErrorHandler.logError(e: err, s: StackTrace.current); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text( + L10n.of(context)!.oopsSomethingWentWrong, ), - ); - if (result.error != null) return; + ), + ); + } + // final result = await showFutureLoadingDialog( + // context: context, + // future: () => Matrix.of(context).client.reportContent( + // event.roomId!, + // event.eventId, + // reason: reason.single, + // score: score, + // ), + // ); + // if (result.error != null) return; + // Pangea# setState(() { showEmojiPicker = false; selectedEvents.clear(); @@ -770,6 +969,25 @@ class ChatController extends State { ); } + void deleteErrorEventsAction() async { + try { + if (selectedEvents.any((event) => event.status != EventStatus.error)) { + throw Exception( + 'Tried to delete failed to send events but one event is not failed to sent', + ); + } + for (final event in selectedEvents) { + await event.remove(); + } + setState(selectedEvents.clear); + } catch (e, s) { + ErrorReporter( + context, + 'Error while delete error events action', + ).onErrorCallback(e, s); + } + } + void redactEventsAction() async { final reasonInput = selectedEvents.any((event) => event.status.isSent) ? await showTextInputDialog( @@ -830,6 +1048,7 @@ class ChatController extends State { if (isArchived) return false; final clients = Matrix.of(context).currentBundle; for (final event in selectedEvents) { + if (!event.status.isSent) return false; if (event.canRedact == false && !(clients!.any((cl) => event.senderId == cl!.userID))) return false; } @@ -843,8 +1062,7 @@ class ChatController extends State { !selectedEvents.single.status.isSent) { return false; } - return currentRoomBundle - .any((cl) => selectedEvents.first.senderId == cl!.userID); + return true; } bool get canEditSelectedEvents { @@ -912,7 +1130,7 @@ class ChatController extends State { } await scrollController.scrollToIndex( eventIndex, - preferPosition: AutoScrollPosition.end, + preferPosition: AutoScrollPosition.middle, ); _updateScrollController(); } @@ -957,15 +1175,6 @@ class ChatController extends State { return sendEmojiAction(emoji.emoji); } - void forgetRoom() async { - final result = await showFutureLoadingDialog( - context: context, - future: room.forget, - ); - if (result.error != null) return; - context.go('/rooms/archive'); - } - void typeEmoji(Emoji? emoji) { if (emoji == null) return; final text = sendController.text; @@ -1019,6 +1228,9 @@ class ChatController extends State { void clearSelectedEvents() => setState(() { selectedEvents.clear(); showEmojiPicker = false; + //#Pangea + choreographer.messageOptions.resetSelectedDisplayLang(); + //Pangea# }); void clearSingleSelectedEvent() { @@ -1053,7 +1265,6 @@ class ChatController extends State { void goToNewRoomAction() async { if (OkCancelResult.ok != await showOkCancelAlertDialog( - useRootNavigator: false, context: context, title: L10n.of(context)!.goToTheNewRoom, message: room @@ -1084,6 +1295,16 @@ class ChatController extends State { } void onSelectMessage(Event event) { + // #Pangea + if (choreographer.itController.isOpen) { + return; + } + pangeaController.instructions.show( + context, + InstructionsEnum.understandingMessages, + event.eventId, + ); + // Pangea# if (!event.redacted) { if (selectedEvents.contains(event)) { setState( @@ -1118,12 +1339,22 @@ class ChatController extends State { return index + 1; } - void onInputBarSubmitted(_) { - send(); + // #Pangea + void onInputBarSubmitted(String _, BuildContext context) { + // void onInputBarSubmitted(_) { + // send(); + choreographer.send(context); + // Pangea# FocusScope.of(context).requestFocus(inputFocus); } - void onAddPopupMenuButtonSelected(String choice) { + //#Pangea + void onAddPopupMenuButtonSelected(String? choice) { + // void onAddPopupMenuButtonSelected(String choice) { + if (choice == null) { + debugger(when: kDebugMode); + } + //Pangea# if (choice == 'file') { sendFileAction(); } @@ -1285,7 +1516,6 @@ class ChatController extends State { context: context, title: L10n.of(context)!.unavailable, okLabel: L10n.of(context)!.next, - useRootNavigator: false, ); } } @@ -1299,6 +1529,37 @@ class ChatController extends State { editEvent = null; }); + // #Pangea + double? availableSpace; + double? inputRowSize; + bool? lastState; + bool get isRowScrollable { + if (availableSpace == null || inputRowSize == null) { + if (lastState == null) { + lastState = false; + Future.delayed(Duration.zero, () { + setState(() {}); + }); + } + return false; + } + const double offSetValue = 10; + final bool currentState = inputRowSize! > (availableSpace! - offSetValue); + if (!lastState! && currentState) { + Future.delayed(Duration.zero, () { + setState(() {}); + }); + } + if (lastState! && !currentState) { + Future.delayed(Duration.zero, () { + setState(() {}); + }); + } + lastState = currentState; + return currentState; + } + // #Pangea + @override Widget build(BuildContext context) => ChatView(this); } diff --git a/lib/pages/chat/chat_app_bar_title.dart b/lib/pages/chat/chat_app_bar_title.dart index ae659fa06..1cb84b48e 100644 --- a/lib/pages/chat/chat_app_bar_title.dart +++ b/lib/pages/chat/chat_app_bar_title.dart @@ -3,13 +3,16 @@ import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:go_router/go_router.dart'; +import 'package:fluffychat/config/themes.dart'; import 'package:fluffychat/pages/chat/chat.dart'; +import 'package:fluffychat/utils/date_time_extension.dart'; import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart'; import 'package:fluffychat/widgets/avatar.dart'; +import 'package:fluffychat/widgets/presence_builder.dart'; class ChatAppBarTitle extends StatelessWidget { final ChatController controller; - const ChatAppBarTitle(this.controller, {Key? key}) : super(key: key); + const ChatAppBarTitle(this.controller, {super.key}); @override Widget build(BuildContext context) { @@ -34,17 +37,48 @@ class ChatAppBarTitle extends StatelessWidget { MatrixLocals(L10n.of(context)!), ), size: 32, + presenceUserId: room.directChatMatrixID, ), ), const SizedBox(width: 12), Expanded( - child: Text( - room.getLocalizedDisplayname(MatrixLocals(L10n.of(context)!)), - maxLines: 1, - overflow: TextOverflow.ellipsis, - style: const TextStyle( - fontSize: 16, - ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + room.getLocalizedDisplayname(MatrixLocals(L10n.of(context)!)), + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontSize: 16, + ), + ), + AnimatedSize( + duration: FluffyThemes.animationDuration, + child: PresenceBuilder( + userId: room.directChatMatrixID, + builder: (context, presence) { + final lastActiveTimestamp = presence?.lastActiveTimestamp; + final style = Theme.of(context).textTheme.bodySmall; + if (presence?.currentlyActive == true) { + return Text( + L10n.of(context)!.currentlyActive, + style: style, + ); + } + if (lastActiveTimestamp != null) { + return Text( + L10n.of(context)!.lastActiveAgo( + lastActiveTimestamp.localizedTimeShort(context), + ), + style: style, + ); + } + return const SizedBox.shrink(); + }, + ), + ), + ], ), ), ], diff --git a/lib/pages/chat/chat_emoji_picker.dart b/lib/pages/chat/chat_emoji_picker.dart index aaad97403..5e45113be 100644 --- a/lib/pages/chat/chat_emoji_picker.dart +++ b/lib/pages/chat/chat_emoji_picker.dart @@ -8,7 +8,7 @@ import 'chat.dart'; class ChatEmojiPicker extends StatelessWidget { final ChatController controller; - const ChatEmojiPicker(this.controller, {Key? key}) : super(key: key); + const ChatEmojiPicker(this.controller, {super.key}); @override Widget build(BuildContext context) { @@ -33,10 +33,7 @@ class ChatEmojiPicker extends StatelessWidget { iconColor: theme.colorScheme.primary.withOpacity(0.5), iconColorSelected: theme.colorScheme.primary, indicatorColor: theme.colorScheme.primary, - noRecents: Text( - L10n.of(context)!.emoteKeyboardNoRecents, - style: theme.textTheme.bodyLarge, - ), + noRecents: const NoRecent(), skinToneDialogBgColor: Color.lerp( theme.colorScheme.background, theme.colorScheme.primaryContainer, @@ -49,3 +46,15 @@ class ChatEmojiPicker extends StatelessWidget { ); } } + +class NoRecent extends StatelessWidget { + const NoRecent({super.key}); + + @override + Widget build(BuildContext context) { + return Text( + L10n.of(context)!.emoteKeyboardNoRecents, + style: Theme.of(context).textTheme.bodyLarge, + ); + } +} diff --git a/lib/pages/chat/chat_event_list.dart b/lib/pages/chat/chat_event_list.dart index 85cf557a2..4f83f18e6 100644 --- a/lib/pages/chat/chat_event_list.dart +++ b/lib/pages/chat/chat_event_list.dart @@ -1,3 +1,5 @@ +// Flutter imports: + import 'package:flutter/material.dart'; import 'package:matrix/matrix.dart'; @@ -9,6 +11,8 @@ import 'package:fluffychat/pages/chat/events/message.dart'; import 'package:fluffychat/pages/chat/seen_by_row.dart'; import 'package:fluffychat/pages/chat/typing_indicators.dart'; import 'package:fluffychat/pages/user_bottom_sheet/user_bottom_sheet.dart'; +import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart'; +import 'package:fluffychat/pangea/widgets/chat/locked_chat_message.dart'; import 'package:fluffychat/utils/adaptive_bottom_sheet.dart'; import 'package:fluffychat/utils/matrix_sdk_extensions/filtered_timeline_extension.dart'; import 'package:fluffychat/utils/platform_infos.dart'; @@ -16,9 +20,9 @@ import 'package:fluffychat/utils/platform_infos.dart'; class ChatEventList extends StatelessWidget { final ChatController controller; const ChatEventList({ - Key? key, + super.key, required this.controller, - }) : super(key: key); + }); @override Widget build(BuildContext context) { @@ -31,118 +35,124 @@ class ChatEventList extends StatelessWidget { thisEventsKeyMap[controller.timeline!.events[i].eventId] = i; } - return ListView.custom( - padding: EdgeInsets.only( - top: 16, - bottom: 4, - left: horizontalPadding, - right: horizontalPadding, - ), - reverse: true, - controller: controller.scrollController, - keyboardDismissBehavior: PlatformInfos.isIOS - ? ScrollViewKeyboardDismissBehavior.onDrag - : ScrollViewKeyboardDismissBehavior.manual, - childrenDelegate: SliverChildBuilderDelegate( - (BuildContext context, int i) { - // Footer to display typing indicator and read receipts: - if (i == 0) { - if (controller.timeline!.isRequestingFuture) { - return const Center( - child: CircularProgressIndicator.adaptive(strokeWidth: 2), + return SelectionArea( + child: ListView.custom( + padding: EdgeInsets.only( + top: 16, + bottom: 4, + left: horizontalPadding, + right: horizontalPadding, + ), + reverse: true, + controller: controller.scrollController, + keyboardDismissBehavior: PlatformInfos.isIOS + ? ScrollViewKeyboardDismissBehavior.onDrag + : ScrollViewKeyboardDismissBehavior.manual, + childrenDelegate: SliverChildBuilderDelegate( + (BuildContext context, int i) { + // Footer to display typing indicator and read receipts: + if (i == 0) { + if (controller.timeline!.isRequestingFuture) { + return const Center( + child: CircularProgressIndicator.adaptive(strokeWidth: 2), + ); + } + if (controller.timeline!.canRequestFuture) { + return Center( + child: IconButton( + onPressed: controller.requestFuture, + icon: const Icon(Icons.refresh_outlined), + ), + ); + } + return Column( + mainAxisSize: MainAxisSize.min, + children: [ + SeenByRow(controller), + TypingIndicators(controller), + ], ); } - if (controller.timeline!.canRequestFuture) { - return Builder( - builder: (context) { - WidgetsBinding.instance.addPostFrameCallback( - (_) => controller.requestFuture(), - ); - return Center( - child: IconButton( - onPressed: controller.requestFuture, - icon: const Icon(Icons.refresh_outlined), - ), - ); - }, - ); - } - return Column( - mainAxisSize: MainAxisSize.min, - children: [ - SeenByRow(controller), - TypingIndicators(controller), - ], - ); - } - // Request history button or progress indicator: - if (i == controller.timeline!.events.length + 1) { - if (controller.timeline!.isRequestingHistory) { - return const Center( - child: CircularProgressIndicator.adaptive(strokeWidth: 2), - ); + // #Pangea + if (i == 1) { + return controller.room.locked && !controller.room.isRoomAdmin + ? const LockedChatMessage() + : const SizedBox.shrink(); } - if (controller.timeline!.canRequestHistory) { - return Builder( - builder: (context) { - WidgetsBinding.instance.addPostFrameCallback( - (_) => controller.requestHistory(), - ); - return Center( - child: IconButton( - onPressed: controller.requestHistory, - icon: const Icon(Icons.refresh_outlined), - ), - ); - }, - ); + // Pangea# + + // Request history button or progress indicator: + if (i == controller.timeline!.events.length + 1) { + if (controller.timeline!.isRequestingHistory) { + return const Center( + child: CircularProgressIndicator.adaptive(strokeWidth: 2), + ); + } + if (controller.timeline!.canRequestHistory) { + return Center( + child: IconButton( + onPressed: controller.requestHistory, + icon: const Icon(Icons.refresh_outlined), + ), + ); + } + return const SizedBox.shrink(); } - return const SizedBox.shrink(); - } + // The message at this index: + // #Pangea + // final event = controller.timeline!.events[i - 1]; + final event = controller.timeline!.events[i - 2]; + // Pangea# - // The message at this index: - final event = controller.timeline!.events[i - 1]; - - return AutoScrollTag( - key: ValueKey(event.eventId), - index: i - 1, - controller: controller.scrollController, - child: event.isVisibleInGui - ? Message( - event, - onSwipe: (direction) => - controller.replyAction(replyTo: event), - onInfoTab: controller.showEventInfo, - onAvatarTab: (Event event) => showAdaptiveBottomSheet( - context: context, - builder: (c) => UserBottomSheet( - user: event.senderFromMemoryOrFallback, - outerContext: context, - onMention: () => controller.sendController.text += - '${event.senderFromMemoryOrFallback.mention} ', + return AutoScrollTag( + key: ValueKey(event.eventId), + index: i - 1, + controller: controller.scrollController, + child: event.isVisibleInGui + ? Message( + event, + onSwipe: () => controller.replyAction(replyTo: event), + // #Pangea + onInfoTab: (_) => {}, + // onInfoTab: controller.showEventInfo, + // Pangea# + onAvatarTab: (Event event) => showAdaptiveBottomSheet( + context: context, + builder: (c) => UserBottomSheet( + user: event.senderFromMemoryOrFallback, + outerContext: context, + onMention: () => controller.sendController.text += + '${event.senderFromMemoryOrFallback.mention} ', + ), ), - ), - onSelect: controller.onSelectMessage, - scrollToEventId: (String eventId) => - controller.scrollToEventId(eventId), - longPressSelect: controller.selectedEvents.isNotEmpty, - selected: controller.selectedEvents - .any((e) => e.eventId == event.eventId), - timeline: controller.timeline!, - displayReadMarker: - controller.readMarkerEventId == event.eventId && - controller.timeline?.allowNewEvent == false, - nextEvent: i < controller.timeline!.events.length - ? controller.timeline!.events[i] - : null, - ) - : const SizedBox.shrink(), - ); - }, - childCount: controller.timeline!.events.length + 2, - findChildIndexCallback: (key) => - controller.findChildIndexCallback(key, thisEventsKeyMap), + onSelect: controller.onSelectMessage, + scrollToEventId: (String eventId) => + controller.scrollToEventId(eventId), + // #Pangea + // longPressSelect: controller.selectedEvents.isEmpty, + selectedDisplayLang: controller + .choreographer.messageOptions.selectedDisplayLang, + immersionMode: controller.choreographer.immersionMode, + definitions: controller.choreographer.definitionsEnabled, + // Pangea# + selected: controller.selectedEvents + .any((e) => e.eventId == event.eventId), + timeline: controller.timeline!, + displayReadMarker: + controller.readMarkerEventId == event.eventId && + controller.timeline?.allowNewEvent == false, + nextEvent: i < controller.timeline!.events.length + ? controller.timeline!.events[i] + : null, + ) + : const SizedBox.shrink(), + ); + }, + childCount: controller.timeline!.events.length + 2, + findChildIndexCallback: (key) => + controller.findChildIndexCallback(key, thisEventsKeyMap), + ), ), ); } diff --git a/lib/pages/chat/chat_input_row.dart b/lib/pages/chat/chat_input_row.dart index 7d2d083a9..6c29f4ddd 100644 --- a/lib/pages/chat/chat_input_row.dart +++ b/lib/pages/chat/chat_input_row.dart @@ -7,6 +7,8 @@ import 'package:keyboard_shortcuts/keyboard_shortcuts.dart'; import 'package:matrix/matrix.dart'; import 'package:fluffychat/config/app_config.dart'; +import 'package:fluffychat/pangea/choreographer/widgets/it_bar.dart'; +import 'package:fluffychat/pangea/choreographer/widgets/send_button.dart'; import 'package:fluffychat/utils/platform_infos.dart'; import 'package:fluffychat/widgets/avatar.dart'; import 'package:fluffychat/widgets/matrix.dart'; @@ -17,7 +19,7 @@ import 'input_bar.dart'; class ChatInputRow extends StatelessWidget { final ChatController controller; - const ChatInputRow(this.controller, {Key? key}) : super(key: key); + const ChatInputRow(this.controller, {super.key}); @override Widget build(BuildContext context) { @@ -25,252 +27,323 @@ class ChatInputRow extends StatelessWidget { controller.emojiPickerType == EmojiPickerType.reaction) { return const SizedBox.shrink(); } - return Row( - crossAxisAlignment: CrossAxisAlignment.end, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: controller.selectMode - ? [ - SizedBox( - height: 56, - child: TextButton( - onPressed: controller.forwardEventsAction, - child: Row( - children: [ - const Icon(Icons.keyboard_arrow_left_outlined), - Text(L10n.of(context)!.forward), - ], - ), - ), - ), - controller.selectedEvents.length == 1 - ? controller.selectedEvents.first - .getDisplayEvent(controller.timeline!) - .status - .isSent - ? SizedBox( - height: 56, - child: TextButton( - onPressed: controller.replyAction, - child: Row( - children: [ - Text(L10n.of(context)!.reply), - const Icon(Icons.keyboard_arrow_right), - ], - ), - ), - ) - : SizedBox( - height: 56, - child: TextButton( - onPressed: controller.sendAgainAction, - child: Row( - children: [ - Text(L10n.of(context)!.tryToSendAgain), - const SizedBox(width: 4), - const Icon(Icons.send_outlined, size: 16), - ], - ), - ), - ) - : const SizedBox.shrink(), - ] - : [ - KeyBoardShortcuts( - keysToPress: { - LogicalKeyboardKey.altLeft, - LogicalKeyboardKey.keyA, - }, - onKeysPressed: () => - controller.onAddPopupMenuButtonSelected('file'), - helpLabel: L10n.of(context)!.sendFile, - child: AnimatedContainer( - duration: FluffyThemes.animationDuration, - curve: FluffyThemes.animationCurve, - height: 56, - width: controller.inputText.isEmpty ? 56 : 0, - alignment: Alignment.center, - clipBehavior: Clip.hardEdge, - decoration: const BoxDecoration(), - child: PopupMenuButton( - icon: const Icon(Icons.add_outlined), - onSelected: controller.onAddPopupMenuButtonSelected, - itemBuilder: (BuildContext context) => - >[ - PopupMenuItem( - value: 'file', - child: ListTile( - leading: const CircleAvatar( - backgroundColor: Colors.green, - foregroundColor: Colors.white, - child: Icon(Icons.attachment_outlined), - ), - title: Text(L10n.of(context)!.sendFile), - contentPadding: const EdgeInsets.all(0), + // #Pangea + return Column( + children: [ + ITBar( + choreographer: controller.choreographer, + ), + Row( + // crossAxisAlignment: CrossAxisAlignment.end, + crossAxisAlignment: CrossAxisAlignment.center, + // Pangea# + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: controller.selectMode + ? [ + if (controller.selectedEvents + .every((event) => event.status == EventStatus.error)) + SizedBox( + height: 56, + child: TextButton( + style: TextButton.styleFrom( + foregroundColor: Theme.of(context).colorScheme.error, + ), + onPressed: controller.deleteErrorEventsAction, + child: Row( + children: [ + const Icon(Icons.delete), + Text(L10n.of(context)!.delete), + ], ), ), - PopupMenuItem( - value: 'image', - child: ListTile( - leading: const CircleAvatar( - backgroundColor: Colors.blue, - foregroundColor: Colors.white, - child: Icon(Icons.image_outlined), - ), - title: Text(L10n.of(context)!.sendImage), - contentPadding: const EdgeInsets.all(0), + ) + else + SizedBox( + height: 56, + child: TextButton( + onPressed: controller.forwardEventsAction, + child: Row( + children: [ + const Icon(Icons.keyboard_arrow_left_outlined), + Text(L10n.of(context)!.forward), + ], ), ), - if (PlatformInfos.isMobile) - PopupMenuItem( - value: 'camera', - child: ListTile( - leading: const CircleAvatar( - backgroundColor: Colors.purple, - foregroundColor: Colors.white, - child: Icon(Icons.camera_alt_outlined), + ), + controller.selectedEvents.length == 1 + ? controller.selectedEvents.first + .getDisplayEvent(controller.timeline!) + .status + .isSent + ? SizedBox( + height: 56, + child: TextButton( + onPressed: controller.replyAction, + child: Row( + children: [ + Text(L10n.of(context)!.reply), + const Icon(Icons.keyboard_arrow_right), + ], + ), + ), + ) + : SizedBox( + height: 56, + child: TextButton( + onPressed: controller.sendAgainAction, + child: Row( + children: [ + Text(L10n.of(context)!.tryToSendAgain), + const SizedBox(width: 4), + const Icon(Icons.send_outlined, size: 16), + ], + ), + ), + ) + : const SizedBox.shrink(), + ] + : [ + KeyBoardShortcuts( + keysToPress: { + LogicalKeyboardKey.altLeft, + LogicalKeyboardKey.keyA, + }, + onKeysPressed: () => + controller.onAddPopupMenuButtonSelected('file'), + helpLabel: L10n.of(context)!.sendFile, + child: AnimatedContainer( + duration: FluffyThemes.animationDuration, + curve: FluffyThemes.animationCurve, + height: 56, + //#Pangea + // width: controller.inputText.isEmpty ? 56 : 0, + width: controller.inputText.isEmpty && + controller.pangeaController.permissionsController + .showChatInputAddButton(controller.roomId) + ? 56 + : 0, + //Pangea# + alignment: Alignment.center, + clipBehavior: Clip.hardEdge, + decoration: const BoxDecoration(), + child: PopupMenuButton( + icon: const Icon(Icons.add_outlined), + onSelected: controller.onAddPopupMenuButtonSelected, + itemBuilder: (BuildContext context) => + >[ + //#Pangea + if (controller.pangeaController.permissionsController + .canShareFile(controller.roomId)) + //Pangea# + PopupMenuItem( + value: 'file', + child: ListTile( + leading: const CircleAvatar( + backgroundColor: Colors.green, + foregroundColor: Colors.white, + child: Icon(Icons.attachment_outlined), + ), + title: Text(L10n.of(context)!.sendFile), + contentPadding: const EdgeInsets.all(0), + ), ), - title: Text(L10n.of(context)!.openCamera), - contentPadding: const EdgeInsets.all(0), - ), - ), - if (PlatformInfos.isMobile) - PopupMenuItem( - value: 'camera-video', - child: ListTile( - leading: const CircleAvatar( - backgroundColor: Colors.red, - foregroundColor: Colors.white, - child: Icon(Icons.videocam_outlined), + //#Pangea + if (controller.pangeaController.permissionsController + .canSharePhoto(controller.roomId)) + //Pangea# + PopupMenuItem( + value: 'image', + child: ListTile( + leading: const CircleAvatar( + backgroundColor: Colors.blue, + foregroundColor: Colors.white, + child: Icon(Icons.image_outlined), + ), + title: Text(L10n.of(context)!.sendImage), + contentPadding: const EdgeInsets.all(0), + ), ), - title: Text(L10n.of(context)!.openVideoCamera), - contentPadding: const EdgeInsets.all(0), - ), - ), - if (controller.room - .getImagePacks(ImagePackUsage.sticker) - .isNotEmpty) - PopupMenuItem( - value: 'sticker', - child: ListTile( - leading: const CircleAvatar( - backgroundColor: Colors.orange, - foregroundColor: Colors.white, - child: Icon(Icons.emoji_emotions_outlined), + //#Pangea + // if (PlatformInfos.isMobile) + if (PlatformInfos.isMobile && + controller.pangeaController.permissionsController + .canSharePhoto(controller.roomId)) + //Pangea# + PopupMenuItem( + value: 'camera', + child: ListTile( + leading: const CircleAvatar( + backgroundColor: Colors.purple, + foregroundColor: Colors.white, + child: Icon(Icons.camera_alt_outlined), + ), + title: Text(L10n.of(context)!.openCamera), + contentPadding: const EdgeInsets.all(0), + ), ), - title: Text(L10n.of(context)!.sendSticker), - contentPadding: const EdgeInsets.all(0), - ), - ), - if (PlatformInfos.isMobile) - PopupMenuItem( - value: 'location', - child: ListTile( - leading: const CircleAvatar( - backgroundColor: Colors.brown, - foregroundColor: Colors.white, - child: Icon(Icons.gps_fixed_outlined), + //#Pangea + // if (PlatformInfos.isMobile) + if (PlatformInfos.isMobile && + controller.pangeaController.permissionsController + .canShareVideo(controller.roomId)) + //Pangea# + PopupMenuItem( + value: 'camera-video', + child: ListTile( + leading: const CircleAvatar( + backgroundColor: Colors.red, + foregroundColor: Colors.white, + child: Icon(Icons.videocam_outlined), + ), + title: Text(L10n.of(context)!.openVideoCamera), + contentPadding: const EdgeInsets.all(0), + ), ), - title: Text(L10n.of(context)!.shareLocation), - contentPadding: const EdgeInsets.all(0), - ), - ), - ], + if (controller.room + .getImagePacks(ImagePackUsage.sticker) + .isNotEmpty) + PopupMenuItem( + value: 'sticker', + child: ListTile( + leading: const CircleAvatar( + backgroundColor: Colors.orange, + foregroundColor: Colors.white, + child: Icon(Icons.emoji_emotions_outlined), + ), + title: Text(L10n.of(context)!.sendSticker), + contentPadding: const EdgeInsets.all(0), + ), + ), + //#Pangea + // if (PlatformInfos.isMobile) + if (PlatformInfos.isMobile && + controller.pangeaController.permissionsController + .canShareLocation(controller.roomId)) + //Pangea# + PopupMenuItem( + value: 'location', + child: ListTile( + leading: const CircleAvatar( + backgroundColor: Colors.brown, + foregroundColor: Colors.white, + child: Icon(Icons.gps_fixed_outlined), + ), + title: Text(L10n.of(context)!.shareLocation), + contentPadding: const EdgeInsets.all(0), + ), + ), + ], + ), + ), ), - ), - ), - Container( - height: 56, - alignment: Alignment.center, - child: KeyBoardShortcuts( - keysToPress: { - LogicalKeyboardKey.altLeft, - LogicalKeyboardKey.keyE, - }, - onKeysPressed: controller.emojiPickerAction, - helpLabel: L10n.of(context)!.emojis, - child: IconButton( - tooltip: L10n.of(context)!.emojis, - icon: PageTransitionSwitcher( - transitionBuilder: ( - Widget child, - Animation primaryAnimation, - Animation secondaryAnimation, - ) { - return SharedAxisTransition( - animation: primaryAnimation, - secondaryAnimation: secondaryAnimation, - transitionType: SharedAxisTransitionType.scaled, - fillColor: Colors.transparent, - child: child, - ); + Container( + height: 56, + alignment: Alignment.center, + child: KeyBoardShortcuts( + keysToPress: { + LogicalKeyboardKey.altLeft, + LogicalKeyboardKey.keyE, }, - child: Icon( - controller.showEmojiPicker - ? Icons.keyboard - : Icons.emoji_emotions_outlined, - key: ValueKey(controller.showEmojiPicker), + onKeysPressed: controller.emojiPickerAction, + helpLabel: L10n.of(context)!.emojis, + child: IconButton( + tooltip: L10n.of(context)!.emojis, + icon: PageTransitionSwitcher( + transitionBuilder: ( + Widget child, + Animation primaryAnimation, + Animation secondaryAnimation, + ) { + return SharedAxisTransition( + animation: primaryAnimation, + secondaryAnimation: secondaryAnimation, + transitionType: SharedAxisTransitionType.scaled, + fillColor: Colors.transparent, + child: child, + ); + }, + child: Icon( + controller.showEmojiPicker + ? Icons.keyboard + : Icons.emoji_emotions_outlined, + key: ValueKey(controller.showEmojiPicker), + ), + ), + onPressed: controller.emojiPickerAction, ), ), - onPressed: controller.emojiPickerAction, ), - ), - ), - if (Matrix.of(context).isMultiAccount && - Matrix.of(context).hasComplexBundles && - Matrix.of(context).currentBundle!.length > 1) - Container( - height: 56, - alignment: Alignment.center, - child: _ChatAccountPicker(controller), - ), - Expanded( - child: Padding( - padding: const EdgeInsets.symmetric(vertical: 4.0), - child: InputBar( - room: controller.room, - minLines: 1, - maxLines: 8, - autofocus: !PlatformInfos.isMobile, - keyboardType: TextInputType.multiline, - textInputAction: - AppConfig.sendOnEnter ? TextInputAction.send : null, - onSubmitted: controller.onInputBarSubmitted, - onSubmitImage: controller.sendImageFromClipBoard, - focusNode: controller.inputFocus, - controller: controller.sendController, - decoration: InputDecoration( - hintText: L10n.of(context)!.writeAMessage, - hintMaxLines: 1, - border: InputBorder.none, - enabledBorder: InputBorder.none, - filled: false, + // #Pangea + // if (Matrix.of(context).isMultiAccount && + // Matrix.of(context).hasComplexBundles && + // Matrix.of(context).currentBundle!.length > 1) + // Container( + // height: 56, + // alignment: Alignment.center, + // child: _ChatAccountPicker(controller), + // ), + // Pangea# + Expanded( + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 4.0), + child: InputBar( + room: controller.room, + minLines: 1, + maxLines: 8, + // #Pangea + // autofocus: !PlatformInfos.isMobile, + autofocus: false, + // Pangea# + keyboardType: TextInputType.multiline, + textInputAction: + AppConfig.sendOnEnter ? TextInputAction.send : null, + // #Pangea + // onSubmitted: controller.onInputBarSubmitted, + onSubmitted: (String value) => + controller.onInputBarSubmitted(value, context), + // #Pangea + onSubmitImage: controller.sendImageFromClipBoard, + focusNode: controller.inputFocus, + controller: controller.sendController, + decoration: InputDecoration( + hintText: L10n.of(context)!.writeAMessage, + hintMaxLines: 1, + border: InputBorder.none, + enabledBorder: InputBorder.none, + filled: false, + ), + onChanged: controller.onInputBarChanged, + ), ), - onChanged: controller.onInputBarChanged, ), - ), - ), - if (PlatformInfos.platformCanRecord && - controller.inputText.isEmpty) - Container( - height: 56, - alignment: Alignment.center, - child: IconButton( - tooltip: L10n.of(context)!.voiceMessage, - icon: const Icon(Icons.mic_none_outlined), - onPressed: controller.voiceMessageAction, - ), - ), - if (!PlatformInfos.isMobile || controller.inputText.isNotEmpty) - Container( - height: 56, - alignment: Alignment.center, - child: IconButton( - icon: const Icon(Icons.send_outlined), - onPressed: controller.send, - tooltip: L10n.of(context)!.send, - ), - ), - ], + if (PlatformInfos.platformCanRecord && + controller.inputText.isEmpty) + Container( + height: 56, + alignment: Alignment.center, + child: IconButton( + tooltip: L10n.of(context)!.voiceMessage, + icon: const Icon(Icons.mic_none_outlined), + onPressed: controller.voiceMessageAction, + ), + ), + if (!PlatformInfos.isMobile || + controller.inputText.isNotEmpty) + // #Pangea + ChoreographerSendButton(controller: controller), + // Container( + // height: 56, + // alignment: Alignment.center, + // child: IconButton( + // icon: const Icon(Icons.send_outlined), + // onPressed: controller.send, + // tooltip: L10n.of(context)!.send, + // ), + // ), + // Pangea# + ], + ), + ], ); } } @@ -278,7 +351,7 @@ class ChatInputRow extends StatelessWidget { class _ChatAccountPicker extends StatelessWidget { final ChatController controller; - const _ChatAccountPicker(this.controller, {Key? key}) : super(key: key); + const _ChatAccountPicker(this.controller); void _popupMenuButtonSelected(String mxid, BuildContext context) { final client = Matrix.of(context) diff --git a/lib/pages/chat/chat_view.dart b/lib/pages/chat/chat_view.dart index a92d6ce88..149055eb0 100644 --- a/lib/pages/chat/chat_view.dart +++ b/lib/pages/chat/chat_view.dart @@ -1,3 +1,5 @@ +// Flutter imports: + import 'package:flutter/material.dart'; import 'package:badges/badges.dart'; @@ -11,11 +13,15 @@ import 'package:fluffychat/config/themes.dart'; import 'package:fluffychat/pages/chat/chat.dart'; import 'package:fluffychat/pages/chat/chat_app_bar_title.dart'; import 'package:fluffychat/pages/chat/chat_event_list.dart'; -import 'package:fluffychat/pages/chat/encryption_button.dart'; import 'package:fluffychat/pages/chat/pinned_events.dart'; import 'package:fluffychat/pages/chat/reactions_picker.dart'; import 'package:fluffychat/pages/chat/reply_display.dart'; import 'package:fluffychat/pages/chat/tombstone_display.dart'; +import 'package:fluffychat/pangea/choreographer/widgets/has_error_button.dart'; +import 'package:fluffychat/pangea/choreographer/widgets/language_display_toggle.dart'; +import 'package:fluffychat/pangea/choreographer/widgets/language_permissions_warning_buttons.dart'; +import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart'; +import 'package:fluffychat/pangea/pages/class_analytics/measure_able.dart'; import 'package:fluffychat/widgets/chat_settings_popup_menu.dart'; import 'package:fluffychat/widgets/connection_status_header.dart'; import 'package:fluffychat/widgets/matrix.dart'; @@ -29,11 +35,14 @@ enum _EventContextAction { info, report } class ChatView extends StatelessWidget { final ChatController controller; - const ChatView(this.controller, {Key? key}) : super(key: key); + const ChatView(this.controller, {super.key}); List _appBarActions(BuildContext context) { if (controller.selectMode) { return [ + // #Pangea + LanguageDisplayToggle(controller: controller), + // Pangea# if (controller.canEditSelectedEvents) IconButton( icon: const Icon(Icons.edit_outlined), @@ -80,61 +89,58 @@ class ChatView extends StatelessWidget { } }, itemBuilder: (context) => [ - PopupMenuItem( - value: _EventContextAction.info, - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - const Icon(Icons.info_outlined), - const SizedBox(width: 12), - Text(L10n.of(context)!.messageInfo), - ], + // #Pangea + // PopupMenuItem( + // value: _EventContextAction.info, + // child: Row( + // mainAxisSize: MainAxisSize.min, + // children: [ + // const Icon(Icons.info_outlined), + // const SizedBox(width: 12), + // Text(L10n.of(context)!.messageInfo), + // ], + // ), + // ), + // Pangea# + if (controller.selectedEvents.single.status.isSent) + PopupMenuItem( + value: _EventContextAction.report, + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + const Icon( + Icons.shield_outlined, + color: Colors.red, + ), + const SizedBox(width: 12), + Text(L10n.of(context)!.reportMessage), + ], + ), ), - ), - PopupMenuItem( - value: _EventContextAction.report, - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - const Icon( - Icons.shield_outlined, - color: Colors.red, - ), - const SizedBox(width: 12), - Text(L10n.of(context)!.reportMessage), - ], - ), - ), ], ), ]; - } else if (controller.isArchived) { - return [ - Padding( - padding: const EdgeInsets.all(8.0), - child: TextButton.icon( - onPressed: controller.forgetRoom, - style: TextButton.styleFrom( - foregroundColor: Theme.of(context).colorScheme.error, - ), - icon: const Icon(Icons.delete_forever_outlined), - label: Text(L10n.of(context)!.delete), - ), - ), - ]; + // #Pangea } else { return [ - if (Matrix.of(context).voipPlugin != null && - controller.room.isDirectChat) - IconButton( - onPressed: controller.onPhoneButtonTap, - icon: const Icon(Icons.call_outlined), - tooltip: L10n.of(context)!.placeCall, - ), - EncryptionButton(controller.room), - ChatSettingsPopupMenu(controller.room, true), + ChatSettingsPopupMenu(controller.room, !controller.room.isDirectChat), ]; } + // } else if (!controller.room.isArchived) { + // return [ + // if (Matrix.of(context).voipPlugin != null && + // controller.room.isDirectChat) + // IconButton( + // onPressed: controller.onPhoneButtonTap, + // icon: const Icon(Icons.call_outlined), + // tooltip: L10n.of(context)!.placeCall, + // ), + // EncryptionButton(controller.room), + // ChatSettingsPopupMenu(controller.room, true), + // ]; + // } + // return []; + // Pangea# } @override @@ -148,16 +154,15 @@ class ChatView extends StatelessWidget { final bottomSheetPadding = FluffyThemes.isColumnMode(context) ? 16.0 : 8.0; final scrollUpBannerEventId = controller.scrollUpBannerEventId; - return WillPopScope( - onWillPop: () async { + return PopScope( + canPop: controller.selectedEvents.isEmpty && !controller.showEmojiPicker, + onPopInvoked: (pop) async { + if (pop) return; if (controller.selectedEvents.isNotEmpty) { controller.clearSelectedEvents(); - return false; } else if (controller.showEmojiPicker) { controller.emojiPickerAction(); - return false; } - return true; }, child: GestureDetector( onTapDown: (_) => controller.setReadMarker(), @@ -183,7 +188,12 @@ class ChatView extends StatelessWidget { color: Theme.of(context).colorScheme.primary, ) : UnreadRoomsBadge( - filter: (r) => r.id != controller.roomId, + filter: (r) => + r.id != controller.roomId + // #Pangea + && + !r.isAnalyticsRoom, + // Pangea# badgePosition: BadgePosition.topEnd(end: 8, top: 4), child: const Center(child: BackButton()), ), @@ -191,17 +201,34 @@ class ChatView extends StatelessWidget { title: ChatAppBarTitle(controller), actions: _appBarActions(context), ), - floatingActionButton: controller.showScrollDownButton && - controller.selectedEvents.isEmpty - ? Padding( - padding: const EdgeInsets.only(bottom: 56.0), - child: FloatingActionButton( - onPressed: controller.scrollDown, - heroTag: null, - mini: true, - child: const Icon(Icons.arrow_downward_outlined), - ), - ) + // #Pangea + // floatingActionButton: controller.showScrollDownButton && + // controller.selectedEvents.isEmpty + floatingActionButton: controller.selectedEvents.isEmpty + ? (controller.showScrollDownButton + // Pangea# + ? Padding( + padding: const EdgeInsets.only(bottom: 56.0), + child: FloatingActionButton( + onPressed: controller.scrollDown, + heroTag: null, + mini: true, + child: const Icon(Icons.arrow_downward_outlined), + ), + ) + // #Pangea + : controller.choreographer.errorService.error != null + ? ChoreographerHasErrorButton( + controller.pangeaController, + controller.choreographer.errorService.error!, + ) + : controller.showPermissionsError + ? LanguagePermissionsButtons( + choreographer: controller.choreographer, + roomID: controller.roomId, + ) + : null) + // #Pangea : null, body: DropTarget( onDragDone: controller.onDragDone, @@ -284,95 +311,120 @@ class ChatView extends StatelessWidget { ), if (controller.room.canSendDefaultMessages && controller.room.membership == Membership.join) - Container( - margin: EdgeInsets.only( - bottom: bottomSheetPadding, - left: bottomSheetPadding, - right: bottomSheetPadding, - ), - constraints: const BoxConstraints( - maxWidth: FluffyThemes.columnWidth * 2.5, - ), - alignment: Alignment.center, - child: Material( - borderRadius: const BorderRadius.only( - bottomLeft: - Radius.circular(AppConfig.borderRadius), - bottomRight: - Radius.circular(AppConfig.borderRadius), - ), - elevation: 4, - shadowColor: Colors.black.withAlpha(64), - clipBehavior: Clip.hardEdge, - color: Theme.of(context).brightness == - Brightness.light - ? Colors.white - : Colors.black, - child: controller.room.isAbandonedDMRoom == - true - ? Row( - mainAxisAlignment: - MainAxisAlignment.spaceEvenly, - children: [ - TextButton.icon( - style: TextButton.styleFrom( - padding: - const EdgeInsets.all(16), - foregroundColor: - Theme.of(context) - .colorScheme - .error, - ), - icon: const Icon( - Icons.archive_outlined, - ), - onPressed: controller.leaveChat, - label: Text( - L10n.of(context)!.leave, - ), - ), - TextButton.icon( - style: TextButton.styleFrom( - padding: - const EdgeInsets.all(16), - ), - icon: const Icon( - Icons.forum_outlined, - ), - onPressed: - controller.recreateChat, - label: Text( - L10n.of(context)!.reopenChat, - ), - ), - ], - ) - : Column( - mainAxisSize: MainAxisSize.min, - children: [ - const ConnectionStatusHeader(), - ReactionsPicker(controller), - ReplyDisplay(controller), - ChatInputRow(controller), - ChatEmojiPicker(controller), - ], + // #Pangea + // Container( + ConditionalFlexible( + isScroll: controller.isRowScrollable, + child: ConditionalScroll( + isScroll: controller.isRowScrollable, + child: MeasurableWidget( + onChange: (size, position) { + controller.inputRowSize = size!.height; + }, + child: Container( + // Pangea# + margin: EdgeInsets.only( + bottom: bottomSheetPadding, + left: bottomSheetPadding, + right: bottomSheetPadding, + ), + constraints: const BoxConstraints( + maxWidth: + FluffyThemes.columnWidth * 2.5, + ), + alignment: Alignment.center, + child: Material( + borderRadius: const BorderRadius.only( + bottomLeft: Radius.circular( + AppConfig.borderRadius, + ), + bottomRight: Radius.circular( + AppConfig.borderRadius, + ), ), + elevation: 4, + shadowColor: Colors.black.withAlpha(64), + clipBehavior: Clip.hardEdge, + color: Theme.of(context).brightness == + Brightness.light + ? Colors.white + : Colors.black, + child: controller + .room.isAbandonedDMRoom == + true + ? Row( + mainAxisAlignment: + MainAxisAlignment + .spaceEvenly, + children: [ + TextButton.icon( + style: TextButton.styleFrom( + padding: + const EdgeInsets.all( + 16, + ), + foregroundColor: + Theme.of(context) + .colorScheme + .error, + ), + icon: const Icon( + Icons.archive_outlined, + ), + onPressed: + controller.leaveChat, + label: Text( + L10n.of(context)!.leave, + ), + ), + TextButton.icon( + style: TextButton.styleFrom( + padding: + const EdgeInsets.all( + 16, + ), + ), + icon: const Icon( + Icons.forum_outlined, + ), + onPressed: + controller.recreateChat, + label: Text( + L10n.of(context)! + .reopenChat, + ), + ), + ], + ) + : Column( + mainAxisSize: MainAxisSize.min, + children: [ + const ConnectionStatusHeader(), + ReactionsPicker(controller), + ReplyDisplay(controller), + ChatInputRow(controller), + ChatEmojiPicker(controller), + ], + ), + ), + ), + ), + ), + ), + if (controller.dragging) + Container( + color: Theme.of(context) + .scaffoldBackgroundColor + .withOpacity(0.9), + alignment: Alignment.center, + child: const Icon( + Icons.upload_outlined, + size: 100, ), ), ], ), ), - if (controller.dragging) - Container( - color: Theme.of(context) - .scaffoldBackgroundColor - .withOpacity(0.9), - alignment: Alignment.center, - child: const Icon( - Icons.upload_outlined, - size: 100, - ), - ), ], ), ), @@ -384,3 +436,35 @@ class ChatView extends StatelessWidget { ); } } + +// #Pangea +Widget ConditionalFlexible({required bool isScroll, required Widget child}) { + if (isScroll) { + return Flexible( + flex: 9999999, + child: child, + ); + } + return child; +} + +class ConditionalScroll extends StatelessWidget { + final bool isScroll; + final Widget child; + const ConditionalScroll({ + super.key, + required this.isScroll, + required this.child, + }); + + @override + Widget build(BuildContext context) { + if (isScroll) { + return SingleChildScrollView( + child: child, + ); + } + return child; + } +} +// #Pangea diff --git a/lib/pages/chat/cupertino_widgets_bottom_sheet.dart b/lib/pages/chat/cupertino_widgets_bottom_sheet.dart new file mode 100644 index 000000000..23dddfa9b --- /dev/null +++ b/lib/pages/chat/cupertino_widgets_bottom_sheet.dart @@ -0,0 +1,49 @@ +import 'package:flutter/cupertino.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:matrix/matrix.dart'; +import 'package:url_launcher/link.dart'; + +import 'edit_widgets_dialog.dart'; + +class CupertinoWidgetsBottomSheet extends StatelessWidget { + final Room room; + + const CupertinoWidgetsBottomSheet({super.key, required this.room}); + + @override + Widget build(BuildContext context) { + return CupertinoActionSheet( + title: Text(L10n.of(context)!.matrixWidgets), + actions: [ + ...room.widgets.map( + (widget) => Link( + builder: (context, callback) { + return CupertinoActionSheetAction( + onPressed: callback ?? () {}, + child: Text(widget.name ?? widget.url), + ); + }, + target: LinkTarget.blank, + uri: Uri.parse(widget.url), + ), + ), + CupertinoActionSheetAction( + child: Text(L10n.of(context)!.editWidgets), + onPressed: () { + Navigator.of(context).pop(); + showCupertinoDialog( + context: context, + builder: (context) => EditWidgetsDialog(room: room), + useRootNavigator: false, + ); + }, + ), + CupertinoActionSheetAction( + onPressed: Navigator.of(context).pop, + child: Text(L10n.of(context)!.cancel), + ), + ], + ); + } +} diff --git a/lib/pages/chat/edit_widgets_dialog.dart b/lib/pages/chat/edit_widgets_dialog.dart index 7d9579a10..2ba163feb 100644 --- a/lib/pages/chat/edit_widgets_dialog.dart +++ b/lib/pages/chat/edit_widgets_dialog.dart @@ -8,7 +8,7 @@ import 'add_widget_tile.dart'; class EditWidgetsDialog extends StatelessWidget { final Room room; - const EditWidgetsDialog({Key? key, required this.room}) : super(key: key); + const EditWidgetsDialog({super.key, required this.room}); @override Widget build(BuildContext context) { diff --git a/lib/pages/chat/encryption_button.dart b/lib/pages/chat/encryption_button.dart index d5a4481c5..c68a1c976 100644 --- a/lib/pages/chat/encryption_button.dart +++ b/lib/pages/chat/encryption_button.dart @@ -8,7 +8,7 @@ import '../../widgets/matrix.dart'; class EncryptionButton extends StatelessWidget { final Room room; - const EncryptionButton(this.room, {Key? key}) : super(key: key); + const EncryptionButton(this.room, {super.key}); @override Widget build(BuildContext context) { diff --git a/lib/pages/chat/event_info_dialog.dart b/lib/pages/chat/event_info_dialog.dart index 5ac29c80c..e8ff6dad9 100644 --- a/lib/pages/chat/event_info_dialog.dart +++ b/lib/pages/chat/event_info_dialog.dart @@ -24,8 +24,8 @@ class EventInfoDialog extends StatelessWidget { const EventInfoDialog({ required this.event, required this.l10n, - Key? key, - }) : super(key: key); + super.key, + }); String get prettyJson { const JsonDecoder decoder = JsonDecoder(); @@ -51,6 +51,8 @@ class EventInfoDialog extends StatelessWidget { leading: Avatar( mxContent: event.senderFromMemoryOrFallback.avatarUrl, name: event.senderFromMemoryOrFallback.calcDisplayname(), + client: event.room.client, + presenceUserId: event.senderId, ), title: Text(L10n.of(context)!.sender), subtitle: Text( diff --git a/lib/pages/chat/events/audio_player.dart b/lib/pages/chat/events/audio_player.dart index 1b0586d27..6335b54bf 100644 --- a/lib/pages/chat/events/audio_player.dart +++ b/lib/pages/chat/events/audio_player.dart @@ -20,8 +20,7 @@ class AudioPlayerWidget extends StatefulWidget { static const int wavesCount = 40; - const AudioPlayerWidget(this.event, {this.color = Colors.black, Key? key}) - : super(key: key); + const AudioPlayerWidget(this.event, {this.color = Colors.black, super.key}); @override AudioPlayerState createState() => AudioPlayerState(); diff --git a/lib/pages/chat/events/cute_events.dart b/lib/pages/chat/events/cute_events.dart index 6b5b0f909..6a9424818 100644 --- a/lib/pages/chat/events/cute_events.dart +++ b/lib/pages/chat/events/cute_events.dart @@ -10,7 +10,7 @@ import 'package:fluffychat/config/app_config.dart'; class CuteContent extends StatefulWidget { final Event event; - const CuteContent(this.event, {Key? key}) : super(key: key); + const CuteContent(this.event, {super.key}); @override State createState() => _CuteContentState(); @@ -98,10 +98,10 @@ class CuteEventOverlay extends StatefulWidget { final VoidCallback onAnimationEnd; const CuteEventOverlay({ - Key? key, + super.key, required this.emoji, required this.onAnimationEnd, - }) : super(key: key); + }); @override State createState() => _CuteEventOverlayState(); @@ -179,7 +179,7 @@ class _CuteOverlayContent extends StatelessWidget { static const double size = 64.0; final String emoji; - const _CuteOverlayContent({Key? key, required this.emoji}) : super(key: key); + const _CuteOverlayContent({required this.emoji}); @override Widget build(BuildContext context) { diff --git a/lib/pages/chat/events/html_message.dart b/lib/pages/chat/events/html_message.dart index cd57545a2..3a47121f4 100644 --- a/lib/pages/chat/events/html_message.dart +++ b/lib/pages/chat/events/html_message.dart @@ -20,11 +20,11 @@ class HtmlMessage extends StatelessWidget { final Color textColor; const HtmlMessage({ - Key? key, + super.key, required this.html, required this.room, this.textColor = Colors.black, - }) : super(key: key); + }); @override Widget build(BuildContext context) { @@ -63,87 +63,97 @@ class HtmlMessage extends StatelessWidget { final linkColor = textColor.withAlpha(150); - // there is no need to pre-validate the html, as we validate it while rendering - return Html( - data: linkifiedRenderHtml, - style: { - '*': Style( + final blockquoteStyle = Style( + border: Border( + left: BorderSide( + width: 3, color: textColor, - margin: Margins.all(0), - fontSize: FontSize(fontSize), ), - 'a': Style(color: linkColor, textDecorationColor: linkColor), - 'h1': Style( - fontSize: FontSize(fontSize * 2), - lineHeight: LineHeight.number(1.5), - fontWeight: FontWeight.w600, - ), - 'h2': Style( - fontSize: FontSize(fontSize * 1.75), - lineHeight: LineHeight.number(1.5), - fontWeight: FontWeight.w500, - ), - 'h3': Style( - fontSize: FontSize(fontSize * 1.5), - lineHeight: LineHeight.number(1.5), - ), - 'h4': Style( - fontSize: FontSize(fontSize * 1.25), - lineHeight: LineHeight.number(1.5), - ), - 'h5': Style( - fontSize: FontSize(fontSize * 1.25), - lineHeight: LineHeight.number(1.5), - ), - 'h6': Style( - fontSize: FontSize(fontSize), - lineHeight: LineHeight.number(1.5), - ), - 'blockquote': Style( - border: Border( - left: BorderSide( - width: 3, - color: textColor, - ), + ), + padding: HtmlPaddings.only(left: 6, bottom: 0), + ); + + // there is no need to pre-validate the html, as we validate it while rendering + return MouseRegion( + cursor: SystemMouseCursors.text, + child: Html( + data: linkifiedRenderHtml, + style: { + '*': Style( + color: textColor, + margin: Margins.all(0), + fontSize: FontSize(fontSize), ), - padding: HtmlPaddings.only(left: 6, bottom: 0), - ), - 'hr': Style( - border: Border.all(color: textColor, width: 0.5), - ), - 'table': Style( - border: Border.all(color: textColor, width: 0.5), - ), - 'tr': Style( - border: Border.all(color: textColor, width: 0.5), - ), - 'td': Style( - border: Border.all(color: textColor, width: 0.5), - padding: HtmlPaddings.all(2), - ), - 'th': Style( - border: Border.all(color: textColor, width: 0.5), - ), - }, - extensions: [ - RoomPillExtension(context, room), - CodeExtension(fontSize: fontSize), - MatrixMathExtension( - style: TextStyle(fontSize: fontSize, color: textColor), - ), - const TableHtmlExtension(), - SpoilerExtension(textColor: textColor), - const ImageExtension(), - FontColorExtension(), - ], - onLinkTap: (url, _, __) => UrlLauncher(context, url).launchUrl(), - onlyRenderTheseTags: const { - ...allowedHtmlTags, - // Needed to make it work properly - 'body', - 'html', - }, - shrinkWrap: true, + 'a': Style(color: linkColor, textDecorationColor: linkColor), + 'h1': Style( + fontSize: FontSize(fontSize * 2), + lineHeight: LineHeight.number(1.5), + fontWeight: FontWeight.w600, + ), + 'h2': Style( + fontSize: FontSize(fontSize * 1.75), + lineHeight: LineHeight.number(1.5), + fontWeight: FontWeight.w500, + ), + 'h3': Style( + fontSize: FontSize(fontSize * 1.5), + lineHeight: LineHeight.number(1.5), + ), + 'h4': Style( + fontSize: FontSize(fontSize * 1.25), + lineHeight: LineHeight.number(1.5), + ), + 'h5': Style( + fontSize: FontSize(fontSize * 1.25), + lineHeight: LineHeight.number(1.5), + ), + 'h6': Style( + fontSize: FontSize(fontSize), + lineHeight: LineHeight.number(1.5), + ), + 'blockquote': blockquoteStyle, + 'tg-forward': blockquoteStyle, + 'hr': Style( + border: Border.all(color: textColor, width: 0.5), + ), + 'table': Style( + border: Border.all(color: textColor, width: 0.5), + ), + 'tr': Style( + border: Border.all(color: textColor, width: 0.5), + ), + 'td': Style( + border: Border.all(color: textColor, width: 0.5), + padding: HtmlPaddings.all(2), + ), + 'th': Style( + border: Border.all(color: textColor, width: 0.5), + ), + }, + extensions: [ + RoomPillExtension(context, room), + CodeExtension(fontSize: fontSize), + MatrixMathExtension( + style: TextStyle(fontSize: fontSize, color: textColor), + ), + const TableHtmlExtension(), + SpoilerExtension(textColor: textColor), + const ImageExtension(), + FontColorExtension(), + ], + onLinkTap: (url, _, element) => UrlLauncher( + context, + url, + element?.text, + ).launchUrl(), + onlyRenderTheseTags: const { + ...allowedHtmlTags, + // Needed to make it work properly + 'body', + 'html', + }, + shrinkWrap: true, + ), ); } @@ -191,6 +201,8 @@ class HtmlMessage extends StatelessWidget { 'ruby', 'rp', 'rt', + // Workaround for https://github.com/krille-chan/fluffychat/issues/507 + 'tg-forward', }; } diff --git a/lib/pages/chat/events/image_bubble.dart b/lib/pages/chat/events/image_bubble.dart index 6974be5f7..ae8e7a83e 100644 --- a/lib/pages/chat/events/image_bubble.dart +++ b/lib/pages/chat/events/image_bubble.dart @@ -3,6 +3,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_blurhash/flutter_blurhash.dart'; import 'package:matrix/matrix.dart'; +import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/pages/image_viewer/image_viewer.dart'; import 'package:fluffychat/widgets/mxc_image.dart'; @@ -17,6 +18,7 @@ class ImageBubble extends StatelessWidget { final double width; final double height; final void Function()? onTap; + final BorderRadius? borderRadius; const ImageBubble( this.event, { @@ -29,8 +31,9 @@ class ImageBubble extends StatelessWidget { this.height = 300, this.animated = false, this.onTap, - Key? key, - }) : super(key: key); + this.borderRadius, + super.key, + }); Widget _buildPlaceholder(BuildContext context) { if (event.messageType == MessageTypes.Sticker) { @@ -49,8 +52,10 @@ class ImageBubble extends StatelessWidget { var height = 32; if (ratio > 1.0) { height = (width / ratio).round(); + if (height <= 0) height = 1; } else { width = (height * ratio).round(); + if (width <= 0) width = 1; } return SizedBox( width: this.width, @@ -79,19 +84,25 @@ class ImageBubble extends StatelessWidget { @override Widget build(BuildContext context) { - return InkWell( - onTap: () => _onTap(context), - child: Hero( - tag: event.eventId, - child: AnimatedSwitcher( - duration: const Duration(seconds: 1), - child: Container( + final borderRadius = + this.borderRadius ?? BorderRadius.circular(AppConfig.borderRadius); + return Material( + shape: RoundedRectangleBorder( + borderRadius: borderRadius, + side: BorderSide(color: Theme.of(context).dividerColor), + ), + child: InkWell( + onTap: () => _onTap(context), + borderRadius: borderRadius, + child: Hero( + tag: event.eventId, + child: ConstrainedBox( constraints: maxSize ? BoxConstraints( maxWidth: width, maxHeight: height, ) - : null, + : const BoxConstraints.expand(), child: MxcImage( event: event, width: width, diff --git a/lib/pages/chat/events/map_bubble.dart b/lib/pages/chat/events/map_bubble.dart index b003bc6ed..c441c7d64 100644 --- a/lib/pages/chat/events/map_bubble.dart +++ b/lib/pages/chat/events/map_bubble.dart @@ -17,8 +17,8 @@ class MapBubble extends StatelessWidget { this.width = 400, this.height = 400, this.radius = 10.0, - Key? key, - }) : super(key: key); + super.key, + }); @override Widget build(BuildContext context) { diff --git a/lib/pages/chat/events/message.dart b/lib/pages/chat/events/message.dart index 72a637aee..8fc28bd42 100644 --- a/lib/pages/chat/events/message.dart +++ b/lib/pages/chat/events/message.dart @@ -5,6 +5,9 @@ import 'package:matrix/matrix.dart'; import 'package:swipe_to_action/swipe_to_action.dart'; import 'package:fluffychat/config/themes.dart'; +import 'package:fluffychat/pangea/enum/use_type.dart'; +import 'package:fluffychat/pangea/models/language_model.dart'; +import 'package:fluffychat/pangea/models/pangea_message_event.dart'; import 'package:fluffychat/utils/date_time_extension.dart'; import 'package:fluffychat/utils/string_color.dart'; import 'package:fluffychat/widgets/avatar.dart'; @@ -20,36 +23,45 @@ class Message extends StatelessWidget { final Event event; final Event? nextEvent; final bool displayReadMarker; - final void Function(Event)? onSelect; - final void Function(Event)? onAvatarTab; - final void Function(Event)? onInfoTab; - final void Function(String)? scrollToEventId; - final void Function(SwipeDirection) onSwipe; + final void Function(Event) onSelect; + final void Function(Event) onAvatarTab; + final void Function(Event) onInfoTab; + final void Function(String) scrollToEventId; + final void Function() onSwipe; final bool longPressSelect; final bool selected; final Timeline timeline; + // #Pangea + final LanguageModel? selectedDisplayLang; + final bool immersionMode; + final bool definitions; + // Pangea# const Message( this.event, { this.nextEvent, this.displayReadMarker = false, this.longPressSelect = false, - this.onSelect, - this.onInfoTab, - this.onAvatarTab, - this.scrollToEventId, + required this.onSelect, + required this.onInfoTab, + required this.onAvatarTab, + required this.scrollToEventId, required this.onSwipe, this.selected = false, required this.timeline, - Key? key, - }) : super(key: key); - - /// Indicates wheither the user may use a mouse instead - /// of touchscreen. - static bool useMouse = false; + // #Pangea + required this.selectedDisplayLang, + required this.immersionMode, + required this.definitions, + // Pangea# + super.key, + }); @override Widget build(BuildContext context) { + // #Pangea + debugPrint('Message.build()'); + // Pangea# if (!{ EventTypes.Message, EventTypes.Sticker, @@ -70,7 +82,7 @@ class Message extends StatelessWidget { final client = Matrix.of(context).client; final ownMessage = event.senderId == client.userID; final alignment = ownMessage ? Alignment.topRight : Alignment.topLeft; - var color = Theme.of(context).colorScheme.surfaceVariant; + var color = Theme.of(context).colorScheme.onInverseSurface; final displayTime = event.type == EventTypes.RoomCreate || nextEvent == null || !event.originServerTs.sameEnvironment(nextEvent!.originServerTs); @@ -84,7 +96,7 @@ class Message extends StatelessWidget { nextEvent!.senderId == event.senderId && !displayTime; final textColor = ownMessage - ? Theme.of(context).colorScheme.onPrimary + ? Theme.of(context).colorScheme.onPrimaryContainer : Theme.of(context).colorScheme.onBackground; final rowMainAxisAlignment = ownMessage ? MainAxisAlignment.end : MainAxisAlignment.start; @@ -114,45 +126,52 @@ class Message extends StatelessWidget { if (ownMessage) { color = displayEvent.status.isError ? Colors.redAccent - : Theme.of(context).colorScheme.primary; + : Theme.of(context).colorScheme.primaryContainer; } + // #Pangea + final pangeaMessageEvent = PangeaMessageEvent( + event: event, + timeline: timeline, + ownMessage: ownMessage, + selected: selected, + ); + // Pangea# + final row = Row( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: rowMainAxisAlignment, children: [ - sameSender || ownMessage - ? SizedBox( - width: Avatar.defaultSize, - child: Padding( - padding: const EdgeInsets.only(top: 8.0), - child: Center( - child: SizedBox( - width: 16, - height: 16, - child: event.status == EventStatus.sending - ? const CircularProgressIndicator.adaptive( - strokeWidth: 2, - ) - : event.status == EventStatus.error - ? const Icon(Icons.error, color: Colors.red) - : null, - ), - ), - ), - ) - : FutureBuilder( - future: event.fetchSenderUser(), - builder: (context, snapshot) { - final user = - snapshot.data ?? event.senderFromMemoryOrFallback; - return Avatar( - mxContent: user.avatarUrl, - name: user.calcDisplayname(), - onTap: () => onAvatarTab!(event), - ); - }, + if (sameSender || ownMessage) + SizedBox( + width: Avatar.defaultSize, + child: Center( + child: SizedBox( + width: 16, + height: 16, + child: event.status == EventStatus.sending + ? const CircularProgressIndicator.adaptive( + strokeWidth: 2, + ) + : event.status == EventStatus.error + ? const Icon(Icons.error, color: Colors.red) + : null, ), + ), + ) + else + FutureBuilder( + future: event.fetchSenderUser(), + builder: (context, snapshot) { + final user = snapshot.data ?? event.senderFromMemoryOrFallback; + return Avatar( + mxContent: user.avatarUrl, + name: user.calcDisplayname(), + presenceUserId: user.stateKey, + onTap: () => onAvatarTab(event), + ); + }, + ), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -191,82 +210,111 @@ class Message extends StatelessWidget { color: noBubble ? Colors.transparent : color, borderRadius: borderRadius, clipBehavior: Clip.antiAlias, - child: Container( - decoration: BoxDecoration( - borderRadius: - BorderRadius.circular(AppConfig.borderRadius), - ), - padding: noBubble || noPadding - ? EdgeInsets.zero - : const EdgeInsets.symmetric( - horizontal: 16, - vertical: 8, - ), - constraints: const BoxConstraints( - maxWidth: FluffyThemes.columnWidth * 1.5, - ), - child: Stack( - children: [ - Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - if (event.relationshipType == - RelationshipTypes.reply) - FutureBuilder( - future: event.getReplyEvent(timeline), - builder: (BuildContext context, snapshot) { - final replyEvent = snapshot.hasData - ? snapshot.data! - : Event( - eventId: event.relationshipEventId!, - content: { - 'msgtype': 'm.text', - 'body': '...', - }, - senderId: event.senderId, - type: 'm.room.message', - room: event.room, - status: EventStatus.sent, - originServerTs: DateTime.now(), - ); - return InkWell( - onTap: () { - if (scrollToEventId != null) { - scrollToEventId!(replyEvent.eventId); - } - }, - child: AbsorbPointer( - child: Container( - margin: const EdgeInsets.symmetric( - vertical: 4.0, - ), - child: ReplyContent( - replyEvent, - ownMessage: ownMessage, - timeline: timeline, - ), + // #Pangea + child: CompositedTransformTarget( + link: MatrixState.pAnyState + .layerLinkAndKey(event.eventId) + .link, + child: Container( + key: MatrixState.pAnyState + .layerLinkAndKey(event.eventId) + .key, + // Pangea# + decoration: BoxDecoration( + borderRadius: + BorderRadius.circular(AppConfig.borderRadius), + ), + padding: noBubble || noPadding + ? EdgeInsets.zero + : const EdgeInsets.symmetric( + horizontal: 16, + vertical: 8, + ), + constraints: const BoxConstraints( + maxWidth: FluffyThemes.columnWidth * 1.5, + ), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (event.relationshipType == RelationshipTypes.reply) + FutureBuilder( + future: event.getReplyEvent(timeline), + builder: (BuildContext context, snapshot) { + final replyEvent = snapshot.hasData + ? snapshot.data! + : Event( + eventId: event.relationshipEventId!, + content: { + 'msgtype': 'm.text', + 'body': '...', + }, + senderId: event.senderId, + type: 'm.room.message', + room: event.room, + status: EventStatus.sent, + originServerTs: DateTime.now(), + ); + return InkWell( + onTap: () => + scrollToEventId(replyEvent.eventId), + child: AbsorbPointer( + child: Container( + margin: const EdgeInsets.symmetric( + vertical: 4.0, + ), + child: ReplyContent( + replyEvent, + ownMessage: ownMessage, + timeline: timeline, ), ), - ); - }, - ), - MessageContent( - displayEvent, - textColor: textColor, - onInfoTab: onInfoTab, + ), + ); + }, ), - if (event.hasAggregatedEvents( - timeline, - RelationshipTypes.edit, - )) - Padding( - padding: const EdgeInsets.only( - top: 4.0, - ), - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ + MessageContent( + displayEvent, + textColor: textColor, + onInfoTab: onInfoTab, + borderRadius: borderRadius, + // #Pangea + selected: selected, + pangeaMessageEvent: pangeaMessageEvent, + selectedDisplayLang: selectedDisplayLang, + immersionMode: immersionMode, + definitions: definitions, + // Pangea# + ), + if (event.hasAggregatedEvents( + timeline, + RelationshipTypes.edit, + ) + // #Pangea + || + (pangeaMessageEvent.showUseType) + // Pangea# + ) + Padding( + padding: const EdgeInsets.only( + top: 4.0, + ), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + // #Pangea + if (pangeaMessageEvent.showUseType) ...[ + pangeaMessageEvent.useType.iconView( + context, + textColor.withAlpha(164), + ), + const SizedBox(width: 4), + ], + if (event.hasAggregatedEvents( + timeline, + RelationshipTypes.edit, + )) ...[ + // Pangea# Icon( Icons.edit_outlined, color: textColor.withAlpha(164), @@ -280,11 +328,11 @@ class Message extends StatelessWidget { ), ), ], - ), + ], ), - ], - ), - ], + ), + ], + ), ), ), ), @@ -386,32 +434,25 @@ class Message extends StatelessWidget { background: const Padding( padding: EdgeInsets.symmetric(horizontal: 12.0), child: Center( - child: Icon(Icons.reply_outlined), + child: Icon(Icons.check_outlined), ), ), direction: SwipeDirection.endToStart, - onSwipe: onSwipe, - child: Center( - child: MouseRegion( - onEnter: (_) => useMouse = true, - onExit: (_) => useMouse = false, - child: InkWell( - onTap: longPressSelect || useMouse ? () => onSelect!(event) : null, - onLongPress: () => onSelect!(event), - child: Container( - color: selected - ? Theme.of(context).primaryColor.withAlpha(100) - : Theme.of(context).primaryColor.withAlpha(0), - constraints: const BoxConstraints( - maxWidth: FluffyThemes.columnWidth * 2.5, - ), - padding: const EdgeInsets.symmetric( - horizontal: 8.0, - vertical: 4.0, - ), - child: container, - ), + onSwipe: (_) => onSwipe(), + child: InkWell( + onTap: () => onSelect(event), + child: Container( + color: selected + ? Theme.of(context).primaryColor.withAlpha(100) + : Theme.of(context).primaryColor.withAlpha(0), + constraints: const BoxConstraints( + maxWidth: FluffyThemes.columnWidth * 2.5, ), + padding: const EdgeInsets.symmetric( + horizontal: 8.0, + vertical: 4.0, + ), + child: container, ), ), ); diff --git a/lib/pages/chat/events/message_content.dart b/lib/pages/chat/events/message_content.dart index 2be0ba826..a498d22e2 100644 --- a/lib/pages/chat/events/message_content.dart +++ b/lib/pages/chat/events/message_content.dart @@ -5,15 +5,16 @@ import 'package:flutter_linkify/flutter_linkify.dart'; import 'package:matrix/matrix.dart'; import 'package:fluffychat/pages/chat/events/video_player.dart'; +import 'package:fluffychat/pangea/models/language_model.dart'; +import 'package:fluffychat/pangea/models/pangea_message_event.dart'; +import 'package:fluffychat/pangea/widgets/igc/pangea_rich_text.dart'; import 'package:fluffychat/utils/adaptive_bottom_sheet.dart'; import 'package:fluffychat/utils/date_time_extension.dart'; import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart'; import 'package:fluffychat/widgets/avatar.dart'; -import 'package:fluffychat/widgets/matrix.dart'; import '../../../config/app_config.dart'; import '../../../utils/platform_infos.dart'; import '../../../utils/url_launcher.dart'; -import '../../bootstrap/bootstrap_dialog.dart'; import 'audio_player.dart'; import 'cute_events.dart'; import 'html_message.dart'; @@ -26,13 +27,32 @@ class MessageContent extends StatelessWidget { final Event event; final Color textColor; final void Function(Event)? onInfoTab; + final BorderRadius borderRadius; + // #Pangea + final bool selected; + final PangeaMessageEvent pangeaMessageEvent; + //question: are there any performance benefits to using booleans + //here rather than passing the choreographer? pangea rich text, a widget + //further down in the chain is also using pangeaController so its not constant + final LanguageModel? selectedDisplayLang; + final bool immersionMode; + final bool definitions; + // Pangea# const MessageContent( this.event, { this.onInfoTab, - Key? key, + super.key, required this.textColor, - }) : super(key: key); + // #Pangea + required this.selected, + required this.pangeaMessageEvent, + required this.selectedDisplayLang, + required this.immersionMode, + required this.definitions, + // Pangea# + required this.borderRadius, + }); void _verifyOrRequestKey(BuildContext context) async { final l10n = L10n.of(context)!; @@ -50,13 +70,15 @@ class MessageContent extends StatelessWidget { ); return; } - final client = Matrix.of(context).client; - if (client.isUnknownSession && client.encryption!.crossSigning.enabled) { - final success = await BootstrapDialog( - client: Matrix.of(context).client, - ).show(context); - if (success != true) return; - } + // #Pangea + // final client = Matrix.of(context).client; + // if (client.isUnknownSession && client.encryption!.crossSigning.enabled) { + // final success = await BootstrapDialog( + // client: Matrix.of(context).client, + // ).show(context); + // if (success != true) return; + // } + // Pangea# event.requestKey(); final sender = event.senderFromMemoryOrFallback; await showAdaptiveBottomSheet( @@ -78,6 +100,7 @@ class MessageContent extends StatelessWidget { leading: Avatar( mxContent: sender.avatarUrl, name: sender.calcDisplayname(), + presenceUserId: sender.stateKey, ), title: Text(sender.calcDisplayname()), subtitle: Text(event.originServerTs.localizedTime(context)), @@ -111,6 +134,7 @@ class MessageContent extends StatelessWidget { width: 400, height: 300, fit: BoxFit.cover, + borderRadius: borderRadius, ); case MessageTypes.Sticker: if (event.redacted) continue textmessage; @@ -231,12 +255,41 @@ class MessageContent extends StatelessWidget { final bigEmotes = event.onlyEmotes && event.numberEmotes > 0 && event.numberEmotes <= 10; + // #Pangea + final messageTextStyle = TextStyle( + color: textColor, + fontSize: bigEmotes ? fontSize * 3 : fontSize, + decoration: event.redacted ? TextDecoration.lineThrough : null, + height: 1.3, + ); + if (pangeaMessageEvent.showRichText) { + return PangeaRichText( + existingStyle: messageTextStyle, + selected: selected, + pangeaMessageEvent: pangeaMessageEvent, + immersionMode: immersionMode, + definitions: definitions, + selectedDisplayLang: selectedDisplayLang, + ); + } + //Pangea# return FutureBuilder( future: event.calcLocalizedBody( MatrixLocals(L10n.of(context)!), hideReply: true, ), builder: (context, snapshot) { + // #Pangea + if (!snapshot.hasData) { + return Text( + event.calcLocalizedBodyFallback( + MatrixLocals(L10n.of(context)!), + hideReply: true, + ), + style: messageTextStyle, + ); + } + // Pangea# return Linkify( text: snapshot.data ?? event.calcLocalizedBodyFallback( @@ -311,8 +364,7 @@ class _ButtonContent extends StatelessWidget { required this.textColor, required this.onPressed, required this.fontSize, - Key? key, - }) : super(key: key); + }); @override Widget build(BuildContext context) { diff --git a/lib/pages/chat/events/message_download_content.dart b/lib/pages/chat/events/message_download_content.dart index 42dcdff97..767ea8e7b 100644 --- a/lib/pages/chat/events/message_download_content.dart +++ b/lib/pages/chat/events/message_download_content.dart @@ -8,8 +8,7 @@ class MessageDownloadContent extends StatelessWidget { final Event event; final Color textColor; - const MessageDownloadContent(this.event, this.textColor, {Key? key}) - : super(key: key); + const MessageDownloadContent(this.event, this.textColor, {super.key}); @override Widget build(BuildContext context) { diff --git a/lib/pages/chat/events/message_reactions.dart b/lib/pages/chat/events/message_reactions.dart index 110553b9e..7e731c93b 100644 --- a/lib/pages/chat/events/message_reactions.dart +++ b/lib/pages/chat/events/message_reactions.dart @@ -1,4 +1,3 @@ -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:collection/collection.dart' show IterableExtension; @@ -6,7 +5,6 @@ import 'package:future_loading_dialog/future_loading_dialog.dart'; import 'package:matrix/matrix.dart'; import 'package:fluffychat/config/app_config.dart'; -import 'package:fluffychat/utils/platform_infos.dart'; import 'package:fluffychat/widgets/avatar.dart'; import 'package:fluffychat/widgets/matrix.dart'; import 'package:fluffychat/widgets/mxc_image.dart'; @@ -15,8 +13,7 @@ class MessageReactions extends StatelessWidget { final Event event; final Timeline timeline; - const MessageReactions(this.event, this.timeline, {Key? key}) - : super(key: key); + const MessageReactions(this.event, this.timeline, {super.key}); @override Widget build(BuildContext context) { @@ -50,36 +47,34 @@ class MessageReactions extends StatelessWidget { spacing: 4.0, runSpacing: 4.0, children: [ - ...reactionList - .map( - (r) => _Reaction( - reactionKey: r.key, - count: r.count, - reacted: r.reacted, - onTap: () { - if (r.reacted) { - final evt = allReactionEvents.firstWhereOrNull( - (e) => - e.senderId == e.room.client.userID && - e.content.tryGetMap('m.relates_to')?['key'] == r.key, - ); - if (evt != null) { - showFutureLoadingDialog( - context: context, - future: () => evt.redactEvent(), - ); - } - } else { - event.room.sendReaction(event.eventId, r.key!); - } - }, - onLongPress: () async => await _AdaptableReactorsDialog( - client: client, - reactionEntry: r, - ).show(context), - ), - ) - .toList(), + ...reactionList.map( + (r) => _Reaction( + reactionKey: r.key, + count: r.count, + reacted: r.reacted, + onTap: () { + if (r.reacted) { + final evt = allReactionEvents.firstWhereOrNull( + (e) => + e.senderId == e.room.client.userID && + e.content.tryGetMap('m.relates_to')?['key'] == r.key, + ); + if (evt != null) { + showFutureLoadingDialog( + context: context, + future: () => evt.redactEvent(), + ); + } + } else { + event.room.sendReaction(event.eventId, r.key!); + } + }, + onLongPress: () async => await _AdaptableReactorsDialog( + client: client, + reactionEntry: r, + ).show(context), + ), + ), if (allReactionEvents.any((e) => e.status.isSending)) const SizedBox( width: 28, @@ -190,24 +185,16 @@ class _AdaptableReactorsDialog extends StatelessWidget { final _ReactionEntry? reactionEntry; const _AdaptableReactorsDialog({ - Key? key, this.client, this.reactionEntry, - }) : super(key: key); + }); - Future show(BuildContext context) => PlatformInfos.isCupertinoStyle - ? showCupertinoDialog( - context: context, - builder: (context) => this, - barrierDismissible: true, - useRootNavigator: false, - ) - : showDialog( - context: context, - builder: (context) => this, - barrierDismissible: true, - useRootNavigator: false, - ); + Future show(BuildContext context) => showAdaptiveDialog( + context: context, + builder: (context) => this, + barrierDismissible: true, + useRootNavigator: false, + ); @override Widget build(BuildContext context) { @@ -223,6 +210,7 @@ class _AdaptableReactorsDialog extends StatelessWidget { mxContent: reactor.avatarUrl, name: reactor.displayName, client: client, + presenceUserId: reactor.stateKey, ), label: Text(reactor.displayName!), ), @@ -232,14 +220,9 @@ class _AdaptableReactorsDialog extends StatelessWidget { final title = Center(child: Text(reactionEntry!.key!)); - return PlatformInfos.isCupertinoStyle - ? CupertinoAlertDialog( - title: title, - content: body, - ) - : AlertDialog( - title: title, - content: body, - ); + return AlertDialog.adaptive( + title: title, + content: body, + ); } } diff --git a/lib/pages/chat/events/reply_content.dart b/lib/pages/chat/events/reply_content.dart index 6de2e5924..4c70ae004 100644 --- a/lib/pages/chat/events/reply_content.dart +++ b/lib/pages/chat/events/reply_content.dart @@ -14,9 +14,9 @@ class ReplyContent extends StatelessWidget { const ReplyContent( this.replyEvent, { this.ownMessage = false, - Key? key, + super.key, this.timeline, - }) : super(key: key); + }); @override Widget build(BuildContext context) { @@ -36,7 +36,7 @@ class ReplyContent extends StatelessWidget { maxLines: 1, style: TextStyle( color: ownMessage - ? Theme.of(context).colorScheme.onPrimary + ? Theme.of(context).colorScheme.onPrimaryContainer : Theme.of(context).colorScheme.onBackground, fontSize: fontSize, ), @@ -49,7 +49,7 @@ class ReplyContent extends StatelessWidget { width: 3, height: fontSize * 2 + 6, color: ownMessage - ? Theme.of(context).colorScheme.onPrimary + ? Theme.of(context).colorScheme.onPrimaryContainer : Theme.of(context).colorScheme.onBackground, ), const SizedBox(width: 6), @@ -68,7 +68,7 @@ class ReplyContent extends StatelessWidget { style: TextStyle( fontWeight: FontWeight.bold, color: ownMessage - ? Theme.of(context).colorScheme.onPrimary + ? Theme.of(context).colorScheme.onPrimaryContainer : Theme.of(context).colorScheme.onBackground, fontSize: fontSize, ), diff --git a/lib/pages/chat/events/state_message.dart b/lib/pages/chat/events/state_message.dart index d60aa8148..b5e54eba3 100644 --- a/lib/pages/chat/events/state_message.dart +++ b/lib/pages/chat/events/state_message.dart @@ -8,7 +8,7 @@ import '../../../config/app_config.dart'; class StateMessage extends StatelessWidget { final Event event; - const StateMessage(this.event, {Key? key}) : super(key: key); + const StateMessage(this.event, {super.key}); @override Widget build(BuildContext context) { diff --git a/lib/pages/chat/events/sticker.dart b/lib/pages/chat/events/sticker.dart index 041eae7ae..8e52bfe39 100644 --- a/lib/pages/chat/events/sticker.dart +++ b/lib/pages/chat/events/sticker.dart @@ -10,7 +10,7 @@ import 'image_bubble.dart'; class Sticker extends StatefulWidget { final Event event; - const Sticker(this.event, {Key? key}) : super(key: key); + const Sticker(this.event, {super.key}); @override StickerState createState() => StickerState(); diff --git a/lib/pages/chat/events/verification_request_content.dart b/lib/pages/chat/events/verification_request_content.dart index a7271125c..5a0c75f4b 100644 --- a/lib/pages/chat/events/verification_request_content.dart +++ b/lib/pages/chat/events/verification_request_content.dart @@ -12,8 +12,8 @@ class VerificationRequestContent extends StatelessWidget { const VerificationRequestContent({ required this.event, required this.timeline, - Key? key, - }) : super(key: key); + super.key, + }); @override Widget build(BuildContext context) { diff --git a/lib/pages/chat/events/video_player.dart b/lib/pages/chat/events/video_player.dart index 3cfd1e703..573e1eb14 100644 --- a/lib/pages/chat/events/video_player.dart +++ b/lib/pages/chat/events/video_player.dart @@ -18,7 +18,7 @@ import '../../../utils/error_reporter.dart'; class EventVideoPlayer extends StatefulWidget { final Event event; - const EventVideoPlayer(this.event, {Key? key}) : super(key: key); + const EventVideoPlayer(this.event, {super.key}); @override EventVideoPlayerState createState() => EventVideoPlayerState(); @@ -59,6 +59,7 @@ class EventVideoPlayerState extends State { ); } else if (!kIsWeb && tmpFile != null && _chewieManager == null) { _chewieManager ??= ChewieController( + useRootNavigator: false, videoPlayerController: VideoPlayerController.file(tmpFile), autoPlay: true, autoInitialize: true, diff --git a/lib/pages/chat/input_bar.dart b/lib/pages/chat/input_bar.dart index cdff8e210..7e939b0c9 100644 --- a/lib/pages/chat/input_bar.dart +++ b/lib/pages/chat/input_bar.dart @@ -2,18 +2,15 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:emojis/emoji.dart'; -import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:flutter_typeahead/flutter_typeahead.dart'; import 'package:matrix/matrix.dart'; import 'package:pasteboard/pasteboard.dart'; import 'package:slugify/slugify.dart'; import 'package:fluffychat/config/app_config.dart'; +import 'package:fluffychat/pangea/widgets/igc/pangea_text_controller.dart'; import 'package:fluffychat/utils/platform_infos.dart'; -import 'package:fluffychat/widgets/mxc_image.dart'; -import '../../widgets/avatar.dart'; import '../../widgets/matrix.dart'; -import 'command_hints.dart'; class InputBar extends StatelessWidget { final Room room; @@ -24,7 +21,10 @@ class InputBar extends StatelessWidget { final ValueChanged? onSubmitted; final ValueChanged? onSubmitImage; final FocusNode? focusNode; - final TextEditingController? controller; + // #Pangea + // final TextEditingController? controller; + final PangeaTextController? controller; + // Pangea# final InputDecoration? decoration; final ValueChanged? onChanged; final bool? autofocus; @@ -44,18 +44,23 @@ class InputBar extends StatelessWidget { this.autofocus, this.textInputAction, this.readOnly = false, - Key? key, - }) : super(key: key); + super.key, + }); List> getSuggestions(String text) { - if (controller!.selection.baseOffset != - controller!.selection.extentOffset || - controller!.selection.baseOffset < 0) { - return []; // no entries if there is selected text - } + // #Pangea + final List> ret = >[]; + // if (controller!.selection.baseOffset != + // controller!.selection.extentOffset || + // controller!.selection.baseOffset < 0) { + // return []; // no entries if there is selected text + // } + // Pangea# final searchText = controller!.text.substring(0, controller!.selection.baseOffset); - final List> ret = >[]; + // #Pangea + // final List> ret = >[]; + // Pangea# const maxResults = 30; final commandMatch = RegExp(r'^/(\w*)$').firstMatch(searchText); @@ -221,104 +226,106 @@ class InputBar extends StatelessWidget { Map suggestion, Client? client, ) { - const size = 30.0; - const padding = EdgeInsets.all(4.0); - if (suggestion['type'] == 'command') { - final command = suggestion['name']!; - final hint = commandHint(L10n.of(context)!, command); - return Tooltip( - message: hint, - waitDuration: const Duration(days: 1), // don't show on hover - child: Container( - padding: padding, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - '/$command', - style: const TextStyle(fontFamily: 'monospace'), - ), - Text( - hint, - maxLines: 1, - overflow: TextOverflow.ellipsis, - style: Theme.of(context).textTheme.bodySmall, - ), - ], - ), - ), - ); - } - if (suggestion['type'] == 'emoji') { - final label = suggestion['label']!; - return Tooltip( - message: label, - waitDuration: const Duration(days: 1), // don't show on hover - child: Container( - padding: padding, - child: Text(label, style: const TextStyle(fontFamily: 'monospace')), - ), - ); - } - if (suggestion['type'] == 'emote') { - return Container( - padding: padding, - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - MxcImage( - // ensure proper ordering ... - key: ValueKey(suggestion['name']), - uri: suggestion['mxc'] is String - ? Uri.parse(suggestion['mxc'] ?? '') - : null, - width: size, - height: size, - ), - const SizedBox(width: 6), - Text(suggestion['name']!), - Expanded( - child: Align( - alignment: Alignment.centerRight, - child: Opacity( - opacity: suggestion['pack_avatar_url'] != null ? 0.8 : 0.5, - child: suggestion['pack_avatar_url'] != null - ? Avatar( - mxContent: Uri.tryParse( - suggestion.tryGet('pack_avatar_url') ?? '', - ), - name: suggestion.tryGet('pack_display_name'), - size: size * 0.9, - client: client, - ) - : Text(suggestion['pack_display_name']!), - ), - ), - ), - ], - ), - ); - } - if (suggestion['type'] == 'user' || suggestion['type'] == 'room') { - final url = Uri.parse(suggestion['avatar_url'] ?? ''); - return Container( - padding: padding, - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Avatar( - mxContent: url, - name: suggestion.tryGet('displayname') ?? - suggestion.tryGet('mxid'), - size: size, - client: client, - ), - const SizedBox(width: 6), - Text(suggestion['displayname'] ?? suggestion['mxid']!), - ], - ), - ); - } + // #Pangea + // const size = 30.0; + // const padding = EdgeInsets.all(4.0); + // if (suggestion['type'] == 'command') { + // final command = suggestion['name']!; + // final hint = commandHint(L10n.of(context)!, command); + // return Tooltip( + // message: hint, + // waitDuration: const Duration(days: 1), // don't show on hover + // child: Container( + // padding: padding, + // child: Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // Text( + // '/$command', + // style: const TextStyle(fontFamily: 'monospace'), + // ), + // Text( + // hint, + // maxLines: 1, + // overflow: TextOverflow.ellipsis, + // style: Theme.of(context).textTheme.bodySmall, + // ), + // ], + // ), + // ), + // ); + // } + // if (suggestion['type'] == 'emoji') { + // final label = suggestion['label']!; + // return Tooltip( + // message: label, + // waitDuration: const Duration(days: 1), // don't show on hover + // child: Container( + // padding: padding, + // child: Text(label, style: const TextStyle(fontFamily: 'monospace')), + // ), + // ); + // } + // if (suggestion['type'] == 'emote') { + // return Container( + // padding: padding, + // child: Row( + // crossAxisAlignment: CrossAxisAlignment.center, + // children: [ + // MxcImage( + // // ensure proper ordering ... + // key: ValueKey(suggestion['name']), + // uri: suggestion['mxc'] is String + // ? Uri.parse(suggestion['mxc'] ?? '') + // : null, + // width: size, + // height: size, + // ), + // const SizedBox(width: 6), + // Text(suggestion['name']!), + // Expanded( + // child: Align( + // alignment: Alignment.centerRight, + // child: Opacity( + // opacity: suggestion['pack_avatar_url'] != null ? 0.8 : 0.5, + // child: suggestion['pack_avatar_url'] != null + // ? Avatar( + // mxContent: Uri.tryParse( + // suggestion.tryGet('pack_avatar_url') ?? '', + // ), + // name: suggestion.tryGet('pack_display_name'), + // size: size * 0.9, + // client: client, + // ) + // : Text(suggestion['pack_display_name']!), + // ), + // ), + // ), + // ], + // ), + // ); + // } + // if (suggestion['type'] == 'user' || suggestion['type'] == 'room') { + // final url = Uri.parse(suggestion['avatar_url'] ?? ''); + // return Container( + // padding: padding, + // child: Row( + // crossAxisAlignment: CrossAxisAlignment.center, + // children: [ + // Avatar( + // mxContent: url, + // name: suggestion.tryGet('displayname') ?? + // suggestion.tryGet('mxid'), + // size: size, + // client: client, + // ), + // const SizedBox(width: 6), + // Text(suggestion['displayname'] ?? suggestion['mxid']!), + // ], + // ), + // ); + // } + // Pangea# return const SizedBox.shrink(); } @@ -445,45 +452,61 @@ class InputBar extends StatelessWidget { }, ), }, - child: TypeAheadField>( - direction: AxisDirection.up, - hideOnEmpty: true, - hideOnLoading: true, - keepSuggestionsOnSuggestionSelected: true, - debounceDuration: const Duration(milliseconds: 50), - // show suggestions after 50ms idle time (default is 300) - textFieldConfiguration: TextFieldConfiguration( - minLines: minLines, - maxLines: maxLines, - keyboardType: keyboardType!, - textInputAction: textInputAction, - autofocus: autofocus!, - onSubmitted: (text) { - // fix for library for now - // it sets the types for the callback incorrectly - onSubmitted!(text); - }, - controller: controller, - decoration: decoration!, - focusNode: focusNode, - onChanged: (text) { - // fix for the library for now - // it sets the types for the callback incorrectly - onChanged!(text); - }, - textCapitalization: TextCapitalization.sentences, + // #Pangea + child: CompositedTransformTarget( + link: controller!.choreographer.inputLayerLinkAndKey.link, + // Pangea# + child: TypeAheadField>( + direction: AxisDirection.up, + hideOnEmpty: true, + hideOnLoading: true, + keepSuggestionsOnSuggestionSelected: true, + debounceDuration: const Duration(milliseconds: 50), + // show suggestions after 50ms idle time (default is 300) + // #Pangea + key: controller!.choreographer.inputLayerLinkAndKey.key, + // Pangea# + textFieldConfiguration: TextFieldConfiguration( + minLines: minLines, + maxLines: maxLines, + keyboardType: keyboardType!, + textInputAction: textInputAction, + autofocus: autofocus!, + onSubmitted: (text) { + // fix for library for now + // it sets the types for the callback incorrectly + onSubmitted!(text); + }, + // #Pangea + onTap: () { + controller!.onInputTap( + context, + fNode: focusNode!, + ); + }, + // Pangea# + controller: controller, + decoration: decoration!, + focusNode: focusNode, + onChanged: (text) { + // fix for the library for now + // it sets the types for the callback incorrectly + onChanged!(text); + }, + textCapitalization: TextCapitalization.sentences, + ), + suggestionsCallback: getSuggestions, + itemBuilder: (c, s) => + buildSuggestion(c, s, Matrix.of(context).client), + onSuggestionSelected: (Map suggestion) => + insertSuggestion(context, suggestion), + errorBuilder: (BuildContext context, Object? error) => + const SizedBox.shrink(), + loadingBuilder: (BuildContext context) => const SizedBox.shrink(), + // fix loading briefly flickering a dark box + noItemsFoundBuilder: (BuildContext context) => const SizedBox + .shrink(), // fix loading briefly showing no suggestions ), - suggestionsCallback: getSuggestions, - itemBuilder: (c, s) => - buildSuggestion(c, s, Matrix.of(context).client), - onSuggestionSelected: (Map suggestion) => - insertSuggestion(context, suggestion), - errorBuilder: (BuildContext context, Object? error) => - const SizedBox.shrink(), - loadingBuilder: (BuildContext context) => const SizedBox.shrink(), - // fix loading briefly flickering a dark box - noItemsFoundBuilder: (BuildContext context) => const SizedBox - .shrink(), // fix loading briefly showing no suggestions ), ), ); diff --git a/lib/pages/chat/pinned_events.dart b/lib/pages/chat/pinned_events.dart index ae81b46e4..e7c90c6e1 100644 --- a/lib/pages/chat/pinned_events.dart +++ b/lib/pages/chat/pinned_events.dart @@ -15,7 +15,7 @@ import 'package:fluffychat/utils/url_launcher.dart'; class PinnedEvents extends StatelessWidget { final ChatController controller; - const PinnedEvents(this.controller, {Key? key}) : super(key: key); + const PinnedEvents(this.controller, {super.key}); Future _displayPinnedEventsDialog( BuildContext context, diff --git a/lib/pages/chat/reactions_picker.dart b/lib/pages/chat/reactions_picker.dart index 4ae5505fd..6434c9970 100644 --- a/lib/pages/chat/reactions_picker.dart +++ b/lib/pages/chat/reactions_picker.dart @@ -11,7 +11,7 @@ import '../../config/themes.dart'; class ReactionsPicker extends StatelessWidget { final ChatController controller; - const ReactionsPicker(this.controller, {Key? key}) : super(key: key); + const ReactionsPicker(this.controller, {super.key}); @override Widget build(BuildContext context) { diff --git a/lib/pages/chat/recording_dialog.dart b/lib/pages/chat/recording_dialog.dart index 86d6cbb61..c25bd2741 100644 --- a/lib/pages/chat/recording_dialog.dart +++ b/lib/pages/chat/recording_dialog.dart @@ -15,8 +15,8 @@ import 'events/audio_player.dart'; class RecordingDialog extends StatefulWidget { static const String recordingFileType = 'm4a'; const RecordingDialog({ - Key? key, - }) : super(key: key); + super.key, + }); @override RecordingDialogState createState() => RecordingDialogState(); @@ -46,7 +46,16 @@ class RecordingDialogState extends State { return; } await WakelockPlus.enable(); + + // We try to pick Opus where supported, since that is a codec optimized + // for speech as well as what the voice messages MSC uses. + final audioCodec = + (await _audioRecorder.isEncoderSupported(AudioEncoder.opus)) + ? AudioEncoder.opus + : AudioEncoder.aacLc; + await _audioRecorder.start( + encoder: audioCodec, path: _recordedPath, bitRate: bitRate, samplingRate: samplingRate, diff --git a/lib/pages/chat/reply_display.dart b/lib/pages/chat/reply_display.dart index 77edee1dc..32bec7c25 100644 --- a/lib/pages/chat/reply_display.dart +++ b/lib/pages/chat/reply_display.dart @@ -10,7 +10,7 @@ import 'events/reply_content.dart'; class ReplyDisplay extends StatelessWidget { final ChatController controller; - const ReplyDisplay(this.controller, {Key? key}) : super(key: key); + const ReplyDisplay(this.controller, {super.key}); @override Widget build(BuildContext context) { diff --git a/lib/pages/chat/seen_by_row.dart b/lib/pages/chat/seen_by_row.dart index 47bc4f9ce..faac0db4d 100644 --- a/lib/pages/chat/seen_by_row.dart +++ b/lib/pages/chat/seen_by_row.dart @@ -8,7 +8,7 @@ import 'package:fluffychat/widgets/matrix.dart'; class SeenByRow extends StatelessWidget { final ChatController controller; - const SeenByRow(this.controller, {Key? key}) : super(key: key); + const SeenByRow(this.controller, {super.key}); @override Widget build(BuildContext context) { @@ -38,14 +38,13 @@ class SeenByRow extends StatelessWidget { ? seenByUsers.sublist(0, maxAvatars) : seenByUsers) .map( - (user) => Avatar( - mxContent: user.avatarUrl, - name: user.calcDisplayname(), - size: 16, - fontSize: 9, - ), - ) - .toList(), + (user) => Avatar( + mxContent: user.avatarUrl, + name: user.calcDisplayname(), + size: 16, + fontSize: 9, + ), + ), if (seenByUsers.length > maxAvatars) SizedBox( width: 16, diff --git a/lib/pages/chat/send_file_dialog.dart b/lib/pages/chat/send_file_dialog.dart index 11b61db79..e5f070fd7 100644 --- a/lib/pages/chat/send_file_dialog.dart +++ b/lib/pages/chat/send_file_dialog.dart @@ -1,9 +1,11 @@ +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:future_loading_dialog/future_loading_dialog.dart'; import 'package:matrix/matrix.dart'; +import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/utils/localized_exception_extension.dart'; import 'package:fluffychat/utils/size_string.dart'; import '../../utils/resize_image.dart'; @@ -15,8 +17,8 @@ class SendFileDialog extends StatefulWidget { const SendFileDialog({ required this.room, required this.files, - Key? key, - }) : super(key: key); + super.key, + }); @override SendFileDialogState createState() => SendFileDialogState(); @@ -84,20 +86,41 @@ class SendFileDialogState extends State { mainAxisSize: MainAxisSize.min, children: [ Flexible( - child: Image.memory( - widget.files.first.bytes, - fit: BoxFit.contain, + child: Material( + borderRadius: BorderRadius.circular(AppConfig.borderRadius), + elevation: + Theme.of(context).appBarTheme.scrolledUnderElevation ?? 4, + shadowColor: Theme.of(context).appBarTheme.shadowColor, + clipBehavior: Clip.hardEdge, + child: Image.memory( + widget.files.first.bytes, + fit: BoxFit.contain, + height: 256, + ), ), ), + const SizedBox(height: 16), + // Workaround for SwitchListTile.adaptive crashes in CupertinoDialog Row( - children: [ - Checkbox( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + CupertinoSwitch( value: origImage, - onChanged: (v) => setState(() => origImage = v ?? false), + onChanged: (v) => setState(() => origImage = v), ), - InkWell( - onTap: () => setState(() => origImage = !origImage), - child: Text('${L10n.of(context)!.sendOriginal} ($sizeString)'), + const SizedBox(width: 16), + Expanded( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + L10n.of(context)!.sendOriginal, + style: const TextStyle(fontWeight: FontWeight.bold), + ), + Text(sizeString), + ], + ), ), ], ), @@ -106,7 +129,7 @@ class SendFileDialogState extends State { } else { contentWidget = Text('$fileName ($sizeString)'); } - return AlertDialog( + return AlertDialog.adaptive( title: Text(sendStr), content: contentWidget, actions: [ diff --git a/lib/pages/chat/send_location_dialog.dart b/lib/pages/chat/send_location_dialog.dart index d29626f56..b2a99004e 100644 --- a/lib/pages/chat/send_location_dialog.dart +++ b/lib/pages/chat/send_location_dialog.dart @@ -9,15 +9,14 @@ import 'package:geolocator/geolocator.dart'; import 'package:matrix/matrix.dart'; import 'package:fluffychat/pages/chat/events/map_bubble.dart'; -import 'package:fluffychat/utils/platform_infos.dart'; class SendLocationDialog extends StatefulWidget { final Room room; const SendLocationDialog({ required this.room, - Key? key, - }) : super(key: key); + super.key, + }); @override SendLocationDialogState createState() => SendLocationDialogState(); @@ -111,23 +110,7 @@ class SendLocationDialogState extends State { ], ); } - if (PlatformInfos.isCupertinoStyle) { - return CupertinoAlertDialog( - title: Text(L10n.of(context)!.shareLocation), - content: contentWidget, - actions: [ - CupertinoDialogAction( - onPressed: Navigator.of(context, rootNavigator: false).pop, - child: Text(L10n.of(context)!.cancel), - ), - CupertinoDialogAction( - onPressed: isSending ? null : sendAction, - child: Text(L10n.of(context)!.send), - ), - ], - ); - } - return AlertDialog( + return AlertDialog.adaptive( title: Text(L10n.of(context)!.shareLocation), content: contentWidget, actions: [ diff --git a/lib/pages/chat/sticker_picker_dialog.dart b/lib/pages/chat/sticker_picker_dialog.dart index 80cae6b54..16065c916 100644 --- a/lib/pages/chat/sticker_picker_dialog.dart +++ b/lib/pages/chat/sticker_picker_dialog.dart @@ -9,7 +9,7 @@ import 'events/image_bubble.dart'; class StickerPickerDialog extends StatefulWidget { final Room room; - const StickerPickerDialog({required this.room, Key? key}) : super(key: key); + const StickerPickerDialog({required this.room, super.key}); @override StickerPickerDialogState createState() => StickerPickerDialogState(); diff --git a/lib/pages/chat/tombstone_display.dart b/lib/pages/chat/tombstone_display.dart index 50609cfd4..e080a0009 100644 --- a/lib/pages/chat/tombstone_display.dart +++ b/lib/pages/chat/tombstone_display.dart @@ -7,7 +7,7 @@ import 'chat.dart'; class TombstoneDisplay extends StatelessWidget { final ChatController controller; - const TombstoneDisplay(this.controller, {Key? key}) : super(key: key); + const TombstoneDisplay(this.controller, {super.key}); @override Widget build(BuildContext context) { diff --git a/lib/pages/chat/typing_indicators.dart b/lib/pages/chat/typing_indicators.dart index 3bb3f907e..8101fd76f 100644 --- a/lib/pages/chat/typing_indicators.dart +++ b/lib/pages/chat/typing_indicators.dart @@ -8,7 +8,7 @@ import 'package:fluffychat/widgets/matrix.dart'; class TypingIndicators extends StatelessWidget { final ChatController controller; - const TypingIndicators(this.controller, {Key? key}) : super(key: key); + const TypingIndicators(this.controller, {super.key}); @override Widget build(BuildContext context) { diff --git a/lib/pages/chat/widgets_bottom_sheet.dart b/lib/pages/chat/widgets_bottom_sheet.dart new file mode 100644 index 000000000..9ea89f614 --- /dev/null +++ b/lib/pages/chat/widgets_bottom_sheet.dart @@ -0,0 +1,49 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:matrix/matrix.dart'; +import 'package:url_launcher/link.dart'; + +import 'edit_widgets_dialog.dart'; + +class WidgetsBottomSheet extends StatelessWidget { + final Room room; + + const WidgetsBottomSheet({super.key, required this.room}); + + @override + Widget build(BuildContext context) { + return ListView.builder( + shrinkWrap: true, + itemBuilder: (context, index) { + if (index == room.widgets.length) { + return ListTile( + leading: const Icon(Icons.edit), + title: Text(L10n.of(context)!.editWidgets), + onTap: () { + Navigator.of(context).pop(); + showDialog( + context: context, + builder: (context) => EditWidgetsDialog(room: room), + useRootNavigator: false, + ); + }, + ); + } + final widget = room.widgets[index]; + return Link( + builder: (context, callback) { + return ListTile( + title: Text(widget.name ?? widget.url), + subtitle: Text(widget.type), + onTap: callback, + ); + }, + target: LinkTarget.blank, + uri: Uri.parse(widget.url), + ); + }, + itemCount: room.widgets.length + 1, + ); + } +} diff --git a/lib/pages/chat_details/chat_details.dart b/lib/pages/chat_details/chat_details.dart index b9da5c654..3bdefe8d5 100644 --- a/lib/pages/chat_details/chat_details.dart +++ b/lib/pages/chat_details/chat_details.dart @@ -13,6 +13,9 @@ import 'package:matrix/matrix.dart'; import 'package:fluffychat/pages/chat_details/chat_details_view.dart'; import 'package:fluffychat/pages/settings/settings.dart'; +import 'package:fluffychat/pangea/utils/set_class_name.dart'; +import 'package:fluffychat/pangea/utils/set_class_topic.dart'; +import 'package:fluffychat/pangea/widgets/class/add_space_toggles.dart'; import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart'; import 'package:fluffychat/utils/platform_infos.dart'; import 'package:fluffychat/widgets/app_lock.dart'; @@ -24,9 +27,9 @@ class ChatDetails extends StatefulWidget { final String roomId; const ChatDetails({ - Key? key, + super.key, required this.roomId, - }) : super(key: key); + }); @override ChatDetailsController createState() => ChatDetailsController(); @@ -40,34 +43,42 @@ class ChatDetailsController extends State { String? get roomId => widget.roomId; - void setDisplaynameAction() async { - final room = Matrix.of(context).client.getRoomById(roomId!)!; - final input = await showTextInputDialog( - context: context, - title: L10n.of(context)!.changeTheNameOfTheGroup, - okLabel: L10n.of(context)!.ok, - cancelLabel: L10n.of(context)!.cancel, - textFields: [ - DialogTextField( - initialText: room.getLocalizedDisplayname( - MatrixLocals( - L10n.of(context)!, - ), - ), - ), - ], - ); - if (input == null) return; - final success = await showFutureLoadingDialog( - context: context, - future: () => room.setName(input.single), - ); - if (success.error == null) { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar(content: Text(L10n.of(context)!.displaynameHasBeenChanged)), - ); - } - } + // #Pangea + final GlobalKey addToSpaceKey = GlobalKey(); + + bool displayAddStudentOptions = false; + void toggleAddStudentOptions() => + setState(() => displayAddStudentOptions = !displayAddStudentOptions); + void setDisplaynameAction() => setClassDisplayname(context, roomId); + // void setDisplaynameAction() async { + // final room = Matrix.of(context).client.getRoomById(roomId!)!; + // final input = await showTextInputDialog( + // context: context, + // title: L10n.of(context)!.changeTheNameOfTheGroup, + // okLabel: L10n.of(context)!.ok, + // cancelLabel: L10n.of(context)!.cancel, + // textFields: [ + // DialogTextField( + // initialText: room.getLocalizedDisplayname( + // MatrixLocals( + // L10n.of(context)!, + // ), + // ), + // ), + // ], + // ); + // if (input == null) return; + // final success = await showFutureLoadingDialog( + // context: context, + // future: () => room.setName(input.single), + // ); + // if (success.error == null) { + // ScaffoldMessenger.of(context).showSnackBar( + // SnackBar(content: Text(L10n.of(context)!.displaynameHasBeenChanged)), + // ); + // } + // } + // Pangea# void editAliases() async { final room = Matrix.of(context).client.getRoomById(roomId!); @@ -103,14 +114,16 @@ class ChatDetailsController extends State { return setAliasAction(); } final select = await showConfirmationDialog( + // #Pangea + useRootNavigator: false, + // Pangea# context: context, title: L10n.of(context)!.editRoomAliases, actions: [ if (adminMode) AlertDialogAction(label: L10n.of(context)!.create, key: 'new'), ...aliases.result! - .map((alias) => AlertDialogAction(key: alias, label: alias)) - .toList(), + .map((alias) => AlertDialogAction(key: alias, label: alias)), ], ); if (select == null) return; @@ -175,6 +188,9 @@ class ChatDetailsController extends State { final domain = room.client.userID!.domain; final input = await showTextInputDialog( + // #Pangea + useRootNavigator: false, + // Pangea# context: context, title: L10n.of(context)!.setInvitationLink, okLabel: L10n.of(context)!.ok, @@ -198,32 +214,35 @@ class ChatDetailsController extends State { void setTopicAction() async { final room = Matrix.of(context).client.getRoomById(roomId!)!; - final input = await showTextInputDialog( - context: context, - title: L10n.of(context)!.setChatDescription, - okLabel: L10n.of(context)!.ok, - cancelLabel: L10n.of(context)!.cancel, - textFields: [ - DialogTextField( - hintText: L10n.of(context)!.noChatDescriptionYet, - initialText: room.topic, - minLines: 4, - maxLines: 8, - ), - ], - ); - if (input == null) return; - final success = await showFutureLoadingDialog( - context: context, - future: () => room.setDescription(input.single), - ); - if (success.error == null) { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text(L10n.of(context)!.chatDescriptionHasBeenChanged), - ), - ); - } + // #Pangea + setClassTopic(room, context); + // final input = await showTextInputDialog( + // context: context, + // title: L10n.of(context)!.setChatDescription, + // okLabel: L10n.of(context)!.ok, + // cancelLabel: L10n.of(context)!.cancel, + // textFields: [ + // DialogTextField( + // hintText: L10n.of(context)!.noChatDescriptionYet, + // initialText: room.topic, + // minLines: 4, + // maxLines: 8, + // ), + // ], + // ); + // if (input == null) return; + // final success = await showFutureLoadingDialog( + // context: context, + // future: () => room.setDescription(input.single), + // ); + // if (success.error == null) { + // ScaffoldMessenger.of(context).showSnackBar( + // SnackBar( + // content: Text(L10n.of(context)!.chatDescriptionHasBeenChanged), + // ), + // ); + // } + // Pangea# } void setGuestAccess() async { @@ -400,4 +419,10 @@ class ChatDetailsController extends State { @override Widget build(BuildContext context) => ChatDetailsView(this); + + // #Pangea + bool showEditNameIcon = false; + void hoverEditNameIcon(bool hovering) => + setState(() => showEditNameIcon = !showEditNameIcon); + // Pangea# } diff --git a/lib/pages/chat_details/chat_details_view.dart b/lib/pages/chat_details/chat_details_view.dart index b7fd77bc9..ecebb9dd8 100644 --- a/lib/pages/chat_details/chat_details_view.dart +++ b/lib/pages/chat_details/chat_details_view.dart @@ -1,25 +1,34 @@ -import 'package:flutter/material.dart'; - -import 'package:flutter_gen/gen_l10n/l10n.dart'; -import 'package:flutter_linkify/flutter_linkify.dart'; -import 'package:go_router/go_router.dart'; -import 'package:matrix/matrix.dart'; - import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/pages/chat_details/chat_details.dart'; import 'package:fluffychat/pages/chat_details/participant_list_item.dart'; +import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart'; +import 'package:fluffychat/pangea/pages/class_settings/class_name_header.dart'; +import 'package:fluffychat/pangea/pages/class_settings/p_class_widgets/class_description_button.dart'; +import 'package:fluffychat/pangea/pages/class_settings/p_class_widgets/class_details_toggle_add_students_tile.dart'; +import 'package:fluffychat/pangea/pages/class_settings/p_class_widgets/class_invitation_buttons.dart'; +import 'package:fluffychat/pangea/pages/class_settings/p_class_widgets/class_name_button.dart'; +import 'package:fluffychat/pangea/pages/class_settings/p_class_widgets/room_rules_editor.dart'; +import 'package:fluffychat/pangea/utils/archive_space.dart'; +import 'package:fluffychat/pangea/utils/lock_room.dart'; +import 'package:fluffychat/pangea/widgets/class/add_class_and_invite.dart'; +import 'package:fluffychat/pangea/widgets/class/add_space_toggles.dart'; +import 'package:fluffychat/pangea/widgets/space/class_settings.dart'; import 'package:fluffychat/utils/fluffy_share.dart'; import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart'; import 'package:fluffychat/widgets/avatar.dart'; import 'package:fluffychat/widgets/chat_settings_popup_menu.dart'; import 'package:fluffychat/widgets/layouts/max_width_body.dart'; import 'package:fluffychat/widgets/matrix.dart'; -import '../../utils/url_launcher.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; +import 'package:go_router/go_router.dart'; +import 'package:matrix/matrix.dart'; class ChatDetailsView extends StatelessWidget { final ChatDetailsController controller; - const ChatDetailsView(this.controller, {Key? key}) : super(key: key); + const ChatDetailsView(this.controller, {super.key}); @override Widget build(BuildContext context) { @@ -57,18 +66,27 @@ class ChatDetailsView extends StatelessWidget { leading: const Center(child: BackButton()), elevation: Theme.of(context).appBarTheme.elevation, actions: [ - if (room.canonicalAlias.isNotEmpty) - IconButton( - tooltip: L10n.of(context)!.share, - icon: Icon(Icons.adaptive.share_outlined), - onPressed: () => FluffyShare.share( - AppConfig.inviteLinkPrefix + room.canonicalAlias, - context, - ), - ), - ChatSettingsPopupMenu(room, false), + // #Pangea + // if (room.canonicalAlias.isNotEmpty) + // IconButton( + // tooltip: L10n.of(context)!.share, + // icon: Icon(Icons.adaptive.share_outlined), + // onPressed: () => FluffyShare.share( + // AppConfig.inviteLinkPrefix + room.canonicalAlias, + // context, + // ), + // ), + if (!room.isSpace) + // Pangea# + ChatSettingsPopupMenu(room, false), ], - title: Text(L10n.of(context)!.chatDetails), + // #Pangea + title: ClassNameHeader( + controller: controller, + room: room, + ), + // title: Text(L10n.of(context)!.chatDetails), + // Pangea# backgroundColor: Theme.of(context).appBarTheme.backgroundColor, ), @@ -207,162 +225,216 @@ class ChatDetailsView extends StatelessWidget { height: 1, color: Theme.of(context).dividerColor, ), - if (!room.canChangeStateEvent(EventTypes.RoomTopic)) + // #Pangea + if (room.canSendEvent('m.room.name')) + ClassNameButton( + room: room, + controller: controller, + ), + if (room.canSendEvent('m.room.topic')) + ClassDescriptionButton( + room: room, + controller: controller, + ), + if ((room.isPangeaClass || room.isExchange) && + room.isRoomAdmin) ListTile( title: Text( - L10n.of(context)!.chatDescription, + L10n.of(context)!.classAnalytics, style: TextStyle( color: Theme.of(context).colorScheme.secondary, fontWeight: FontWeight.bold, ), ), - ) - else - Padding( - padding: const EdgeInsets.all(16.0), - child: OutlinedButton.icon( - onPressed: controller.setTopicAction, - label: Text(L10n.of(context)!.setChatDescription), - icon: const Icon(Icons.edit_outlined), - ), - ), - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 16.0, - ), - child: SelectableLinkify( - text: room.topic.isEmpty - ? L10n.of(context)!.noChatDescriptionYet - : room.topic, - options: const LinkifyOptions(humanize: false), - linkStyle: - const TextStyle(color: Colors.blueAccent), - style: TextStyle( - fontSize: 14, - fontStyle: room.topic.isEmpty - ? FontStyle.italic - : FontStyle.normal, - color: - Theme.of(context).textTheme.bodyMedium!.color, - decorationColor: - Theme.of(context).textTheme.bodyMedium!.color, - ), - onOpen: (url) => - UrlLauncher(context, url.url).launchUrl(), - ), - ), - const SizedBox(height: 16), - Divider( - height: 1, - color: Theme.of(context).dividerColor, - ), - if (room.joinRules == JoinRules.public) - ListTile( - leading: CircleAvatar( - backgroundColor: - Theme.of(context).scaffoldBackgroundColor, - foregroundColor: iconColor, - child: const Icon(Icons.link_outlined), - ), - trailing: const Icon(Icons.chevron_right_outlined), - onTap: controller.editAliases, - title: Text(L10n.of(context)!.editRoomAliases), - subtitle: Text( - (room.canonicalAlias.isNotEmpty) - ? room.canonicalAlias - : L10n.of(context)!.none, - ), - ), - ListTile( - leading: CircleAvatar( - backgroundColor: - Theme.of(context).scaffoldBackgroundColor, - foregroundColor: iconColor, - child: const Icon( - Icons.insert_emoticon_outlined, - ), - ), - title: Text(L10n.of(context)!.emoteSettings), - subtitle: Text(L10n.of(context)!.setCustomEmotes), - onTap: controller.goToEmoteSettings, - trailing: const Icon(Icons.chevron_right_outlined), - ), - if (!room.isDirectChat) - ListTile( - leading: CircleAvatar( - backgroundColor: - Theme.of(context).scaffoldBackgroundColor, - foregroundColor: iconColor, - child: const Icon(Icons.shield_outlined), - ), - title: Text( - L10n.of(context)!.whoIsAllowedToJoinThisGroup, - ), - trailing: room.canChangeJoinRules - ? const Icon(Icons.chevron_right_outlined) - : null, - subtitle: Text( - room.joinRules?.getLocalizedString( - MatrixLocals(L10n.of(context)!), - ) ?? - L10n.of(context)!.none, - ), - onTap: room.canChangeJoinRules - ? controller.setJoinRules - : null, - ), - if (!room.isDirectChat) - ListTile( - leading: CircleAvatar( - backgroundColor: - Theme.of(context).scaffoldBackgroundColor, - foregroundColor: iconColor, - child: const Icon(Icons.visibility_outlined), - ), - trailing: room.canChangeHistoryVisibility - ? const Icon(Icons.chevron_right_outlined) - : null, - title: Text( - L10n.of(context)!.visibilityOfTheChatHistory, - ), - subtitle: Text( - room.historyVisibility?.getLocalizedString( - MatrixLocals(L10n.of(context)!), - ) ?? - L10n.of(context)!.none, - ), - onTap: room.canChangeHistoryVisibility - ? controller.setHistoryVisibility - : null, - ), - if (room.joinRules == JoinRules.public) - ListTile( leading: CircleAvatar( backgroundColor: Theme.of(context).scaffoldBackgroundColor, foregroundColor: iconColor, child: const Icon( - Icons.person_add_alt_1_outlined, + Icons.analytics_outlined, ), ), - trailing: room.canChangeGuestAccess - ? const Icon(Icons.chevron_right_outlined) - : null, - title: Text( - L10n.of(context)!.areGuestsAllowedToJoin, + onTap: () => context.go( + '/rooms/analytics/${room.id}', ), - subtitle: Text( - room.guestAccess.getLocalizedString( - MatrixLocals(L10n.of(context)!), - ), - ), - onTap: room.canChangeGuestAccess - ? controller.setGuestAccess - : null, ), - if (!room.isDirectChat) + if (room.classSettings != null && room.isRoomAdmin) + ClassSettings( + roomId: controller.roomId, + startOpen: false, + ), + if (room.pangeaRoomRules != null && room.isRoomAdmin) + RoomRulesEditor( + roomId: controller.roomId, + startOpen: false, + ), + // if (!room.canChangeStateEvent(EventTypes.RoomTopic)) + // ListTile( + // title: Text( + // L10n.of(context)!.chatDescription, + // style: TextStyle( + // color: Theme.of(context).colorScheme.secondary, + // fontWeight: FontWeight.bold, + // ), + // ), + // ) + // else + // Padding( + // padding: const EdgeInsets.all(16.0), + // child: OutlinedButton.icon( + // onPressed: controller.setTopicAction, + // label: Text(L10n.of(context)!.setChatDescription), + // icon: const Icon(Icons.edit_outlined), + // ), + // ), + // Padding( + // padding: const EdgeInsets.symmetric( + // horizontal: 16.0, + // ), + // child: SelectableLinkify( + // text: room.topic.isEmpty + // ? L10n.of(context)!.noChatDescriptionYet + // : room.topic, + // options: const LinkifyOptions(humanize: false), + // linkStyle: + // const TextStyle(color: Colors.blueAccent), + // style: TextStyle( + // fontSize: 14, + // fontStyle: room.topic.isEmpty + // ? FontStyle.italic + // : FontStyle.normal, + // color: + // Theme.of(context).textTheme.bodyMedium!.color, + // decorationColor: + // Theme.of(context).textTheme.bodyMedium!.color, + // ), + // onOpen: (url) => + // UrlLauncher(context, url.url).launchUrl(), + // ), + // ), + // const SizedBox(height: 16), + // Divider( + // height: 1, + // color: Theme.of(context).dividerColor, + // ), + // if (room.joinRules == JoinRules.public) + // ListTile( + // leading: CircleAvatar( + // backgroundColor: + // Theme.of(context).scaffoldBackgroundColor, + // foregroundColor: iconColor, + // child: const Icon(Icons.link_outlined), + // ), + // trailing: const Icon(Icons.chevron_right_outlined), + // onTap: controller.editAliases, + // title: Text(L10n.of(context)!.editRoomAliases), + // subtitle: Text( + // (room.canonicalAlias.isNotEmpty) + // ? room.canonicalAlias + // : L10n.of(context)!.none, + // ), + // ), + // ListTile( + // leading: CircleAvatar( + // backgroundColor: + // Theme.of(context).scaffoldBackgroundColor, + // foregroundColor: iconColor, + // child: const Icon( + // Icons.insert_emoticon_outlined, + // ), + // ), + // title: Text(L10n.of(context)!.emoteSettings), + // subtitle: Text(L10n.of(context)!.setCustomEmotes), + // onTap: controller.goToEmoteSettings, + // trailing: const Icon(Icons.chevron_right_outlined), + // ), + // if (!room.isDirectChat) + // ListTile( + // leading: CircleAvatar( + // backgroundColor: + // Theme.of(context).scaffoldBackgroundColor, + // foregroundColor: iconColor, + // child: const Icon(Icons.shield_outlined), + // ), + // title: Text( + // L10n.of(context)!.whoIsAllowedToJoinThisGroup, + // ), + // trailing: room.canChangeJoinRules + // ? const Icon(Icons.chevron_right_outlined) + // : null, + // subtitle: Text( + // room.joinRules?.getLocalizedString( + // MatrixLocals(L10n.of(context)!), + // ) ?? + // L10n.of(context)!.none, + // ), + // onTap: room.canChangeJoinRules + // ? controller.setJoinRules + // : null, + // ), + // if (!room.isDirectChat) + // ListTile( + // leading: CircleAvatar( + // backgroundColor: + // Theme.of(context).scaffoldBackgroundColor, + // foregroundColor: iconColor, + // child: const Icon(Icons.visibility_outlined), + // ), + // trailing: room.canChangeHistoryVisibility + // ? const Icon(Icons.chevron_right_outlined) + // : null, + // title: Text( + // L10n.of(context)!.visibilityOfTheChatHistory, + // ), + // subtitle: Text( + // room.historyVisibility?.getLocalizedString( + // MatrixLocals(L10n.of(context)!), + // ) ?? + // L10n.of(context)!.none, + // ), + // onTap: room.canChangeHistoryVisibility + // ? controller.setHistoryVisibility + // : null, + // ), + // if (room.joinRules == JoinRules.public) + // ListTile( + // leading: CircleAvatar( + // backgroundColor: + // Theme.of(context).scaffoldBackgroundColor, + // foregroundColor: iconColor, + // child: const Icon( + // Icons.person_add_alt_1_outlined, + // ), + // ), + // trailing: room.canChangeGuestAccess + // ? const Icon(Icons.chevron_right_outlined) + // : null, + // title: Text( + // L10n.of(context)!.areGuestsAllowedToJoin, + // ), + // subtitle: Text( + // room.guestAccess.getLocalizedString( + // MatrixLocals(L10n.of(context)!), + // ), + // ), + // onTap: room.canChangeGuestAccess + // ? controller.setGuestAccess + // : null, + // ), + // if (!room.isDirectChat) + if (!room.isDirectChat && !room.isSpace) + // Pangea# ListTile( - title: Text(L10n.of(context)!.chatPermissions), + // #Pangea + // title: Text(L10n.of(context)!.chatPermissions), + title: Text( + L10n.of(context)!.editChatPermissions, + style: TextStyle( + color: Theme.of(context).colorScheme.secondary, + fontWeight: FontWeight.bold, + ), + ), + // Pangea# subtitle: Text( L10n.of(context)!.whoCanPerformWhichAction, ), @@ -374,7 +446,9 @@ class ChatDetailsView extends StatelessWidget { Icons.edit_attributes_outlined, ), ), - trailing: const Icon(Icons.chevron_right_outlined), + // #Pangea + // trailing: const Icon(Icons.chevron_right_outlined), + // Pangea# onTap: () => context .push('/rooms/${room.id}/details/permissions'), ), @@ -382,6 +456,111 @@ class ChatDetailsView extends StatelessWidget { height: 1, color: Theme.of(context).dividerColor, ), + // #Pangea + if (room.canInvite) + ListTile( + title: Text( + room.isSpace + ? L10n.of(context)!.inviteUsersFromPangea + : L10n.of(context)!.inviteStudentByUserName, + style: TextStyle( + color: Theme.of(context).colorScheme.secondary, + fontWeight: FontWeight.bold, + ), + ), + leading: CircleAvatar( + backgroundColor: + Theme.of(context).scaffoldBackgroundColor, + foregroundColor: + Theme.of(context).textTheme.bodyLarge!.color, + child: const Icon( + Icons.add, + ), + ), + onTap: () => context.go('/rooms/${room.id}/invite'), + ), + if (room.showClassEditOptions && room.isSpace) + SpaceDetailsToggleAddStudentsTile( + controller: controller, + ), + if (controller.displayAddStudentOptions && + room.showClassEditOptions) + ClassInvitationButtons(roomId: controller.roomId!), + if (!room.isPangeaClass) + AddToSpaceToggles( + roomId: room.id, + key: controller.addToSpaceKey, + startOpen: false, + mode: room.isExchange + ? AddToClassMode.exchange + : AddToClassMode.chat, + ), + const Divider(height: 1), + if (!room.isSpace || (room.isSpace && room.isRoomAdmin)) + ListTile( + title: Text( + room.isSpace + ? L10n.of(context)!.archiveSpace + : L10n.of(context)!.archive, + style: TextStyle( + color: Theme.of(context).colorScheme.secondary, + fontWeight: FontWeight.bold, + ), + ), + leading: CircleAvatar( + backgroundColor: + Theme.of(context).scaffoldBackgroundColor, + foregroundColor: iconColor, + child: const Icon( + Icons.archive_outlined, + ), + ), + onTap: () => showFutureLoadingDialog( + context: context, + future: () async { + room.isSpace + ? await archiveSpace( + room, + Matrix.of(context).client, + ) + : await room.leave(); + context.go('/rooms'); + }, + ), + ), + if (room.isRoomAdmin) + SwitchListTile.adaptive( + activeColor: AppConfig.activeToggleColor, + title: Text( + room.isSpace + ? L10n.of(context)!.lockSpace + : L10n.of(context)!.lockChat, + style: TextStyle( + color: Theme.of(context).colorScheme.secondary, + fontWeight: FontWeight.bold, + ), + ), + secondary: CircleAvatar( + backgroundColor: + Theme.of(context).scaffoldBackgroundColor, + foregroundColor: iconColor, + child: Icon( + room.locked + ? Icons.lock_outlined + : Icons.no_encryption_outlined, + ), + ), + value: room.locked, + onChanged: (value) => showFutureLoadingDialog( + context: context, + future: () => toggleLockRoom( + room, + Matrix.of(context).client, + ), + ), + ), + const Divider(height: 1), + // Pangea# ListTile( title: Text( L10n.of(context)!.countParticipants( @@ -393,18 +572,20 @@ class ChatDetailsView extends StatelessWidget { ), ), ), - if (!room.isDirectChat && room.canInvite) - ListTile( - title: Text(L10n.of(context)!.inviteContact), - leading: CircleAvatar( - backgroundColor: Theme.of(context).primaryColor, - foregroundColor: Colors.white, - radius: Avatar.defaultSize / 2, - child: const Icon(Icons.add_outlined), - ), - trailing: const Icon(Icons.chevron_right_outlined), - onTap: () => context.go('/rooms/${room.id}/invite'), - ), + // #Pangea + // if (!room.isDirectChat && room.canInvite) + // ListTile( + // title: Text(L10n.of(context)!.inviteContact), + // leading: CircleAvatar( + // backgroundColor: Theme.of(context).primaryColor, + // foregroundColor: Colors.white, + // radius: Avatar.defaultSize / 2, + // child: const Icon(Icons.add_outlined), + // ), + // trailing: const Icon(Icons.chevron_right_outlined), + // onTap: () => context.go('/rooms/${room.id}/invite'), + // ), + // Pangea# ], ) : i < members.length + 1 diff --git a/lib/pages/chat_details/participant_list_item.dart b/lib/pages/chat_details/participant_list_item.dart index 11848cb68..adbafe200 100644 --- a/lib/pages/chat_details/participant_list_item.dart +++ b/lib/pages/chat_details/participant_list_item.dart @@ -3,6 +3,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:matrix/matrix.dart'; +import 'package:fluffychat/pangea/utils/bot_name.dart'; import 'package:fluffychat/utils/adaptive_bottom_sheet.dart'; import '../../widgets/avatar.dart'; import '../user_bottom_sheet/user_bottom_sheet.dart'; @@ -10,7 +11,7 @@ import '../user_bottom_sheet/user_bottom_sheet.dart'; class ParticipantListItem extends StatelessWidget { final User user; - const ParticipantListItem(this.user, {Key? key}) : super(key: key); + const ParticipantListItem(this.user, {super.key}); @override Widget build(BuildContext context) { @@ -26,16 +27,33 @@ class ParticipantListItem extends StatelessWidget { ? L10n.of(context)!.moderator : ''; + // #Pangea + if (user.id == BotName.byEnvironment) { + return const SizedBox(); + } + // Pangea# + return Opacity( - opacity: user.membership == Membership.join ? 1 : 0.5, + //#Pangea + // opacity: user.membership == Membership.join? 1 : 0.5, + opacity: + user.membership == Membership.join && user.id != BotName.byEnvironment + ? 1 + : 0.5, + //Pangea# child: ListTile( - onTap: () => showAdaptiveBottomSheet( - context: context, - builder: (c) => UserBottomSheet( - user: user, - outerContext: context, - ), - ), + //#Pangea + // onTap: () => showAdaptiveBottomSheet( + onTap: user.id == BotName.byEnvironment + ? null + : () => showAdaptiveBottomSheet( + //Pangea# + context: context, + builder: (c) => UserBottomSheet( + user: user, + outerContext: context, + ), + ), title: Row( children: [ Expanded( @@ -52,18 +70,23 @@ class ParticipantListItem extends StatelessWidget { ), margin: const EdgeInsets.symmetric(horizontal: 8), decoration: BoxDecoration( - color: Theme.of(context).colorScheme.primaryContainer, + // #Pangea + // color: Theme.of(context).colorScheme.primaryContainer, + color: Theme.of(context).secondaryHeaderColor, borderRadius: BorderRadius.circular(8), - border: Border.all( - color: Theme.of(context).colorScheme.primary, - ), + // border: Border.all( + // color: Theme.of(context).colorScheme.primary, + // ), + // Pangea# ), child: Text( permissionBatch, - style: TextStyle( - fontSize: 14, - color: Theme.of(context).colorScheme.primary, - ), + // #Pangea + // style: TextStyle( + // fontSize: 14, + // color: Theme.of(context).colorScheme.primary, + // ), + // Pangea# ), ), membershipBatch[user.membership]!.isEmpty @@ -81,8 +104,11 @@ class ParticipantListItem extends StatelessWidget { ], ), subtitle: Text(user.id), - leading: - Avatar(mxContent: user.avatarUrl, name: user.calcDisplayname()), + leading: Avatar( + mxContent: user.avatarUrl, + name: user.calcDisplayname(), + presenceUserId: user.stateKey, + ), ), ); } diff --git a/lib/pages/chat_encryption_settings/chat_encryption_settings.dart b/lib/pages/chat_encryption_settings/chat_encryption_settings.dart index b8df84c80..c7aed03a3 100644 --- a/lib/pages/chat_encryption_settings/chat_encryption_settings.dart +++ b/lib/pages/chat_encryption_settings/chat_encryption_settings.dart @@ -12,7 +12,7 @@ import 'package:fluffychat/widgets/matrix.dart'; import '../key_verification/key_verification_dialog.dart'; class ChatEncryptionSettings extends StatefulWidget { - const ChatEncryptionSettings({Key? key}) : super(key: key); + const ChatEncryptionSettings({super.key}); @override ChatEncryptionSettingsController createState() => diff --git a/lib/pages/chat_encryption_settings/chat_encryption_settings_view.dart b/lib/pages/chat_encryption_settings/chat_encryption_settings_view.dart index fc78f30ae..20764021e 100644 --- a/lib/pages/chat_encryption_settings/chat_encryption_settings_view.dart +++ b/lib/pages/chat_encryption_settings/chat_encryption_settings_view.dart @@ -1,4 +1,3 @@ -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; @@ -14,8 +13,7 @@ import 'package:fluffychat/widgets/layouts/max_width_body.dart'; class ChatEncryptionSettingsView extends StatelessWidget { final ChatEncryptionSettingsController controller; - const ChatEncryptionSettingsView(this.controller, {Key? key}) - : super(key: key); + const ChatEncryptionSettingsView(this.controller, {super.key}); @override Widget build(BuildContext context) { @@ -54,11 +52,13 @@ class ChatEncryptionSettingsView extends StatelessWidget { value: room.encrypted, onChanged: controller.enableEncryption, ), - Icon( - CupertinoIcons.lock_shield, - size: 128, - color: Theme.of(context).colorScheme.onInverseSurface, - ), + // #Pangea + // Icon( + // CupertinoIcons.lock_shield, + // size: 128, + // color: Theme.of(context).colorScheme.onInverseSurface, + // ), + // Pangea# const Divider(), if (room.isDirectChat) Padding( diff --git a/lib/pages/chat_list/chat_list.dart b/lib/pages/chat_list/chat_list.dart index b972847fd..3567d2624 100644 --- a/lib/pages/chat_list/chat_list.dart +++ b/lib/pages/chat_list/chat_list.dart @@ -6,6 +6,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:adaptive_dialog/adaptive_dialog.dart'; +import 'package:collection/collection.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:future_loading_dialog/future_loading_dialog.dart'; import 'package:go_router/go_router.dart'; @@ -17,7 +18,12 @@ import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/config/themes.dart'; import 'package:fluffychat/pages/chat_list/chat_list_view.dart'; import 'package:fluffychat/pages/settings_security/settings_security.dart'; -import 'package:fluffychat/utils/famedlysdk_store.dart'; +import 'package:fluffychat/pangea/controllers/pangea_controller.dart'; +import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart'; +import 'package:fluffychat/pangea/utils/add_to_space.dart'; +import 'package:fluffychat/pangea/utils/chat_list_handle_space_tap.dart'; +import 'package:fluffychat/pangea/utils/error_handler.dart'; +import 'package:fluffychat/pangea/utils/firebase_analytics.dart'; import 'package:fluffychat/utils/localized_exception_extension.dart'; import 'package:fluffychat/utils/matrix_sdk_extensions/client_stories_extension.dart'; import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart'; @@ -28,7 +34,6 @@ import '../../utils/url_launcher.dart'; import '../../utils/voip/callkeep_manager.dart'; import '../../widgets/fluffy_chat_app.dart'; import '../../widgets/matrix.dart'; -import '../bootstrap/bootstrap_dialog.dart'; import 'package:fluffychat/utils/tor_stub.dart' if (dart.library.html) 'package:tor_detector_web/tor_detector_web.dart'; @@ -61,10 +66,10 @@ class ChatList extends StatefulWidget { final String? activeChat; const ChatList({ - Key? key, + super.key, this.displayNavigationRail = false, required this.activeChat, - }) : super(key: key); + }); @override ChatListController createState() => ChatListController(); @@ -87,6 +92,9 @@ class ChatListController extends State void resetActiveSpaceId() { setState(() { activeSpaceId = null; + //#Pangea + context.go("/rooms"); + //Pangea# }); } @@ -109,6 +117,15 @@ class ChatListController extends State } } + // #Pangea + bool isSelected(int i) { + if (activeFilter == ActiveFilter.spaces && activeSpaceId != null) { + return false; + } + return i == selectedIndex; + } + // Pangea# + ActiveFilter getActiveFilterByDestination(int? i) { switch (i) { case 1: @@ -129,8 +146,18 @@ class ChatListController extends State void onDestinationSelected(int? i) { setState(() { + // #Pangea + debugPrint('onDestinationSelected $i'); + // Pangea# activeFilter = getActiveFilterByDestination(i); }); + // #Pangea + final bool clickedAllSpaces = (!AppConfig.separateChatTypes && i == 1) || + (AppConfig.separateChatTypes && i == 2); + if (clickedAllSpaces) { + setActiveSpace(null); + } + // Pangea# } ActiveFilter activeFilter = AppConfig.separateChatTypes @@ -140,23 +167,63 @@ class ChatListController extends State bool Function(Room) getRoomFilterByActiveFilter(ActiveFilter activeFilter) { switch (activeFilter) { case ActiveFilter.allChats: - return (room) => !room.isSpace && !room.isStoryRoom; + return (room) => + !room.isSpace && + !room.isStoryRoom + // #Pangea + && + !room.isAnalyticsRoom; + // Pangea# case ActiveFilter.groups: return (room) => - !room.isSpace && !room.isDirectChat && !room.isStoryRoom; + !room.isSpace && + !room.isDirectChat && + !room.isStoryRoom + // #Pangea + && + !room.isAnalyticsRoom; + // Pangea# case ActiveFilter.messages: return (room) => - !room.isSpace && room.isDirectChat && !room.isStoryRoom; + !room.isSpace && + room.isDirectChat && + !room.isStoryRoom + // #Pangea + && + !room.isAnalyticsRoom; + // Pangea# case ActiveFilter.spaces: return (r) => r.isSpace; } } List get filteredRooms => Matrix.of(context) - .client - .rooms - .where(getRoomFilterByActiveFilter(activeFilter)) - .toList(); + .client + .rooms + .where( + getRoomFilterByActiveFilter(activeFilter), + ) + // #Pangea + .sorted((roomA, roomB) { + // put rooms with unread messages at the top of the list + if (roomA.membership == Membership.invite && + roomB.membership != Membership.invite) { + return -1; + } + if (roomA.membership != Membership.invite && + roomB.membership == Membership.invite) { + return 1; + } + + final bool aUnread = roomA.notificationCount > 0 || roomA.markedUnread; + final bool bUnread = roomB.notificationCount > 0 || roomB.markedUnread; + if (aUnread && !bUnread) return -1; + if (!aUnread && bUnread) return 1; + + return 0; + }) + // Pangea# + .toList(); bool isSearchMode = false; Future? publicRoomsResponse; @@ -167,6 +234,9 @@ class ChatListController extends State bool isSearching = false; static const String _serverStoreNamespace = 'im.fluffychat.search.server'; + //#Pangea + final PangeaController pangeaController = MatrixState.pangeaController; + //Pangea# void setServer() async { final newServer = await showTextInputDialog( @@ -189,7 +259,7 @@ class ChatListController extends State ], ); if (newServer == null) return; - Store().setItem(_serverStoreNamespace, newServer.single); + Matrix.of(context).store.setString(_serverStoreNamespace, newServer.single); setState(() { searchServer = newServer.single; }); @@ -372,6 +442,11 @@ class ChatListController extends State } } + //#Pangea + StreamSubscription? classStream; + StreamSubscription? _invitedSpaceSubscription; + //Pangea# + @override void initState() { _initReceiveSharingIntent(); @@ -382,7 +457,8 @@ class ChatListController extends State CallKeepManager().initialize(); WidgetsBinding.instance.addPostFrameCallback((_) async { if (mounted) { - searchServer = await Store().getItem(_serverStoreNamespace); + searchServer = + Matrix.of(context).store.getString(_serverStoreNamespace); Matrix.of(context).backgroundPush?.setupPush(); } @@ -394,6 +470,40 @@ class ChatListController extends State _checkTorBrowser(); + //#Pangea + classStream = pangeaController.classController.stateStream.listen((event) { + if (event["activeSpaceId"] != null && mounted) { + setActiveSpace(event["activeSpaceId"]); + } + }); + + _invitedSpaceSubscription = pangeaController + .matrixState.client.onSync.stream + .where((event) => event.rooms?.invite != null) + .listen((event) { + for (final inviteEntry in event.rooms!.invite!.entries) { + if (inviteEntry.value.inviteState == null) continue; + final bool isSpace = inviteEntry.value.inviteState!.any( + (event) => + event.type == EventTypes.RoomCreate && + event.content['type'] == 'm.space', + ); + if (!isSpace) continue; + final String spaceId = inviteEntry.key; + final Room? space = pangeaController.matrixState.client.getRoomById( + spaceId, + ); + if (space != null) { + chatListHandleSpaceTap( + context, + this, + space, + ); + } + } + }); + //Pangea# + super.initState(); } @@ -402,6 +512,10 @@ class ChatListController extends State _intentDataStreamSubscription?.cancel(); _intentFileStreamSubscription?.cancel(); _intentUriStreamSubscription?.cancel(); + //#Pangea + classStream?.cancel(); + _invitedSpaceSubscription?.cancel(); + //Pangea# scrollController.removeListener(_onScroll); super.dispose(); } @@ -471,14 +585,24 @@ class ChatListController extends State title: L10n.of(context)!.areYouSure, okLabel: L10n.of(context)!.yes, cancelLabel: L10n.of(context)!.cancel, + message: L10n.of(context)!.archiveRoomDescription, ) == OkCancelResult.ok; if (!confirmed) return; + // #Pangea + final bool archivedActiveRoom = + selectedRoomIds.contains(Matrix.of(context).activeRoomId); + // Pangea# await showFutureLoadingDialog( context: context, future: () => _archiveSelectedRooms(), ); setState(() {}); + // #Pangea + if (archivedActiveRoom) { + context.go('/rooms'); + } + // Pangea# } void setStatus() async { @@ -526,7 +650,17 @@ class ChatListController extends State actions: Matrix.of(context) .client .rooms - .where((r) => r.isSpace) + .where( + (r) => + r.isSpace + // #Pangea + && + selectedRoomIds + .map((id) => Matrix.of(context).client.getRoomById(id)) + .where((e) => !(e?.isPangeaClass ?? true)) + .every((e) => r.canIAddSpaceChild(e)), + //Pangea# + ) .map( (space) => AlertDialogAction( key: space.id, @@ -541,11 +675,19 @@ class ChatListController extends State context: context, future: () async { final space = Matrix.of(context).client.getRoomById(selectedSpace)!; - if (space.canSendDefaultStates) { - for (final roomId in selectedRoomIds) { - await space.setSpaceChild(roomId); - } - } + // #Pangea + await pangeaAddToSpace( + space, + selectedRoomIds.toList(), + context, + pangeaController, + ); + // if (space.canSendDefaultStates) { + // for (final roomId in selectedRoomIds) { + // await space.setSpaceChild(roomId); + // } + // } + // Pangea# }, ); if (result.error == null) { @@ -583,16 +725,35 @@ class ChatListController extends State await client.accountDataLoading; if (client.prevBatch == null) { await client.onSync.stream.first; + // #Pangea + pangeaController.startChatWithBotIfNotPresent(); + //Pangea# // Display first login bootstrap if enabled - if (client.encryption?.keyManager.enabled == true) { - if (await client.encryption?.keyManager.isCached() == false || - await client.encryption?.crossSigning.isCached() == false || - client.isUnknownSession && !mounted) { - await BootstrapDialog(client: client).show(context); - } - } + // #Pangea + // if (client.encryption?.keyManager.enabled == true) { + // if (await client.encryption?.keyManager.isCached() == false || + // await client.encryption?.crossSigning.isCached() == false || + // client.isUnknownSession && !mounted) { + // await BootstrapDialog(client: client).show(context); + // } + // } + // Pangea# } + + // #Pangea + if (mounted) { + GoogleAnalytics.analyticsUserUpdate(client.userID); + await pangeaController.subscriptionController.initialize(); + pangeaController.afterSyncAndFirstLoginInitialization(context); + await pangeaController.inviteBotToExistingSpaces(); + } else { + ErrorHandler.logError( + m: "didn't run afterSyncAndFirstLoginInitialization because not mounted", + ); + // debugger(when: kDebugMode); + } + // Pangea# if (!mounted) return; setState(() { waitForFirstSync = true; diff --git a/lib/pages/chat_list/chat_list_body.dart b/lib/pages/chat_list/chat_list_body.dart index 69b438e8c..7a47424a9 100644 --- a/lib/pages/chat_list/chat_list_body.dart +++ b/lib/pages/chat_list/chat_list_body.dart @@ -1,4 +1,3 @@ -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:animations/animations.dart'; @@ -9,10 +8,9 @@ import 'package:fluffychat/pages/chat_list/chat_list.dart'; import 'package:fluffychat/pages/chat_list/chat_list_item.dart'; import 'package:fluffychat/pages/chat_list/search_title.dart'; import 'package:fluffychat/pages/chat_list/space_view.dart'; -import 'package:fluffychat/pages/chat_list/stories_header.dart'; import 'package:fluffychat/pages/user_bottom_sheet/user_bottom_sheet.dart'; +import 'package:fluffychat/pangea/widgets/chat_list/chat_list_body_text.dart'; import 'package:fluffychat/utils/adaptive_bottom_sheet.dart'; -import 'package:fluffychat/utils/matrix_sdk_extensions/client_stories_extension.dart'; import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart'; import 'package:fluffychat/utils/stream_extension.dart'; import 'package:fluffychat/widgets/avatar.dart'; @@ -25,7 +23,7 @@ import 'chat_list_header.dart'; class ChatListViewBody extends StatelessWidget { final ChatListController controller; - const ChatListViewBody(this.controller, {Key? key}) : super(key: key); + const ChatListViewBody(this.controller, {super.key}); @override Widget build(BuildContext context) { @@ -71,11 +69,13 @@ class ChatListViewBody extends StatelessWidget { ); } final rooms = controller.filteredRooms; - final displayStoriesHeader = { - ActiveFilter.allChats, - ActiveFilter.messages, - }.contains(controller.activeFilter) && - client.storiesRooms.isNotEmpty; + // Pangea# + // final displayStoriesHeader = { + // ActiveFilter.allChats, + // ActiveFilter.messages, + // }.contains(controller.activeFilter) && + // client.storiesRooms.isNotEmpty; + // Pangea# return SafeArea( child: CustomScrollView( controller: controller.scrollController, @@ -163,11 +163,13 @@ class ChatListViewBody extends StatelessWidget { icon: const Icon(Icons.camera_alt_outlined), ), ], - if (displayStoriesHeader) - StoriesHeader( - key: const Key('stories_header'), - filter: controller.searchController.text, - ), + // #Pangea + // if (displayStoriesHeader) + // StoriesHeader( + // key: const Key('stories_header'), + // filter: controller.searchController.text, + // ), + // Pangea# const ConnectionStatusHeader(), AnimatedContainer( height: controller.isTorBrowser ? 64 : 0, @@ -196,13 +198,31 @@ class ChatListViewBody extends StatelessWidget { !controller.isSearchMode) ...[ Padding( padding: const EdgeInsets.all(32.0), - child: Icon( - CupertinoIcons.chat_bubble_2, - size: 128, - color: - Theme.of(context).colorScheme.onInverseSurface, + // #Pangea + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Image.asset( + 'private_chat_wallpaper.png', + height: 256, + ), + ], + ), + // child: Icon( + // CupertinoIcons.chat_bubble_2, + // size: 128, + // color: + // Theme.of(context).colorScheme.onInverseSurface, + // ), + // Pangea# + ), + // #Pangea + Center( + child: ChatListBodyStartText( + controller: controller, ), ), + // Pangea# ], ], ), @@ -313,8 +333,7 @@ class _SearchItem extends StatelessWidget { required this.title, this.avatar, required this.onPressed, - Key? key, - }) : super(key: key); + }); @override Widget build(BuildContext context) => InkWell( diff --git a/lib/pages/chat_list/chat_list_header.dart b/lib/pages/chat_list/chat_list_header.dart index f9675a8dd..7ced10244 100644 --- a/lib/pages/chat_list/chat_list_header.dart +++ b/lib/pages/chat_list/chat_list_header.dart @@ -5,12 +5,11 @@ import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:fluffychat/config/themes.dart'; import 'package:fluffychat/pages/chat_list/chat_list.dart'; import 'package:fluffychat/pages/chat_list/client_chooser_button.dart'; -import '../../widgets/matrix.dart'; class ChatListHeader extends StatelessWidget implements PreferredSizeWidget { final ChatListController controller; - const ChatListHeader({Key? key, required this.controller}) : super(key: key); + const ChatListHeader({super.key, required this.controller}); @override Widget build(BuildContext context) { @@ -43,80 +42,85 @@ class ChatListHeader extends StatelessWidget implements PreferredSizeWidget { controller.selectedRoomIds.length.toString(), key: const ValueKey(SelectMode.select), ) - : TextField( - controller: controller.searchController, - focusNode: controller.searchFocusNode, - textInputAction: TextInputAction.search, - onChanged: controller.onSearchEnter, - decoration: InputDecoration( - fillColor: Theme.of(context).colorScheme.secondaryContainer, - border: UnderlineInputBorder( - borderSide: BorderSide.none, - borderRadius: BorderRadius.circular(99), - ), - hintText: L10n.of(context)!.search, - floatingLabelBehavior: FloatingLabelBehavior.never, - prefixIcon: controller.isSearchMode - ? IconButton( - tooltip: L10n.of(context)!.cancel, - icon: const Icon(Icons.close_outlined), - onPressed: controller.cancelSearch, - color: Theme.of(context).colorScheme.onBackground, - ) - : IconButton( - onPressed: controller.startSearch, - icon: Icon( - Icons.search_outlined, - color: Theme.of(context).colorScheme.onBackground, - ), - ), - suffixIcon: controller.isSearchMode - ? controller.isSearching - ? const Padding( - padding: EdgeInsets.symmetric( - vertical: 10.0, - horizontal: 12, - ), - child: SizedBox.square( - dimension: 24, - child: CircularProgressIndicator.adaptive( - strokeWidth: 2, - ), - ), - ) - : TextButton.icon( - onPressed: controller.setServer, - style: TextButton.styleFrom( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(99), - ), - textStyle: const TextStyle(fontSize: 12), - ), - icon: const Icon(Icons.edit_outlined, size: 16), - label: Text( - controller.searchServer ?? - Matrix.of(context) - .client - .homeserver! - .host, - maxLines: 2, - ), - ) - : SizedBox( - width: 0, - child: ClientChooserButton(controller), - ), - ), - ), + // #Pangea + : ClientChooserButton(controller), + // : TextField( + // controller: controller.searchController, + // focusNode: controller.searchFocusNode, + // textInputAction: TextInputAction.search, + // onChanged: controller.onSearchEnter, + // decoration: InputDecoration( + // fillColor: Theme.of(context).colorScheme.secondaryContainer, + // border: UnderlineInputBorder( + // borderSide: BorderSide.none, + // borderRadius: BorderRadius.circular(99), + // ), + // hintText: L10n.of(context)!.searchChatsRooms, + // floatingLabelBehavior: FloatingLabelBehavior.never, + // prefixIcon: controller.isSearchMode + // ? IconButton( + // tooltip: L10n.of(context)!.cancel, + // icon: const Icon(Icons.close_outlined), + // onPressed: controller.cancelSearch, + // color: Theme.of(context).colorScheme.onBackground, + // ) + // : IconButton( + // onPressed: controller.startSearch, + // icon: Icon( + // Icons.search_outlined, + // color: Theme.of(context).colorScheme.onBackground, + // ), + // ), + // suffixIcon: controller.isSearchMode + // ? controller.isSearching + // ? const Padding( + // padding: EdgeInsets.symmetric( + // vertical: 10.0, + // horizontal: 12, + // ), + // child: SizedBox.square( + // dimension: 24, + // child: CircularProgressIndicator.adaptive( + // strokeWidth: 2, + // ), + // ), + // ) + // : TextButton.icon( + // onPressed: controller.setServer, + // style: TextButton.styleFrom( + // shape: RoundedRectangleBorder( + // borderRadius: BorderRadius.circular(99), + // ), + // textStyle: const TextStyle(fontSize: 12), + // ), + // icon: const Icon(Icons.edit_outlined, size: 16), + // label: Text( + // controller.searchServer ?? + // Matrix.of(context) + // .client + // .homeserver! + // .host, + // maxLines: 2, + // ), + // ) + // : SizedBox( + // width: 0, + // child: ClientChooserButton(controller), + // ), + // ), + // ), + // Pangea# actions: selectMode == SelectMode.share ? [ - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 16.0, - vertical: 8.0, - ), - child: ClientChooserButton(controller), - ), + // #Pangea + // Padding( + // padding: const EdgeInsets.symmetric( + // horizontal: 16.0, + // vertical: 8.0, + // ), + // child: ClientChooserButton(controller), + // ), + // Pangea# ] : selectMode == SelectMode.select ? [ @@ -154,7 +158,10 @@ class ChatListHeader extends StatelessWidget implements PreferredSizeWidget { onPressed: controller.toggleMuted, ), IconButton( - icon: const Icon(Icons.delete_outlined), + // #Pangea + // icon: const Icon(Icons.delete_outlined), + icon: const Icon(Icons.archive_outlined), + // Pangea# tooltip: L10n.of(context)!.archive, onPressed: controller.archiveAction, ), diff --git a/lib/pages/chat_list/chat_list_item.dart b/lib/pages/chat_list/chat_list_item.dart index 9475b8a48..d535b2e65 100644 --- a/lib/pages/chat_list/chat_list_item.dart +++ b/lib/pages/chat_list/chat_list_item.dart @@ -7,6 +7,8 @@ import 'package:go_router/go_router.dart'; import 'package:matrix/matrix.dart'; import 'package:fluffychat/config/app_config.dart'; +import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart'; +import 'package:fluffychat/pangea/utils/get_chat_list_item_subtitle.dart'; import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart'; import 'package:fluffychat/utils/room_status_extension.dart'; import '../../config/themes.dart'; @@ -23,6 +25,7 @@ class ChatListItem extends StatelessWidget { final bool selected; final void Function()? onTap; final void Function()? onLongPress; + final void Function()? onForget; const ChatListItem( this.room, { @@ -30,8 +33,9 @@ class ChatListItem extends StatelessWidget { this.selected = false, this.onTap, this.onLongPress, - Key? key, - }) : super(key: key); + this.onForget, + super.key, + }); void clickAction(BuildContext context) async { if (onTap != null) return onTap!(); @@ -132,6 +136,7 @@ class ChatListItem extends StatelessWidget { title: L10n.of(context)!.areYouSure, okLabel: L10n.of(context)!.yes, cancelLabel: L10n.of(context)!.no, + message: L10n.of(context)!.archiveRoomDescription, ); if (confirmed == OkCancelResult.cancel) return; await showFutureLoadingDialog( @@ -155,6 +160,11 @@ class ChatListItem extends StatelessWidget { : 14.0 : 0.0; final hasNotifications = room.notificationCount > 0; + final backgroundColor = selected + ? Theme.of(context).colorScheme.primaryContainer + : activeChat + ? Theme.of(context).colorScheme.secondaryContainer + : null; final displayname = room.getLocalizedDisplayname( MatrixLocals(L10n.of(context)!), ); @@ -166,11 +176,7 @@ class ChatListItem extends StatelessWidget { child: Material( borderRadius: BorderRadius.circular(AppConfig.borderRadius), clipBehavior: Clip.hardEdge, - color: selected - ? Theme.of(context).colorScheme.primaryContainer - : activeChat - ? Theme.of(context).colorScheme.secondaryContainer - : Colors.transparent, + color: backgroundColor, child: ListTile( visualDensity: const VisualDensity(vertical: -0.5), contentPadding: const EdgeInsets.symmetric(horizontal: 8), @@ -189,6 +195,11 @@ class ChatListItem extends StatelessWidget { mxContent: room.avatar, name: displayname, onTap: onLongPress, + //#Pangea + littleIcon: room.roomTypeIcon, + // Pangea# + presenceUserId: room.directChatMatrixID, + presenceBackgroundColor: backgroundColor, ), title: Row( children: [ @@ -274,17 +285,26 @@ class ChatListItem extends StatelessWidget { softWrap: false, ) : FutureBuilder( - future: room.lastEvent?.calcLocalizedBody( - MatrixLocals(L10n.of(context)!), - hideReply: true, - hideEdit: true, - plaintextBody: true, - removeMarkdown: true, - withSenderNamePrefix: !room.isDirectChat || - room.directChatMatrixID != - room.lastEvent?.senderId, - ) ?? - Future.value(L10n.of(context)!.emptyChat), + // #Pangea + // future: room.lastEvent?.calcLocalizedBody( + // MatrixLocals(L10n.of(context)!), + // hideReply: true, + // hideEdit: true, + // plaintextBody: true, + // removeMarkdown: true, + // withSenderNamePrefix: !room.isDirectChat || + // room.directChatMatrixID != + // room.lastEvent?.senderId, + // ) ?? + // Future.value(L10n.of(context)!.emptyChat), + future: room.lastEvent != null + ? GetChatListItemSubtitle().getSubtitle( + context, + room.lastEvent, + MatrixState.pangeaController, + ) + : Future.value(L10n.of(context)!.emptyChat), + // Pangea# builder: (context, snapshot) { return Text( room.membership == Membership.invite @@ -361,6 +381,12 @@ class ChatListItem extends StatelessWidget { ], ), onTap: () => clickAction(context), + trailing: onForget == null + ? null + : IconButton( + icon: const Icon(Icons.delete_outlined), + onPressed: onForget, + ), ), ), ); diff --git a/lib/pages/chat_list/chat_list_view.dart b/lib/pages/chat_list/chat_list_view.dart index b60371746..ccfcf0629 100644 --- a/lib/pages/chat_list/chat_list_view.dart +++ b/lib/pages/chat_list/chat_list_view.dart @@ -1,15 +1,15 @@ import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; import 'package:badges/badges.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; -import 'package:go_router/go_router.dart'; -import 'package:keyboard_shortcuts/keyboard_shortcuts.dart'; +import 'package:matrix/matrix.dart'; import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/config/themes.dart'; import 'package:fluffychat/pages/chat_list/chat_list.dart'; import 'package:fluffychat/pages/chat_list/navi_rail_item.dart'; +import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart'; +import 'package:fluffychat/pangea/utils/chat_list_handle_space_tap.dart'; import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart'; import 'package:fluffychat/widgets/avatar.dart'; import 'package:fluffychat/widgets/unread_rooms_badge.dart'; @@ -20,7 +20,7 @@ import 'start_chat_fab.dart'; class ChatListView extends StatelessWidget { final ChatListController controller; - const ChatListView(this.controller, {Key? key}) : super(key: key); + const ChatListView(this.controller, {super.key}); List getNavigationDestinations(BuildContext context) { final badgePosition = BadgePosition.topEnd(top: -12, end: -8); @@ -39,7 +39,10 @@ class ChatListView extends StatelessWidget { controller.getRoomFilterByActiveFilter(ActiveFilter.messages), child: const Icon(Icons.forum), ), - label: L10n.of(context)!.messages, + //#Pangea + // label: L10n.of(context)!.messages, + label: L10n.of(context)!.directChats, + //Pangea# ), NavigationDestination( icon: UnreadRoomsBadge( @@ -68,14 +71,24 @@ class ChatListView extends StatelessWidget { controller.getRoomFilterByActiveFilter(ActiveFilter.allChats), child: const Icon(Icons.forum), ), - label: L10n.of(context)!.chats, + // #Pangea + // label: L10n.of(context)!.chats, + label: L10n.of(context)!.allChats, + // Pangea# ), if (controller.spaces.isNotEmpty) - const NavigationDestination( - icon: Icon(Icons.workspaces_outlined), - selectedIcon: Icon(Icons.workspaces), - label: 'Spaces', + // #Pangea + // const NavigationDestination( + // icon: Icon(Icons.workspaces_outlined), + // selectedIcon: Icon(Icons.workspaces), + // label: 'Spaces', + // ), + NavigationDestination( + icon: const Icon(Icons.workspaces_outlined), + selectedIcon: const Icon(Icons.workspaces), + label: L10n.of(context)!.allSpaces, ), + // Pangea# ]; } @@ -86,16 +99,23 @@ class ChatListView extends StatelessWidget { stream: Matrix.of(context).onShareContentChanged.stream, builder: (_, __) { final selectMode = controller.selectMode; - return WillPopScope( - onWillPop: () async { + return PopScope( + canPop: controller.selectMode == SelectMode.normal && + !controller.isSearchMode && + controller.activeFilter == + (AppConfig.separateChatTypes + ? ActiveFilter.messages + : ActiveFilter.allChats), + onPopInvoked: (pop) async { + if (pop) return; final selMode = controller.selectMode; if (controller.isSearchMode) { controller.cancelSearch(); - return false; + return; } if (selMode != SelectMode.normal) { controller.cancelAction(); - return false; + return; } if (controller.activeFilter != (AppConfig.separateChatTypes @@ -103,9 +123,8 @@ class ChatListView extends StatelessWidget { : ActiveFilter.allChats)) { controller .onDestinationSelected(AppConfig.separateChatTypes ? 1 : 0); - return false; + return; } - return true; }, child: Row( children: [ @@ -115,14 +134,17 @@ class ChatListView extends StatelessWidget { builder: (context) { final allSpaces = client.rooms.where((room) => room.isSpace); - final rootSpaces = allSpaces - .where( - (space) => !allSpaces.any( - (parentSpace) => parentSpace.spaceChildren - .any((child) => child.roomId == space.id), - ), - ) - .toList(); + // #Pangea + // final rootSpaces = allSpaces + // .where( + // (space) => !allSpaces.any( + // (parentSpace) => parentSpace.spaceChildren + // .any((child) => child.roomId == space.id), + // ), + // ) + // .toList(); + final rootSpaces = allSpaces.toList(); + // Pangea# final destinations = getNavigationDestinations(context); return SizedBox( @@ -133,7 +155,10 @@ class ChatListView extends StatelessWidget { itemBuilder: (context, i) { if (i < destinations.length) { return NaviRailItem( - isSelected: i == controller.selectedIndex, + // #Pangea + // isSelected: i == controller.selectedIndex, + isSelected: controller.isSelected(i), + // Pangea# onTap: () => controller.onDestinationSelected(i), icon: destinations[i].icon, selectedIcon: destinations[i].selectedIcon, @@ -144,13 +169,25 @@ class ChatListView extends StatelessWidget { final isSelected = controller.activeFilter == ActiveFilter.spaces && rootSpaces[i].id == controller.activeSpaceId; + //#Pangea + final Room? room = Matrix.of(context) + .client + .getRoomById(rootSpaces[i].id); + // Pangea# return NaviRailItem( toolTip: rootSpaces[i].getLocalizedDisplayname( MatrixLocals(L10n.of(context)!), ), isSelected: isSelected, - onTap: () => - controller.setActiveSpace(rootSpaces[i].id), + // #Pangea + // onTap: () => + // controller.setActiveSpace(rootSpaces[i].id), + onTap: () => chatListHandleSpaceTap( + context, + controller, + rootSpaces[i], + ), + // Pangea# icon: Avatar( mxContent: rootSpaces[i].avatar, name: rootSpaces[i].getLocalizedDisplayname( @@ -158,6 +195,9 @@ class ChatListView extends StatelessWidget { ), size: 32, fontSize: 12, + // #Pangea + littleIcon: room?.roomTypeIcon, + // Pangea# ), ); }, @@ -193,22 +233,32 @@ class ChatListView extends StatelessWidget { destinations: getNavigationDestinations(context), ) : null, - floatingActionButton: KeyBoardShortcuts( - keysToPress: { - LogicalKeyboardKey.controlLeft, - LogicalKeyboardKey.keyN, - }, - onKeysPressed: () => context.go('/rooms/newprivatechat'), - helpLabel: L10n.of(context)!.newChat, - child: selectMode == SelectMode.normal && - !controller.isSearchMode - ? StartChatFloatingActionButton( - activeFilter: controller.activeFilter, - roomsIsEmpty: false, - scrolledToTop: controller.scrolledToTop, - ) - : const SizedBox.shrink(), - ), + // #Pangea + // floatingActionButton: KeyBoardShortcuts( + // keysToPress: { + // LogicalKeyboardKey.controlLeft, + // LogicalKeyboardKey.keyN, + // }, + // onKeysPressed: () => context.go('/rooms/newprivatechat'), + // helpLabel: L10n.of(context)!.newChat, + // child: selectMode == SelectMode.normal && + // !controller.isSearchMode + // ? StartChatFloatingActionButton( + // activeFilter: controller.activeFilter, + // roomsIsEmpty: false, + // scrolledToTop: controller.scrolledToTop, + // ) + // : const SizedBox.shrink(), + // ), + floatingActionButton: selectMode == SelectMode.normal + ? StartChatFloatingActionButton( + activeFilter: controller.activeFilter, + roomsIsEmpty: false, + scrolledToTop: controller.scrolledToTop, + controller: controller, + ) + : null, + // Pangea# ), ), ), diff --git a/lib/pages/chat_list/client_chooser_button.dart b/lib/pages/chat_list/client_chooser_button.dart index 2791a4a0c..5907d9f08 100644 --- a/lib/pages/chat_list/client_chooser_button.dart +++ b/lib/pages/chat_list/client_chooser_button.dart @@ -1,13 +1,18 @@ +import 'dart:developer'; + +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:adaptive_dialog/adaptive_dialog.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:go_router/go_router.dart'; import 'package:keyboard_shortcuts/keyboard_shortcuts.dart'; import 'package:matrix/matrix.dart'; -import 'package:fluffychat/widgets/avatar.dart'; +import 'package:fluffychat/pangea/extensions/client_extension.dart'; +import 'package:fluffychat/pangea/utils/class_code.dart'; +import 'package:fluffychat/pangea/utils/find_conversation_partner_dialog.dart'; +import 'package:fluffychat/pangea/utils/logout.dart'; import 'package:fluffychat/widgets/matrix.dart'; import '../../utils/fluffy_share.dart'; import 'chat_list.dart'; @@ -15,66 +20,147 @@ import 'chat_list.dart'; class ClientChooserButton extends StatelessWidget { final ChatListController controller; - const ClientChooserButton(this.controller, {Key? key}) : super(key: key); + const ClientChooserButton(this.controller, {super.key}); List> _bundleMenuItems(BuildContext context) { final matrix = Matrix.of(context); - final bundles = matrix.accountBundles.keys.toList() - ..sort( - (a, b) => a!.isValidMatrixId == b!.isValidMatrixId - ? 0 - : a.isValidMatrixId && !b.isValidMatrixId - ? -1 - : 1, - ); + // #Pangea + // final bundles = matrix.accountBundles.keys.toList() + // ..sort( + // (a, b) => a!.isValidMatrixId == b!.isValidMatrixId + // ? 0 + // : a.isValidMatrixId && !b.isValidMatrixId + // ? -1 + // : 1, + // ); + // Pangea# return >[ + // #Pangea + // PopupMenuItem( + // value: SettingsAction.newStory, + // child: Row( + // children: [ + // const Icon(Icons.camera_outlined), + // const SizedBox(width: 18), + // Text(L10n.of(context)!.yourStory), + // ], + // ), + // ), + // PopupMenuItem( + // value: SettingsAction.newGroup, + // child: Row( + // children: [ + // const Icon(Icons.group_add_outlined), + // const SizedBox(width: 18), + // Text(L10n.of(context)!.createGroup), + // ], + // ), + // ), PopupMenuItem( - value: SettingsAction.newStory, + value: SettingsAction.joinWithClassCode, child: Row( children: [ - const Icon(Icons.camera_outlined), + const Icon(Icons.join_full_outlined), const SizedBox(width: 18), - Text(L10n.of(context)!.yourStory), + Expanded(child: Text(L10n.of(context)!.joinWithClassCode)), ], ), ), PopupMenuItem( - value: SettingsAction.newGroup, + enabled: matrix.client.classesAndExchangesImTeaching.isNotEmpty, + value: SettingsAction.classAnalytics, child: Row( children: [ - const Icon(Icons.group_add_outlined), + const Icon(Icons.analytics_outlined), const SizedBox(width: 18), - Text(L10n.of(context)!.createGroup), + Expanded(child: Text(L10n.of(context)!.classAnalytics)), ], ), ), PopupMenuItem( - value: SettingsAction.newSpace, + enabled: matrix.client.classesImIn.isNotEmpty, + value: SettingsAction.myAnalytics, child: Row( children: [ - const Icon(Icons.workspaces_outlined), + const Icon(Icons.analytics_outlined), const SizedBox(width: 18), - Text(L10n.of(context)!.createNewSpace), + Expanded(child: Text(L10n.of(context)!.myLearning)), ], ), ), PopupMenuItem( - value: SettingsAction.invite, + value: SettingsAction.newClass, child: Row( children: [ - Icon(Icons.adaptive.share_outlined), + const Icon(Icons.school), const SizedBox(width: 18), - Text(L10n.of(context)!.inviteContact), + Expanded(child: Text(L10n.of(context)!.createNewClass)), ], ), ), + // PopupMenuItem( + // value: SettingsAction.newSpace, + // child: Row( + // children: [ + // const Icon(Icons.workspaces_outlined), + // const SizedBox(width: 18), + // Text(L10n.of(context)!.createNewSpace), + // ], + // ), + // ), + PopupMenuItem( + value: SettingsAction.newExchange, + child: Row( + children: [ + const Icon(Icons.connecting_airports), + const SizedBox(width: 18), + Expanded(child: Text(L10n.of(context)!.newExchange)), + ], + ), + ), + PopupMenuItem( + value: SettingsAction.findAClass, + enabled: false, + child: Row( + children: [ + const Icon(Icons.class_outlined), + const SizedBox(width: 18), + Expanded(child: Text(L10n.of(context)!.findAClass)), + ], + ), + ), + if (controller.pangeaController.permissionsController.isUser18()) + PopupMenuItem( + value: SettingsAction.findAConversationPartner, + child: Row( + children: [ + const Icon(Icons.add_circle_outline), + const SizedBox(width: 18), + Expanded(child: Text(L10n.of(context)!.findALanguagePartner)), + ], + ), + ), + // PopupMenuItem( + // value: SettingsAction.invite, + // child: Row( + // children: [ + // Icon(Icons.adaptive.share_outlined), + // const SizedBox(width: 18), + // Text(L10n.of(context)!.inviteContact), + // ], + // ), + // ), + // Pangea# PopupMenuItem( value: SettingsAction.archive, child: Row( children: [ const Icon(Icons.archive_outlined), const SizedBox(width: 18), - Text(L10n.of(context)!.archive), + // #Pangea + // Text(L10n.of(context)!.archive), + Expanded(child: Text(L10n.of(context)!.archive)), + // Pangea# ], ), ), @@ -84,87 +170,99 @@ class ClientChooserButton extends StatelessWidget { children: [ const Icon(Icons.settings_outlined), const SizedBox(width: 18), - Text(L10n.of(context)!.settings), + // #Pangea + // Text(L10n.of(context)!.settings), + Expanded(child: Text(L10n.of(context)!.settings)), + // Pangea# ], ), ), - const PopupMenuItem( - value: null, - child: Divider(height: 1), - ), - for (final bundle in bundles) ...[ - if (matrix.accountBundles[bundle]!.length != 1 || - matrix.accountBundles[bundle]!.single!.userID != bundle) - PopupMenuItem( - value: null, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: [ - Text( - bundle!, - style: TextStyle( - color: Theme.of(context).textTheme.titleMedium!.color, - fontSize: 14, - ), - ), - const Divider(height: 1), - ], - ), - ), - ...matrix.accountBundles[bundle]! - .map( - (client) => PopupMenuItem( - value: client, - child: FutureBuilder( - // analyzer does not understand this type cast for error - // handling - // - // ignore: unnecessary_cast - future: (client!.fetchOwnProfile() as Future) - .onError((e, s) => null), - builder: (context, snapshot) => Row( - children: [ - Avatar( - mxContent: snapshot.data?.avatarUrl, - name: snapshot.data?.displayName ?? - client.userID!.localpart, - size: 32, - fontSize: 12, - ), - const SizedBox(width: 12), - Expanded( - child: Text( - snapshot.data?.displayName ?? - client.userID!.localpart!, - overflow: TextOverflow.ellipsis, - ), - ), - const SizedBox(width: 12), - IconButton( - icon: const Icon(Icons.edit_outlined), - onPressed: () => controller.editBundlesForAccount( - client.userID, - bundle, - ), - ), - ], - ), - ), - ), - ) - .toList(), - ], + // #Pangea + // const PopupMenuItem( + // value: null, + // child: Divider(height: 1), + // ), + // for (final bundle in bundles) ...[ + // if (matrix.accountBundles[bundle]!.length != 1 || + // matrix.accountBundles[bundle]!.single!.userID != bundle) + // PopupMenuItem( + // value: null, + // child: Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // mainAxisSize: MainAxisSize.min, + // children: [ + // Text( + // bundle!, + // style: TextStyle( + // color: Theme.of(context).textTheme.titleMedium!.color, + // fontSize: 14, + // ), + // ), + // const Divider(height: 1), + // ], + // ), + // ), + // ...matrix.accountBundles[bundle]!.map( + // (client) => PopupMenuItem( + // value: client, + // child: FutureBuilder( + // // analyzer does not understand this type cast for error + // // handling + // // + // // ignore: unnecessary_cast + // future: (client!.fetchOwnProfile() as Future) + // .onError((e, s) => null), + // builder: (context, snapshot) => Row( + // children: [ + // Avatar( + // mxContent: snapshot.data?.avatarUrl, + // name: + // snapshot.data?.displayName ?? client.userID!.localpart, + // size: 32, + // fontSize: 12, + // ), + // const SizedBox(width: 12), + // Expanded( + // child: Text( + // snapshot.data?.displayName ?? client.userID!.localpart!, + // overflow: TextOverflow.ellipsis, + // ), + // ), + // const SizedBox(width: 12), + // IconButton( + // icon: const Icon(Icons.edit_outlined), + // onPressed: () => controller.editBundlesForAccount( + // client.userID, + // bundle, + // ), + // ), + // ], + // ), + // ), + // ), + // ), + // ], + // PopupMenuItem( + // value: SettingsAction.addAccount, + // child: Row( + // children: [ + // const Icon(Icons.person_add_outlined), + // const SizedBox(width: 18), + // Text(L10n.of(context)!.addAccount), + // ], + // ), + // ), PopupMenuItem( - value: SettingsAction.addAccount, + value: SettingsAction.logout, child: Row( children: [ - const Icon(Icons.person_add_outlined), + const Icon(Icons.logout_outlined), const SizedBox(width: 18), - Text(L10n.of(context)!.addAccount), + Expanded(child: Text(L10n.of(context)!.logout)), ], ), ), + // Pangea# ]; } @@ -214,17 +312,32 @@ class ClientChooserButton extends StatelessWidget { PopupMenuButton( onSelected: (o) => _clientSelected(o, context), itemBuilder: _bundleMenuItems, + // #Pangea child: Material( - color: Colors.transparent, - borderRadius: BorderRadius.circular(99), - child: Avatar( - mxContent: snapshot.data?.avatarUrl, - name: snapshot.data?.displayName ?? - matrix.client.userID!.localpart, - size: 32, - fontSize: 12, + borderRadius: const BorderRadius.only( + bottomLeft: Radius.circular(12), + bottomRight: Radius.circular(12), + ), + clipBehavior: Clip.hardEdge, + child: ListTile( + tileColor: Theme.of(context).scaffoldBackgroundColor, + hoverColor: Theme.of(context).colorScheme.onSurfaceVariant, + leading: const Icon(Icons.settings_outlined), + title: Text(L10n.of(context)!.mainMenu), ), ), + // child: Material( + // color: Colors.transparent, + // borderRadius: BorderRadius.circular(99), + // child: Avatar( + // mxContent: snapshot.data?.avatarUrl, + // name: snapshot.data?.displayName ?? + // matrix.client.userID!.localpart, + // size: 32, + // fontSize: 12, + // ), + // ), + // Pangea# ), ], ), @@ -252,26 +365,28 @@ class ClientChooserButton extends StatelessWidget { controller.setActiveBundle(object); } else if (object is SettingsAction) { switch (object) { - case SettingsAction.addAccount: - final consent = await showOkCancelAlertDialog( - context: context, - title: L10n.of(context)!.addAccount, - message: L10n.of(context)!.enableMultiAccounts, - okLabel: L10n.of(context)!.next, - cancelLabel: L10n.of(context)!.cancel, - ); - if (consent != OkCancelResult.ok) return; - context.go('/rooms/settings/addaccount'); - break; - case SettingsAction.newStory: - context.go('/rooms/stories/create'); - break; - case SettingsAction.newGroup: - context.go('/rooms/newgroup'); - break; - case SettingsAction.newSpace: - context.go('/rooms/newspace'); - break; + // #Pangea + // case SettingsAction.addAccount: + // final consent = await showOkCancelAlertDialog( + // context: context, + // title: L10n.of(context)!.addAccount, + // message: L10n.of(context)!.enableMultiAccounts, + // okLabel: L10n.of(context)!.next, + // cancelLabel: L10n.of(context)!.cancel, + // ); + // if (consent != OkCancelResult.ok) return; + // context.go('/rooms/settings/addaccount'); + // break; + // case SettingsAction.newStory: + // context.go('/rooms/stories/create'); + // break; + // case SettingsAction.newGroup: + // context.go('/rooms/newgroup'); + // break; + // case SettingsAction.newSpace: + // context.go('/rooms/newspace'); + // break; + // Pangea# case SettingsAction.invite: FluffyShare.shareInviteLink(context); break; @@ -281,6 +396,39 @@ class ClientChooserButton extends StatelessWidget { case SettingsAction.archive: context.go('/rooms/archive'); break; + // #Pangea + case SettingsAction.newClass: + context.go('/rooms/newspace'); + break; + case SettingsAction.newExchange: + context.go('/rooms/newspace/exchange'); + break; + case SettingsAction.joinWithClassCode: + ClassCodeUtil.joinWithClassCodeDialog( + context, + controller.pangeaController, + null, + ); + break; + case SettingsAction.findAConversationPartner: + findConversationPartnerDialog( + context, + controller.pangeaController, + ); + break; + case SettingsAction.classAnalytics: + context.go('/rooms/analytics'); + break; + case SettingsAction.myAnalytics: + context.go('/rooms/mylearning'); + break; + case SettingsAction.findAClass: + debugger(when: kDebugMode, message: "left to implement"); + break; + case SettingsAction.logout: + pLogoutAction(context); + break; + // Pangea# } } } @@ -356,11 +504,23 @@ class ClientChooserButton extends StatelessWidget { } enum SettingsAction { - addAccount, - newStory, - newGroup, - newSpace, + // #Pangea + // addAccount, + // newStory, + // newGroup, + // newSpace, + // Pangea# invite, settings, archive, + // #Pangea + joinWithClassCode, + classAnalytics, + myAnalytics, + findAClass, + findAConversationPartner, + logout, + newClass, + newExchange + // Pangea# } diff --git a/lib/pages/chat_list/navi_rail_item.dart b/lib/pages/chat_list/navi_rail_item.dart index 7eef55468..2004f3568 100644 --- a/lib/pages/chat_list/navi_rail_item.dart +++ b/lib/pages/chat_list/navi_rail_item.dart @@ -16,8 +16,8 @@ class NaviRailItem extends StatefulWidget { required this.onTap, required this.icon, this.selectedIcon, - Key? key, - }) : super(key: key); + super.key, + }); @override State createState() => _NaviRailItemState(); diff --git a/lib/pages/chat_list/search_title.dart b/lib/pages/chat_list/search_title.dart index 3ed0e64d4..62bcfb684 100644 --- a/lib/pages/chat_list/search_title.dart +++ b/lib/pages/chat_list/search_title.dart @@ -13,8 +13,8 @@ class SearchTitle extends StatelessWidget { this.trailing, this.onTap, this.color, - Key? key, - }) : super(key: key); + super.key, + }); @override Widget build(BuildContext context) => Material( diff --git a/lib/pages/chat_list/space_view.dart b/lib/pages/chat_list/space_view.dart index 8bbb63691..f88596085 100644 --- a/lib/pages/chat_list/space_view.dart +++ b/lib/pages/chat_list/space_view.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:flutter/material.dart'; import 'package:adaptive_dialog/adaptive_dialog.dart'; @@ -10,6 +12,10 @@ import 'package:matrix/matrix.dart'; import 'package:fluffychat/pages/chat_list/chat_list.dart'; import 'package:fluffychat/pages/chat_list/chat_list_item.dart'; import 'package:fluffychat/pages/chat_list/search_title.dart'; +import 'package:fluffychat/pangea/constants/class_default_values.dart'; +import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart'; +import 'package:fluffychat/pangea/utils/archive_space.dart'; +import 'package:fluffychat/pangea/utils/chat_list_handle_space_tap.dart'; import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart'; import 'package:fluffychat/widgets/avatar.dart'; import '../../utils/localized_exception_extension.dart'; @@ -21,9 +27,9 @@ class SpaceView extends StatefulWidget { final ScrollController scrollController; const SpaceView( this.controller, { - Key? key, + super.key, required this.scrollController, - }) : super(key: key); + }); @override State createState() => _SpaceViewState(); @@ -35,9 +41,15 @@ class _SpaceViewState extends State { String? prevBatch; void _refresh() { - setState(() { - _requests.remove(widget.controller.activeSpaceId); - }); + // #Pangea + if (mounted) { + // Pangea# + setState(() { + _requests.remove(widget.controller.activeSpaceId); + }); + // #Pangea + } + // Pangea# } Future getFuture(String activeSpaceId) => @@ -73,7 +85,10 @@ class _SpaceViewState extends State { } if (spaceChild.roomType == 'm.space') { if (spaceChild.roomId == widget.controller.activeSpaceId) { - context.go('/rooms/${spaceChild.roomId}'); + // #Pangea + // context.go('/rooms/${spaceChild.roomId}'); + context.push('/spaces/${spaceChild.roomId}'); + // Pangea# } else { widget.controller.setActiveSpace(spaceChild.roomId); } @@ -110,11 +125,31 @@ class _SpaceViewState extends State { label: L10n.of(context)!.removeFromSpace, icon: Icons.delete_sweep_outlined, ), + // #Pangea + if (room != null && + room.ownPowerLevel >= ClassDefaultValues.powerLevelOfAdmin) + SheetAction( + key: SpaceChildContextAction.addToSpace, + label: L10n.of(context)!.addToSpace, + icon: Icons.workspaces_outlined, + ), + if (room != null && room.isRoomAdmin) + SheetAction( + key: SpaceChildContextAction.archive, + label: room.isSpace + ? L10n.of(context)!.archiveSpace + : L10n.of(context)!.archive, + icon: Icons.architecture_outlined, + ), + // Pangea# if (room != null) SheetAction( key: SpaceChildContextAction.leave, label: L10n.of(context)!.leave, - icon: Icons.delete_outlined, + // #Pangea + // icon: Icons.delete_outlined, + icon: Icons.arrow_forward, + // Pangea# isDestructiveAction: true, ), ], @@ -128,7 +163,15 @@ class _SpaceViewState extends State { case SpaceChildContextAction.leave: await showFutureLoadingDialog( context: context, - future: room!.leave, + // #Pangea + // future: room!.leave, + future: () async { + await room!.leave(); + if (Matrix.of(context).activeRoomId == room.id) { + context.go('/rooms'); + } + }, + // Pangea# ); break; case SpaceChildContextAction.removeFromSpace: @@ -137,9 +180,49 @@ class _SpaceViewState extends State { future: () => activeSpace!.removeSpaceChild(spaceChild!.roomId), ); break; + // #Pangea + case SpaceChildContextAction.archive: + widget.controller.cancelAction(); + widget.controller.toggleSelection(room!.id); + room.isSpace + ? await showFutureLoadingDialog( + context: context, + future: () async { + await archiveSpace( + room, + Matrix.of(context).client, + ); + widget.controller.selectedRoomIds.clear(); + }, + ) + : await widget.controller.archiveAction(); + _refresh(); + break; + case SpaceChildContextAction.addToSpace: + widget.controller.cancelAction(); + widget.controller.toggleSelection(room!.id); + await widget.controller.addToSpace(); + break; + // Pangea# } } + // #Pangea + StreamSubscription? _roomSubscription; + + @override + void initState() { + super.initState(); + _refresh(); + } + + @override + void dispose() { + super.dispose(); + _roomSubscription?.cancel(); + } + // Pangea# + @override Widget build(BuildContext context) { final client = Matrix.of(context).client; @@ -147,12 +230,14 @@ class _SpaceViewState extends State { final allSpaces = client.rooms.where((room) => room.isSpace); if (activeSpaceId == null) { final rootSpaces = allSpaces - .where( - (space) => !allSpaces.any( - (parentSpace) => parentSpace.spaceChildren - .any((child) => child.roomId == space.id), - ), - ) + // #Pangea + // .where( + // (space) => !allSpaces.any( + // (parentSpace) => parentSpace.spaceChildren + // .any((child) => child.roomId == space.id), + // ), + // ) + // Pangea# .toList(); return CustomScrollView( @@ -172,17 +257,34 @@ class _SpaceViewState extends State { leading: Avatar( mxContent: rootSpace.avatar, name: displayname, + // #Pangea + littleIcon: rootSpace.roomTypeIcon, + // Pangea# ), title: Text( displayname, maxLines: 1, overflow: TextOverflow.ellipsis, ), + // #Pangea subtitle: Text( - L10n.of(context)! - .numChats(rootSpace.spaceChildren.length.toString()), + rootSpace.membership == Membership.join + ? L10n.of(context)!.numChats( + rootSpace.spaceChildren.length.toString(), + ) + : L10n.of(context)!.youreInvited, ), - onTap: () => widget.controller.setActiveSpace(rootSpace.id), + onTap: () => chatListHandleSpaceTap( + context, + widget.controller, + rootSpaces[i], + ), + // subtitle: Text( + // L10n.of(context)! + // .numChats(rootSpace.spaceChildren.length.toString()), + // ), + // onTap: () => widget.controller.setActiveSpace(rootSpace.id), + // Pangea# onLongPress: () => _onSpaceChildContextMenu(null, rootSpace), trailing: const Icon(Icons.chevron_right_outlined), @@ -195,6 +297,25 @@ class _SpaceViewState extends State { ], ); } + + // #Pangea + _roomSubscription = client.onSync.stream + .where((event) => event.rooms?.join?.isNotEmpty ?? false) + .listen((event) { + if (mounted) { + final List joinedRoomIds = event.rooms!.join!.keys.toList(); + final joinedRoomFutures = joinedRoomIds.map( + (joinedRoomId) => client.waitForRoomInSync( + joinedRoomId, + join: true, + ), + ); + Future.wait(joinedRoomFutures).then((_) { + _refresh(); + }); + } + }); + // Pangea# return FutureBuilder( future: getFuture(activeSpaceId), builder: (context, snapshot) { @@ -232,15 +353,56 @@ class _SpaceViewState extends State { (space) => space.spaceChildren.any((child) => child.roomId == activeSpaceId), ); - final spaceChildren = response.rooms; + // #Pangea + // final spaceChildren = response.rooms; + List spaceChildren = response.rooms; + final space = Matrix.of(context).client.getRoomById(activeSpaceId); + if (space != null) { + final matchingSpaceChildren = space.spaceChildren + .where( + (spaceChild) => spaceChildren + .map((hierarchyMember) => hierarchyMember.roomId) + .contains(spaceChild.roomId), + ) + .toList(); + spaceChildren = spaceChildren + .where( + (spaceChild) => + matchingSpaceChildren.any( + (matchingSpaceChild) => + matchingSpaceChild.roomId == spaceChild.roomId && + matchingSpaceChild.suggested == true, + ) || + [Membership.join, Membership.invite].contains( + Matrix.of(context) + .client + .getRoomById(spaceChild.roomId) + ?.membership, + ), + ) + .toList(); + } + spaceChildren.sort((a, b) { + final bool aIsSpace = a.roomType == 'm.space'; + final bool bIsSpace = b.roomType == 'm.space'; + + if (aIsSpace && !bIsSpace) { + return -1; + } else if (!aIsSpace && bIsSpace) { + return 1; + } + return 0; + }); + // Pangea# + final canLoadMore = response.nextBatch != null; - return WillPopScope( - onWillPop: () async { + return PopScope( + canPop: parentSpace == null, + onPopInvoked: (pop) async { + if (pop) return; if (parentSpace != null) { widget.controller.setActiveSpace(parentSpace.id); - return false; } - return true; }, child: CustomScrollView( controller: widget.scrollController, @@ -318,15 +480,26 @@ class _SpaceViewState extends State { .withAlpha(128), trailing: const Padding( padding: EdgeInsets.symmetric(horizontal: 16.0), - child: Icon(Icons.edit_outlined), + // #Pangea + // child: Icon(Icons.edit_outlined), + child: Icon(Icons.settings_outlined), + // Pangea# ), - onTap: () => _onJoinSpaceChild(spaceChild), + // #Pangea + // onTap: () => _onJoinSpaceChild(spaceChild), + onTap: () => context.push( + '/spaces/${spaceChild.roomId}', + ), + // Pangea# ); } return ListTile( leading: Avatar( mxContent: spaceChild.avatarUrl, name: spaceChild.name, + //#Pangea + littleIcon: room?.roomTypeIcon, + //Pangea# ), title: Row( children: [ @@ -353,7 +526,16 @@ class _SpaceViewState extends State { ], ], ), - onTap: () => _onJoinSpaceChild(spaceChild), + //#Pangea + // onTap: () => _onJoinSpaceChild(spaceChild), + onTap: room?.isSpace ?? false + ? () => chatListHandleSpaceTap( + context, + widget.controller, + room!, + ) + : () => _onJoinSpaceChild(spaceChild), + //Pangea# onLongPress: () => _onSpaceChildContextMenu(spaceChild, room), subtitle: Text( @@ -386,4 +568,9 @@ enum SpaceChildContextAction { join, leave, removeFromSpace, + // #Pangea + // deleteChat, + archive, + addToSpace + // Pangea# } diff --git a/lib/pages/chat_list/start_chat_fab.dart b/lib/pages/chat_list/start_chat_fab.dart index f702ad69d..01f0d4165 100644 --- a/lib/pages/chat_list/start_chat_fab.dart +++ b/lib/pages/chat_list/start_chat_fab.dart @@ -1,31 +1,50 @@ +import 'dart:core'; + import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:go_router/go_router.dart'; -import '../../config/themes.dart'; -import 'chat_list.dart'; +import 'package:fluffychat/config/themes.dart'; +import 'package:fluffychat/pages/chat_list/chat_list.dart'; class StartChatFloatingActionButton extends StatelessWidget { final ActiveFilter activeFilter; final ValueNotifier scrolledToTop; final bool roomsIsEmpty; + // #Pangea + final ChatListController controller; + // Pangea# const StartChatFloatingActionButton({ - Key? key, + super.key, required this.activeFilter, required this.scrolledToTop, required this.roomsIsEmpty, - }) : super(key: key); + // #Pangea + required this.controller, + // Pangea# + }); void _onPressed(BuildContext context) { + //#Pangea + if (controller.activeSpaceId != null) { + context.go('/rooms/newgroup/${controller.activeSpaceId}'); + return; + } + //Pangea# switch (activeFilter) { case ActiveFilter.allChats: case ActiveFilter.messages: - context.go('/rooms/newprivatechat'); - break; + // #Pangea + // context.go('/rooms/newprivatechat'); + // break; + // Pangea# case ActiveFilter.groups: - context.go('/rooms/newgroup'); + // #Pangea + // context.go('/rooms/newgroup'); + context.go('/rooms/newgroup/${controller.activeSpaceId}'); + // Pangea# break; case ActiveFilter.spaces: context.go('/rooms/newspace'); @@ -34,10 +53,17 @@ class StartChatFloatingActionButton extends StatelessWidget { } IconData get icon { + // #Pangea + if (controller.activeSpaceId != null) { + return Icons.group_add_outlined; + } + // Pangea# switch (activeFilter) { case ActiveFilter.allChats: case ActiveFilter.messages: - return Icons.add_outlined; + // #Pangea + // return Icons.add_outlined; + // Pangea# case ActiveFilter.groups: return Icons.group_add_outlined; case ActiveFilter.spaces: @@ -46,6 +72,11 @@ class StartChatFloatingActionButton extends StatelessWidget { } String getLabel(BuildContext context) { + // #Pangea + if (controller.activeSpaceId != null) { + return L10n.of(context)!.newGroup; + } + // Pangea# switch (activeFilter) { case ActiveFilter.allChats: case ActiveFilter.messages: diff --git a/lib/pages/chat_list/stories_header.dart b/lib/pages/chat_list/stories_header.dart index ab6caabbc..d5325b91f 100644 --- a/lib/pages/chat_list/stories_header.dart +++ b/lib/pages/chat_list/stories_header.dart @@ -23,7 +23,7 @@ enum ContextualRoomAction { class StoriesHeader extends StatelessWidget { final String filter; - const StoriesHeader({required this.filter, Key? key}) : super(key: key); + const StoriesHeader({required this.filter, super.key}); void _addToStoryAction(BuildContext context) => context.go('/rooms/stories/create'); @@ -186,8 +186,7 @@ class _StoryButton extends StatefulWidget { this.hasPosts = true, this.unread = false, this.onLongPressed, - Key? key, - }) : super(key: key); + }); @override State<_StoryButton> createState() => _StoryButtonState(); diff --git a/lib/pages/chat_list/test.dart b/lib/pages/chat_list/test.dart new file mode 100644 index 000000000..3207c9637 --- /dev/null +++ b/lib/pages/chat_list/test.dart @@ -0,0 +1,48 @@ +// void resetActiveSpaceId() { +// setState(() { +// activeSpaceId = null; +// }); +// } + +// void setActiveSpace(String? spaceId) { +// setState(() { +// activeSpaceId = spaceId; +// activeFilter = ActiveFilter.spaces; +// }); +// } + +// int get selectedIndex { +// switch (activeFilter) { +// case ActiveFilter.allChats: +// case ActiveFilter.messages: +// return 0; +// case ActiveFilter.groups: +// return 1; +// case ActiveFilter.spaces: +// return AppConfig.separateChatTypes ? 2 : 1; +// } +// } + +// ActiveFilter getActiveFilterByDestination(int? i) { +// switch (i) { +// case 1: +// if (AppConfig.separateChatTypes) { +// return ActiveFilter.groups; +// } +// return ActiveFilter.spaces; +// case 2: +// return ActiveFilter.spaces; +// case 0: +// default: +// if (AppConfig.separateChatTypes) { +// return ActiveFilter.messages; +// } +// return ActiveFilter.allChats; +// } +// } + +// void onDestinationSelected(int? i) { +// setState(() { +// activeFilter = getActiveFilterByDestination(i); +// }); +// } diff --git a/lib/pages/chat_permissions_settings/chat_permissions_settings.dart b/lib/pages/chat_permissions_settings/chat_permissions_settings.dart index 394206f17..a6cdcbef0 100644 --- a/lib/pages/chat_permissions_settings/chat_permissions_settings.dart +++ b/lib/pages/chat_permissions_settings/chat_permissions_settings.dart @@ -13,7 +13,7 @@ import 'package:fluffychat/widgets/matrix.dart'; import 'package:fluffychat/widgets/permission_slider_dialog.dart'; class ChatPermissionsSettings extends StatefulWidget { - const ChatPermissionsSettings({Key? key}) : super(key: key); + const ChatPermissionsSettings({super.key}); @override ChatPermissionsSettingsController createState() => @@ -99,6 +99,7 @@ class ChatPermissionsSettingsController extends State { okLabel: L10n.of(context)!.yes, cancelLabel: L10n.of(context)!.cancel, title: L10n.of(context)!.areYouSure, + message: L10n.of(context)!.roomUpgradeDescription, )) { return; } diff --git a/lib/pages/chat_permissions_settings/chat_permissions_settings_view.dart b/lib/pages/chat_permissions_settings/chat_permissions_settings_view.dart index fd10b9af0..072e20405 100644 --- a/lib/pages/chat_permissions_settings/chat_permissions_settings_view.dart +++ b/lib/pages/chat_permissions_settings/chat_permissions_settings_view.dart @@ -11,8 +11,7 @@ import 'package:fluffychat/widgets/matrix.dart'; class ChatPermissionsSettingsView extends StatelessWidget { final ChatPermissionsSettingsController controller; - const ChatPermissionsSettingsView(this.controller, {Key? key}) - : super(key: key); + const ChatPermissionsSettingsView(this.controller, {super.key}); @override Widget build(BuildContext context) { diff --git a/lib/pages/chat_permissions_settings/permission_list_tile.dart b/lib/pages/chat_permissions_settings/permission_list_tile.dart index 0ac68f44c..a9d159854 100644 --- a/lib/pages/chat_permissions_settings/permission_list_tile.dart +++ b/lib/pages/chat_permissions_settings/permission_list_tile.dart @@ -10,12 +10,12 @@ class PermissionsListTile extends StatelessWidget { final void Function()? onTap; const PermissionsListTile({ - Key? key, + super.key, required this.permissionKey, required this.permission, this.category, this.onTap, - }) : super(key: key); + }); String getLocalizedPowerLevelString(BuildContext context) { if (category == null) { diff --git a/lib/pages/device_settings/device_settings.dart b/lib/pages/device_settings/device_settings.dart index 59e9e6583..3ad1266c8 100644 --- a/lib/pages/device_settings/device_settings.dart +++ b/lib/pages/device_settings/device_settings.dart @@ -13,7 +13,7 @@ import 'package:fluffychat/utils/localized_exception_extension.dart'; import '../../widgets/matrix.dart'; class DevicesSettings extends StatefulWidget { - const DevicesSettings({Key? key}) : super(key: key); + const DevicesSettings({super.key}); @override DevicesSettingsController createState() => DevicesSettingsController(); @@ -34,10 +34,14 @@ class DevicesSettingsController extends State { void removeDevicesAction(List devices) async { if (await showOkCancelAlertDialog( + // #Pangea + useRootNavigator: false, + // Pangea# context: context, title: L10n.of(context)!.areYouSure, okLabel: L10n.of(context)!.yes, cancelLabel: L10n.of(context)!.cancel, + message: L10n.of(context)!.removeDevicesDescription, ) == OkCancelResult.cancel) return; final matrix = Matrix.of(context); @@ -68,6 +72,9 @@ class DevicesSettingsController extends State { void renameDeviceAction(Device device) async { final displayName = await showTextInputDialog( + // #Pangea + useRootNavigator: false, + // Pangea# context: context, title: L10n.of(context)!.changeDeviceName, okLabel: L10n.of(context)!.ok, diff --git a/lib/pages/device_settings/device_settings_view.dart b/lib/pages/device_settings/device_settings_view.dart index b03f0dc7b..4094c0227 100644 --- a/lib/pages/device_settings/device_settings_view.dart +++ b/lib/pages/device_settings/device_settings_view.dart @@ -9,7 +9,7 @@ import 'user_device_list_item.dart'; class DevicesSettingsView extends StatelessWidget { final DevicesSettingsController controller; - const DevicesSettingsView(this.controller, {Key? key}) : super(key: key); + const DevicesSettingsView(this.controller, {super.key}); @override Widget build(BuildContext context) { diff --git a/lib/pages/device_settings/user_device_list_item.dart b/lib/pages/device_settings/user_device_list_item.dart index 887b3b445..db793ac35 100644 --- a/lib/pages/device_settings/user_device_list_item.dart +++ b/lib/pages/device_settings/user_device_list_item.dart @@ -31,8 +31,8 @@ class UserDeviceListItem extends StatelessWidget { required this.verify, required this.block, required this.unblock, - Key? key, - }) : super(key: key); + super.key, + }); @override Widget build(BuildContext context) { diff --git a/lib/pages/dialer/dialer.dart b/lib/pages/dialer/dialer.dart index 1af65ce9d..a8e5a9202 100644 --- a/lib/pages/dialer/dialer.dart +++ b/lib/pages/dialer/dialer.dart @@ -38,10 +38,9 @@ import 'pip/pip_view.dart'; class _StreamView extends StatelessWidget { const _StreamView( this.wrappedStream, { - Key? key, this.mainView = false, required this.matrixClient, - }) : super(key: key); + }); final WrappedMediaStream wrappedStream; final Client matrixClient; @@ -128,8 +127,8 @@ class Calling extends StatefulWidget { required this.client, required this.callId, this.onClear, - Key? key, - }) : super(key: key); + super.key, + }); @override MyCallingPage createState() => MyCallingPage(); diff --git a/lib/pages/dialer/pip/pip_view.dart b/lib/pages/dialer/pip/pip_view.dart index 74008aaf1..5396c9136 100644 --- a/lib/pages/dialer/pip/pip_view.dart +++ b/lib/pages/dialer/pip/pip_view.dart @@ -15,13 +15,13 @@ class PIPView extends StatefulWidget { ) builder; const PIPView({ - Key? key, + super.key, required this.builder, this.initialCorner = PIPViewCorner.topRight, this.floatingWidth, this.floatingHeight, this.avoidKeyboard = true, - }) : super(key: key); + }); @override PIPViewState createState() => PIPViewState(); diff --git a/lib/pages/homeserver_picker/homeserver_app_bar.dart b/lib/pages/homeserver_picker/homeserver_app_bar.dart index d1fd7149e..3b7611ed2 100644 --- a/lib/pages/homeserver_picker/homeserver_app_bar.dart +++ b/lib/pages/homeserver_picker/homeserver_app_bar.dart @@ -11,8 +11,7 @@ import 'homeserver_picker.dart'; class HomeserverAppBar extends StatelessWidget { final HomeserverPickerController controller; - const HomeserverAppBar({Key? key, required this.controller}) - : super(key: key); + const HomeserverAppBar({super.key, required this.controller}); @override Widget build(BuildContext context) { @@ -51,6 +50,7 @@ class HomeserverAppBar extends StatelessWidget { controller.checkHomeserverAction(); }, textFieldConfiguration: TextFieldConfiguration( + enabled: !controller.isLoggingIn, controller: controller.homeserverController, decoration: InputDecoration( prefixIcon: Navigator.of(context).canPop() diff --git a/lib/pages/homeserver_picker/homeserver_bottom_sheet.dart b/lib/pages/homeserver_picker/homeserver_bottom_sheet.dart index d7cd534bf..0fc6d0112 100644 --- a/lib/pages/homeserver_picker/homeserver_bottom_sheet.dart +++ b/lib/pages/homeserver_picker/homeserver_bottom_sheet.dart @@ -5,8 +5,7 @@ import 'package:url_launcher/url_launcher_string.dart'; class HomeserverBottomSheet extends StatelessWidget { final HomeserverBenchmarkResult homeserver; - const HomeserverBottomSheet({required this.homeserver, Key? key}) - : super(key: key); + const HomeserverBottomSheet({required this.homeserver, super.key}); @override Widget build(BuildContext context) { diff --git a/lib/pages/homeserver_picker/homeserver_picker.dart b/lib/pages/homeserver_picker/homeserver_picker.dart index a5df23a51..7c1e82ccf 100644 --- a/lib/pages/homeserver_picker/homeserver_picker.dart +++ b/lib/pages/homeserver_picker/homeserver_picker.dart @@ -16,6 +16,8 @@ import 'package:universal_html/html.dart' as html; import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/pages/homeserver_picker/homeserver_picker_view.dart'; +import 'package:fluffychat/pangea/utils/error_handler.dart'; +import 'package:fluffychat/pangea/utils/firebase_analytics.dart'; import 'package:fluffychat/utils/platform_infos.dart'; import 'package:fluffychat/widgets/app_lock.dart'; import 'package:fluffychat/widgets/matrix.dart'; @@ -25,7 +27,7 @@ import 'package:fluffychat/utils/tor_stub.dart' if (dart.library.html) 'package:tor_detector_web/tor_detector_web.dart'; class HomeserverPicker extends StatefulWidget { - const HomeserverPicker({Key? key}) : super(key: key); + const HomeserverPicker({super.key}); @override HomeserverPickerController createState() => HomeserverPickerController(); @@ -33,6 +35,8 @@ class HomeserverPicker extends StatefulWidget { class HomeserverPickerController extends State { bool isLoading = false; + bool isLoggingIn = false; + final TextEditingController homeserverController = TextEditingController( text: AppConfig.defaultHomeserver, ); @@ -113,25 +117,36 @@ class HomeserverPickerController extends State { Map? _rawLoginTypes; - void ssoLoginAction(String id) async { + // #Pangea + // void ssoLoginAction(String id) async { + void ssoLoginAction(IdentityProvider provider) async { + final id = provider.id!; + //Pangea# final redirectUrl = kIsWeb - ? '${html.window.origin!}/web/auth.html' - : isDefaultPlatform - ? '${AppConfig.appOpenUrlScheme.toLowerCase()}://login' - : 'http://localhost:3001//login'; + // #Pangea + // ? '${html.window.origin!}/web/auth.html' + // : isDefaultPlatform + // ? '${AppConfig.appOpenUrlScheme.toLowerCase()}://login' + // : 'http://localhost:3001//login'; + ? '${html.window.origin!}/auth.html' + : '${AppConfig.appOpenUrlScheme.toLowerCase()}://login'; + //Pangea# final url = '${Matrix.of(context).getLoginClient().homeserver?.toString()}/_matrix/client/r0/login/sso/redirect/${Uri.encodeComponent(id)}?redirectUrl=${Uri.encodeQueryComponent(redirectUrl)}'; final urlScheme = isDefaultPlatform ? Uri.parse(redirectUrl).scheme : "http://localhost:3001"; final result = await FlutterWebAuth2.authenticate( - url: url, + url: url.toString(), callbackUrlScheme: urlScheme, ); final token = Uri.parse(result).queryParameters['loginToken']; if (token?.isEmpty ?? false) return; - await showFutureLoadingDialog( + // #Pangea + final loginRes = await showFutureLoadingDialog( + // await showFutureLoadingDialog( + // Pangea# context: context, future: () => Matrix.of(context).getLoginClient().login( LoginType.mLoginToken, @@ -139,14 +154,22 @@ class HomeserverPickerController extends State { initialDeviceDisplayName: PlatformInfos.clientName, ), ); + //Pangea# + if (loginRes.result != null) { + GoogleAnalytics.login(provider.name!, loginRes.result!.userId); + } + //Pangea# } List? get identityProviders { final loginTypes = _rawLoginTypes; if (loginTypes == null) return null; - final rawProviders = loginTypes.tryGetList('flows')!.singleWhere( - (flow) => flow['type'] == AuthenticationTypes.sso, - )['identity_providers']; + final List? rawProviders = loginTypes.tryGetList('flows')!.singleWhere( + (flow) => flow['type'] == AuthenticationTypes.sso, + )['identity_providers'] ?? + [ + {'id': null}, + ]; final list = (rawProviders as List) .map((json) => IdentityProvider.fromJson(json)) .toList(); @@ -183,6 +206,9 @@ class HomeserverPickerController extends State { Matrix.of(context).initMatrix(); } catch (e, s) { Logs().e('Future error:', e, s); + // #Pangea + ErrorHandler.logError(e: e, s: s); + // Pangea# } }, ); diff --git a/lib/pages/homeserver_picker/homeserver_picker_view.dart b/lib/pages/homeserver_picker/homeserver_picker_view.dart index 3cd9d713e..59301c6a1 100644 --- a/lib/pages/homeserver_picker/homeserver_picker_view.dart +++ b/lib/pages/homeserver_picker/homeserver_picker_view.dart @@ -1,71 +1,84 @@ +// Flutter imports: + import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:fluffychat/config/app_config.dart'; +import 'package:fluffychat/pangea/pages/connect/p_sso_button.dart'; +import 'package:fluffychat/pangea/widgets/common/pangea_logo_svg.dart'; +import 'package:fluffychat/pangea/widgets/signup/signup_buttons.dart'; import 'package:fluffychat/widgets/layouts/login_scaffold.dart'; -import 'package:fluffychat/widgets/matrix.dart'; -import '../../config/themes.dart'; -import '../../widgets/mxc_image.dart'; -import 'homeserver_app_bar.dart'; import 'homeserver_picker.dart'; class HomeserverPickerView extends StatelessWidget { final HomeserverPickerController controller; - const HomeserverPickerView(this.controller, {Key? key}) : super(key: key); + const HomeserverPickerView(this.controller, {super.key}); @override Widget build(BuildContext context) { final identityProviders = controller.identityProviders; final errorText = controller.error; return LoginScaffold( - enforceMobileMode: Matrix.of(context).client.isLogged(), + // #Pangea + // enforceMobileMode: Matrix.of(context).client.isLogged(), + // appBar: AppBar( + // titleSpacing: 12, + // automaticallyImplyLeading: false, + // title: HomeserverAppBar(controller: controller), + // ), appBar: AppBar( - titleSpacing: 12, - automaticallyImplyLeading: false, - title: HomeserverAppBar(controller: controller), + centerTitle: true, + title: Text( + AppConfig.applicationName, + ), ), + // Pangea# body: SafeArea( child: Column( children: [ // display a prominent banner to import session for TOR browser // users. This feature is just some UX sugar as TOR users are // usually forced to logout as TOR browser is non-persistent - AnimatedContainer( - height: controller.isTorBrowser ? 64 : 0, - duration: FluffyThemes.animationDuration, - curve: FluffyThemes.animationCurve, - clipBehavior: Clip.hardEdge, - decoration: const BoxDecoration(), - child: Material( - clipBehavior: Clip.hardEdge, - borderRadius: - const BorderRadius.vertical(bottom: Radius.circular(8)), - color: Theme.of(context).colorScheme.surface, - child: ListTile( - leading: const Icon(Icons.vpn_key), - title: Text(L10n.of(context)!.hydrateTor), - subtitle: Text(L10n.of(context)!.hydrateTorLong), - trailing: const Icon(Icons.chevron_right_outlined), - onTap: controller.restoreBackup, - ), - ), - ), + // #Pangea + // AnimatedContainer( + // height: controller.isTorBrowser ? 64 : 0, + // duration: FluffyThemes.animationDuration, + // curve: FluffyThemes.animationCurve, + // clipBehavior: Clip.hardEdge, + // decoration: const BoxDecoration(), + // child: Material( + // clipBehavior: Clip.hardEdge, + // borderRadius: + // const BorderRadius.vertical(bottom: Radius.circular(8)), + // color: Theme.of(context).colorScheme.surface, + // child: ListTile( + // leading: const Icon(Icons.vpn_key), + // title: Text(L10n.of(context)!.hydrateTor), + // subtitle: Text(L10n.of(context)!.hydrateTorLong), + // trailing: const Icon(Icons.chevron_right_outlined), + // onTap: controller.restoreBackup, + // ), + // ), + // ), + // Pangea# Expanded( child: controller.isLoading ? const Center(child: CircularProgressIndicator.adaptive()) : ListView( children: [ - Padding( - padding: const EdgeInsets.symmetric(horizontal: 8.0), - child: FluffyThemes.isColumnMode(context) - ? Image.asset( - 'assets/info-logo.png', - height: 96, - ) - : Image.asset('assets/banner_transparent.png'), - ), + // #Pangea + // Padding( + // padding: const EdgeInsets.symmetric(horizontal: 8.0), + // child: FluffyThemes.isColumnMode(context) + // ? Image.asset( + // 'assets/info-logo.png', + // height: 96, + // ) + // : Image.asset('assets/banner_transparent.png'), + // ), + // Pangea# const SizedBox(height: 12), if (errorText != null) ...[ const Center( @@ -86,73 +99,116 @@ class HomeserverPickerView extends StatelessWidget { ), ), ), - Center( - child: Text( - L10n.of(context)! - .pleaseTryAgainLaterOrChooseDifferentServer, - textAlign: TextAlign.center, - style: TextStyle( - color: Theme.of(context).colorScheme.error, - fontSize: 12, - ), - ), - ), + // #Pangea + // Center( + // child: Text( + // L10n.of(context)! + // .pleaseTryAgainLaterOrChooseDifferentServer, + // textAlign: TextAlign.center, + // style: TextStyle( + // color: Theme.of(context).colorScheme.error, + // fontSize: 12, + // ), + // ), + // ), + // Pangea# const SizedBox(height: 12), ], + // #Pangea + const SignupButtons(), + // Pangea# if (identityProviders != null) ...[ ...identityProviders.map( - (provider) => _LoginButton( - icon: provider.icon == null - ? const Icon(Icons.open_in_new_outlined) - : Material( - color: Colors.white, - borderRadius: BorderRadius.circular( - AppConfig.borderRadius, - ), - clipBehavior: Clip.hardEdge, - child: MxcImage( - placeholder: (_) => - const Icon(Icons.web_outlined), - uri: Uri.parse(provider.icon!), - width: 24, - height: 24, - ), - ), - label: L10n.of(context)!.signInWith( - provider.name ?? - provider.brand ?? - L10n.of(context)!.singlesignon, + // #Pangea + (provider) => Padding( + padding: const EdgeInsets.all(12.0), + child: Hero( + tag: + "ssobutton ${provider.id ?? provider.name}", + child: PangeaSsoButton( + identityProvider: provider, + onPressed: () => + controller.ssoLoginAction(provider), + ), ), - onPressed: () => - controller.ssoLoginAction(provider.id!), ), + // (provider) => _LoginButton( + // icon: provider.icon == null + // ? const Icon(Icons.open_in_new_outlined) + // : Material( + // color: Colors.white, + // borderRadius: BorderRadius.circular( + // AppConfig.borderRadius, + // ), + // clipBehavior: Clip.hardEdge, + // child: MxcImage( + // placeholder: (_) => + // const Icon(Icons.web_outlined), + // uri: Uri.parse(provider.icon!), + // width: 24, + // height: 24, + // ), + // ), + // label: L10n.of(context)!.signInWith( + // provider.name ?? + // provider.brand ?? + // L10n.of(context)!.singlesignon, + // ), + // onPressed: () => + // controller.ssoLoginAction(provider.id!), + // Pangea# ), ], if (controller.supportsPasswordLogin) - _LoginButton( - onPressed: controller.login, - icon: const Icon(Icons.login_outlined), - label: L10n.of(context)!.signInWithPassword, - ), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 12), - child: Center( - child: SizedBox( - width: 256, - child: TextButton( - style: TextButton.styleFrom( - padding: - const EdgeInsets.symmetric(vertical: 12), - ), - onPressed: controller.restoreBackup, - child: Text( - L10n.of(context)!.hydrate, - textAlign: TextAlign.center, + // #Pangea + Padding( + padding: const EdgeInsets.all(12.0), + child: Hero( + tag: 'signinButton', + child: ElevatedButton( + onPressed: controller.login, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const PangeaLogoSvg(width: 20), + Padding( + padding: const EdgeInsets.symmetric( + horizontal: 10, + ), + child: Text( + "${L10n.of(context)!.loginOrSignup} Pangea Chat", + ), + ), + ], ), ), ), ), - ), + // _LoginButton( + // onPressed: controller.login, + // icon: const Icon(Icons.login_outlined), + // label: L10n.of(context)!.signInWithPassword, + // ), + // Padding( + // padding: const EdgeInsets.symmetric(horizontal: 12), + // child: Center( + // child: SizedBox( + // width: 256, + // child: TextButton( + // style: TextButton.styleFrom( + // padding: + // const EdgeInsets.symmetric(vertical: 12), + // ), + // onPressed: controller.restoreBackup, + // child: Text( + // L10n.of(context)!.hydrate, + // textAlign: TextAlign.center, + // ), + // ), + // ), + // ), + // ), + // Pangea# ], ), ), @@ -172,8 +228,7 @@ class _LoginButton extends StatelessWidget { required this.icon, required this.label, required this.onPressed, - Key? key, - }) : super(key: key); + }); @override Widget build(BuildContext context) { diff --git a/lib/pages/image_viewer/image_viewer.dart b/lib/pages/image_viewer/image_viewer.dart index ac4505c40..94ab19dd4 100644 --- a/lib/pages/image_viewer/image_viewer.dart +++ b/lib/pages/image_viewer/image_viewer.dart @@ -11,7 +11,7 @@ import '../../utils/matrix_sdk_extensions/event_extension.dart'; class ImageViewer extends StatefulWidget { final Event event; - const ImageViewer(this.event, {Key? key}) : super(key: key); + const ImageViewer(this.event, {super.key}); @override ImageViewerController createState() => ImageViewerController(); diff --git a/lib/pages/image_viewer/image_viewer_view.dart b/lib/pages/image_viewer/image_viewer_view.dart index 3bd6166c7..7646c8a60 100644 --- a/lib/pages/image_viewer/image_viewer_view.dart +++ b/lib/pages/image_viewer/image_viewer_view.dart @@ -9,7 +9,7 @@ import 'image_viewer.dart'; class ImageViewerView extends StatelessWidget { final ImageViewerController controller; - const ImageViewerView(this.controller, {Key? key}) : super(key: key); + const ImageViewerView(this.controller, {super.key}); @override Widget build(BuildContext context) { diff --git a/lib/pages/invitation_selection/invitation_selection.dart b/lib/pages/invitation_selection/invitation_selection.dart index 74d301630..6736f099a 100644 --- a/lib/pages/invitation_selection/invitation_selection.dart +++ b/lib/pages/invitation_selection/invitation_selection.dart @@ -8,16 +8,24 @@ import 'package:future_loading_dialog/future_loading_dialog.dart'; import 'package:matrix/matrix.dart'; import 'package:fluffychat/pages/invitation_selection/invitation_selection_view.dart'; +import 'package:fluffychat/pangea/constants/class_default_values.dart'; +import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart'; +import 'package:fluffychat/pangea/utils/bot_name.dart'; +import 'package:fluffychat/pangea/utils/error_handler.dart'; import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart'; import 'package:fluffychat/widgets/matrix.dart'; import '../../utils/localized_exception_extension.dart'; +//#Pangea +enum InvitationSelectionMode { admin, member } +//Pangea# + class InvitationSelection extends StatefulWidget { final String roomId; const InvitationSelection({ - Key? key, + super.key, required this.roomId, - }) : super(key: key); + }); @override InvitationSelectionController createState() => @@ -49,9 +57,74 @@ class InvitationSelectionController extends State { b.calcDisplayname().toLowerCase(), ), ); - return contacts; + //#Pangea + // return contacts; + return contacts.where((u) => u.id != BotName.byEnvironment).toList(); + //Pangea# } + //#Pangea + // add all students (already local) from spaceParents who aren't already in room to eligibleStudents + // use room.members to get all users in room + bool _initialized = false; + Future> eligibleStudents( + BuildContext context, + String text, + ) async { + if (!_initialized) { + _initialized = true; + await requestParentSpaceParticipants(); + } + + final eligibleStudents = []; + final spaceParents = room.pangeaSpaceParents; + final userId = Matrix.of(context).client.userID; + for (final Room space in spaceParents) { + eligibleStudents.addAll( + space.getParticipants().where( + (spaceUser) => + spaceUser.id != BotName.byEnvironment && + spaceUser.id != "@support:staging.pangea.chat" && + spaceUser.id != userId && + (text.isEmpty || + (spaceUser.displayName + ?.toLowerCase() + .contains(text.toLowerCase()) ?? + false) || + spaceUser.id.toLowerCase().contains(text.toLowerCase())), + ), + ); + } + return eligibleStudents; + } + + Future + eligibleStudentsAsSearchUserDirectoryResponse( + BuildContext context, + String text, + ) async { + return SearchUserDirectoryResponse( + results: (await eligibleStudents(context, text)) + .map( + (e) => Profile( + userId: e.id, + avatarUrl: e.avatarUrl, + displayName: e.displayName, + ), + ) + .toList(), + limited: false, + ); + } + + List studentsInRoom(BuildContext context) => room + .getParticipants() + .where( + (u) => [Membership.join, Membership.invite].contains(u.membership), + ) + .toList(); + //Pangea# + void inviteAction(BuildContext context, String id, String displayname) async { final room = Matrix.of(context).client.getRoomById(roomId!)!; if (OkCancelResult.ok != @@ -71,7 +144,29 @@ class InvitationSelectionController extends State { } final success = await showFutureLoadingDialog( context: context, - future: () => room.invite(id), + //#Pangea + // future: () => room.invite(id), + future: () => Future.wait([ + room.invite(id), + room.setPower(id, ClassDefaultValues.powerLevelOfAdmin), + if (room.isSpace) + ...room.spaceChildren + .map( + (e) => roomId != null + ? Matrix.of(context).client.getRoomById(e.roomId!) + : null, + ) + .where((element) => element != null) + .cast() + .map( + (e) => Future.wait([ + e.invite(id), + e.setPower(id, ClassDefaultValues.powerLevelOfAdmin), + ]), + ), + ]), + onError: (e) => ErrorHandler.logError(e: e, s: StackTrace.current), + // Pangea# ); if (success.error == null) { ScaffoldMessenger.of(context).showSnackBar( @@ -102,7 +197,15 @@ class InvitationSelectionController extends State { final matrix = Matrix.of(context); SearchUserDirectoryResponse response; try { - response = await matrix.client.searchUserDirectory(text, limit: 10); + //#Pangea + // response = await matrix.client.searchUserDirectory(text, limit: 10); + response = await (mode == InvitationSelectionMode.admin + ? matrix.client.searchUserDirectory(text, limit: 10) + : eligibleStudentsAsSearchUserDirectoryResponse( + context, + text, + )); + //Pangea# } catch (e) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text((e).toLocalizedString(context))), @@ -121,9 +224,82 @@ class InvitationSelectionController extends State { ], ); } + //#Pangea + final participants = Matrix.of(context) + .client + .getRoomById(roomId!)! + .getParticipants() + .where( + (user) => + [Membership.join, Membership.invite].contains(user.membership), + ) + .toList(); + foundProfiles.removeWhere( + (profile) => + participants.indexWhere((u) => u.id == profile.userId) != -1 && + BotName.byEnvironment != profile.userId, + ); + //Pangea# }); } + //#Pangea + Room? _room; + Room get room => _room ??= Matrix.of(context).client.getRoomById(roomId!)!; + + // request participants for all parent spaces + Future requestParentSpaceParticipants() async { + final spaceParents = room.pangeaSpaceParents; + await Future.wait([ + ...spaceParents.map((r) async { + await r.requestParticipants(); + }), + room.requestParticipants(), + ]); + } + + InvitationSelectionMode mode = InvitationSelectionMode.member; + + StreamSubscription? _spaceSubscription; + @override + void initState() { + Future.delayed( + Duration.zero, + () => setState( + () => mode = room.isSpace + ? InvitationSelectionMode.admin + : InvitationSelectionMode.member, + ), + ); + _spaceSubscription = Matrix.of(context) + .client + .onSync + .stream + .where( + (event) => + event.rooms?.join?.keys.any( + (ithRoomId) => room.pangeaSpaceParents + .map((e) => e.id) + .contains(ithRoomId), + ) ?? + false, + ) + .listen( + (SyncUpdate syncUpdate) async { + await requestParentSpaceParticipants(); + setState(() {}); + }, + ); + super.initState(); + } + + @override + void dispose() { + _spaceSubscription?.cancel(); + super.dispose(); + } + //Pangea# + @override Widget build(BuildContext context) => InvitationSelectionView(this); } diff --git a/lib/pages/invitation_selection/invitation_selection_view.dart b/lib/pages/invitation_selection/invitation_selection_view.dart index 202e4b378..5d5540084 100644 --- a/lib/pages/invitation_selection/invitation_selection_view.dart +++ b/lib/pages/invitation_selection/invitation_selection_view.dart @@ -11,7 +11,7 @@ import 'package:fluffychat/widgets/matrix.dart'; class InvitationSelectionView extends StatelessWidget { final InvitationSelectionController controller; - const InvitationSelectionView(this.controller, {Key? key}) : super(key: key); + const InvitationSelectionView(this.controller, {super.key}); @override Widget build(BuildContext context) { @@ -28,7 +28,9 @@ class InvitationSelectionView extends StatelessWidget { ); } - final groupName = room.name.isEmpty ? L10n.of(context)!.group : room.name; + // #Pangea + // final groupName = room.name.isEmpty ? L10n.of(context)!.group : room.name; + // Pangea# return Scaffold( appBar: AppBar( leading: const Center(child: BackButton()), @@ -43,7 +45,12 @@ class InvitationSelectionView extends StatelessWidget { child: TextField( textInputAction: TextInputAction.search, decoration: InputDecoration( - hintText: L10n.of(context)!.inviteContactToGroup(groupName), + // #Pangea + hintText: controller.mode == InvitationSelectionMode.admin + ? L10n.of(context)!.inviteUsersFromPangea + : L10n.of(context)!.inviteStudentByUserName, + // hintText: L10n.of(context)!.inviteContactToGroup(groupName), + // Pangea# prefixIcon: controller.loading ? const Padding( padding: EdgeInsets.symmetric( @@ -92,7 +99,12 @@ class InvitationSelectionView extends StatelessWidget { ), ) : FutureBuilder>( - future: controller.getContacts(context), + // #Pangea + future: controller.mode == InvitationSelectionMode.admin + ? controller.getContacts(context) + : controller.eligibleStudents(context, ""), + // future: controller.getContacts(context), + // Pangea# builder: (BuildContext context, snapshot) { if (!snapshot.hasData) { return const Center( @@ -142,13 +154,12 @@ class _InviteContactListTile extends StatelessWidget { final void Function() onTap; const _InviteContactListTile({ - Key? key, required this.userId, required this.displayname, required this.avatarUrl, required this.isMember, required this.onTap, - }) : super(key: key); + }); @override Widget build(BuildContext context) { @@ -158,6 +169,7 @@ class _InviteContactListTile extends StatelessWidget { leading: Avatar( mxContent: avatarUrl, name: displayname, + presenceUserId: userId, ), title: Text( displayname, diff --git a/lib/pages/key_verification/key_verification_dialog.dart b/lib/pages/key_verification/key_verification_dialog.dart index 7d9633ccd..417825960 100644 --- a/lib/pages/key_verification/key_verification_dialog.dart +++ b/lib/pages/key_verification/key_verification_dialog.dart @@ -10,22 +10,21 @@ import 'package:future_loading_dialog/future_loading_dialog.dart'; import 'package:matrix/encryption.dart'; import 'package:matrix/matrix.dart'; -import 'package:fluffychat/utils/adaptive_bottom_sheet.dart'; import 'package:fluffychat/widgets/avatar.dart'; class KeyVerificationDialog extends StatefulWidget { - Future show(BuildContext context) => showAdaptiveBottomSheet( + Future show(BuildContext context) => showAdaptiveDialog( context: context, builder: (context) => this, - isDismissible: false, + barrierDismissible: false, ); final KeyVerification request; const KeyVerificationDialog({ - Key? key, + super.key, required this.request, - }) : super(key: key); + }); @override KeyVerificationPageState createState() => KeyVerificationPageState(); @@ -342,24 +341,17 @@ class KeyVerificationPageState extends State { ); break; } - return Scaffold( - appBar: AppBar( - leading: const Center(child: CloseButton()), - title: title, - ), - body: ListView( - padding: const EdgeInsets.all(12.0), - children: [body], - ), - bottomNavigationBar: SafeArea( - child: Padding( - padding: const EdgeInsets.all(12.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.end, - children: buttons, - ), + + return AlertDialog.adaptive( + title: title, + content: SizedBox( + height: 256, + width: 256, + child: ListView( + children: [body], ), ), + actions: buttons, ); } } diff --git a/lib/pages/login/login.dart b/lib/pages/login/login.dart index d4d5d1f26..0c6e819e7 100644 --- a/lib/pages/login/login.dart +++ b/lib/pages/login/login.dart @@ -7,13 +7,15 @@ import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:future_loading_dialog/future_loading_dialog.dart'; import 'package:matrix/matrix.dart'; +import 'package:fluffychat/pangea/controllers/pangea_controller.dart'; +import 'package:fluffychat/pangea/utils/firebase_analytics.dart'; import 'package:fluffychat/utils/localized_exception_extension.dart'; import 'package:fluffychat/widgets/matrix.dart'; import '../../utils/platform_infos.dart'; import 'login_view.dart'; class Login extends StatefulWidget { - const Login({Key? key}) : super(key: key); + const Login({super.key}); @override LoginController createState() => LoginController(); @@ -27,6 +29,27 @@ class LoginController extends State { bool loading = false; bool showPassword = false; + // #Pangea + final PangeaController pangeaController = MatrixState.pangeaController; + @override + void initState() { + // TODO: implement initState + super.initState(); + loading = true; + pangeaController.checkHomeServerAction().then((value) { + setState(() { + loading = false; + }); + }).catchError((e) { + final String err = e as String; + setState(() { + loading = false; + passwordError = err.toLocalizedString(context); + }); + }); + } + // Pangea# + void toggleShowPassword() => setState(() => showPassword = !loading && !showPassword); @@ -67,7 +90,10 @@ class LoginController extends State { } else { identifier = AuthenticationUserIdentifier(user: username); } - await matrix.getLoginClient().login( + // #Pangea + // await matrix.getLoginClient().login( + final loginRes = await matrix.getLoginClient().login( + // Pangea# LoginType.mLoginPassword, identifier: identifier, // To stay compatible with older server versions @@ -78,6 +104,9 @@ class LoginController extends State { password: passwordController.text, initialDeviceDisplayName: PlatformInfos.clientName, ); + // #Pangea + GoogleAnalytics.login("pangea", loginRes.userId); + // Pangea# } on MatrixException catch (exception) { setState(() => passwordError = exception.errorMessage); return setState(() => loading = false); diff --git a/lib/pages/login/login_view.dart b/lib/pages/login/login_view.dart index 50fa1e383..259210113 100644 --- a/lib/pages/login/login_view.dart +++ b/lib/pages/login/login_view.dart @@ -1,33 +1,61 @@ -import 'package:flutter/material.dart'; +// Flutter imports: +import 'package:fluffychat/pangea/utils/password_forgotten.dart'; +import 'package:fluffychat/widgets/layouts/login_scaffold.dart'; +import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; -import 'package:fluffychat/widgets/layouts/login_scaffold.dart'; -import 'package:fluffychat/widgets/matrix.dart'; import 'login.dart'; class LoginView extends StatelessWidget { final LoginController controller; - const LoginView(this.controller, {Key? key}) : super(key: key); + const LoginView(this.controller, {super.key}); @override Widget build(BuildContext context) { return LoginScaffold( - enforceMobileMode: Matrix.of(context).client.isLogged(), + // #Pangea + // enforceMobileMode: Matrix.of(context).client.isLogged(), + // Pangea# appBar: AppBar( - leading: controller.loading ? null : const BackButton(), + // #Pangea + // leading: controller.loading ? null : const BackButton(), + leading: controller.loading + ? null + : Padding( + padding: const EdgeInsets.only(left: 10), + child: ElevatedButton( + onPressed: () => Navigator.of(context).pop(), + style: ButtonStyle( + padding: MaterialStateProperty.all(EdgeInsets.zero), + backgroundColor: MaterialStateProperty.all( + Theme.of(context) + .colorScheme + .background + .withOpacity(0.75), + ), + shape: MaterialStateProperty.all( + const CircleBorder(), + ), + ), + child: const Icon(Icons.arrow_back), + ), + ), + // Pangea# automaticallyImplyLeading: !controller.loading, centerTitle: true, - title: Text( - L10n.of(context)!.logInTo( - Matrix.of(context) - .getLoginClient() - .homeserver - .toString() - .replaceFirst('https://', ''), - ), - ), + // #Pangea + // title: Text( + // L10n.of(context)!.logInTo( + // Matrix.of(context) + // .getLoginClient() + // .homeserver + // .toString() + // .replaceFirst('https://', ''), + // ), + // ), + // Pangea# ), body: Builder( builder: (context) { @@ -49,8 +77,20 @@ class LoginView extends StatelessWidget { decoration: InputDecoration( prefixIcon: const Icon(Icons.account_box_outlined), errorText: controller.usernameError, - errorStyle: const TextStyle(color: Colors.orange), + // #Pangea + // errorStyle: const TextStyle(color: Colors.orange), + errorStyle: TextStyle( + color: Theme.of(context).textTheme.bodyMedium?.color, + fontSize: 14, + ), + // Pangea# hintText: L10n.of(context)!.emailOrUsername, + // #Pangea + fillColor: Theme.of(context) + .colorScheme + .background + .withOpacity(0.75), + // Pangea# ), ), ), @@ -68,17 +108,43 @@ class LoginView extends StatelessWidget { decoration: InputDecoration( prefixIcon: const Icon(Icons.lock_outlined), errorText: controller.passwordError, - errorStyle: const TextStyle(color: Colors.orange), - suffixIcon: IconButton( - onPressed: controller.toggleShowPassword, - icon: Icon( - controller.showPassword - ? Icons.visibility_off_outlined - : Icons.visibility_outlined, - color: Colors.black, + // #Pangea + // errorStyle: const TextStyle(color: Colors.orange), + errorStyle: TextStyle( + color: Theme.of(context).textTheme.bodyMedium?.color, + fontSize: 14, + ), + // prevent enter key from clicking show password button + suffixIcon: MouseRegion( + cursor: SystemMouseCursors.click, + child: GestureDetector( + behavior: HitTestBehavior.opaque, + onTap: controller.toggleShowPassword, + child: Icon( + controller.showPassword + ? Icons.visibility_off_outlined + : Icons.visibility_outlined, + color: Colors.black, + ), ), ), + // suffixIcon: IconButton( + // onPressed: controller.toggleShowPassword, + // icon: Icon( + // controller.showPassword + // ? Icons.visibility_off_outlined + // : Icons.visibility_outlined, + // color: Colors.black, + // ), + // ), + // Pangea# hintText: L10n.of(context)!.password, + // #Pangea + fillColor: Theme.of(context) + .colorScheme + .background + .withOpacity(0.75), + // Pangea# ), ), ), @@ -86,28 +152,40 @@ class LoginView extends StatelessWidget { tag: 'signinButton', child: Padding( padding: const EdgeInsets.all(12.0), - child: ElevatedButton.icon( - style: ElevatedButton.styleFrom( - backgroundColor: Theme.of(context).colorScheme.primary, - foregroundColor: - Theme.of(context).colorScheme.onPrimary, - ), - onPressed: controller.loading ? null : controller.login, - icon: const Icon(Icons.login_outlined), - label: controller.loading + // #Pangea + child: ElevatedButton( + onPressed: + controller.loading ? null : () => controller.login(), + child: controller.loading ? const LinearProgressIndicator() : Text(L10n.of(context)!.login), ), + // child: ElevatedButton.icon( + // style: ElevatedButton.styleFrom( + // backgroundColor: Theme.of(context).colorScheme.primary, + // foregroundColor: + // Theme.of(context).colorScheme.onPrimary, + // ), + // onPressed: controller.loading ? null : controller.login, + // icon: const Icon(Icons.login_outlined), + // label: controller.loading + // ? const LinearProgressIndicator() + // : Text(L10n.of(context)!.login), + // ), + // Pangea$ ), ), Padding( padding: const EdgeInsets.symmetric(horizontal: 16.0), child: Row( children: [ - Expanded( + const Expanded( child: Divider( thickness: 1, - color: Theme.of(context).dividerColor, + // #Pangea + color: Colors.white, + // color: Theme.of(context).dividerColor, + // Pangea# ), ), Padding( @@ -117,10 +195,13 @@ class LoginView extends StatelessWidget { style: const TextStyle(fontSize: 18), ), ), - Expanded( + const Expanded( child: Divider( thickness: 1, - color: Theme.of(context).dividerColor, + // #Pangea + color: Colors.white, + // color: Theme.of(context).dividerColor, + // Pangea# ), ), ], @@ -128,17 +209,27 @@ class LoginView extends StatelessWidget { ), Padding( padding: const EdgeInsets.all(12.0), - child: ElevatedButton.icon( + // #Pangea + child: ElevatedButton( onPressed: controller.loading ? () {} - : controller.passwordForgotten, - style: ElevatedButton.styleFrom( - foregroundColor: Theme.of(context).colorScheme.error, - backgroundColor: Theme.of(context).colorScheme.onError, - ), - icon: const Icon(Icons.safety_check_outlined), - label: Text(L10n.of(context)!.passwordForgotten), + : controller.pangeaPasswordForgotten, + style: + ElevatedButton.styleFrom(foregroundColor: Colors.red), + child: Text(L10n.of(context)!.passwordForgotten), ), + // child: ElevatedButton.icon( + // onPressed: controller.loading + // ? () {} + // : controller.passwordForgotten, + // style: ElevatedButton.styleFrom( + // foregroundColor: Theme.of(context).colorScheme.error, + // backgroundColor: Theme.of(context).colorScheme.onError, + // ), + // icon: const Icon(Icons.safety_check_outlined), + // label: Text(L10n.of(context)!.passwordForgotten), + // ), + // Pangea# ), ], ), diff --git a/lib/pages/new_group/new_group.dart b/lib/pages/new_group/new_group.dart index 70ea22eff..b01186a53 100644 --- a/lib/pages/new_group/new_group.dart +++ b/lib/pages/new_group/new_group.dart @@ -1,46 +1,163 @@ +import 'dart:typed_data'; + import 'package:flutter/material.dart'; -import 'package:future_loading_dialog/future_loading_dialog.dart'; +import 'package:file_picker/file_picker.dart'; +import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:go_router/go_router.dart'; import 'package:matrix/matrix.dart' as sdk; import 'package:fluffychat/pages/new_group/new_group_view.dart'; +import 'package:fluffychat/pangea/controllers/pangea_controller.dart'; +import 'package:fluffychat/pangea/models/chat_topic_model.dart'; +import 'package:fluffychat/pangea/models/lemma.dart'; +import 'package:fluffychat/pangea/utils/class_chat_power_levels.dart'; +import 'package:fluffychat/pangea/utils/firebase_analytics.dart'; +import 'package:fluffychat/pangea/widgets/class/add_space_toggles.dart'; import 'package:fluffychat/widgets/matrix.dart'; class NewGroup extends StatefulWidget { - const NewGroup({Key? key}) : super(key: key); + const NewGroup({super.key}); @override NewGroupController createState() => NewGroupController(); } class NewGroupController extends State { - TextEditingController controller = TextEditingController(); + TextEditingController nameController = TextEditingController(); + + TextEditingController topicController = TextEditingController(); + bool publicGroup = false; + bool groupCanBeFound = true; + + Uint8List? avatar; + + Uri? avatarUrl; + + Object? error; + + bool loading = false; + + // #Pangea + PangeaController pangeaController = MatrixState.pangeaController; + final GlobalKey addToSpaceKey = GlobalKey(); + + ChatTopic chatTopic = ChatTopic.empty; + + void setVocab(List vocab) => setState(() => chatTopic.vocab = vocab); + + String? get activeSpaceId => + GoRouterState.of(context).pathParameters['spaceid']; + // Pangea# void setPublicGroup(bool b) => setState(() => publicGroup = b); - void submitAction([_]) async { - final client = Matrix.of(context).client; - final roomID = await showFutureLoadingDialog( - context: context, - future: () async { - final roomId = await client.createGroupChat( - visibility: - publicGroup ? sdk.Visibility.public : sdk.Visibility.private, - preset: publicGroup - ? sdk.CreateRoomPreset.publicChat - : sdk.CreateRoomPreset.privateChat, - groupName: controller.text.isNotEmpty ? controller.text : null, - ); - return roomId; - }, + void setGroupCanBeFound(bool b) => setState(() => groupCanBeFound = b); + + void selectPhoto() async { + final photo = await FilePicker.platform.pickFiles( + type: FileType.image, + allowMultiple: false, + withData: true, ); - if (roomID.error == null) { - context.go('/rooms/${roomID.result!}/invite'); + + setState(() { + avatarUrl = null; + avatar = photo?.files.singleOrNull?.bytes; + }); + } + + void submitAction([_]) async { + // #Pangea + if (nameController.text.isEmpty) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text(L10n.of(context)!.emptyChatNameWarning), + ), + ); + return; + } + // Pangea# + final client = Matrix.of(context).client; + + try { + setState(() { + loading = true; + error = null; + }); + + final avatar = this.avatar; + avatarUrl ??= avatar == null ? null : await client.uploadContent(avatar); + + if (!mounted) return; + + final roomId = await client.createGroupChat( + // #Pangea + // visibility: + // publicGroup ? sdk.Visibility.public : sdk.Visibility.private, + // preset: publicGroup + // ? sdk.CreateRoomPreset.publicChat + // : sdk.CreateRoomPreset.privateChat, + // groupName: nameController.text.isNotEmpty ? nameController.text : null, + // initialState: [ + // if (topicController.text.isNotEmpty) + // sdk.StateEvent( + // type: sdk.EventTypes.RoomTopic, + // content: {'topic': topicController.text}, + // ), + // if (avatar != null) + // sdk.StateEvent( + // type: sdk.EventTypes.RoomAvatar, + // content: {'url': avatarUrl.toString()}, + // ), + // ], + groupName: nameController.text, + preset: sdk.CreateRoomPreset.publicChat, + powerLevelContentOverride: + await ClassChatPowerLevels.powerLevelOverrideForClassChat( + context, + addToSpaceKey.currentState!.parents + .map((suggestionStatus) => suggestionStatus.room) + .toList(), + ), + // Pangea# + ); + if (!mounted) return; + if (publicGroup && groupCanBeFound) { + await client.setRoomVisibilityOnDirectory( + roomId, + visibility: sdk.Visibility.public, + ); + } + //#Pangea + GoogleAnalytics.createChat(roomId); + await addToSpaceKey.currentState!.addSpaces(roomId); + //Pangea# + context.go('/rooms/$roomId/invite'); + } catch (e, s) { + sdk.Logs().d('Unable to create group', e, s); + setState(() { + error = e; + loading = false; + }); } } + //#Pangea + @override + void initState() { + Future.delayed(Duration.zero, () { + chatTopic.langCode = + pangeaController.languageController.activeL2Code(roomID: null) ?? + pangeaController.pLanguageStore.targetOptions.first.langCode; + setState(() {}); + }); + + super.initState(); + } + //Pangea# + @override Widget build(BuildContext context) => NewGroupView(this); } diff --git a/lib/pages/new_group/new_group_view.dart b/lib/pages/new_group/new_group_view.dart index 7b8dd7b1c..72d663618 100644 --- a/lib/pages/new_group/new_group_view.dart +++ b/lib/pages/new_group/new_group_view.dart @@ -2,58 +2,176 @@ import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:fluffychat/config/themes.dart'; import 'package:fluffychat/pages/new_group/new_group.dart'; +import 'package:fluffychat/pangea/widgets/class/add_class_and_invite.dart'; +import 'package:fluffychat/pangea/widgets/class/add_space_toggles.dart'; +import 'package:fluffychat/utils/localized_exception_extension.dart'; +import 'package:fluffychat/widgets/avatar.dart'; import 'package:fluffychat/widgets/layouts/max_width_body.dart'; class NewGroupView extends StatelessWidget { final NewGroupController controller; - const NewGroupView(this.controller, {Key? key}) : super(key: key); + const NewGroupView(this.controller, {super.key}); @override Widget build(BuildContext context) { + final avatar = controller.avatar; + final error = controller.error; return Scaffold( appBar: AppBar( + leading: Center( + child: BackButton( + onPressed: controller.loading ? null : Navigator.of(context).pop, + ), + ), title: Text(L10n.of(context)!.createGroup), ), body: MaxWidthBody( child: Column( mainAxisSize: MainAxisSize.min, children: [ + const SizedBox(height: 16), Padding( - padding: const EdgeInsets.all(12.0), - child: TextField( - controller: controller.controller, - autofocus: true, - autocorrect: false, - textInputAction: TextInputAction.go, - onSubmitted: controller.submitAction, - decoration: InputDecoration( - labelText: L10n.of(context)!.optionalGroupName, - prefixIcon: const Icon(Icons.people_outlined), - hintText: L10n.of(context)!.enterAGroupName, + padding: const EdgeInsets.symmetric(horizontal: 16.0), + child: Row( + children: [ + InkWell( + borderRadius: BorderRadius.circular(90), + onTap: controller.loading ? null : controller.selectPhoto, + child: CircleAvatar( + radius: Avatar.defaultSize / 2, + child: avatar == null + ? const Icon(Icons.camera_alt_outlined) + : ClipRRect( + borderRadius: BorderRadius.circular(90), + child: Image.memory( + avatar, + width: Avatar.defaultSize, + height: Avatar.defaultSize, + fit: BoxFit.cover, + ), + ), + ), + ), + const SizedBox(width: 16), + Expanded( + child: TextField( + controller: controller.nameController, + autocorrect: false, + readOnly: controller.loading, + decoration: InputDecoration( + prefixIcon: const Icon(Icons.people_outlined), + hintText: L10n.of(context)!.groupName, + ), + ), + ), + ], + ), + ), + const SizedBox(height: 16), + // #Pangea + // Padding( + // padding: const EdgeInsets.symmetric(horizontal: 16.0), + // child: TextField( + // controller: controller.topicController, + // minLines: 4, + // maxLines: 4, + // maxLength: 255, + // readOnly: controller.loading, + // decoration: InputDecoration( + // hintText: L10n.of(context)!.addChatDescription, + // ), + // ), + // ), + AddToSpaceToggles( + key: controller.addToSpaceKey, + startOpen: false, + activeSpaceId: controller.activeSpaceId, + mode: AddToClassMode.chat, + ), + // const SizedBox(height: 16), + // SwitchListTile.adaptive( + // secondary: const Icon(Icons.public_outlined), + // title: Text(L10n.of(context)!.groupIsPublic), + // value: controller.publicGroup, + // onChanged: controller.loading ? null : controller.setPublicGroup, + // ), + // AnimatedSize( + // duration: FluffyThemes.animationDuration, + // child: controller.publicGroup + // ? SwitchListTile.adaptive( + // secondary: const Icon(Icons.search_outlined), + // title: Text(L10n.of(context)!.groupCanBeFoundViaSearch), + // value: controller.groupCanBeFound, + // onChanged: controller.loading + // ? null + // : controller.setGroupCanBeFound, + // ) + // : const SizedBox.shrink(), + // ), + // SwitchListTile.adaptive( + // secondary: Icon( + // Icons.lock_outlined, + // color: Theme.of(context).colorScheme.onBackground, + // ), + // title: Text( + // L10n.of(context)!.enableEncryption, + // style: TextStyle( + // color: Theme.of(context).colorScheme.onBackground, + // ), + // ), + // value: !controller.publicGroup, + // onChanged: null, + // ), + // Pangea# + Padding( + padding: const EdgeInsets.all(16.0), + child: SizedBox( + width: double.infinity, + child: ElevatedButton( + style: ElevatedButton.styleFrom( + foregroundColor: Theme.of(context).colorScheme.onPrimary, + backgroundColor: Theme.of(context).colorScheme.primary, + ), + onPressed: + controller.loading ? null : controller.submitAction, + child: controller.loading + ? const LinearProgressIndicator() + : Row( + children: [ + Expanded( + child: Text( + L10n.of(context)!.createGroupAndInviteUsers, + ), + ), + Icon(Icons.adaptive.arrow_forward_outlined), + ], + ), ), ), ), - SwitchListTile.adaptive( - secondary: const Icon(Icons.public_outlined), - title: Text(L10n.of(context)!.groupIsPublic), - value: controller.publicGroup, - onChanged: controller.setPublicGroup, - ), - SwitchListTile.adaptive( - secondary: const Icon(Icons.lock_outlined), - title: Text(L10n.of(context)!.enableEncryption), - value: !controller.publicGroup, - onChanged: null, + AnimatedSize( + duration: FluffyThemes.animationDuration, + child: error == null + ? const SizedBox.shrink() + : ListTile( + leading: Icon( + Icons.warning_outlined, + color: Theme.of(context).colorScheme.error, + ), + title: Text( + error.toLocalizedString(context), + style: TextStyle( + color: Theme.of(context).colorScheme.error, + ), + ), + ), ), ], ), ), - floatingActionButton: FloatingActionButton( - onPressed: controller.submitAction, - child: const Icon(Icons.arrow_forward_outlined), - ), ); } } diff --git a/lib/pages/new_private_chat/new_private_chat.dart b/lib/pages/new_private_chat/new_private_chat.dart index 179d4aab1..c1d8c649a 100644 --- a/lib/pages/new_private_chat/new_private_chat.dart +++ b/lib/pages/new_private_chat/new_private_chat.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -7,6 +9,7 @@ import 'package:matrix/matrix.dart'; import 'package:fluffychat/pages/new_private_chat/new_private_chat_view.dart'; import 'package:fluffychat/pages/new_private_chat/qr_scanner_modal.dart'; +import 'package:fluffychat/pages/user_bottom_sheet/user_bottom_sheet.dart'; import 'package:fluffychat/utils/adaptive_bottom_sheet.dart'; import 'package:fluffychat/utils/fluffy_share.dart'; import 'package:fluffychat/utils/platform_infos.dart'; @@ -14,7 +17,7 @@ import 'package:fluffychat/utils/url_launcher.dart'; import 'package:fluffychat/widgets/matrix.dart'; class NewPrivateChat extends StatefulWidget { - const NewPrivateChat({Key? key}) : super(key: key); + const NewPrivateChat({super.key}); @override NewPrivateChatController createState() => NewPrivateChatController(); @@ -23,38 +26,43 @@ class NewPrivateChat extends StatefulWidget { class NewPrivateChatController extends State { final TextEditingController controller = TextEditingController(); final FocusNode textFieldFocus = FocusNode(); - final formKey = GlobalKey(); - bool loading = false; - // remove leading matrix.to from text field in order to simplify pasting - final List removeMatrixToFormatters = [ - FilteringTextInputFormatter.deny(NewPrivateChatController.prefix), - FilteringTextInputFormatter.deny(NewPrivateChatController.prefixNoProtocol), - ]; + Future>? searchResponse; - static const Set supportedSigils = {'@', '!', '#'}; + Timer? _searchCoolDown; - static const String prefix = 'https://matrix.to/#/'; - static const String prefixNoProtocol = 'matrix.to/#/'; + static const Duration _coolDown = Duration(milliseconds: 500); - void submitAction([_]) async { - controller.text = controller.text.trim(); - if (!formKey.currentState!.validate()) return; - UrlLauncher(context, '$prefix${controller.text}').openMatrixToUrl(); + void searchUsers([String? input]) async { + final searchTerm = input ?? controller.text; + if (searchTerm.isEmpty) { + _searchCoolDown?.cancel(); + setState(() { + searchResponse = _searchCoolDown = null; + }); + return; + } + + _searchCoolDown?.cancel(); + _searchCoolDown = Timer(_coolDown, () { + setState(() { + searchResponse = _searchUser(searchTerm); + }); + }); } - String? validateForm(String? value) { - if (value!.isEmpty) { - return L10n.of(context)!.pleaseEnterAMatrixIdentifier; + Future> _searchUser(String searchTerm) async { + final result = + await Matrix.of(context).client.searchUserDirectory(searchTerm); + final profiles = result.results; + + if (searchTerm.isValidMatrixId && + searchTerm.sigil == '@' && + !profiles.any((profile) => profile.userId == searchTerm)) { + profiles.add(Profile(userId: searchTerm)); } - if (!controller.text.isValidMatrixId || - !supportedSigils.contains(controller.text.sigil)) { - return L10n.of(context)!.makeSureTheIdentifierIsValid; - } - if (controller.text == Matrix.of(context).client.userID) { - return L10n.of(context)!.youCannotInviteYourself; - } - return null; + + return profiles; } void inviteAction() => FluffyShare.shareInviteLink(context); @@ -75,10 +83,29 @@ class NewPrivateChatController extends State { } await showAdaptiveBottomSheet( context: context, - builder: (_) => const QrScannerModal(), + builder: (_) => QrScannerModal( + onScan: (link) => UrlLauncher(context, link).openMatrixToUrl(), + ), ); } + void copyUserId() async { + await Clipboard.setData( + ClipboardData(text: Matrix.of(context).client.userID!), + ); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text(L10n.of(context)!.copiedToClipboard)), + ); + } + + void openUserModal(Profile profile) => showAdaptiveBottomSheet( + context: context, + builder: (c) => UserBottomSheet( + profile: profile, + outerContext: context, + ), + ); + @override Widget build(BuildContext context) => NewPrivateChatView(this); } diff --git a/lib/pages/new_private_chat/new_private_chat_view.dart b/lib/pages/new_private_chat/new_private_chat_view.dart index 4672633b6..fbe6d0443 100644 --- a/lib/pages/new_private_chat/new_private_chat_view.dart +++ b/lib/pages/new_private_chat/new_private_chat_view.dart @@ -4,130 +4,253 @@ import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:go_router/go_router.dart'; -import 'package:qr_flutter/qr_flutter.dart'; +import 'package:matrix/matrix.dart'; +import 'package:fluffychat/config/app_config.dart'; +import 'package:fluffychat/config/themes.dart'; import 'package:fluffychat/pages/new_private_chat/new_private_chat.dart'; +import 'package:fluffychat/utils/localized_exception_extension.dart'; import 'package:fluffychat/utils/platform_infos.dart'; +import 'package:fluffychat/utils/url_launcher.dart'; +import 'package:fluffychat/widgets/avatar.dart'; import 'package:fluffychat/widgets/layouts/max_width_body.dart'; import 'package:fluffychat/widgets/matrix.dart'; class NewPrivateChatView extends StatelessWidget { final NewPrivateChatController controller; - const NewPrivateChatView(this.controller, {Key? key}) : super(key: key); - - static const double _qrCodePadding = 8; + const NewPrivateChatView(this.controller, {super.key}); @override Widget build(BuildContext context) { + final searchResponse = controller.searchResponse; final qrCodeSize = min(MediaQuery.of(context).size.width - 16, 256).toDouble(); return Scaffold( appBar: AppBar( + scrolledUnderElevation: 0, leading: const Center(child: BackButton()), title: Text(L10n.of(context)!.newChat), backgroundColor: Theme.of(context).scaffoldBackgroundColor, actions: [ - Padding( - padding: const EdgeInsets.all(8.0), - child: TextButton( - onPressed: () => context.go('/rooms/newgroup'), - child: Text( - L10n.of(context)!.createGroup, - style: - TextStyle(color: Theme.of(context).colorScheme.secondary), - ), - ), + IconButton( + onPressed: + UrlLauncher(context, AppConfig.startChatTutorial).launchUrl, + icon: const Icon(Icons.info_outlined), ), ], ), - body: Column( - children: [ - Expanded( - child: MaxWidthBody( - withFrame: false, - child: Container( - margin: const EdgeInsets.all(_qrCodePadding), - alignment: Alignment.center, - padding: const EdgeInsets.all(_qrCodePadding * 2), - child: Material( - borderRadius: BorderRadius.circular(12), - elevation: 10, - color: Colors.white, - shadowColor: Theme.of(context).appBarTheme.shadowColor, - clipBehavior: Clip.hardEdge, - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - QrImageView( - data: - 'https://matrix.to/#/${Matrix.of(context).client.userID}', - version: QrVersions.auto, - size: qrCodeSize, - ), - TextButton.icon( - style: TextButton.styleFrom( - fixedSize: - Size.fromWidth(qrCodeSize - (2 * _qrCodePadding)), - foregroundColor: Colors.black, + body: MaxWidthBody( + withScrolling: false, + child: Column( + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 12.0), + child: TextField( + controller: controller.controller, + onChanged: controller.searchUsers, + decoration: InputDecoration( + hintText: 'Search for @users...', + prefixIcon: searchResponse == null + ? const Icon(Icons.search_outlined) + : FutureBuilder( + future: searchResponse, + builder: (context, snapshot) { + if (snapshot.connectionState != + ConnectionState.done) { + return const Padding( + padding: EdgeInsets.all(10.0), + child: SizedBox.square( + dimension: 24, + child: CircularProgressIndicator.adaptive( + strokeWidth: 1, + ), + ), + ); + } + return const Icon(Icons.search_outlined); + }, + ), + suffixIcon: controller.controller.text.isEmpty + ? null + : IconButton( + icon: const Icon(Icons.clear_outlined), + onPressed: () { + controller.controller.clear(); + controller.searchUsers(); + }, + ), + ), + ), + ), + Expanded( + child: AnimatedCrossFade( + duration: FluffyThemes.animationDuration, + crossFadeState: searchResponse == null + ? CrossFadeState.showFirst + : CrossFadeState.showSecond, + firstChild: ListView( + children: [ + ListTile( + title: SelectableText.rich( + TextSpan( + children: [ + TextSpan( + text: L10n.of(context)!.yourGlobalUserIdIs, + ), + TextSpan( + text: Matrix.of(context).client.userID, + style: const TextStyle( + fontWeight: FontWeight.w600, + ), + ), + ], + ), + style: TextStyle( + color: + Theme.of(context).colorScheme.onPrimaryContainer, + fontSize: 14, ), - icon: Icon(Icons.adaptive.share_outlined), - label: Text(L10n.of(context)!.shareInviteLink), - onPressed: controller.inviteAction, ), - const SizedBox(height: 8), - if (PlatformInfos.isMobile) ...[ - OutlinedButton.icon( - style: OutlinedButton.styleFrom( - backgroundColor: - Theme.of(context).colorScheme.primaryContainer, - fixedSize: Size.fromWidth( - qrCodeSize - (2 * _qrCodePadding), + trailing: IconButton( + icon: Icon( + Icons.copy_outlined, + size: 16, + color: + Theme.of(context).colorScheme.onPrimaryContainer, + ), + onPressed: controller.copyUserId, + ), + ), + if (PlatformInfos.isMobile) + ListTile( + leading: CircleAvatar( + backgroundColor: + Theme.of(context).colorScheme.primaryContainer, + foregroundColor: + Theme.of(context).colorScheme.onPrimaryContainer, + child: const Icon(Icons.qr_code_scanner_outlined), + ), + title: Text(L10n.of(context)!.scanQrCode), + onTap: controller.openScannerAction, + ), + ListTile( + leading: CircleAvatar( + backgroundColor: + Theme.of(context).colorScheme.secondaryContainer, + foregroundColor: + Theme.of(context).colorScheme.onSecondaryContainer, + child: Icon(Icons.adaptive.share_outlined), + ), + title: Text(L10n.of(context)!.shareInviteLink), + onTap: controller.inviteAction, + ), + ListTile( + leading: CircleAvatar( + backgroundColor: + Theme.of(context).colorScheme.tertiaryContainer, + foregroundColor: + Theme.of(context).colorScheme.onTertiaryContainer, + child: const Icon(Icons.group_add_outlined), + ), + title: Text(L10n.of(context)!.createGroup), + onTap: () => context.go('/rooms/newgroup'), + ), + const SizedBox(height: 24), + Center( + child: Material( + borderRadius: BorderRadius.circular(12), + elevation: 10, + color: Colors.white, + shadowColor: Theme.of(context).appBarTheme.shadowColor, + clipBehavior: Clip.hardEdge, + // #Pangea - commenting this out because it's not super important and is throwing an error + // child: QrImageView( + // data: + // 'https://matrix.to/#/${Matrix.of(context).client.userID}', + // version: QrVersions.auto, + // size: qrCodeSize, + // ), + // Pangea# + ), + ), + ], + ), + secondChild: FutureBuilder( + future: searchResponse, + builder: (context, snapshot) { + final result = snapshot.data; + final error = snapshot.error; + if (error != null) { + return Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + error.toLocalizedString(context), + textAlign: TextAlign.center, + style: TextStyle( + color: Theme.of(context).colorScheme.error, ), ), - icon: const Icon(Icons.qr_code_scanner_outlined), - label: Text(L10n.of(context)!.scanQrCode), - onPressed: controller.openScannerAction, - ), - const SizedBox(height: 8), - ], - ], - ), + const SizedBox(height: 12), + OutlinedButton.icon( + onPressed: controller.searchUsers, + icon: const Icon(Icons.refresh_outlined), + label: Text(L10n.of(context)!.tryAgain), + ), + ], + ); + } + if (result == null) { + return const Center( + child: CircularProgressIndicator.adaptive(), + ); + } + if (result.isEmpty) { + return Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Icon(Icons.search_outlined, size: 86), + Padding( + padding: const EdgeInsets.all(16.0), + child: Text( + L10n.of(context)!.noUsersFoundWithQuery( + controller.controller.text, + ), + style: TextStyle( + color: Theme.of(context).colorScheme.primary, + ), + textAlign: TextAlign.center, + ), + ), + ], + ); + } + return ListView.builder( + itemCount: result.length, + itemBuilder: (context, i) { + final contact = result[i]; + final displayname = contact.displayName ?? + contact.userId.localpart ?? + contact.userId; + return ListTile( + leading: Avatar( + name: displayname, + mxContent: contact.avatarUrl, + presenceUserId: contact.userId, + ), + title: Text(displayname), + subtitle: Text(contact.userId), + onTap: () => controller.openUserModal(contact), + ); + }, + ); + }, ), ), ), - ), - MaxWidthBody( - child: Padding( - padding: const EdgeInsets.all(12.0), - child: Form( - key: controller.formKey, - child: TextFormField( - controller: controller.controller, - autocorrect: false, - textInputAction: TextInputAction.go, - focusNode: controller.textFieldFocus, - onFieldSubmitted: controller.submitAction, - validator: controller.validateForm, - inputFormatters: controller.removeMatrixToFormatters, - decoration: InputDecoration( - contentPadding: const EdgeInsets.symmetric( - horizontal: 12, - vertical: 6, - ), - labelText: L10n.of(context)!.enterInviteLinkOrMatrixId, - hintText: '@username', - prefixText: NewPrivateChatController.prefixNoProtocol, - suffixIcon: IconButton( - icon: const Icon(Icons.send_outlined), - onPressed: controller.submitAction, - ), - ), - ), - ), - ), - ), - ], + ], + ), ), ); } diff --git a/lib/pages/new_private_chat/qr_scanner_modal.dart b/lib/pages/new_private_chat/qr_scanner_modal.dart index 8c125e460..b509941e5 100644 --- a/lib/pages/new_private_chat/qr_scanner_modal.dart +++ b/lib/pages/new_private_chat/qr_scanner_modal.dart @@ -6,10 +6,9 @@ import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:qr_code_scanner/qr_code_scanner.dart'; -import 'package:fluffychat/utils/url_launcher.dart'; - class QrScannerModal extends StatefulWidget { - const QrScannerModal({Key? key}) : super(key: key); + final void Function(String) onScan; + const QrScannerModal({required this.onScan, super.key}); @override QrScannerModalState createState() => QrScannerModalState(); @@ -69,7 +68,8 @@ class QrScannerModalState extends State { sub = controller.scannedDataStream.listen((scanData) { sub.cancel(); Navigator.of(context).pop(); - UrlLauncher(context, scanData.code).openMatrixToUrl(); + final data = scanData.code; + if (data != null) widget.onScan(data); }); } diff --git a/lib/pages/new_space/new_space.dart b/lib/pages/new_space/new_space.dart index 9d4a8272a..2ff854e2c 100644 --- a/lib/pages/new_space/new_space.dart +++ b/lib/pages/new_space/new_space.dart @@ -1,15 +1,30 @@ +import 'dart:developer'; + +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:future_loading_dialog/future_loading_dialog.dart'; import 'package:go_router/go_router.dart'; import 'package:matrix/matrix.dart' as sdk; import 'package:matrix/matrix.dart'; import 'package:fluffychat/pages/new_space/new_space_view.dart'; +import 'package:fluffychat/pangea/constants/class_default_values.dart'; +import 'package:fluffychat/pangea/constants/pangea_event_types.dart'; +import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart'; +import 'package:fluffychat/pangea/pages/class_settings/p_class_widgets/room_rules_editor.dart'; +import 'package:fluffychat/pangea/utils/bot_name.dart'; +import 'package:fluffychat/pangea/utils/class_chat_power_levels.dart'; +import 'package:fluffychat/pangea/utils/class_code.dart'; +import 'package:fluffychat/pangea/utils/error_handler.dart'; +import 'package:fluffychat/pangea/utils/firebase_analytics.dart'; +import 'package:fluffychat/pangea/widgets/class/add_space_toggles.dart'; +import 'package:fluffychat/pangea/widgets/space/class_settings.dart'; import 'package:fluffychat/widgets/matrix.dart'; class NewSpace extends StatefulWidget { - const NewSpace({Key? key}) : super(key: key); + const NewSpace({super.key}); @override NewSpaceController createState() => NewSpaceController(); @@ -17,30 +32,205 @@ class NewSpace extends StatefulWidget { class NewSpaceController extends State { TextEditingController controller = TextEditingController(); - bool publicGroup = false; + // #Pangea + // bool publicGroup = false; + bool publicGroup = true; + final GlobalKey rulesEditorKey = GlobalKey(); + final GlobalKey addToSpaceKey = GlobalKey(); + final GlobalKey classSettingsKey = + GlobalKey(); + //Pangea# void setPublicGroup(bool b) => setState(() => publicGroup = b); - void submitAction([_]) async { - final matrix = Matrix.of(context); - final roomID = await showFutureLoadingDialog( - context: context, - future: () => matrix.client.createRoom( - preset: publicGroup - ? sdk.CreateRoomPreset.publicChat - : sdk.CreateRoomPreset.privateChat, - creationContent: {'type': RoomCreationTypes.mSpace}, - visibility: publicGroup ? sdk.Visibility.public : null, - roomAliasName: publicGroup && controller.text.isNotEmpty - ? controller.text.trim().toLowerCase().replaceAll(' ', '_') - : null, - name: controller.text.isNotEmpty ? controller.text : null, + // #Pangea + bool newClassMode = true; + + //in initState, set newClassMode to true if parameter "newClass" is true + //use Vrouter + @override + void initState() { + super.initState(); + Future.delayed(Duration.zero, () { + newClassMode = + GoRouterState.of(context).pathParameters['newexchange'] != 'exchange'; + setState(() {}); + }); + } + + List get initialState { + final events = []; + + events.add( + StateEvent( + type: EventTypes.RoomPowerLevels, + stateKey: '', + content: { + 'events': { + PangeaEventTypes.studentAnalyticsSummary: 0, + EventTypes.spaceChild: 0, + }, + 'users_default': 0, + 'users': { + Matrix.of(context).client.userID: + ClassDefaultValues.powerLevelOfAdmin, + }, + }, ), ); - if (roomID.error == null) { - context.go('/rooms/${roomID.result!}'); + + if (rulesEditorKey.currentState?.rules != null) { + events.add(rulesEditorKey.currentState!.rules.toStateEvent); + } else { + debugger(when: kDebugMode); } + if (classSettingsKey.currentState != null) { + events.add(classSettingsKey.currentState!.classSettings.toStateEvent); + } else { + debugger(when: kDebugMode && newClassMode); + } + + return events; } + //Pangea# + + void submitAction([_]) async { + final matrix = Matrix.of(context); + // #Pangea + if (rulesEditorKey.currentState == null) { + debugger(when: kDebugMode); + return; + } + if (classSettingsKey.currentState != null && + classSettingsKey.currentState!.sameLanguages) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text(L10n.of(context)!.noIdenticalLanguages), + ), + ); + return; + } + if (controller.text.isEmpty) { + final String warning = newClassMode + ? L10n.of(context)!.emptyClassNameWarning + : L10n.of(context)!.emptyExchangeNameWarning; + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text(warning)), + ); + return; + } + if (newClassMode) { + final int? languageLevel = + classSettingsKey.currentState!.classSettings.languageLevel; + if (languageLevel == null) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text(L10n.of(context)!.languageLevelWarning)), + ); + return; + } + } + //Pangea# + final roomID = await showFutureLoadingDialog( + context: context, + // #Pangea + // future: () async => matrix.client.createRoom( + future: () async { + final roomId = await matrix.client.createRoom( + initialState: initialState, + //Pangea# + preset: publicGroup + ? sdk.CreateRoomPreset.publicChat + : sdk.CreateRoomPreset.privateChat, + creationContent: {'type': RoomCreationTypes.mSpace}, + visibility: publicGroup ? sdk.Visibility.public : null, + // #Pangea + // roomAliasName: publicGroup && controller.text.isNotEmpty + // ? controller.text.trim().toLowerCase().replaceAll(' ', '_') + // : null, + powerLevelContentOverride: addToSpaceKey.currentState != null + ? await ClassChatPowerLevels.powerLevelOverrideForClassChat( + context, + addToSpaceKey.currentState!.parents + .map((suggestionStatus) => suggestionStatus.room) + .toList(), + ) + : null, + roomAliasName: ClassCodeUtil.generateClassCode(), + // Pangea# + name: controller.text.isNotEmpty ? controller.text : null, + ); + // #Pangea + Room? room = Matrix.of(context).client.getRoomById(roomId); + + final List> futures = [ + Matrix.of(context).client.waitForRoomInSync(roomId, join: true), + ]; + if (addToSpaceKey.currentState != null) { + futures.add(addToSpaceKey.currentState!.addSpaces(roomId)); + } + await Future.wait(futures); + + room = Matrix.of(context).client.getRoomById(roomId); + + final newChatRoomId = await Matrix.of(context).client.createGroupChat( + enableEncryption: false, + preset: sdk.CreateRoomPreset.publicChat, + groupName: + '${controller.text}: ${L10n.of(context)!.classWelcomeChat}', + ); + GoogleAnalytics.createChat(newChatRoomId); + + room!.setSpaceChild(newChatRoomId, suggested: true); + newClassMode + ? GoogleAnalytics.addParent( + newChatRoomId, + room.classCode, + ) + : GoogleAnalytics.addChatToExchange( + newChatRoomId, + room.classCode, + ); + + GoogleAnalytics.createClass(room.name, room.classCode); + try { + await room.invite(BotName.byEnvironment); + } catch (err) { + ErrorHandler.logError( + e: "Failed to invite pangea bot to space ${room.id}", + ); + } + + return roomId; + }, + title: L10n.of(context)!.creatingSpacePleaseWait, + onError: (exception) { + debugger(when: kDebugMode); + ErrorHandler.logError(e: exception); + return exception.toString(); + }, + // Pangea# + ); + + // #Pangea + if (roomID.result == null) return; + MatrixState.pangeaController.classController + .setActiveSpaceIdInChatListController(roomID.result!); + + if (roomID.error == null) { + context.push('/spaces/${roomID.result!}'); + } + // if (roomID.error == null) { + // context.go('/rooms/${roomID.result!}'); + // } + // Pangea# + } + + // #Pangea + //toggle newClassMode + void toggleClassMode(bool newValue) { + setState(() => newClassMode = newValue); + } + // Pangea# @override Widget build(BuildContext context) => NewSpaceView(this); diff --git a/lib/pages/new_space/new_space_view.dart b/lib/pages/new_space/new_space_view.dart index ce4f967c9..32027cb84 100644 --- a/lib/pages/new_space/new_space_view.dart +++ b/lib/pages/new_space/new_space_view.dart @@ -1,20 +1,56 @@ import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:fluffychat/config/app_config.dart'; +import 'package:fluffychat/pangea/constants/class_default_values.dart'; +import 'package:fluffychat/pangea/pages/class_settings/p_class_widgets/room_rules_editor.dart'; +import 'package:fluffychat/pangea/widgets/class/add_class_and_invite.dart'; +import 'package:fluffychat/pangea/widgets/class/add_space_toggles.dart'; +import 'package:fluffychat/pangea/widgets/space/class_settings.dart'; import 'package:fluffychat/widgets/layouts/max_width_body.dart'; import 'new_space.dart'; class NewSpaceView extends StatelessWidget { final NewSpaceController controller; - const NewSpaceView(this.controller, {Key? key}) : super(key: key); + const NewSpaceView(this.controller, {super.key}); @override Widget build(BuildContext context) { + // #Pangea + final activeColor = Theme.of(context).brightness == Brightness.dark + ? AppConfig.primaryColorLight + : AppConfig.primaryColor; + // Pangea# return Scaffold( appBar: AppBar( - title: Text(L10n.of(context)!.createNewSpace), + // #Pangea + centerTitle: true, + title: Text( + controller.newClassMode + ? L10n.of(context)!.createNewClass + : L10n.of(context)!.newExchange, + ), + actions: [ + IconButton( + icon: const Icon(Icons.class_outlined), + selectedIcon: const Icon(Icons.class_), + color: controller.newClassMode ? activeColor : null, + isSelected: controller.newClassMode, + onPressed: () => controller.toggleClassMode(true), + ), + IconButton( + icon: const Icon(Icons.connecting_airports), + selectedIcon: const Icon(Icons.connecting_airports), + color: !controller.newClassMode ? activeColor : null, + isSelected: !controller.newClassMode, + onPressed: () => controller.toggleClassMode(false), + ), + ], + // title: Text(L10n.of(context)!.createNewSpace), + // Pangea# ), body: MaxWidthBody( child: Column( @@ -23,6 +59,10 @@ class NewSpaceView extends StatelessWidget { Padding( padding: const EdgeInsets.all(12.0), child: TextField( + // #Pangea + maxLength: ClassDefaultValues.maxClassName, + maxLengthEnforcement: MaxLengthEnforcement.enforced, + // Pangea# controller: controller.controller, autofocus: true, autocorrect: false, @@ -35,18 +75,40 @@ class NewSpaceView extends StatelessWidget { ), ), ), - SwitchListTile.adaptive( - title: Text(L10n.of(context)!.spaceIsPublic), - value: controller.publicGroup, - onChanged: controller.setPublicGroup, - ), - ListTile( - trailing: const Padding( - padding: EdgeInsets.symmetric(horizontal: 16.0), - child: Icon(Icons.info_outlined), + // #Pangea + if (controller.newClassMode) + ClassSettings( + key: controller.classSettingsKey, + roomId: null, + startOpen: true, ), - subtitle: Text(L10n.of(context)!.newSpaceDescription), + if (!controller.newClassMode) + AddToSpaceToggles( + key: controller.addToSpaceKey, + startOpen: false, + mode: !controller.newClassMode + ? AddToClassMode.exchange + : AddToClassMode.chat, + ), + RoomRulesEditor( + key: controller.rulesEditorKey, + roomId: null, + startOpen: false, ), + const SizedBox(height: 45), + // SwitchListTile.adaptive( + // title: Text(L10n.of(context)!.spaceIsPublic), + // value: controller.publicGroup, + // onChanged: controller.setPublicGroup, + // ), + // ListTile( + // trailing: const Padding( + // padding: EdgeInsets.symmetric(horizontal: 16.0), + // child: Icon(Icons.info_outlined), + // ), + // subtitle: Text(L10n.of(context)!.newSpaceDescription), + // ), + // Pangea# ], ), ), diff --git a/lib/pages/settings/settings.dart b/lib/pages/settings/settings.dart index b4b9c2f1f..988ec3ff4 100644 --- a/lib/pages/settings/settings.dart +++ b/lib/pages/settings/settings.dart @@ -10,14 +10,14 @@ import 'package:future_loading_dialog/future_loading_dialog.dart'; import 'package:image_picker/image_picker.dart'; import 'package:matrix/matrix.dart'; +import 'package:fluffychat/pangea/utils/logout.dart'; import 'package:fluffychat/utils/platform_infos.dart'; import 'package:fluffychat/widgets/app_lock.dart'; import '../../widgets/matrix.dart'; -import '../bootstrap/bootstrap_dialog.dart'; import 'settings_view.dart'; class Settings extends StatefulWidget { - const Settings({Key? key}) : super(key: key); + const Settings({super.key}); @override SettingsController createState() => SettingsController(); @@ -61,23 +61,26 @@ class SettingsController extends State { void logoutAction() async { final noBackup = showChatBackupBanner == true; - if (await showOkCancelAlertDialog( - useRootNavigator: false, - context: context, - title: L10n.of(context)!.areYouSureYouWantToLogout, - message: L10n.of(context)!.noBackupWarning, - isDestructiveAction: noBackup, - okLabel: L10n.of(context)!.logout, - cancelLabel: L10n.of(context)!.cancel, - ) == - OkCancelResult.cancel) { - return; - } - final matrix = Matrix.of(context); - await showFutureLoadingDialog( - context: context, - future: () => matrix.client.logout(), - ); + // #Pangea + pLogoutAction(context, isDestructiveAction: noBackup); + // if (await showOkCancelAlertDialog( + // useRootNavigator: false, + // context: context, + // title: L10n.of(context)!.areYouSureYouWantToLogout, + // message: L10n.of(context)!.noBackupWarning, + // isDestructiveAction: noBackup, + // okLabel: L10n.of(context)!.logout, + // cancelLabel: L10n.of(context)!.cancel, + // ) == + // OkCancelResult.cancel) { + // return; + // } + // final matrix = Matrix.of(context); + // await showFutureLoadingDialog( + // context: context, + // future: () => matrix.client.logout(), + // ); + // Pangea# } void setAvatarAction() async { @@ -160,7 +163,9 @@ class SettingsController extends State { @override void initState() { - WidgetsBinding.instance.addPostFrameCallback((_) => checkBootstrap()); + // #Pangea + // WidgetsBinding.instance.addPostFrameCallback((_) => checkBootstrap()); + // Pangea# super.initState(); } @@ -189,19 +194,21 @@ class SettingsController extends State { bool? showChatBackupBanner; void firstRunBootstrapAction([_]) async { - if (showChatBackupBanner != true) { - showOkAlertDialog( - context: context, - title: L10n.of(context)!.chatBackup, - message: L10n.of(context)!.onlineKeyBackupEnabled, - okLabel: L10n.of(context)!.close, - ); - return; - } - await BootstrapDialog( - client: Matrix.of(context).client, - ).show(context); - checkBootstrap(); + // #Pangea + // if (showChatBackupBanner != true) { + // showOkAlertDialog( + // context: context, + // title: L10n.of(context)!.chatBackup, + // message: L10n.of(context)!.onlineKeyBackupEnabled, + // okLabel: L10n.of(context)!.close, + // ); + // return; + // } + // await BootstrapDialog( + // client: Matrix.of(context).client, + // ).show(context); + // checkBootstrap(); + // Pangea# } @override diff --git a/lib/pages/settings/settings_view.dart b/lib/pages/settings/settings_view.dart index c7277e023..6025e480b 100644 --- a/lib/pages/settings/settings_view.dart +++ b/lib/pages/settings/settings_view.dart @@ -6,8 +6,8 @@ import 'package:matrix/matrix.dart'; import 'package:url_launcher/url_launcher_string.dart'; import 'package:fluffychat/config/app_config.dart'; +import 'package:fluffychat/pangea/config/environment.dart'; import 'package:fluffychat/utils/fluffy_share.dart'; -import 'package:fluffychat/utils/platform_infos.dart'; import 'package:fluffychat/widgets/avatar.dart'; import 'package:fluffychat/widgets/matrix.dart'; import 'settings.dart'; @@ -15,11 +15,13 @@ import 'settings.dart'; class SettingsView extends StatelessWidget { final SettingsController controller; - const SettingsView(this.controller, {Key? key}) : super(key: key); + const SettingsView(this.controller, {super.key}); @override Widget build(BuildContext context) { - final showChatBackupBanner = controller.showChatBackupBanner; + // #Pangea + // final showChatBackupBanner = controller.showChatBackupBanner; + // Pangea# return Scaffold( appBar: AppBar( leading: Center( @@ -137,21 +139,23 @@ class SettingsView extends StatelessWidget { }, ), const Divider(thickness: 1), - if (showChatBackupBanner == null) - ListTile( - leading: const Icon(Icons.backup_outlined), - title: Text(L10n.of(context)!.chatBackup), - trailing: const CircularProgressIndicator.adaptive(), - ) - else - SwitchListTile.adaptive( - controlAffinity: ListTileControlAffinity.trailing, - value: controller.showChatBackupBanner == false, - secondary: const Icon(Icons.backup_outlined), - title: Text(L10n.of(context)!.chatBackup), - onChanged: controller.firstRunBootstrapAction, - ), - const Divider(thickness: 1), + // #Pangea + // if (showChatBackupBanner == null) + // ListTile( + // leading: const Icon(Icons.backup_outlined), + // title: Text(L10n.of(context)!.chatBackup), + // trailing: const CircularProgressIndicator.adaptive(), + // ) + // else + // SwitchListTile.adaptive( + // controlAffinity: ListTileControlAffinity.trailing, + // value: controller.showChatBackupBanner == false, + // secondary: const Icon(Icons.backup_outlined), + // title: Text(L10n.of(context)!.chatBackup), + // onChanged: controller.firstRunBootstrapAction, + // ), + // const Divider(thickness: 1), + // Pangea# ListTile( leading: const Icon(Icons.format_paint_outlined), title: Text(L10n.of(context)!.changeTheme), @@ -176,6 +180,24 @@ class SettingsView extends StatelessWidget { onTap: () => context.go('/rooms/settings/chat'), trailing: const Icon(Icons.chevron_right_outlined), ), + // #Pangea + ListTile( + leading: const Icon(Icons.account_circle_outlined), + title: Text(L10n.of(context)!.learningSettings), + onTap: () => context.go('/rooms/settings/learning'), + trailing: const Icon( + Icons.chevron_right_outlined, + ), + ), + ListTile( + leading: const Icon(Icons.account_circle_outlined), + title: Text(L10n.of(context)!.subscriptionManagement), + onTap: () => context.go('/rooms/settings/subscription'), + trailing: const Icon( + Icons.chevron_right_outlined, + ), + ), + // Pangea# ListTile( leading: const Icon(Icons.shield_outlined), title: Text(L10n.of(context)!.security), @@ -195,12 +217,25 @@ class SettingsView extends StatelessWidget { onTap: () => launchUrlString(AppConfig.privacyUrl), trailing: const Icon(Icons.open_in_new_outlined), ), + // #Pangea + // ListTile( + // leading: const Icon(Icons.info_outline_rounded), + // title: Text(L10n.of(context)!.about), + // onTap: () => PlatformInfos.showDialog(context), + // trailing: const Icon(Icons.chevron_right_outlined), + // ), ListTile( - leading: const Icon(Icons.info_outline_rounded), - title: Text(L10n.of(context)!.about), - onTap: () => PlatformInfos.showDialog(context), - trailing: const Icon(Icons.chevron_right_outlined), + leading: const Icon(Icons.shield_outlined), + title: Text(L10n.of(context)!.termsAndConditions), + onTap: () => launchUrlString(AppConfig.termsOfServiceUrl), + trailing: const Icon(Icons.open_in_new_outlined), ), + if (Environment.isStaging) + ListTile( + leading: const Icon(Icons.bug_report_outlined), + title: Text(L10n.of(context)!.connectedToStaging), + ), + // Pangea# ], ), ), diff --git a/lib/pages/settings_3pid/settings_3pid.dart b/lib/pages/settings_3pid/settings_3pid.dart index ff3256934..d46cac2a9 100644 --- a/lib/pages/settings_3pid/settings_3pid.dart +++ b/lib/pages/settings_3pid/settings_3pid.dart @@ -11,7 +11,7 @@ import 'settings_3pid_view.dart'; class Settings3Pid extends StatefulWidget { static int sendAttempt = 0; - const Settings3Pid({Key? key}) : super(key: key); + const Settings3Pid({super.key}); @override Settings3PidController createState() => Settings3PidController(); diff --git a/lib/pages/settings_3pid/settings_3pid_view.dart b/lib/pages/settings_3pid/settings_3pid_view.dart index 245077d9c..101062a63 100644 --- a/lib/pages/settings_3pid/settings_3pid_view.dart +++ b/lib/pages/settings_3pid/settings_3pid_view.dart @@ -4,13 +4,12 @@ import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:matrix/matrix.dart'; import 'package:fluffychat/pages/settings_3pid/settings_3pid.dart'; -import 'package:fluffychat/widgets/layouts/max_width_body.dart'; import 'package:fluffychat/widgets/matrix.dart'; class Settings3PidView extends StatelessWidget { final Settings3PidController controller; - const Settings3PidView(this.controller, {Key? key}) : super(key: key); + const Settings3PidView(this.controller, {super.key}); @override Widget build(BuildContext context) { @@ -27,73 +26,76 @@ class Settings3PidView extends StatelessWidget { ), ], ), - body: MaxWidthBody( - child: FutureBuilder?>( - future: controller.request, - builder: ( - BuildContext context, - AsyncSnapshot?> snapshot, - ) { - if (snapshot.hasError) { - return Center( - child: Text( - snapshot.error.toString(), - textAlign: TextAlign.center, - ), - ); - } - if (!snapshot.hasData) { - return const Center( - child: CircularProgressIndicator.adaptive(strokeWidth: 2), - ); - } - final identifier = snapshot.data!; - return Column( - children: [ - ListTile( - leading: CircleAvatar( - backgroundColor: Theme.of(context).scaffoldBackgroundColor, - foregroundColor: - identifier.isEmpty ? Colors.orange : Colors.grey, - child: Icon( - identifier.isEmpty - ? Icons.warning_outlined - : Icons.info_outlined, - ), - ), - title: Text( - identifier.isEmpty - ? L10n.of(context)!.noPasswordRecoveryDescription - : L10n.of(context)! - .withTheseAddressesRecoveryDescription, - ), - ), - const Divider(height: 1), - Expanded( - child: ListView.builder( - itemCount: identifier.length, - itemBuilder: (BuildContext context, int i) => ListTile( - leading: CircleAvatar( - backgroundColor: - Theme.of(context).scaffoldBackgroundColor, - foregroundColor: Colors.grey, - child: Icon(identifier[i].iconData), - ), - title: Text(identifier[i].address), - trailing: IconButton( - tooltip: L10n.of(context)!.delete, - icon: const Icon(Icons.delete_forever_outlined), - color: Colors.red, - onPressed: () => controller.delete3Pid(identifier[i]), - ), - ), - ), - ), - ], + body: + // #Pangea + // MaxWidthBody( + // child: + // Pangea# + FutureBuilder?>( + future: controller.request, + builder: ( + BuildContext context, + AsyncSnapshot?> snapshot, + ) { + if (snapshot.hasError) { + return Center( + child: Text( + snapshot.error.toString(), + textAlign: TextAlign.center, + ), ); - }, - ), + } + if (!snapshot.hasData) { + return const Center( + child: CircularProgressIndicator.adaptive(strokeWidth: 2), + ); + } + final identifier = snapshot.data!; + return Column( + children: [ + ListTile( + leading: CircleAvatar( + backgroundColor: Theme.of(context).scaffoldBackgroundColor, + foregroundColor: + identifier.isEmpty ? Colors.orange : Colors.grey, + child: Icon( + identifier.isEmpty + ? Icons.warning_outlined + : Icons.info_outlined, + ), + ), + title: Text( + identifier.isEmpty + ? L10n.of(context)!.noPasswordRecoveryDescription + : L10n.of(context)!.withTheseAddressesRecoveryDescription, + ), + ), + const Divider(height: 1), + Expanded( + child: ListView.builder( + itemCount: identifier.length, + itemBuilder: (BuildContext context, int i) => ListTile( + leading: CircleAvatar( + backgroundColor: + Theme.of(context).scaffoldBackgroundColor, + foregroundColor: Colors.grey, + child: Icon(identifier[i].iconData), + ), + title: Text(identifier[i].address), + trailing: IconButton( + tooltip: L10n.of(context)!.delete, + icon: const Icon(Icons.delete_forever_outlined), + color: Colors.red, + onPressed: () => controller.delete3Pid(identifier[i]), + ), + ), + ), + ), + ], + ); + }, ), + // ), ); } } diff --git a/lib/pages/settings_chat/settings_chat.dart b/lib/pages/settings_chat/settings_chat.dart index b25941669..1c1035559 100644 --- a/lib/pages/settings_chat/settings_chat.dart +++ b/lib/pages/settings_chat/settings_chat.dart @@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; import 'settings_chat_view.dart'; class SettingsChat extends StatefulWidget { - const SettingsChat({Key? key}) : super(key: key); + const SettingsChat({super.key}); @override SettingsChatController createState() => SettingsChatController(); diff --git a/lib/pages/settings_chat/settings_chat_view.dart b/lib/pages/settings_chat/settings_chat_view.dart index 76522bffa..3ad9a8314 100644 --- a/lib/pages/settings_chat/settings_chat_view.dart +++ b/lib/pages/settings_chat/settings_chat_view.dart @@ -1,20 +1,18 @@ import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; -import 'package:go_router/go_router.dart'; import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/config/setting_keys.dart'; import 'package:fluffychat/utils/platform_infos.dart'; import 'package:fluffychat/utils/voip/callkeep_manager.dart'; import 'package:fluffychat/widgets/layouts/max_width_body.dart'; -import 'package:fluffychat/widgets/matrix.dart'; import 'package:fluffychat/widgets/settings_switch_list_tile.dart'; import 'settings_chat.dart'; class SettingsChatView extends StatelessWidget { final SettingsChatController controller; - const SettingsChatView(this.controller, {Key? key}) : super(key: key); + const SettingsChatView(this.controller, {super.key}); @override Widget build(BuildContext context) { @@ -25,19 +23,21 @@ class SettingsChatView extends StatelessWidget { child: MaxWidthBody( child: Column( children: [ - ListTile( - title: Text(L10n.of(context)!.emoteSettings), - onTap: () => context.go('/rooms/settings/chat/emotes'), - trailing: const Icon(Icons.chevron_right_outlined), - leading: const Icon(Icons.emoji_emotions_outlined), - ), - const Divider(), - SettingsSwitchListTile.adaptive( - title: L10n.of(context)!.renderRichContent, - onChanged: (b) => AppConfig.renderHtml = b, - storeKey: SettingKeys.renderHtml, - defaultValue: AppConfig.renderHtml, - ), + // #Pangea + // ListTile( + // title: Text(L10n.of(context)!.emoteSettings), + // onTap: () => context.go('/rooms/settings/chat/emotes'), + // trailing: const Icon(Icons.chevron_right_outlined), + // leading: const Icon(Icons.emoji_emotions_outlined), + // ), + // const Divider(), + // SettingsSwitchListTile.adaptive( + // title: L10n.of(context)!.renderRichContent, + // onChanged: (b) => AppConfig.renderHtml = b, + // storeKey: SettingKeys.renderHtml, + // defaultValue: AppConfig.renderHtml, + // ), + // Pangea# SettingsSwitchListTile.adaptive( title: L10n.of(context)!.hideRedactedEvents, onChanged: (b) => AppConfig.hideRedactedEvents = b, @@ -50,12 +50,14 @@ class SettingsChatView extends StatelessWidget { storeKey: SettingKeys.hideUnknownEvents, defaultValue: AppConfig.hideUnknownEvents, ), - SettingsSwitchListTile.adaptive( - title: L10n.of(context)!.hideUnimportantStateEvents, - onChanged: (b) => AppConfig.hideUnimportantStateEvents = b, - storeKey: SettingKeys.hideUnimportantStateEvents, - defaultValue: AppConfig.hideUnimportantStateEvents, - ), + // #Pangea + // SettingsSwitchListTile.adaptive( + // title: L10n.of(context)!.hideUnimportantStateEvents, + // onChanged: (b) => AppConfig.hideUnimportantStateEvents = b, + // storeKey: SettingKeys.hideUnimportantStateEvents, + // defaultValue: AppConfig.hideUnimportantStateEvents, + // ), + // Pangea# if (PlatformInfos.isMobile) SettingsSwitchListTile.adaptive( title: L10n.of(context)!.autoplayImages, @@ -64,28 +66,30 @@ class SettingsChatView extends StatelessWidget { defaultValue: AppConfig.autoplayImages, ), const Divider(), - SettingsSwitchListTile.adaptive( - title: L10n.of(context)!.sendTypingNotifications, - onChanged: (b) => AppConfig.sendTypingNotifications = b, - storeKey: SettingKeys.sendTypingNotifications, - defaultValue: AppConfig.sendTypingNotifications, - ), - SettingsSwitchListTile.adaptive( - title: L10n.of(context)!.sendOnEnter, - onChanged: (b) => AppConfig.sendOnEnter = b, - storeKey: SettingKeys.sendOnEnter, - defaultValue: AppConfig.sendOnEnter, - ), - SettingsSwitchListTile.adaptive( - title: L10n.of(context)!.experimentalVideoCalls, - onChanged: (b) { - AppConfig.experimentalVoip = b; - Matrix.of(context).createVoipPlugin(); - return; - }, - storeKey: SettingKeys.experimentalVoip, - defaultValue: AppConfig.experimentalVoip, - ), + // #Pangea + // SettingsSwitchListTile.adaptive( + // title: L10n.of(context)!.sendTypingNotifications, + // onChanged: (b) => AppConfig.sendTypingNotifications = b, + // storeKey: SettingKeys.sendTypingNotifications, + // defaultValue: AppConfig.sendTypingNotifications, + // ), + // SettingsSwitchListTile.adaptive( + // title: L10n.of(context)!.sendOnEnter, + // onChanged: (b) => AppConfig.sendOnEnter = b, + // storeKey: SettingKeys.sendOnEnter, + // defaultValue: AppConfig.sendOnEnter, + // ), + // SettingsSwitchListTile.adaptive( + // title: L10n.of(context)!.experimentalVideoCalls, + // onChanged: (b) { + // AppConfig.experimentalVoip = b; + // Matrix.of(context).createVoipPlugin(); + // return; + // }, + // storeKey: SettingKeys.experimentalVoip, + // defaultValue: AppConfig.experimentalVoip, + // ), + // Pangea# if (PlatformInfos.isMobile) ListTile( title: Text(L10n.of(context)!.callingPermissions), @@ -96,6 +100,7 @@ class SettingsChatView extends StatelessWidget { child: Icon(Icons.call), ), ), + const Divider(height: 1), SettingsSwitchListTile.adaptive( title: L10n.of(context)!.separateChatTypes, onChanged: (b) => AppConfig.separateChatTypes = b, diff --git a/lib/pages/settings_emotes/import_archive_dialog.dart b/lib/pages/settings_emotes/import_archive_dialog.dart index faf069120..0ed5bb21f 100644 --- a/lib/pages/settings_emotes/import_archive_dialog.dart +++ b/lib/pages/settings_emotes/import_archive_dialog.dart @@ -33,6 +33,8 @@ class _ImportEmoteArchiveDialogState extends State { bool _loading = false; + double _progress = 0; + @override void initState() { _importFileMap(); @@ -44,7 +46,11 @@ class _ImportEmoteArchiveDialogState extends State { return AlertDialog( title: Text(L10n.of(context)!.importEmojis), content: _loading - ? const Center(child: CircularProgressIndicator()) + ? Center( + child: CircularProgressIndicator( + value: _progress, + ), + ) : SingleChildScrollView( child: Wrap( alignment: WrapAlignment.spaceEvenly, @@ -97,6 +103,7 @@ class _ImportEmoteArchiveDialogState extends State { Future _addEmotePack() async { setState(() { _loading = true; + _progress = 0; }); final imports = _importMap; final successfulUploads = {}; @@ -134,52 +141,56 @@ class _ImportEmoteArchiveDialogState extends State { } for (final entry in imports.entries) { + setState(() { + _progress += 1 / imports.length; + }); final file = entry.key; final imageCode = entry.value; - // try { - var mxcFile = MatrixImageFile( - bytes: file.content, - name: file.name, - ); try { - mxcFile = (await mxcFile.generateThumbnail( + var mxcFile = MatrixImageFile( + bytes: file.content, + name: file.name, + ); + + final thumbnail = (await mxcFile.generateThumbnail( nativeImplementations: ClientManager.nativeImplementations, - ))!; - } catch (e, s) { - Logs().w('Unable to create thumbnail', e, s); - } - final uri = await Matrix.of(context).client.uploadContent( - mxcFile.bytes, - filename: mxcFile.name, - contentType: mxcFile.mimeType, - ); - - final info = { - ...mxcFile.info, - }; - - // normalize width / height to 256, required for stickers - if (info['w'] is int && info['h'] is int) { - final ratio = info['w'] / info['h']; - if (info['w'] > info['h']) { - info['w'] = 256; - info['h'] = (256.0 / ratio).round(); + )); + if (thumbnail == null) { + Logs().w('Unable to create thumbnail'); } else { - info['h'] = 256; - info['w'] = (ratio * 256.0).round(); + mxcFile = thumbnail; } - } - widget.controller.pack!.images[imageCode] = - ImagePackImageContent.fromJson({ - 'url': uri.toString(), - 'info': info, - }); - successfulUploads.add(file.name); - /*} catch (e) { + final uri = await Matrix.of(context).client.uploadContent( + mxcFile.bytes, + filename: mxcFile.name, + contentType: mxcFile.mimeType, + ); - Logs().d('Could not upload emote $imageCode'); - }*/ + final info = { + ...mxcFile.info, + }; + + // normalize width / height to 256, required for stickers + if (info['w'] is int && info['h'] is int) { + final ratio = info['w'] / info['h']; + if (info['w'] > info['h']) { + info['w'] = 256; + info['h'] = (256.0 / ratio).round(); + } else { + info['h'] = 256; + info['w'] = (ratio * 256.0).round(); + } + } + widget.controller.pack!.images[imageCode] = + ImagePackImageContent.fromJson({ + 'url': uri.toString(), + 'info': info, + }); + successfulUploads.add(file.name); + } catch (e) { + Logs().d('Could not upload emote $imageCode'); + } } await widget.controller.save(context); @@ -188,6 +199,7 @@ class _ImportEmoteArchiveDialogState extends State { ); _loading = false; + _progress = 0; // in case we have unhandled / duplicated emotes left, don't pop if (mounted) setState(() {}); @@ -204,11 +216,11 @@ class _EmojiImportPreview extends StatefulWidget { final VoidCallback onRemove; const _EmojiImportPreview({ - Key? key, + super.key, required this.entry, required this.onNameChanged, required this.onRemove, - }) : super(key: key); + }); @override State<_EmojiImportPreview> createState() => _EmojiImportPreviewState(); diff --git a/lib/pages/settings_emotes/settings_emotes.dart b/lib/pages/settings_emotes/settings_emotes.dart index 98d5a214d..2ef905b17 100644 --- a/lib/pages/settings_emotes/settings_emotes.dart +++ b/lib/pages/settings_emotes/settings_emotes.dart @@ -23,7 +23,7 @@ import 'package:archive/archive.dart' if (dart.library.io) 'package:archive/archive_io.dart'; class EmotesSettings extends StatefulWidget { - const EmotesSettings({Key? key}) : super(key: key); + const EmotesSettings({super.key}); @override EmotesSettingsController createState() => EmotesSettingsController(); @@ -309,6 +309,8 @@ class EmotesSettingsController extends State { await showDialog( context: context, + // breaks [Matrix.of] calls otherwise + useRootNavigator: false, builder: (context) => ImportEmoteArchiveDialog( controller: this, archive: archive, diff --git a/lib/pages/settings_emotes/settings_emotes_view.dart b/lib/pages/settings_emotes/settings_emotes_view.dart index 5803ee94a..acb93788e 100644 --- a/lib/pages/settings_emotes/settings_emotes_view.dart +++ b/lib/pages/settings_emotes/settings_emotes_view.dart @@ -15,7 +15,7 @@ enum PopupMenuEmojiActions { import, export } class EmotesSettingsView extends StatelessWidget { final EmotesSettingsController controller; - const EmotesSettingsView(this.controller, {Key? key}) : super(key: key); + const EmotesSettingsView(this.controller, {super.key}); @override Widget build(BuildContext context) { diff --git a/lib/pages/settings_ignore_list/settings_ignore_list.dart b/lib/pages/settings_ignore_list/settings_ignore_list.dart index cf0713aa9..0b27cee3b 100644 --- a/lib/pages/settings_ignore_list/settings_ignore_list.dart +++ b/lib/pages/settings_ignore_list/settings_ignore_list.dart @@ -8,7 +8,7 @@ import 'settings_ignore_list_view.dart'; class SettingsIgnoreList extends StatefulWidget { final String? initialUserId; - const SettingsIgnoreList({Key? key, this.initialUserId}) : super(key: key); + const SettingsIgnoreList({super.key, this.initialUserId}); @override SettingsIgnoreListController createState() => SettingsIgnoreListController(); diff --git a/lib/pages/settings_ignore_list/settings_ignore_list_view.dart b/lib/pages/settings_ignore_list/settings_ignore_list_view.dart index 438e530b3..dc0a31468 100644 --- a/lib/pages/settings_ignore_list/settings_ignore_list_view.dart +++ b/lib/pages/settings_ignore_list/settings_ignore_list_view.dart @@ -5,14 +5,13 @@ import 'package:future_loading_dialog/future_loading_dialog.dart'; import 'package:matrix/matrix.dart'; import 'package:fluffychat/widgets/avatar.dart'; -import 'package:fluffychat/widgets/layouts/max_width_body.dart'; import '../../widgets/matrix.dart'; import 'settings_ignore_list.dart'; class SettingsIgnoreListView extends StatelessWidget { final SettingsIgnoreListController controller; - const SettingsIgnoreListView(this.controller, {Key? key}) : super(key: key); + const SettingsIgnoreListView(this.controller, {super.key}); @override Widget build(BuildContext context) { @@ -22,76 +21,79 @@ class SettingsIgnoreListView extends StatelessWidget { leading: const Center(child: BackButton()), title: Text(L10n.of(context)!.ignoredUsers), ), - body: MaxWidthBody( - child: Column( - children: [ - Padding( - padding: const EdgeInsets.all(16.0), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - TextField( - controller: controller.controller, - autocorrect: false, - textInputAction: TextInputAction.done, - onSubmitted: (_) => controller.ignoreUser(context), - decoration: InputDecoration( - border: const OutlineInputBorder(), - hintText: 'bad_guy:domain.abc', - prefixText: '@', - labelText: L10n.of(context)!.ignoreUsername, - suffixIcon: IconButton( - tooltip: L10n.of(context)!.ignore, - icon: const Icon(Icons.done_outlined), - onPressed: () => controller.ignoreUser(context), + body: + // #Pangea + // MaxWidthBody( + // child: + // Pangea# + Column( + children: [ + Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + TextField( + controller: controller.controller, + autocorrect: false, + textInputAction: TextInputAction.done, + onSubmitted: (_) => controller.ignoreUser(context), + decoration: InputDecoration( + border: const OutlineInputBorder(), + hintText: 'bad_guy:domain.abc', + prefixText: '@', + labelText: L10n.of(context)!.ignoreUsername, + suffixIcon: IconButton( + tooltip: L10n.of(context)!.ignore, + icon: const Icon(Icons.done_outlined), + onPressed: () => controller.ignoreUser(context), + ), + ), + ), + const SizedBox(height: 16), + Text( + L10n.of(context)!.ignoreListDescription, + style: const TextStyle(color: Colors.orange), + ), + ], + ), + ), + const Divider(height: 1), + Expanded( + child: StreamBuilder( + stream: client.onAccountData.stream + .where((a) => a.type == 'm.ignored_user_list'), + builder: (context, snapshot) { + return ListView.builder( + itemCount: client.ignoredUsers.length, + itemBuilder: (c, i) => FutureBuilder( + future: client.getProfileFromUserId(client.ignoredUsers[i]), + builder: (c, s) => ListTile( + leading: Avatar( + mxContent: s.data?.avatarUrl ?? Uri.parse(''), + name: s.data?.displayName ?? client.ignoredUsers[i], + ), + title: Text( + s.data?.displayName ?? client.ignoredUsers[i], + ), + trailing: IconButton( + tooltip: L10n.of(context)!.delete, + icon: const Icon(Icons.delete_forever_outlined), + onPressed: () => showFutureLoadingDialog( + context: context, + future: () => + client.unignoreUser(client.ignoredUsers[i]), + ), ), ), ), - const SizedBox(height: 16), - Text( - L10n.of(context)!.ignoreListDescription, - style: const TextStyle(color: Colors.orange), - ), - ], - ), + ); + }, ), - const Divider(height: 1), - Expanded( - child: StreamBuilder( - stream: client.onAccountData.stream - .where((a) => a.type == 'm.ignored_user_list'), - builder: (context, snapshot) { - return ListView.builder( - itemCount: client.ignoredUsers.length, - itemBuilder: (c, i) => FutureBuilder( - future: - client.getProfileFromUserId(client.ignoredUsers[i]), - builder: (c, s) => ListTile( - leading: Avatar( - mxContent: s.data?.avatarUrl ?? Uri.parse(''), - name: s.data?.displayName ?? client.ignoredUsers[i], - ), - title: Text( - s.data?.displayName ?? client.ignoredUsers[i], - ), - trailing: IconButton( - tooltip: L10n.of(context)!.delete, - icon: const Icon(Icons.delete_forever_outlined), - onPressed: () => showFutureLoadingDialog( - context: context, - future: () => - client.unignoreUser(client.ignoredUsers[i]), - ), - ), - ), - ), - ); - }, - ), - ), - ], - ), + ), + ], ), + // ), ); } } diff --git a/lib/pages/settings_multiple_emotes/settings_multiple_emotes.dart b/lib/pages/settings_multiple_emotes/settings_multiple_emotes.dart index b4901832d..276bc08ad 100644 --- a/lib/pages/settings_multiple_emotes/settings_multiple_emotes.dart +++ b/lib/pages/settings_multiple_emotes/settings_multiple_emotes.dart @@ -5,7 +5,7 @@ import 'package:go_router/go_router.dart'; import 'settings_multiple_emotes_view.dart'; class MultipleEmotesSettings extends StatefulWidget { - const MultipleEmotesSettings({Key? key}) : super(key: key); + const MultipleEmotesSettings({super.key}); @override MultipleEmotesSettingsController createState() => diff --git a/lib/pages/settings_multiple_emotes/settings_multiple_emotes_view.dart b/lib/pages/settings_multiple_emotes/settings_multiple_emotes_view.dart index b699e37bf..8d62549c7 100644 --- a/lib/pages/settings_multiple_emotes/settings_multiple_emotes_view.dart +++ b/lib/pages/settings_multiple_emotes/settings_multiple_emotes_view.dart @@ -10,8 +10,7 @@ import 'package:fluffychat/widgets/matrix.dart'; class MultipleEmotesSettingsView extends StatelessWidget { final MultipleEmotesSettingsController controller; - const MultipleEmotesSettingsView(this.controller, {Key? key}) - : super(key: key); + const MultipleEmotesSettingsView(this.controller, {super.key}); @override Widget build(BuildContext context) { diff --git a/lib/pages/settings_notifications/settings_notifications.dart b/lib/pages/settings_notifications/settings_notifications.dart index ff9dcbd35..6ab4740af 100644 --- a/lib/pages/settings_notifications/settings_notifications.dart +++ b/lib/pages/settings_notifications/settings_notifications.dart @@ -54,7 +54,7 @@ class NotificationSettingsItem { } class SettingsNotifications extends StatefulWidget { - const SettingsNotifications({Key? key}) : super(key: key); + const SettingsNotifications({super.key}); @override SettingsNotificationsController createState() => diff --git a/lib/pages/settings_notifications/settings_notifications_view.dart b/lib/pages/settings_notifications/settings_notifications_view.dart index 0cdef98dd..65ddac162 100644 --- a/lib/pages/settings_notifications/settings_notifications_view.dart +++ b/lib/pages/settings_notifications/settings_notifications_view.dart @@ -12,8 +12,7 @@ import 'settings_notifications.dart'; class SettingsNotificationsView extends StatelessWidget { final SettingsNotificationsController controller; - const SettingsNotificationsView(this.controller, {Key? key}) - : super(key: key); + const SettingsNotificationsView(this.controller, {super.key}); @override Widget build(BuildContext context) { diff --git a/lib/pages/settings_security/settings_security.dart b/lib/pages/settings_security/settings_security.dart index b3a58ca68..60f746e89 100644 --- a/lib/pages/settings_security/settings_security.dart +++ b/lib/pages/settings_security/settings_security.dart @@ -16,7 +16,7 @@ import '../bootstrap/bootstrap_dialog.dart'; import 'settings_security_view.dart'; class SettingsSecurity extends StatefulWidget { - const SettingsSecurity({Key? key}) : super(key: key); + const SettingsSecurity({super.key}); @override SettingsSecurityController createState() => SettingsSecurityController(); diff --git a/lib/pages/settings_security/settings_security_view.dart b/lib/pages/settings_security/settings_security_view.dart index fc241a850..54e8b4e70 100644 --- a/lib/pages/settings_security/settings_security_view.dart +++ b/lib/pages/settings_security/settings_security_view.dart @@ -11,7 +11,7 @@ import 'settings_security.dart'; class SettingsSecurityView extends StatelessWidget { final SettingsSecurityController controller; - const SettingsSecurityView(this.controller, {Key? key}) : super(key: key); + const SettingsSecurityView(this.controller, {super.key}); @override Widget build(BuildContext context) { @@ -22,12 +22,14 @@ class SettingsSecurityView extends StatelessWidget { child: MaxWidthBody( child: Column( children: [ - ListTile( - leading: const Icon(Icons.camera_outlined), - trailing: const Icon(Icons.chevron_right_outlined), - title: Text(L10n.of(context)!.whoCanSeeMyStories), - onTap: () => context.go('/rooms/settings/security/stories'), - ), + // #Pangea + // ListTile( + // leading: const Icon(Icons.camera_outlined), + // trailing: const Icon(Icons.chevron_right_outlined), + // title: Text(L10n.of(context)!.whoCanSeeMyStories), + // onTap: () => context.go('/rooms/settings/security/stories'), + // ), + // Pangea# ListTile( leading: const Icon(Icons.block_outlined), trailing: const Icon(Icons.chevron_right_outlined), diff --git a/lib/pages/settings_stories/settings_stories.dart b/lib/pages/settings_stories/settings_stories.dart index 802c07d0c..16e9208bb 100644 --- a/lib/pages/settings_stories/settings_stories.dart +++ b/lib/pages/settings_stories/settings_stories.dart @@ -8,7 +8,7 @@ import 'package:fluffychat/widgets/matrix.dart'; import '../../utils/matrix_sdk_extensions/client_stories_extension.dart'; class SettingsStories extends StatefulWidget { - const SettingsStories({Key? key}) : super(key: key); + const SettingsStories({super.key}); @override SettingsStoriesController createState() => SettingsStoriesController(); diff --git a/lib/pages/settings_stories/settings_stories_view.dart b/lib/pages/settings_stories/settings_stories_view.dart index 31524eef4..f5d71fab3 100644 --- a/lib/pages/settings_stories/settings_stories_view.dart +++ b/lib/pages/settings_stories/settings_stories_view.dart @@ -8,7 +8,7 @@ import 'package:fluffychat/widgets/avatar.dart'; class SettingsStoriesView extends StatelessWidget { final SettingsStoriesController controller; - const SettingsStoriesView(this.controller, {Key? key}) : super(key: key); + const SettingsStoriesView(this.controller, {super.key}); @override Widget build(BuildContext context) { diff --git a/lib/pages/settings_style/settings_style.dart b/lib/pages/settings_style/settings_style.dart index 619dc2c6d..67c6d9738 100644 --- a/lib/pages/settings_style/settings_style.dart +++ b/lib/pages/settings_style/settings_style.dart @@ -11,7 +11,7 @@ import '../../widgets/matrix.dart'; import 'settings_style_view.dart'; class SettingsStyle extends StatefulWidget { - const SettingsStyle({Key? key}) : super(key: key); + const SettingsStyle({super.key}); @override SettingsStyleController createState() => SettingsStyleController(); @@ -30,13 +30,13 @@ class SettingsStyleController extends State { if (pickedFile == null) return; await Matrix.of(context) .store - .setItem(SettingKeys.wallpaper, pickedFile.path); + .setString(SettingKeys.wallpaper, pickedFile.path!); setState(() {}); } void deleteWallpaperAction() async { Matrix.of(context).wallpaper = null; - await Matrix.of(context).store.deleteItem(SettingKeys.wallpaper); + await Matrix.of(context).store.remove(SettingKeys.wallpaper); setState(() {}); } @@ -76,7 +76,7 @@ class SettingsStyleController extends State { void changeFontSizeFactor(double d) { setState(() => AppConfig.fontSizeFactor = d); - Matrix.of(context).store.setItem( + Matrix.of(context).store.setString( SettingKeys.fontSizeFactor, AppConfig.fontSizeFactor.toString(), ); diff --git a/lib/pages/settings_style/settings_style_view.dart b/lib/pages/settings_style/settings_style_view.dart index f7646fdc2..9104912e7 100644 --- a/lib/pages/settings_style/settings_style_view.dart +++ b/lib/pages/settings_style/settings_style_view.dart @@ -11,7 +11,7 @@ import 'settings_style.dart'; class SettingsStyleView extends StatelessWidget { final SettingsStyleController controller; - const SettingsStyleView(this.controller, {Key? key}) : super(key: key); + const SettingsStyleView(this.controller, {super.key}); @override Widget build(BuildContext context) { diff --git a/lib/pages/story/story_page.dart b/lib/pages/story/story_page.dart index 1fafdf0fa..1a0333c2b 100644 --- a/lib/pages/story/story_page.dart +++ b/lib/pages/story/story_page.dart @@ -24,7 +24,7 @@ import 'package:fluffychat/widgets/avatar.dart'; import 'package:fluffychat/widgets/matrix.dart'; class StoryPage extends StatefulWidget { - const StoryPage({Key? key}) : super(key: key); + const StoryPage({super.key}); @override StoryPageController createState() => StoryPageController(); diff --git a/lib/pages/story/story_view.dart b/lib/pages/story/story_view.dart index 03e25502b..913becfbf 100644 --- a/lib/pages/story/story_view.dart +++ b/lib/pages/story/story_view.dart @@ -19,7 +19,7 @@ import '../../config/themes.dart'; class StoryView extends StatelessWidget { final StoryPageController controller; - const StoryView(this.controller, {Key? key}) : super(key: key); + const StoryView(this.controller, {super.key}); static const List textShadows = [ Shadow( diff --git a/lib/pages/tasks/model/matrix_todo_list.dart b/lib/pages/tasks/model/matrix_todo_list.dart new file mode 100644 index 000000000..fdcb88970 --- /dev/null +++ b/lib/pages/tasks/model/matrix_todo_list.dart @@ -0,0 +1,59 @@ +import 'package:matrix/matrix.dart'; + +extension MatrixTodoExtension on Room { + static const String stateKey = 'im.fluffychat.matrix_todos'; + static const String contentKey = 'todos'; + + List? get matrixTodos => getState(stateKey) + ?.content + .tryGetList(contentKey) + ?.map((json) => MatrixTodo.fromJson(json)) + .toList(); + + Future updateMatrixTodos(List matrixTodos) => + client.setRoomStateWithKey( + id, + stateKey, + '', + {contentKey: matrixTodos.map((todo) => todo.toJson()).toList()}, + ); +} + +class MatrixTodo { + String title; + String? description; + DateTime? dueDate; + bool done; + List? subTasks; + + MatrixTodo({ + required this.title, + this.description, + this.dueDate, + this.done = false, + this.subTasks, + }); + + factory MatrixTodo.fromJson(Map json) => MatrixTodo( + title: json['title'] as String, + description: json['description'] as String?, + dueDate: json['due_date'] == null + ? null + : DateTime.fromMillisecondsSinceEpoch(json['due_date'] as int), + done: json['done'] as bool, + subTasks: json['sub_tasks'] == null + ? null + : (json['sub_tasks'] as List) + .map((json) => MatrixTodo.fromJson(json)) + .toList(), + ); + + Map toJson() => { + 'title': title, + if (description != null) 'description': description, + if (dueDate != null) 'due_date': dueDate?.millisecondsSinceEpoch, + 'done': done, + if (subTasks != null) + 'sub_tasks': subTasks?.map((t) => t.toJson()).toList(), + }; +} diff --git a/lib/pages/tasks/tasks.dart b/lib/pages/tasks/tasks.dart new file mode 100644 index 000000000..7743b99e5 --- /dev/null +++ b/lib/pages/tasks/tasks.dart @@ -0,0 +1,255 @@ +import 'package:flutter/material.dart'; + +import 'package:adaptive_dialog/adaptive_dialog.dart'; +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:matrix/matrix.dart'; + +import 'package:fluffychat/pages/tasks/tasks_view.dart'; +import 'package:fluffychat/utils/localized_exception_extension.dart'; +import 'model/matrix_todo_list.dart'; + +class TasksPage extends StatefulWidget { + final Room room; + const TasksPage({required this.room, super.key}); + + @override + State createState() => TasksController(); +} + +class TasksController extends State { + bool isLoading = false; + DateTime? newTaskDateTime; + String? newTaskDescription; + + final FocusNode focusNode = FocusNode(); + final TextEditingController textEditingController = TextEditingController(); + + List? _tmpTodos; + + List get todos => _tmpTodos ?? widget.room.matrixTodos ?? []; + + Stream get onUpdate => widget.room.client.onSync.stream.where( + (syncUpdate) => + syncUpdate.rooms?.join?[widget.room.id]?.state + ?.any((event) => event.type == MatrixTodoExtension.stateKey) ?? + false, + ); + + void setNewTaskDateTime() async { + final now = DateTime.now(); + final date = await showDatePicker( + context: context, + initialDate: DateTime.now(), + firstDate: now.subtract(const Duration(days: 365 * 100)), + lastDate: now.add(const Duration(days: 365 * 100)), + ); + if (date == null) return; + setState(() { + newTaskDateTime = date; + }); + } + + void setNewTaskDescription() async { + final text = await showTextInputDialog( + context: context, + title: L10n.of(context)!.addDescription, + textFields: [ + DialogTextField( + hintText: L10n.of(context)!.addDescription, + maxLength: 512, + minLines: 4, + maxLines: 8, + ), + ], + ); + if (text == null || text.single.isEmpty) return; + setState(() { + newTaskDescription = text.single; + }); + } + + void addTodo([_]) { + if (textEditingController.text.isEmpty) return; + updateTodos( + update: (todos) => [ + ...todos, + MatrixTodo( + title: textEditingController.text, + dueDate: newTaskDateTime, + description: newTaskDescription, + ), + ], + onSuccess: () { + newTaskDateTime = null; + newTaskDescription = null; + textEditingController.clear(); + focusNode.requestFocus(); + }, + ); + } + + void toggleDone(int i) => updateTodos( + update: (todos) { + todos[i].done = !todos[i].done; + return todos; + }, + ); + + void cleanUp() => updateTodos( + update: (todos) => todos..removeWhere((t) => t.done), + ); + + void onReorder(int oldindex, int newindex) { + if (newindex > oldindex) { + newindex -= 1; + } + updateTodos( + update: (todos) { + final todo = todos.removeAt(oldindex); + todos.insert(newindex, todo); + return todos; + }, + tmpTodo: true, + ); + } + + void updateTodos({ + required List Function(List) update, + void Function()? onSuccess, + bool tmpTodo = false, + }) async { + setState(() { + isLoading = true; + }); + try { + final newTodos = update(todos); + assert(todos != newTodos); + if (tmpTodo) { + setState(() { + _tmpTodos = newTodos; + }); + onUpdate.first.then((_) { + _tmpTodos = null; + }); + } + await widget.room + .updateMatrixTodos(newTodos) + .timeout(const Duration(seconds: 30)); + onSuccess?.call(); + } on MatrixException catch (e) { + final retryAfterMs = e.retryAfterMs; + if (retryAfterMs == null) rethrow; + Logs().w('Rate limit! Try again in $retryAfterMs ms'); + await Future.delayed(Duration(milliseconds: retryAfterMs)); + updateTodos(update: update, onSuccess: onSuccess); + } catch (e, s) { + Logs().w('Unable to update todo list', e, s); + if (_tmpTodos != null) { + setState(() { + _tmpTodos = null; + }); + } + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + duration: const Duration(seconds: 20), + content: Row( + children: [ + Icon( + Icons.signal_wifi_connected_no_internet_4_outlined, + color: Theme.of(context).colorScheme.background, + ), + const SizedBox(width: 16), + Expanded( + child: Text( + e.toLocalizedString(context), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + ), + ], + ), + action: e is TodoListChangedException + ? null + : SnackBarAction( + label: 'Try again', + onPressed: () { + updateTodos(update: update, onSuccess: onSuccess); + }, + ), + ), + ); + } finally { + setState(() { + isLoading = false; + }); + } + } + + void editTodo(int i, MatrixTodo todo) async { + final texts = await showTextInputDialog( + context: context, + title: L10n.of(context)!.editTodo, + textFields: [ + DialogTextField( + hintText: L10n.of(context)!.newTodo, + initialText: todo.title, + maxLength: 64, + validator: (text) { + if (text == null) return L10n.of(context)!.pleaseAddATitle; + return null; + }, + ), + DialogTextField( + hintText: L10n.of(context)!.addDescription, + maxLength: 512, + minLines: 4, + maxLines: 8, + initialText: todo.description, + ), + ], + ); + if (texts == null) return; + updateTodos( + update: (todos) { + if (todos[i].toJson().toString() != todo.toJson().toString()) { + throw TodoListChangedException(); + } + todos[i].title = texts[0]; + todos[i].description = texts[1].isEmpty ? null : texts[1]; + return todos; + }, + ); + } + + void deleteTodo(int i) => updateTodos( + update: (list) { + list.removeAt(i); + return list; + }, + ); + + void editTodoDueDate(int i, MatrixTodo todo) async { + final now = DateTime.now(); + final date = await showDatePicker( + context: context, + initialDate: todo.dueDate ?? DateTime.now(), + firstDate: now.subtract(const Duration(days: 365 * 100)), + lastDate: now.add(const Duration(days: 365 * 100)), + ); + if (date == null) return; + updateTodos( + update: (todos) { + if (todos[i].toJson().toString() != todo.toJson().toString()) { + throw TodoListChangedException(); + } + todos[i].dueDate = date; + return todos; + }, + ); + } + + @override + Widget build(BuildContext context) => TasksView(this); +} + +class TodoListChangedException implements Exception {} diff --git a/lib/pages/tasks/tasks_view.dart b/lib/pages/tasks/tasks_view.dart new file mode 100644 index 000000000..8046b44d1 --- /dev/null +++ b/lib/pages/tasks/tasks_view.dart @@ -0,0 +1,234 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:intl/intl.dart'; + +import 'package:fluffychat/config/themes.dart'; +import 'package:fluffychat/pages/tasks/tasks.dart'; + +class TasksView extends StatelessWidget { + final TasksController controller; + const TasksView(this.controller, {super.key}); + + @override + Widget build(BuildContext context) { + final tag = Localizations.maybeLocaleOf(context)?.toLanguageTag(); + return StreamBuilder( + stream: controller.widget.room.onUpdate.stream, + builder: (context, snapshot) { + final list = controller.todos; + return Scaffold( + appBar: AppBar( + title: Text(L10n.of(context)!.todoLists), + actions: [ + AnimatedCrossFade( + duration: FluffyThemes.animationDuration, + firstChild: const SizedBox( + width: 32, + height: 32, + ), + secondChild: const Padding( + padding: EdgeInsets.all(8.0), + child: SizedBox( + width: 16, + height: 16, + child: CircularProgressIndicator.adaptive(strokeWidth: 2), + ), + ), + crossFadeState: controller.isLoading + ? CrossFadeState.showSecond + : CrossFadeState.showFirst, + ), + if (list.any((todo) => todo.done)) + IconButton( + icon: const Icon(Icons.cleaning_services_outlined), + onPressed: controller.cleanUp, + ), + ], + ), + body: Column( + children: [ + Expanded( + child: Opacity( + opacity: controller.isLoading ? 0.66 : 1, + child: list.isEmpty + ? Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Icon( + Icons.task_alt, + size: 80, + color: Theme.of(context).colorScheme.secondary, + ), + const SizedBox(height: 16), + SizedBox( + width: 256, + child: Text( + L10n.of(context)!.noTodosYet, + textAlign: TextAlign.center, + ), + ), + const SizedBox(height: 16), + SizedBox( + width: 256, + child: Text( + L10n.of(context)!.todosUnencrypted, + textAlign: TextAlign.center, + style: const TextStyle(color: Colors.orange), + ), + ), + ], + ) + : ReorderableListView.builder( + onReorder: controller.onReorder, + itemCount: list.length, + buildDefaultDragHandles: false, + itemBuilder: (context, i) { + final todo = list[i]; + final description = todo.description; + final dueDate = todo.dueDate; + return ListTile( + key: Key(todo.toJson().toString()), + leading: Icon( + todo.done + ? Icons.check_circle + : Icons.circle_outlined, + ), + title: Text( + todo.title, + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: TextStyle( + decoration: todo.done + ? TextDecoration.lineThrough + : null, + ), + ), + subtitle: description == null && dueDate == null + ? null + : Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + if (description != null) + Text( + description, + maxLines: 2, + ), + if (dueDate != null) + SizedBox( + height: 24, + child: OutlinedButton.icon( + style: OutlinedButton.styleFrom( + padding: + const EdgeInsets.symmetric( + horizontal: 6, + ), + ), + icon: const Icon( + Icons.calendar_month, + size: 16, + ), + label: Text( + DateFormat.yMMMd(tag) + .format(dueDate), + style: const TextStyle( + fontSize: 12, + ), + ), + onPressed: () => + controller.editTodoDueDate( + i, + todo, + ), + ), + ), + ], + ), + onTap: controller.isLoading + ? null + : () => controller.toggleDone(i), + trailing: Row( + mainAxisSize: MainAxisSize.min, + children: [ + IconButton( + icon: const Icon( + Icons.edit_outlined, + size: 16, + ), + onPressed: () => + controller.editTodo(i, todo), + ), + IconButton( + icon: const Icon( + Icons.delete_outlined, + size: 16, + ), + onPressed: () => controller.deleteTodo(i), + ), + ReorderableDragStartListener( + index: i, + child: + const Icon(Icons.drag_handle_outlined), + ), + ], + ), + ); + }, + ), + ), + ), + Padding( + padding: const EdgeInsets.all(12.0), + child: TextField( + focusNode: controller.focusNode, + readOnly: controller.isLoading, + controller: controller.textEditingController, + onSubmitted: controller.addTodo, + maxLength: 64, + decoration: InputDecoration( + counterStyle: const TextStyle(height: double.minPositive), + counterText: '', + hintText: L10n.of(context)!.newTodo, + prefixIcon: Row( + mainAxisSize: MainAxisSize.min, + children: [ + IconButton( + icon: Icon( + controller.newTaskDateTime == null + ? Icons.calendar_month_outlined + : Icons.calendar_month, + color: controller.newTaskDateTime == null + ? null + : Theme.of(context).primaryColor, + ), + onPressed: controller.setNewTaskDateTime, + ), + IconButton( + icon: Icon( + Icons.text_fields, + color: controller.newTaskDescription == null + ? null + : Theme.of(context).primaryColor, + ), + onPressed: controller.setNewTaskDescription, + ), + ], + ), + suffixIcon: IconButton( + icon: const Icon(Icons.add_outlined), + onPressed: + controller.isLoading ? null : controller.addTodo, + ), + ), + ), + ), + ], + ), + ); + }, + ); + } +} diff --git a/lib/pages/user_bottom_sheet/user_bottom_sheet.dart b/lib/pages/user_bottom_sheet/user_bottom_sheet.dart index 491f86ef9..9d87f559c 100644 --- a/lib/pages/user_bottom_sheet/user_bottom_sheet.dart +++ b/lib/pages/user_bottom_sheet/user_bottom_sheet.dart @@ -34,7 +34,7 @@ class LoadProfileBottomSheet extends StatelessWidget { @override Widget build(BuildContext context) { return FutureBuilder( - future: Matrix.of(context) + future: Matrix.of(outerContext) .client .getUserProfile(userId) .timeout(const Duration(seconds: 3)), @@ -74,14 +74,13 @@ class UserBottomSheet extends StatefulWidget { final Object? profileSearchError; const UserBottomSheet({ - Key? key, + super.key, this.user, this.profile, required this.outerContext, this.onMention, this.profileSearchError, - }) : assert(user != null || profile != null), - super(key: key); + }) : assert(user != null || profile != null); @override UserBottomSheetController createState() => UserBottomSheetController(); @@ -92,15 +91,7 @@ class UserBottomSheetController extends State { final user = widget.user; final userId = user?.id ?? widget.profile?.userId; if (userId == null) throw ('user or profile must not be null!'); - // ignore: prefer_function_declarations_over_variables - final Function askConfirmation = () async => (await showOkCancelAlertDialog( - useRootNavigator: false, - context: context, - title: L10n.of(context)!.areYouSure, - okLabel: L10n.of(context)!.yes, - cancelLabel: L10n.of(context)!.no, - ) == - OkCancelResult.ok); + switch (action) { case UserBottomSheetAction.report: if (user == null) throw ('User must not be null for this action!'); @@ -138,7 +129,7 @@ class UserBottomSheetController extends State { if (reason == null || reason.single.isEmpty) return; final result = await showFutureLoadingDialog( context: context, - future: () => Matrix.of(context).client.reportContent( + future: () => Matrix.of(widget.outerContext).client.reportContent( user.roomId!, user.eventId, reason: reason.single, @@ -157,7 +148,15 @@ class UserBottomSheetController extends State { break; case UserBottomSheetAction.ban: if (user == null) throw ('User must not be null for this action!'); - if (await askConfirmation()) { + if (await showOkCancelAlertDialog( + useRootNavigator: false, + context: context, + title: L10n.of(context)!.areYouSure, + okLabel: L10n.of(context)!.yes, + cancelLabel: L10n.of(context)!.no, + message: L10n.of(context)!.banUserDescription, + ) == + OkCancelResult.ok) { await showFutureLoadingDialog( context: context, future: () => user.ban(), @@ -167,7 +166,15 @@ class UserBottomSheetController extends State { break; case UserBottomSheetAction.unban: if (user == null) throw ('User must not be null for this action!'); - if (await askConfirmation()) { + if (await showOkCancelAlertDialog( + useRootNavigator: false, + context: context, + title: L10n.of(context)!.areYouSure, + okLabel: L10n.of(context)!.yes, + cancelLabel: L10n.of(context)!.no, + message: L10n.of(context)!.unbanUserDescription, + ) == + OkCancelResult.ok) { await showFutureLoadingDialog( context: context, future: () => user.unban(), @@ -177,7 +184,15 @@ class UserBottomSheetController extends State { break; case UserBottomSheetAction.kick: if (user == null) throw ('User must not be null for this action!'); - if (await askConfirmation()) { + if (await showOkCancelAlertDialog( + useRootNavigator: false, + context: context, + title: L10n.of(context)!.areYouSure, + okLabel: L10n.of(context)!.yes, + cancelLabel: L10n.of(context)!.no, + message: L10n.of(context)!.kickUserDescription, + ) == + OkCancelResult.ok) { await showFutureLoadingDialog( context: context, future: () => user.kick(), @@ -192,7 +207,16 @@ class UserBottomSheetController extends State { currentLevel: user.powerLevel, ); if (newPermission != null) { - if (newPermission == 100 && await askConfirmation() == false) break; + if (newPermission == 100 && + await showOkCancelAlertDialog( + useRootNavigator: false, + context: context, + title: L10n.of(context)!.areYouSure, + okLabel: L10n.of(context)!.yes, + cancelLabel: L10n.of(context)!.no, + message: L10n.of(context)!.makeAdminDescription, + ) == + OkCancelResult.ok) break; await showFutureLoadingDialog( context: context, future: () => user.setPower(newPermission), @@ -203,23 +227,19 @@ class UserBottomSheetController extends State { case UserBottomSheetAction.message: final roomIdResult = await showFutureLoadingDialog( context: context, - future: () => Matrix.of(context) + future: () => Matrix.of(widget.outerContext) .client .startDirectChat(user?.id ?? widget.profile!.userId), ); if (roomIdResult.error != null) return; widget.outerContext.go('/rooms/${roomIdResult.result!}'); - Navigator.of(context, rootNavigator: false).pop(); + Navigator.of(context, rootNavigator: false) + ..pop() + ..pop(); + widget.outerContext.go('/rooms/${roomIdResult.result!}'); break; case UserBottomSheetAction.ignore: - if (await askConfirmation()) { - await showFutureLoadingDialog( - context: context, - future: () => Matrix.of(context) - .client - .ignoreUser(user?.id ?? widget.profile!.userId), - ); - } + context.go('/rooms/settings/security/ignorelist'); } } diff --git a/lib/pages/user_bottom_sheet/user_bottom_sheet_view.dart b/lib/pages/user_bottom_sheet/user_bottom_sheet_view.dart index 1926193d7..bdb1d945e 100644 --- a/lib/pages/user_bottom_sheet/user_bottom_sheet_view.dart +++ b/lib/pages/user_bottom_sheet/user_bottom_sheet_view.dart @@ -3,15 +3,17 @@ import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:matrix/matrix.dart'; +import 'package:fluffychat/utils/date_time_extension.dart'; import 'package:fluffychat/utils/fluffy_share.dart'; import 'package:fluffychat/widgets/avatar.dart'; +import 'package:fluffychat/widgets/presence_builder.dart'; import '../../widgets/matrix.dart'; import 'user_bottom_sheet.dart'; class UserBottomSheetView extends StatelessWidget { final UserBottomSheetController controller; - const UserBottomSheetView(this.controller, {Key? key}) : super(key: key); + const UserBottomSheetView(this.controller, {super.key}); @override Widget build(BuildContext context) { @@ -30,7 +32,60 @@ class UserBottomSheetView extends StatelessWidget { leading: CloseButton( onPressed: Navigator.of(context, rootNavigator: false).pop, ), - title: Text(displayname.trim().split(' ').first), + title: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(displayname), + PresenceBuilder( + userId: userId, + client: client, + builder: (context, presence) { + if (presence == null || + (presence.presence == PresenceType.offline && + presence.lastActiveTimestamp == null)) { + return const SizedBox.shrink(); + } + + final dotColor = presence.presence.isOnline + ? Colors.green + : presence.presence.isUnavailable + ? Colors.red + : Colors.grey; + + final lastActiveTimestamp = presence.lastActiveTimestamp; + + return Row( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + width: 8, + height: 8, + margin: const EdgeInsets.only(right: 8), + decoration: BoxDecoration( + color: dotColor, + borderRadius: BorderRadius.circular(16), + ), + ), + if (presence.currentlyActive == true) + Text( + L10n.of(context)!.currentlyActive, + overflow: TextOverflow.ellipsis, + style: Theme.of(context).textTheme.bodySmall, + ) + else if (lastActiveTimestamp != null) + Text( + L10n.of(context)!.lastActiveAgo( + lastActiveTimestamp.localizedTimeShort(context), + ), + overflow: TextOverflow.ellipsis, + style: Theme.of(context).textTheme.bodySmall, + ), + ], + ); + }, + ), + ], + ), actions: [ if (userId != client.userID && !client.ignoredUsers.contains(userId)) diff --git a/lib/pangea/choreographer/controllers/alternative_translator.dart b/lib/pangea/choreographer/controllers/alternative_translator.dart new file mode 100644 index 000000000..4221a3479 --- /dev/null +++ b/lib/pangea/choreographer/controllers/alternative_translator.dart @@ -0,0 +1,198 @@ +import 'dart:developer'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:http/http.dart' as http; + +import 'package:fluffychat/pangea/choreographer/controllers/choreographer.dart'; +import 'package:fluffychat/pangea/choreographer/controllers/error_service.dart'; +import 'package:fluffychat/pangea/repo/full_text_translation_repo.dart'; +import 'package:fluffychat/pangea/utils/error_handler.dart'; +import '../../repo/similarity_repo.dart'; + +class AlternativeTranslator { + final Choreographer choreographer; + bool showAlternativeTranslations = false; + bool loadingAlternativeTranslations = false; + bool showTranslationFeedback = false; + String? userTranslation; + FeedbackKey? translationFeedbackKey; + List translations = []; + SimilartyResponseModel? similarityResponse; + + AlternativeTranslator(this.choreographer); + + void clear() { + userTranslation = null; + showAlternativeTranslations = false; + loadingAlternativeTranslations = false; + showTranslationFeedback = false; + translationFeedbackKey = null; + translations = []; + similarityResponse = null; + } + + // void onSeeAlternativeTranslationsTap() { + // if (choreographer.itController.sourceText == null) { + // ErrorHandler.logError( + // m: "sourceText null in onSeeAlternativeTranslationsTap", + // s: StackTrace.current, + // ); + // choreographer.itController.closeIT(); + // return; + // } + // showAlternativeTranslations = true; + // loadingAlternativeTranslations = true; + // translate(choreographer.itController.sourceText!); + // choreographer.setState(); + // } + + // Future translate(String text) async { + // throw Exception('disabled translaations'); + // try { + // final FullTextTranslationResponseModel results = + // await FullTextTranslationRepo.translate( + // accessToken: await choreographer.accessToken, + // request: FullTextTranslationRequestModel( + // text: text, + // tgtLang: choreographer.l2LangCode!, + // userL2: choreographer.l2LangCode!, + // userL1: choreographer.l1LangCode!, + // ), + // ); + // // translations = results.translations; + // } catch (err, stack) { + // showAlternativeTranslations = false; + // debugger(when: kDebugMode); + // ErrorHandler.logError(e: err, s: stack); + // } finally { + // loadingAlternativeTranslations = false; + // choreographer.setState(); + // } + // } + + Future setTranslationFeedback() async { + try { + choreographer.startLoading(); + translationFeedbackKey = FeedbackKey.loadingPleaseWait; + + showTranslationFeedback = true; + + userTranslation = choreographer.currentText; + + if (choreographer.itController.allCorrect) { + translationFeedbackKey = FeedbackKey.allCorrect; + return; + } + + final String? goldRouteTranslation = + choreographer.itController.goldRouteTracker.fullTranslation; + + final FullTextTranslationResponseModel results = + await FullTextTranslationRepo.translate( + accessToken: await choreographer.accessToken, + request: FullTextTranslationRequestModel( + text: choreographer.itController.sourceText!, + tgtLang: choreographer.l2LangCode!, + userL2: choreographer.l2LangCode!, + userL1: choreographer.l1LangCode!, + deepL: goldRouteTranslation == null, + ), + ); + translations = results.translations; + if (results.deepL != null || goldRouteTranslation != null) { + translations.insert(0, (results.deepL ?? goldRouteTranslation)!); + } + // final List altAndUser = [...results.translations]; + // if (results.deepL != null) { + // altAndUser.add(results.deepL!); + // } + // altAndUser.add(userTranslation); + + if (userTranslation?.toLowerCase() == + results.bestTranslation.toLowerCase()) { + translationFeedbackKey = FeedbackKey.allCorrect; + return; + } + + similarityResponse = await SimilarityRepo.get( + accessToken: await choreographer.accessToken, + request: SimilarityRequestModel( + benchmark: results.bestTranslation, + toCompare: [userTranslation!], + ), + ); + + // if (similarityResponse! + // .userTranslationIsSameAsBotTranslation(userTranslation!)) { + // translationFeedbackKey = FeedbackKey.allCorrect; + // return; + // } + + // if (similarityResponse! + // .userTranslationIsDifferentButBetter(userTranslation!)) { + // translationFeedbackKey = FeedbackKey.newWayAllGood; + // return; + // } + showAlternativeTranslations = true; + translationFeedbackKey = FeedbackKey.othersAreBetter; + } catch (err, stack) { + if (err is! http.Response) { + ErrorHandler.logError(e: err, s: stack); + } + choreographer.errorService.setError( + ChoreoError(type: ChoreoErrorType.unknown, raw: err), + ); + } finally { + choreographer.stopLoading(); + } + } + + String translationFeedback(BuildContext context) { + if (L10n.of(context) == null) { + debugger(when: kDebugMode); + } + switch (translationFeedbackKey) { + case FeedbackKey.allCorrect: + return "Score: 100%\n${L10n.of(context)!.allCorrect}"; + case FeedbackKey.newWayAllGood: + return "Score: 100%\n${L10n.of(context)!.newWayAllGood}"; + case FeedbackKey.othersAreBetter: + final num userScore = + (similarityResponse!.userScore(userTranslation!) * 100).round(); + final String displayScore = userScore.toString(); + if (userScore > 90) { + return "Score: $displayScore%\n${L10n.of(context)!.almostPerfect}"; + } + if (userScore > 80) { + return "Score: $displayScore%\n${L10n.of(context)!.prettyGood}"; + } + return "Score: $displayScore%\n${L10n.of(context)!.othersAreBetter}"; + // case FeedbackKey.commonalityFeedback: + // final int count = controller.completedITSteps + // .where((element) => element.isCorrect) + // .toList() + // .length; + // final int total = controller.completedITSteps.length; + // return L10n.of(context)!.commonalityFeedback(count,total); + case FeedbackKey.loadingPleaseWait: + return L10n.of(context)!.letMeThink; + case FeedbackKey.allDone: + return L10n.of(context)!.allDone; + default: + return L10n.of(context)!.loadingPleaseWait; + } + } +} + +enum FeedbackKey { + allCorrect, + newWayAllGood, + othersAreBetter, + loadingPleaseWait, + allDone, +} + +extension FeedbackKeyExtension on FeedbackKey {} diff --git a/lib/pangea/choreographer/controllers/analytics_sender.dart b/lib/pangea/choreographer/controllers/analytics_sender.dart new file mode 100644 index 000000000..fe4575f38 --- /dev/null +++ b/lib/pangea/choreographer/controllers/analytics_sender.dart @@ -0,0 +1,24 @@ +import 'package:fluffychat/pangea/choreographer/controllers/it_controller.dart'; + +class MlController { + final ITController controller; + MlController(this.controller); + + // sendPayloads(String message, String messageId) async { + // final MessageServiceModel serviceModel = MessageServiceModel( + // classId: controller.state!.classId, + // roomId: controller.state!.roomId, + // message: message.toString(), + // messageId: messageId.toString(), + // payloadIds: controller.state!.payLoadIds, + // userId: controller.state!.userId!, + // l1Lang: controller.state!.sourceLangCode, + // l2Lang: controller.state!.targetLangCode!, + // ); + // try { + // await MessageServiceRepo.sendPayloads(serviceModel); + // } catch (err) { + // debugPrint('$err in sendPayloads'); + // } + // } +} diff --git a/lib/pangea/choreographer/controllers/choreographer.dart b/lib/pangea/choreographer/controllers/choreographer.dart new file mode 100644 index 000000000..c45a42ab0 --- /dev/null +++ b/lib/pangea/choreographer/controllers/choreographer.dart @@ -0,0 +1,529 @@ +import 'dart:async'; +import 'dart:developer'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + +import 'package:sentry_flutter/sentry_flutter.dart'; + +import 'package:fluffychat/pages/chat/chat.dart'; +import 'package:fluffychat/pangea/choreographer/controllers/alternative_translator.dart'; +import 'package:fluffychat/pangea/choreographer/controllers/igc_controller.dart'; +import 'package:fluffychat/pangea/choreographer/controllers/message_options.dart'; +import 'package:fluffychat/pangea/constants/language_keys.dart'; +import 'package:fluffychat/pangea/constants/pangea_event_types.dart'; +import 'package:fluffychat/pangea/controllers/pangea_controller.dart'; +import 'package:fluffychat/pangea/enum/edit_type.dart'; +import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart'; +import 'package:fluffychat/pangea/models/class_model.dart'; +import 'package:fluffychat/pangea/models/it_step.dart'; +import 'package:fluffychat/pangea/models/message_data_models.dart'; +import 'package:fluffychat/pangea/models/widget_measurement.dart'; +import 'package:fluffychat/pangea/utils/any_state_holder.dart'; +import 'package:fluffychat/pangea/utils/error_handler.dart'; +import '../../../widgets/matrix.dart'; +import '../../enum/use_type.dart'; +import '../../models/choreo_record.dart'; +import '../../models/language_model.dart'; +import '../../models/pangea_match_model.dart'; +import '../../widgets/igc/pangea_text_controller.dart'; +import 'error_service.dart'; +import 'it_controller.dart'; + +enum ChoreoMode { igc, it } + +class Choreographer { + PangeaController pangeaController; + ChatController chatController; + late PangeaTextController _textController; + late ITController itController; + late IgcController igc; + late MessageOptions messageOptions; + late AlternativeTranslator altTranslator; + late ErrorService errorService; + + bool isFetching = false; + Timer? debounceTimer; + String? _roomId; + ChoreoRecord choreoRecord = ChoreoRecord.newRecord; + // last checked by IGC or translation + String? _lastChecked; + ChoreoMode choreoMode = ChoreoMode.igc; + final StreamController stateListener = StreamController(); + + bool toldToPay = false; + + Choreographer(this.pangeaController, this.chatController) { + _initialize(); + } + _initialize() { + _textController = PangeaTextController(choreographer: this); + itController = ITController(this); + igc = IgcController(this); + messageOptions = MessageOptions(this); + errorService = ErrorService(this); + altTranslator = AlternativeTranslator(this); + _textController.addListener(_onChangeListener); + + clear(); + } + + void send(BuildContext context) { + if (isFetching) return; + + if (!pangeaController.subscriptionController.isSubscribed && !toldToPay) { + toldToPay = true; + pangeaController.subscriptionController.showPaywall(context); + return; + } + + if (!igc.hasRelevantIGCTextData) { + getLanguageHelp().then((value) => _sendWithIGC(context)); + } else { + _sendWithIGC(context); + } + } + + void _sendWithIGC(BuildContext context) { + if (igc.canSendMessage) { + final PangeaRepresentation? originalWritten = + choreoRecord.includedIT && itController.sourceText != null + ? PangeaRepresentation( + langCode: l1LangCode ?? LanguageKeys.unknownLanguage, + text: itController.sourceText!, + originalWritten: true, + originalSent: false, + ) + : null; + + // PTODO - just put this in original message event + final PangeaRepresentation originalSent = PangeaRepresentation( + langCode: langCodeOfCurrentText ?? LanguageKeys.unknownLanguage, + text: currentText, + originalSent: true, + originalWritten: originalWritten == null, + ); + final ChoreoRecord? applicableChoreo = + isITandIGCEnabled && igc.igcTextData != null ? choreoRecord : null; + + final UseType useType = useTypeCalculator(applicableChoreo); + debugPrint("use type in choreographer $useType"); + + chatController.send( + // PTODO - turn this back on in conjunction with saving tokens + // we need to save those tokens as well, in order for exchanges to work + // properly. in an exchange, the other user will want + // originalWritten: originalWritten, + originalSent: originalSent, + tokensSent: igc.igcTextData?.tokens != null + ? PangeaMessageTokens(tokens: igc.igcTextData!.tokens) + : null, + //TODO - save originalwritten tokens + choreo: applicableChoreo, + useType: useType, + ); + + clear(); + } else { + igc.showFirstMatch(context); + } + } + + _resetDebounceTimer() { + if (debounceTimer != null) { + debounceTimer!.cancel(); + debounceTimer = null; + } + } + + void onITStart(PangeaMatch itMatch) { + if (!itMatch.isITStart) { + throw Exception("this isn't an itStart match!"); + } + choreoMode = ChoreoMode.it; + itController.initializeIT( + ITStartData(_textController.text, igc.detectedLangCode), + ); + itMatch.status = PangeaMatchStatus.accepted; + + choreoRecord.addRecord(_textController.text, match: itMatch); + + //PTODO - if totally in L1, save tokens, that's good stuff + + igc.clear(); + + _textController.setSystemText("", EditType.itStart); + } + + _onChangeListener() { + if (_noChange) { + return; + } + + if ([ + EditType.igc, + ].contains(_textController.editType)) { + igc.justGetTokensAndAddThemToIGCTextData(); + textController.editType = EditType.keyboard; + return; + } + + MatrixState.pAnyState.closeOverlay(); + + if (errorService.isError) { + return; + } + + // if (igc.igcTextData != null) { + igc.clear(); + // setState(); + // } + + _resetDebounceTimer(); + + if (editTypeIsKeyboard) { + debounceTimer ??= Timer( + const Duration(milliseconds: 1500), + () => getLanguageHelp(), + ); + } else { + getLanguageHelp(ChoreoMode.it == choreoMode); + } + + //Note: we don't set the keyboard type on each keyboard stroke so this is how we default to + //a change being from the keyboard unless explicitly set to one of the other + //types when that action happens (e.g. an it/igc choice is selected) + textController.editType = EditType.keyboard; + } + + Future getLanguageHelp([bool tokensOnly = false]) async { + try { + if (errorService.isError) return; + if (!pangeaController.subscriptionController.isSubscribed && + pangeaController.subscriptionController.initialized) { + debugPrint('setting not subscribed error'); + errorService.setErrorAndLock( + ChoreoError( + type: ChoreoErrorType.unsubscribed, + ), + ); + return; + } + startLoading(); + if (choreoMode == ChoreoMode.it && + itController.isTranslationDone && + !tokensOnly) { + debugger(when: kDebugMode); + } + await (choreoMode == ChoreoMode.it && !itController.isTranslationDone + ? itController.getTranslationData(_useCustomInput) + : igc.getIGCTextData(tokensOnly: tokensOnly)); + } catch (err, stack) { + ErrorHandler.logError(e: err, s: stack); + } finally { + stopLoading(); + } + } + + void onITChoiceSelect(ITStep step) { + choreoRecord.addRecord(_textController.text, step: step); + _textController.setSystemText( + _textController.text + step.continuances[step.chosen!].text, + step.continuances[step.chosen!].gold + ? EditType.itGold + : EditType.itStandard, + ); + _textController.selection = + TextSelection.collapsed(offset: _textController.text.length); + giveInputFocus(); + } + + Future onReplacementSelect({ + required int matchIndex, + required int choiceIndex, + }) async { + try { + if (igc.igcTextData == null) { + ErrorHandler.logError( + e: "onReplacementSelect with null igcTextData", + s: StackTrace.current, + ); + MatrixState.pAnyState.closeOverlay(); + } + if (igc.igcTextData!.matches[matchIndex].match.choices == null) { + ErrorHandler.logError( + e: "onReplacementSelect with null choices", + s: StackTrace.current, + ); + MatrixState.pAnyState.closeOverlay(); + } + + //if it's the wrong choice, return + // if (!igc.igcTextData!.matches[matchIndex].match.choices![choiceIndex] + // .selected) { + // igc.igcTextData!.matches[matchIndex].match.choices![choiceIndex] + // .selected = true; + // setState(); + // return; + // } + + igc.igcTextData!.matches[matchIndex].match.choices![choiceIndex] + .selected = true; + + //if it's the right choice, replace in text + choreoRecord.addRecord( + _textController.text, + match: igc.igcTextData!.matches[matchIndex].copyWith + ..status = PangeaMatchStatus.accepted, + ); + + igc.igcTextData!.acceptReplacement( + matchIndex, + choiceIndex, + ); + + _textController.setSystemText( + igc.igcTextData!.originalInput, + EditType.igc, + ); + + MatrixState.pAnyState.closeOverlay(); + setState(); + } catch (err, stack) { + debugger(when: kDebugMode); + Sentry.addBreadcrumb( + Breadcrumb.fromJson( + { + "igctextDdata": igc.igcTextData?.toJson(), + "matchIndex": matchIndex, + "choiceIndex": choiceIndex, + }, + ), + ); + ErrorHandler.logError(e: err, s: stack); + igc.igcTextData?.matches.clear(); + } finally { + giveInputFocus(); + setState(); + } + } + + void onIgnoreMatch({required int cursorOffset}) { + try { + if (igc.igcTextData == null) { + debugger(when: kDebugMode); + ErrorHandler.logError( + m: "should not be in onIgnoreMatch with null igcTextData", + s: StackTrace.current, + ); + return; + } + + final int matchIndex = igc.igcTextData!.getTopMatchIndexForOffset( + cursorOffset, + ); + + if (matchIndex == -1) { + debugger(when: kDebugMode); + throw Exception("Cannnot find the ignored match in igcTextData"); + } + + igc.igcTextData!.matches[matchIndex].status = PangeaMatchStatus.ignored; + choreoRecord.addRecord( + _textController.text, + match: igc.igcTextData!.matches[matchIndex], + ); + + igc.igcTextData!.matches.removeAt(matchIndex); + } catch (err, stack) { + debugger(when: kDebugMode); + Sentry.addBreadcrumb( + Breadcrumb.fromJson( + {"igcTextData": igc.igcTextData?.toJson(), "offset": cursorOffset}, + ), + ); + ErrorHandler.logError( + e: err, + s: stack, + ); + igc.igcTextData?.matches.clear(); + } finally { + setState(); + giveInputFocus(); + } + } + + void onSelectAlternativeTranslation(String translation) { + // PTODO - add some kind of record of this + // choreoRecord.addRecord(_textController.text, match); + + _textController.setSystemText( + translation, + EditType.alternativeTranslation, + ); + altTranslator.clear(); + altTranslator.translationFeedbackKey = FeedbackKey.allDone; + altTranslator.showTranslationFeedback = true; + giveInputFocus(); + setState(); + } + + giveInputFocus() { + Future.delayed(Duration.zero, () { + chatController.inputFocus.requestFocus(); + }); + } + + String get currentText => _textController.text; + + PangeaTextController get textController => _textController; + + Future get accessToken => pangeaController.userController.accessToken; + + clear() { + choreoMode = ChoreoMode.igc; + _lastChecked = null; + isFetching = false; + choreoRecord = ChoreoRecord.newRecord; + itController.clear(); + igc.clear(); + // errorService.clear(); + _resetDebounceTimer(); + } + + void onMatchError({int? cursorOffset}) { + if (cursorOffset == null) { + igc.igcTextData?.matches.clear(); + } else { + final int? matchIndex = igc.igcTextData?.getTopMatchIndexForOffset( + cursorOffset, + ); + matchIndex == -1 || matchIndex == null + ? igc.igcTextData?.matches.clear() + : igc.igcTextData?.matches.removeAt(matchIndex); + } + + setState(); + giveInputFocus(); + } + + dispose() { + _textController.dispose(); + } + + LanguageModel? get l2Lang { + return pangeaController.languageController.activeL2Model( + roomID: roomId, + ); + } + + String? get l2LangCode => l2Lang?.langCode; + + LanguageModel? get l1Lang => + pangeaController.languageController.activeL1Model( + roomID: roomId, + ); + String? get l1LangCode => l1Lang?.langCode; + + String? get classId => roomId != null + ? pangeaController.matrixState.client + .getRoomById(roomId) + ?.firstParentWithState(PangeaEventTypes.classSettings) + ?.id + : null; + + String? get userId => pangeaController.userController.userId; + + bool get _noChange => + _lastChecked != null && _lastChecked == _textController.text; + + void startLoading() { + _lastChecked = _textController.text; + isFetching = true; + setState(); + } + + void stopLoading() { + isFetching = false; + setState(); + } + + get roomId => _roomId; + void setRoomId(String? roomId) { + _roomId = roomId ?? ''; + } + + bool get _useCustomInput => [ + EditType.keyboard, + EditType.igc, + EditType.alternativeTranslation, + ].contains(_textController.editType); + + bool get editTypeIsKeyboard => EditType.keyboard == _textController.editType; + + String? get langCodeOfCurrentText { + if (igc.detectedLangCode != null) return igc.detectedLangCode!; + + if (itController.isOpen) return l2LangCode!; + + return null; + } + + setState() { + if (!stateListener.isClosed) { + stateListener.add(0); + } + } + + WidgetMeasurements get inputBarSize => _textController.measurements!; + + bool get showIsError => !itController.isOpen && errorService.isError; + + LayerLinkAndKey get itBarLinkAndKey => + MatrixState.pAnyState.layerLinkAndKey(itBarTransformTargetKey); + + String get itBarTransformTargetKey => 'it_bar$roomId'; + + LayerLinkAndKey get inputLayerLinkAndKey => + MatrixState.pAnyState.layerLinkAndKey(inputTransformTargetKey); + + String get inputTransformTargetKey => 'input$roomId'; + + LayerLinkAndKey get itBotLayerLinkAndKey => + MatrixState.pAnyState.layerLinkAndKey(itBotTransformTargetKey); + + String get itBotTransformTargetKey => 'itBot$roomId'; + + bool get igcEnabled => pangeaController.permissionsController.isToolEnabled( + ToolSetting.interactiveGrammar, + chatController.room, + ); + + bool get itEnabled => pangeaController.permissionsController.isToolEnabled( + ToolSetting.interactiveTranslator, + chatController.room, + ); + + bool get definitionsEnabled => + pangeaController.permissionsController.isToolEnabled( + ToolSetting.definitions, + chatController.room, + ); + + bool get immersionMode => + pangeaController.permissionsController.isToolEnabled( + ToolSetting.immersionMode, + chatController.room, + ); + + bool get translationEnabled => + pangeaController.permissionsController.isToolEnabled( + ToolSetting.translations, + chatController.room, + ); + + bool get isITandIGCEnabled => + pangeaController.permissionsController.isWritingAssistanceEnabled( + chatController.room, + ); +} diff --git a/lib/pangea/choreographer/controllers/error_service.dart b/lib/pangea/choreographer/controllers/error_service.dart new file mode 100644 index 000000000..8ec044244 --- /dev/null +++ b/lib/pangea/choreographer/controllers/error_service.dart @@ -0,0 +1,101 @@ +import 'package:flutter/material.dart'; + +import 'package:fluffychat/pangea/choreographer/controllers/choreographer.dart'; +import '../../utils/error_handler.dart'; + +enum ChoreoErrorType { + unknown, + classDisabled, + userDisabled, + unsubscribed, +} + +class ChoreoError { + final ChoreoErrorType type; + final Object? raw; + + ChoreoError({required this.type, this.raw}); + + String title(BuildContext context) { + switch (type) { + case ChoreoErrorType.classDisabled: + return "Class Disabled"; + case ChoreoErrorType.userDisabled: + return "User Disabled"; + case ChoreoErrorType.unsubscribed: + return "Unsubscribed"; + default: + return ErrorCopy(context, raw).title; + } + } + + String description(BuildContext context) { + switch (type) { + case ChoreoErrorType.classDisabled: + return "Class Disabled"; + case ChoreoErrorType.userDisabled: + return "User Disabled"; + case ChoreoErrorType.unsubscribed: + return "Unsubscribed"; + default: + return ErrorCopy(context, raw).body; + } + } + + IconData get icon { + switch (type) { + case ChoreoErrorType.classDisabled: + return Icons.history_edu_outlined; + case ChoreoErrorType.userDisabled: + return Icons.history_edu_outlined; + case ChoreoErrorType.unsubscribed: + return Icons.lock_outline; + default: + return Icons.error_outline; + } + } +} + +class ErrorService { + ChoreoError? _error; + int coolDownSeconds = 0; + final Choreographer controller; + + ErrorService(this.controller); + + bool get isError => _error != null; + + ChoreoError? get error => _error; + + Duration get defaultCooldown { + coolDownSeconds += 3; + return Duration(seconds: coolDownSeconds); + } + + setError(ChoreoError? error, {Duration? duration}) { + _error = error; + Future.delayed(duration ?? defaultCooldown, () { + clear(); + _setState(); + }); + _setState(); + } + + setErrorAndLock(ChoreoError? error) { + _error = error; + _setState(); + } + + resetError() { + clear(); + _setState(); + } + + void _setState() { + controller.setState(); + } + + void clear() { + _error = null; + } +} diff --git a/lib/pangea/choreographer/controllers/igc_controller.dart b/lib/pangea/choreographer/controllers/igc_controller.dart new file mode 100644 index 000000000..ebe4522b7 --- /dev/null +++ b/lib/pangea/choreographer/controllers/igc_controller.dart @@ -0,0 +1,238 @@ +import 'dart:async'; +import 'dart:developer'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + +import 'package:sentry_flutter/sentry_flutter.dart'; + +import 'package:fluffychat/pangea/choreographer/controllers/choreographer.dart'; +import 'package:fluffychat/pangea/choreographer/controllers/error_service.dart'; +import 'package:fluffychat/pangea/models/igc_text_data_model.dart'; +import 'package:fluffychat/pangea/models/pangea_match_model.dart'; +import 'package:fluffychat/pangea/models/span_data.dart'; +import 'package:fluffychat/pangea/repo/igc_repo.dart'; +import 'package:fluffychat/pangea/widgets/igc/span_card.dart'; +import '../../../widgets/matrix.dart'; +import '../../models/language_detection_model.dart'; +import '../../models/span_card_model.dart'; +import '../../repo/span_data_repo.dart'; +import '../../repo/tokens_repo.dart'; +import '../../utils/error_handler.dart'; +import '../../utils/overlay.dart'; + +class IgcController { + Choreographer choreographer; + IGCTextData? igcTextData; + Object? igcError; + + Completer igcCompleter = Completer(); + + IgcController(this.choreographer); + + Future getIGCTextData({required bool tokensOnly}) async { + try { + if (choreographer.currentText.isEmpty) return clear(); + + debugPrint('getIGCTextData called with ${choreographer.currentText}'); + + debugPrint('getIGCTextData called with tokensOnly = $tokensOnly'); + + final IGCRequestBody reqBody = IGCRequestBody( + fullText: choreographer.currentText, + userL1: choreographer.l1LangCode!, + userL2: choreographer.l2LangCode!, + enableIGC: choreographer.igcEnabled && !tokensOnly, + enableIT: choreographer.itEnabled && !tokensOnly, + tokensOnly: tokensOnly, + ); + + final IGCTextData igcTextDataResponse = await IgcRepo.getIGC( + await choreographer.accessToken, + igcRequest: reqBody, + ); + // temp fix + igcTextDataResponse.originalInput = reqBody.fullText; + + //this will happen when the user changes the input while igc is fetching results + if (igcTextDataResponse.originalInput != choreographer.currentText) { + // final current = choreographer.currentText; + // final igctext = igcTextDataResponse.originalInput; + // Sentry.addBreadcrumb( + // Breadcrumb(message: "igc return input does not match current text"), + // ); + // debugger(when: kDebugMode); + return; + } + + //TO-DO: in api call, specify turning off IT and/or grammar checking + if (!choreographer.igcEnabled) { + igcTextDataResponse.matches = igcTextDataResponse.matches + .where((match) => !match.isGrammarMatch) + .toList(); + } + if (!choreographer.itEnabled) { + igcTextDataResponse.matches = igcTextDataResponse.matches + .where((match) => !match.isOutOfTargetMatch) + .toList(); + } + if (!choreographer.itEnabled && !choreographer.igcEnabled) { + igcTextDataResponse.matches = []; + } + + igcTextData = igcTextDataResponse; + + debugPrint("igc text ${igcTextData.toString()}"); + } catch (err, stack) { + debugger(when: kDebugMode); + choreographer.errorService.setError( + ChoreoError(type: ChoreoErrorType.unknown, raw: err), + ); + ErrorHandler.logError(e: err, s: stack); + clear(); + } + } + + Future getSpanDetails(int matchIndex) async { + if (igcTextData == null || + igcTextData!.matches.isEmpty || + matchIndex < 0 || + matchIndex >= igcTextData!.matches.length) { + debugger(when: kDebugMode); + return; + } + final SpanData span = igcTextData!.matches[matchIndex].match; + + final SpanDetailsRepoReqAndRes response = await SpanDataRepo.getSpanDetails( + await choreographer.accessToken, + request: SpanDetailsRepoReqAndRes( + userL1: choreographer.l1LangCode!, + userL2: choreographer.l2LangCode!, + enableIGC: choreographer.igcEnabled, + enableIT: choreographer.itEnabled, + span: span, + ), + ); + + igcTextData!.matches[matchIndex].match = response.span; + + choreographer.setState(); + } + + Future justGetTokensAndAddThemToIGCTextData() async { + try { + if (igcTextData == null) { + debugger(when: kDebugMode); + choreographer.getLanguageHelp(); + return; + } + igcTextData!.loading = true; + choreographer.startLoading(); + if (igcTextData!.originalInput != choreographer.textController.text) { + debugger(when: kDebugMode); + ErrorHandler.logError( + m: "igcTextData fullText does not match current text", + s: StackTrace.current, + data: igcTextData!.toJson(), + ); + } + final TokensResponseModel res = await TokensRepo.tokenize( + await choreographer.pangeaController.userController.accessToken, + TokensRequestModel( + fullText: igcTextData!.originalInput, + userL1: choreographer.l1LangCode!, + userL2: choreographer.l2LangCode!, + ), + ); + igcTextData?.tokens = res.tokens; + } catch (err, stack) { + debugger(when: kDebugMode); + choreographer.errorService.setError( + ChoreoError(type: ChoreoErrorType.unknown, raw: err), + ); + Sentry.addBreadcrumb( + Breadcrumb.fromJson({"igctextDdata": igcTextData?.toJson()}), + ); + ErrorHandler.logError(e: err, s: stack); + } finally { + igcTextData!.loading = false; + choreographer.stopLoading(); + } + } + + void showFirstMatch(BuildContext context) { + if (igcTextData == null || igcTextData!.matches.isEmpty) { + debugger(when: kDebugMode); + ErrorHandler.logError( + m: "should not be calling showFirstMatch with this igcTextData ${igcTextData?.toJson().toString()}", + s: StackTrace.current, + ); + return; + } + + const int firstMatchIndex = 0; + final PangeaMatch match = igcTextData!.matches[firstMatchIndex]; + + OverlayUtil.showPositionedCard( + context: context, + cardToShow: SpanCard( + scm: SpanCardModel( + matchIndex: firstMatchIndex, + onReplacementSelect: choreographer.onReplacementSelect, + onSentenceRewrite: (value) async {}, + onIgnore: () => choreographer.onIgnoreMatch( + cursorOffset: match.match.offset, + ), + onITStart: () { + if (choreographer.itEnabled) { + choreographer.onITStart(igcTextData!.matches[firstMatchIndex]); + } + }, + choreographer: choreographer, + ), + roomId: choreographer.roomId, + ), + cardSize: match.isITStart ? const Size(350, 220) : const Size(350, 400), + transformTargetId: choreographer.inputTransformTargetKey, + ); + } + + bool get hasRelevantIGCTextData { + if (igcTextData == null) return false; + + if (igcTextData!.originalInput != choreographer.currentText) { + debugPrint( + "returning isIGCTextDataRelevant false because text has changed", + ); + return false; + } + return true; + } + + String? get detectedLangCode { + if (!hasRelevantIGCTextData) return null; + + final LanguageDetection first = igcTextData!.detections.first; + + return first.langCode; + } + + clear() { + igcTextData = null; + MatrixState.pAnyState.closeOverlay(); + } + + bool get canSendMessage { + if (choreographer.isFetching) return false; + if (igcTextData == null || + choreographer.errorService.isError || + igcTextData!.matches.isEmpty) { + return true; + } + + return !((choreographer.itEnabled && + igcTextData!.matches.any((match) => match.isOutOfTargetMatch)) || + (choreographer.igcEnabled && + igcTextData!.matches.any((match) => !match.isOutOfTargetMatch))); + } +} diff --git a/lib/pangea/choreographer/controllers/it_controller.dart b/lib/pangea/choreographer/controllers/it_controller.dart new file mode 100644 index 000000000..da6a9b2a3 --- /dev/null +++ b/lib/pangea/choreographer/controllers/it_controller.dart @@ -0,0 +1,435 @@ +import 'dart:async'; +import 'dart:developer'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + +import 'package:http/http.dart' as http; +import 'package:sentry_flutter/sentry_flutter.dart'; + +import 'package:fluffychat/pangea/choreographer/controllers/error_service.dart'; +import 'package:fluffychat/pangea/constants/choreo_constants.dart'; +import 'package:fluffychat/pangea/repo/full_text_translation_repo.dart'; +import 'package:fluffychat/pangea/utils/error_handler.dart'; +import '../../models/custom_input_translation_model.dart'; +import '../../models/it_response_model.dart'; +import '../../models/it_step.dart'; +import '../../models/system_choice_translation_model.dart'; +import '../../repo/interactive_translation_repo.dart'; +import '../../repo/message_service.repo.dart'; +import 'choreographer.dart'; + +class ITController { + Choreographer choreographer; + + bool _isOpen = false; + bool _isEditingSourceText = false; + bool showChoiceFeedback = false; + + ITStartData? _itStartData; + String? sourceText; + List completedITSteps = []; + CurrentITStep? currentITStep; + GoldRouteTracker goldRouteTracker = GoldRouteTracker.defaultTracker; + List payLoadIds = []; + + ITController(this.choreographer); + + void clear() { + _isOpen = false; + showChoiceFeedback = false; + _isEditingSourceText = false; + + _itStartData = null; + sourceText = null; + completedITSteps = []; + currentITStep = null; + goldRouteTracker = GoldRouteTracker.defaultTracker; + payLoadIds = []; + + choreographer.altTranslator.clear(); + choreographer.errorService.resetError(); + choreographer.choreoMode = ChoreoMode.igc; + choreographer.setState(); + } + + Future initializeIT(ITStartData itStartData) async { + Future.delayed(const Duration(microseconds: 100), () { + _isOpen = true; + }); + _itStartData = itStartData; + } + + void closeIT() { + //if they close it before choosing anything, just put their text back + //PTODO - explore using last itStep + if (choreographer.currentText.isEmpty) { + choreographer.textController.text = sourceText ?? ""; + } + clear(); + } + + /// if IGC isn't positive that text is full L1 then translate to L1 + Future _setSourceText() async { + // try { + if (_itStartData == null || _itStartData!.text.isEmpty) { + Sentry.addBreadcrumb( + Breadcrumb( + message: "choreo context", + data: { + "igcTextData": choreographer.igc.igcTextData?.toJson(), + "currentText": choreographer.currentText, + }, + ), + ); + throw Exception("null _itStartData or empty text in _setSourceText"); + } + debugPrint("_setSourceText with detectedLang ${_itStartData!.langCode}"); + if (_itStartData!.langCode == choreographer.l1LangCode) { + sourceText = _itStartData!.text; + return; + } + + final FullTextTranslationResponseModel res = + await FullTextTranslationRepo.translate( + accessToken: await choreographer.accessToken, + request: FullTextTranslationRequestModel( + text: _itStartData!.text, + tgtLang: choreographer.l1LangCode!, + srcLang: choreographer.l2LangCode, + userL1: choreographer.l1LangCode!, + userL2: choreographer.l2LangCode!, + ), + ); + sourceText = res.bestTranslation; + // } catch (err, stack) { + // debugger(when: kDebugMode); + // if (_itStartData?.text.isNotEmpty ?? false) { + // ErrorHandler.logError(e: err, s: stack); + // sourceText = _itStartData!.text; + // } else { + // rethrow; + // } + // } + } + + // used 1) at very beginning (with custom input = null) + // and 2) if they make direct edits to the text field + Future getTranslationData(bool useCustomInput) async { + try { + choreographer.startLoading(); + + final String currentText = choreographer.currentText; + final String? translationId = currentITStep?.translationId; + + if (sourceText == null) await _setSourceText(); + + if (useCustomInput && currentITStep != null) { + completedITSteps.add( + ITStep( + currentITStep!.continuances, + customInput: currentText, + ), + ); + } + + currentITStep = null; + + final ITResponseModel res = await (useCustomInput || + currentText.isEmpty || + translationId == null || + completedITSteps.last.chosenContinuance?.indexSavedByServer == + null + ? _customInputTranslation(currentText) + : _systemChoiceTranslation(translationId)); + + if (res.goldContinuances != null && res.goldContinuances!.isNotEmpty) { + goldRouteTracker = GoldRouteTracker( + res.goldContinuances!, + sourceText!, + ); + } + + currentITStep = CurrentITStep( + sourceText: sourceText!, + currentText: currentText, + responseModel: res, + storedGoldContinuances: goldRouteTracker.continuances, + ); + + _addPayloadId(res); + + if (isTranslationDone) { + choreographer.altTranslator.setTranslationFeedback(); + choreographer.getLanguageHelp(true); + } + } catch (e, s) { + debugger(when: kDebugMode); + if (e is! http.Response) { + ErrorHandler.logError(e: e, s: s); + } + choreographer.errorService.setErrorAndLock( + ChoreoError(type: ChoreoErrorType.unknown, raw: e), + ); + } finally { + choreographer.stopLoading(); + } + } + + Future onEditSourceTextSubmit(String newSourceText) async { + try { + sourceText = newSourceText; + _isEditingSourceText = false; + final String currentText = choreographer.currentText; + + choreographer.startLoading(); + + final List responses = await Future.wait([ + _customInputTranslation(""), + _customInputTranslation(choreographer.currentText), + ]); + if (responses[0].goldContinuances != null && + responses[0].goldContinuances!.isNotEmpty) { + goldRouteTracker = GoldRouteTracker( + responses[0].goldContinuances!, + sourceText!, + ); + } + currentITStep = CurrentITStep( + sourceText: sourceText!, + currentText: currentText, + responseModel: responses[1], + storedGoldContinuances: goldRouteTracker.continuances, + ); + + _addPayloadId(responses[1]); + } catch (err, stack) { + debugger(when: kDebugMode); + if (err is! http.Response) { + ErrorHandler.logError(e: err, s: stack); + } + choreographer.errorService.setErrorAndLock( + ChoreoError(type: ChoreoErrorType.unknown, raw: err), + ); + } finally { + choreographer.stopLoading(); + } + } + + Future _customInputTranslation(String textInput) async { + return ITRepo.customInputTranslate( + CustomInputRequestModel( + //this should be set by this time + text: sourceText!, + customInput: textInput, + sourceLangCode: sourceLangCode, + targetLangCode: targetLangCode, + userId: choreographer.userId!, + roomId: choreographer.roomId!, + classId: choreographer.classId, + ), + ); + } + + // used when user selects a choice + Future _systemChoiceTranslation(String translationId) => + ITRepo.systemChoiceTranslate( + SystemChoiceRequestModel( + userId: choreographer.userId!, + nextWordIndex: + completedITSteps.last.chosenContinuance?.indexSavedByServer, + roomId: choreographer.roomId!, + translationId: translationId, + targetLangCode: targetLangCode, + sourceLangCode: sourceLangCode, + classId: choreographer.classId, + ), + ); + + MessageServiceModel? messageServiceModelWithMessageId() => + usedInteractiveTranslation + ? MessageServiceModel( + classId: choreographer.classId, + roomId: choreographer.roomId, + message: choreographer.currentText, + messageId: null, + payloadIds: payLoadIds, + userId: choreographer.userId!, + l1Lang: sourceLangCode, + l2Lang: targetLangCode, + ) + : null; + + //maybe we store IT data in the same format? make a specific kind of match? + void selectTranslation(int chosenIndex) { + final itStep = ITStep(currentITStep!.continuances, chosen: chosenIndex); + + completedITSteps.add(itStep); + + showChoiceFeedback = true; + Future.delayed( + const Duration( + milliseconds: ChoreoConstants.millisecondsToDisplayFeedback, + ), + () { + showChoiceFeedback = false; + choreographer.setState(); + }, + ); + + choreographer.onITChoiceSelect(itStep); + choreographer.setState(); + } + + String get uniqueKeyForLayerLink => "itChoices${choreographer.roomId}"; + + void _addPayloadId(ITResponseModel res) { + payLoadIds.add(res.payloadId); + } + + bool get usedInteractiveTranslation => sourceText != null; + + bool get isTranslationDone => currentITStep != null && currentITStep!.isFinal; + + bool get isOpen => _isOpen; + + String get targetLangCode => choreographer.l2LangCode!; + + String get sourceLangCode => choreographer.l1LangCode!; + + bool get isLoading => choreographer.isFetching; + + bool get correctChoicesSelected => + completedITSteps.every((ITStep step) => step.isCorrect); + + String latestChoiceFeedback(BuildContext context) => + completedITSteps.isNotEmpty + ? completedITSteps.last.choiceFeedback(context) + : ""; + + // String translationFeedback(BuildContext context) => + // completedITSteps.isNotEmpty + // ? completedITSteps.last.translationFeedback(context) + // : ""; + + bool get showAlternativeTranslationsOption => completedITSteps.isNotEmpty + ? completedITSteps.last.showAlternativeTranslationOption && + sourceText != null + : false; + + setIsEditingSourceText(bool value) { + _isEditingSourceText = value; + choreographer.setState(); + } + + bool get isEditingSourceText => _isEditingSourceText; + + int get correctChoices => + completedITSteps.where((element) => element.isCorrect).length; + + int get wildcardChoices => + completedITSteps.where((element) => element.isYellow).length; + + int get incorrectChoices => + completedITSteps.where((element) => element.isWrong).length; + + int get customChoices => + completedITSteps.where((element) => element.isCustom).length; + + bool get allCorrect => completedITSteps.every((element) => element.isCorrect); +} + +class ITStartData { + String text; + String? langCode; + + ITStartData(this.text, this.langCode); +} + +class GoldRouteTracker { + late String _originalText; + List continuances; + + GoldRouteTracker(this.continuances, String originalText) { + _originalText = originalText; + } + + static get defaultTracker => GoldRouteTracker([], ""); + + Continuance? currentContinuance({ + required String currentText, + required String sourceText, + }) { + if (_originalText != sourceText) { + debugPrint("$_originalText != $_originalText"); + return null; + } + + String stack = ""; + for (final cont in continuances) { + if (stack == currentText) { + return cont; + } + stack += cont.text; + } + + return null; + } + + String? get fullTranslation { + if (continuances.isEmpty) return null; + String full = ""; + for (final cont in continuances) { + full += cont.text; + } + return full; + } +} + +class CurrentITStep { + late List continuances; + late bool isFinal; + late String? translationId; + late int payloadId; + + CurrentITStep({ + required String sourceText, + required String currentText, + required ITResponseModel responseModel, + required List? storedGoldContinuances, + }) { + final List gold = + storedGoldContinuances ?? responseModel.goldContinuances ?? []; + final goldTracker = GoldRouteTracker(gold, sourceText); + + isFinal = responseModel.isFinal; + translationId = responseModel.translationId; + payloadId = responseModel.payloadId; + + if (responseModel.continuances.isEmpty) { + continuances = []; + } else { + final Continuance? goldCont = goldTracker.currentContinuance( + currentText: currentText, + sourceText: sourceText, + ); + if (goldCont != null) { + continuances = [ + ...responseModel.continuances + .where((c) => c.text.toLowerCase() != goldCont.text.toLowerCase()) + .map((e) { + //we only want one green choice and for that to be our gold + if (e.level == ChoreoConstants.levelThresholdForGreen) { + e.level = ChoreoConstants.levelThresholdForYellow; + } + return e; + }), + goldCont, + ]; + continuances.shuffle(); + } else { + continuances = responseModel.continuances; + } + } + } +} diff --git a/lib/pangea/choreographer/controllers/message_options.dart b/lib/pangea/choreographer/controllers/message_options.dart new file mode 100644 index 000000000..0e5e68461 --- /dev/null +++ b/lib/pangea/choreographer/controllers/message_options.dart @@ -0,0 +1,46 @@ +import 'package:flutter/cupertino.dart'; + +import 'package:fluffychat/pangea/choreographer/controllers/choreographer.dart'; +import 'package:fluffychat/pangea/constants/language_keys.dart'; +import 'package:fluffychat/pangea/models/language_model.dart'; +import 'package:fluffychat/pangea/utils/firebase_analytics.dart'; + +class MessageOptions { + Choreographer choreographer; + LanguageModel? _selectedDisplayLang; + + MessageOptions(this.choreographer); + + LanguageModel? get selectedDisplayLang { + if (_selectedDisplayLang != null && + _selectedDisplayLang!.langCode != LanguageKeys.unknownLanguage) { + return _selectedDisplayLang; + } + _selectedDisplayLang = choreographer.l2Lang; + return _selectedDisplayLang; + } + + bool get isTranslationOn => + _selectedDisplayLang?.langCode != choreographer.l2LangCode; + + // void setSelectedDisplayLang(LanguageModel? newLang) { + // _selectedDisplayLang = newLang; + // choreographer.setState(); + // } + + void toggleSelectedDisplayLang() { + if (_selectedDisplayLang?.langCode == choreographer.l2LangCode) { + _selectedDisplayLang = choreographer.l1Lang; + } else { + _selectedDisplayLang = choreographer.l2Lang; + } + debugPrint('toggleSelectedDisplayLang: ${_selectedDisplayLang?.langCode}'); + choreographer.setState(); + GoogleAnalytics.messageTranslate(); + } + + void resetSelectedDisplayLang() { + _selectedDisplayLang = choreographer.l2Lang; + choreographer.setState(); + } +} diff --git a/lib/pangea/choreographer/route_type.dart b/lib/pangea/choreographer/route_type.dart new file mode 100644 index 000000000..0abc175e0 --- /dev/null +++ b/lib/pangea/choreographer/route_type.dart @@ -0,0 +1,5 @@ +class ITState { + static const String loading = 'loading'; + static const String choices = 'choices'; + static const String error = 'error'; +} diff --git a/lib/pangea/choreographer/widgets/choice_array.dart b/lib/pangea/choreographer/widgets/choice_array.dart new file mode 100644 index 000000000..ca3f3bf7d --- /dev/null +++ b/lib/pangea/choreographer/widgets/choice_array.dart @@ -0,0 +1,137 @@ +import 'dart:developer'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; + +import '../../utils/bot_style.dart'; +import 'it_shimmer.dart'; + +class ChoicesArray extends StatelessWidget { + final bool isLoading; + final List? choices; + final void Function(int) onPressed; + final void Function(int)? onLongPress; + final int? selectedChoiceIndex; + final String originalSpan; + final String Function(int) uniqueKeyForLayerLink; + const ChoicesArray({ + super.key, + required this.isLoading, + required this.choices, + required this.onPressed, + required this.originalSpan, + required this.uniqueKeyForLayerLink, + required this.selectedChoiceIndex, + this.onLongPress, + }); + + @override + Widget build(BuildContext context) { + final ThemeData theme = Theme.of(context); + return isLoading && (choices == null || choices!.length <= 1) + ? ItShimmer(originalSpan: originalSpan) + : Wrap( + alignment: WrapAlignment.center, + children: choices + ?.asMap() + .entries + .map( + (entry) => ChoiceItem( + theme: theme, + onLongPress: onLongPress, + onPressed: onPressed, + entry: entry, + isSelected: selectedChoiceIndex == entry.key, + ), + ) + .toList() ?? + [], + ); + } +} + +class Choice { + Choice({ + this.color, + required this.text, + }); + + final Color? color; + final String text; +} + +class ChoiceItem extends StatelessWidget { + const ChoiceItem({ + super.key, + required this.theme, + required this.onLongPress, + required this.onPressed, + required this.entry, + required this.isSelected, + }); + + final MapEntry entry; + final ThemeData theme; + final void Function(int p1)? onLongPress; + final void Function(int p1) onPressed; + final bool isSelected; + + @override + Widget build(BuildContext context) { + try { + return Tooltip( + message: onLongPress != null ? L10n.of(context)!.holdForInfo : "", + waitDuration: onLongPress != null + ? const Duration(milliseconds: 500) + : const Duration(days: 1), + child: Container( + margin: const EdgeInsets.all(2), + padding: EdgeInsets.zero, + decoration: isSelected + ? BoxDecoration( + borderRadius: const BorderRadius.all(Radius.circular(10)), + border: Border.all( + color: entry.value.color ?? theme.colorScheme.primary, + style: BorderStyle.solid, + width: 2.0, + ), + ) + : null, + child: TextButton( + style: ButtonStyle( + padding: MaterialStateProperty.all( + const EdgeInsets.symmetric(horizontal: 7), + ), + //if index is selected, then give the background a slight primary color + backgroundColor: MaterialStateProperty.all( + entry.value.color != null + ? entry.value.color!.withOpacity(0.2) + : theme.colorScheme.primary.withOpacity(0.1), + ), + textStyle: MaterialStateProperty.all( + BotStyle.text(context), + ), + shape: MaterialStateProperty.all( + RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + ), + ), + ), + onLongPress: + onLongPress != null ? () => onLongPress!(entry.key) : null, + onPressed: () => onPressed(entry.key), + child: Text( + entry.value.text, + style: BotStyle.text(context), + ), + ), + ), + ); + } catch (e) { + debugger(when: kDebugMode); + return Container(); + } + } +} diff --git a/lib/pangea/choreographer/widgets/counters.dart b/lib/pangea/choreographer/widgets/counters.dart new file mode 100644 index 000000000..5e1c57b9c --- /dev/null +++ b/lib/pangea/choreographer/widgets/counters.dart @@ -0,0 +1,89 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; + +import 'package:fluffychat/pangea/constants/choreo_constants.dart'; +import '../../../config/app_config.dart'; + +class Counter extends StatelessWidget { + final int count; + final String label; + final Color color; + const Counter({ + super.key, + required this.count, + required this.label, + required this.color, + }); + + @override + Widget build(BuildContext context) { + return Tooltip( + message: label, + // textStyle: BotStyle.text(context, setColor: false), + child: Container( + padding: const EdgeInsets.all(4.0), + decoration: BoxDecoration( + color: color, + borderRadius: BorderRadius.circular(50.0), + ), + child: Column( + children: [ + Text( + count.toString(), + style: const TextStyle( + fontSize: 20.0, + fontWeight: FontWeight.bold, + ), + ), + ], + ), + ), + ); + } +} + +class CounterDisplay extends StatelessWidget { + final int correct; + final int incorrect; + final int yellow; + final int custom; + const CounterDisplay({ + super.key, + required this.correct, + required this.incorrect, + required this.yellow, + required this.custom, + }); + + @override + Widget build(BuildContext context) { + return Row( + children: [ + Counter( + count: custom, + label: L10n.of(context)!.customInputFeedbackChoice, + // color: Theme.of(context).brightness == Brightness.dark + // ? AppConfig.primaryColorLight + // : AppConfig.primaryColor, + color: AppConfig.primaryColor, + ), + Counter( + count: correct, + label: L10n.of(context)!.greenFeedback, + color: ChoreoConstants.green, + ), + Counter( + color: ChoreoConstants.yellow, + label: L10n.of(context)!.yellowFeedback, + count: yellow, + ), + Counter( + count: incorrect, + label: L10n.of(context)!.redFeedback, + color: ChoreoConstants.red, + ), + ], + ); + } +} diff --git a/lib/pangea/choreographer/widgets/has_error_button.dart b/lib/pangea/choreographer/widgets/has_error_button.dart new file mode 100644 index 000000000..47bf7ea7f --- /dev/null +++ b/lib/pangea/choreographer/widgets/has_error_button.dart @@ -0,0 +1,40 @@ +import 'package:flutter/material.dart'; + +import '../../controllers/pangea_controller.dart'; +import '../controllers/error_service.dart'; + +class ChoreographerHasErrorButton extends StatelessWidget { + final ChoreoError error; + final PangeaController pangeaController; + + const ChoreographerHasErrorButton( + this.pangeaController, + this.error, { + super.key, + }); + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.only(bottom: 56.0), + child: FloatingActionButton( + onPressed: () { + if (error.type == ChoreoErrorType.unknown) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + duration: const Duration(seconds: 5), + content: Text( + "${error.title(context)} ${error.description(context)}", + ), + ), + ); + } else if (error.type == ChoreoErrorType.unsubscribed) { + pangeaController.subscriptionController.showPaywall(context); + } + }, + mini: true, + child: Icon(error.icon), + ), + ); + } +} diff --git a/lib/pangea/choreographer/widgets/it_bar.dart b/lib/pangea/choreographer/widgets/it_bar.dart new file mode 100644 index 000000000..883761a9a --- /dev/null +++ b/lib/pangea/choreographer/widgets/it_bar.dart @@ -0,0 +1,330 @@ +import 'dart:developer'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + +import 'package:fluffychat/pangea/choreographer/controllers/choreographer.dart'; +import 'package:fluffychat/pangea/choreographer/controllers/it_controller.dart'; +import 'package:fluffychat/pangea/choreographer/widgets/it_bar_buttons.dart'; +import 'package:fluffychat/pangea/choreographer/widgets/translation_finished_flow.dart'; +import 'package:fluffychat/pangea/constants/choreo_constants.dart'; +import 'package:fluffychat/pangea/utils/error_handler.dart'; +import 'package:fluffychat/pangea/widgets/igc/word_data_card.dart'; +import '../../../config/app_config.dart'; +import '../../models/it_response_model.dart'; +import '../../utils/overlay.dart'; +import 'choice_array.dart'; + +class ITBar extends StatelessWidget { + final Choreographer choreographer; + const ITBar({super.key, required this.choreographer}); + + ITController get controller => choreographer.itController; + + @override + Widget build(BuildContext context) { + if (!controller.isOpen) return const SizedBox(); + + return CompositedTransformTarget( + link: choreographer.itBarLinkAndKey.link, + child: Container( + key: choreographer.itBarLinkAndKey.key, + decoration: BoxDecoration( + color: Theme.of(context).brightness == Brightness.light + ? Colors.white + : Colors.black, + borderRadius: const BorderRadius.only( + topLeft: Radius.circular(AppConfig.borderRadius), + topRight: Radius.circular(AppConfig.borderRadius), + ), + ), + width: double.infinity, + padding: const EdgeInsets.fromLTRB(0, 3, 3, 3), + child: Stack( + children: [ + SingleChildScrollView( + child: Column( + children: [ + // Row( + // mainAxisAlignment: MainAxisAlignment.spaceBetween, + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // // Row( + // // mainAxisAlignment: MainAxisAlignment.start, + // // crossAxisAlignment: CrossAxisAlignment.start, + // // children: [ + // // CounterDisplay( + // // correct: controller.correctChoices, + // // custom: controller.customChoices, + // // incorrect: controller.incorrectChoices, + // // yellow: controller.wildcardChoices, + // // ), + // // CompositedTransformTarget( + // // link: choreographer.itBotLayerLinkAndKey.link, + // // child: ITBotButton( + // // key: choreographer.itBotLayerLinkAndKey.key, + // // choreographer: choreographer, + // // ), + // // ), + // // ], + // // ), + // ITCloseButton(choreographer: choreographer), + // ], + // ), + // const SizedBox(height: 40.0), + OriginalText(controller: controller), + const SizedBox(height: 7.0), + IntrinsicHeight( + child: Container( + constraints: const BoxConstraints(minHeight: 80), + width: double.infinity, + padding: const EdgeInsets.symmetric(horizontal: 4.0), + child: Center( + child: controller.choreographer.errorService.isError + ? ITError( + error: controller + .choreographer.errorService.error!, + controller: controller, + ) + : controller.showChoiceFeedback + ? ChoiceFeedbackText(controller: controller) + : controller.isTranslationDone + ? TranslationFeedback( + controller: controller, + ) + : ITChoices(controller: controller), + ), + ), + ), + ], + ), + ), + Positioned( + top: 0.0, + right: 0.0, + child: ITCloseButton(choreographer: choreographer), + ), + ], + ), + ), + ); + } +} + +class ChoiceFeedbackText extends StatelessWidget { + const ChoiceFeedbackText({ + super.key, + required this.controller, + }); + + final ITController controller; + + @override + Widget build(BuildContext context) { + //reimplement if we decide we want it + return const SizedBox(); + // return AnimatedTextKit( + // isRepeatingAnimation: false, + // animatedTexts: [ + // ScaleAnimatedText( + // controller.latestChoiceFeedback(context), + // duration: Duration( + // milliseconds: + // (ChoreoConstants.millisecondsToDisplayFeedback / 2).round(), + // ), + // scalingFactor: 1.4, + // textStyle: BotStyle.text(context), + // ), + // ], + // ); + } +} + +class OriginalText extends StatelessWidget { + const OriginalText({ + super.key, + required this.controller, + }); + + final ITController controller; + + @override + Widget build(BuildContext context) { + return Container( + constraints: const BoxConstraints(minHeight: 50), + padding: const EdgeInsets.only(left: 60.0, right: 40.0), + decoration: const BoxDecoration( + borderRadius: BorderRadius.only( + topLeft: Radius.circular(AppConfig.borderRadius), + topRight: Radius.circular(AppConfig.borderRadius), + ), + ), + child: Row( + //PTODO - does this already update after reset or we need to setState? + mainAxisAlignment: MainAxisAlignment.center, + children: [ + if (!controller.isEditingSourceText) + controller.sourceText != null + ? Flexible(child: Text(controller.sourceText!)) + : const LinearProgressIndicator(), + if (controller.isEditingSourceText) + Expanded( + child: TextField( + controller: TextEditingController(text: controller.sourceText), + autofocus: true, + enableSuggestions: false, + maxLines: null, + textInputAction: TextInputAction.send, + onSubmitted: controller.onEditSourceTextSubmit, + obscureText: false, + decoration: const InputDecoration( + border: OutlineInputBorder(), + ), + ), + ), + if (!controller.isEditingSourceText && controller.sourceText != null) + IconButton( + onPressed: () => controller.setIsEditingSourceText(true), + icon: const Icon(Icons.edit_outlined), + ), + ], + ), + ); + } +} + +class ITChoices extends StatelessWidget { + const ITChoices({ + super.key, + required this.controller, + }); + + // final choices = [ + // "we need a really long translation to see what's going to happen with that. it should probably have multiple sentences so that we can see what happens there.we need a really long translation to see what's going to happen with that. it should probably have multiple sentences so that we can see what happens there.", + // "we need a really long translation to see what's going to happen with that. it should probably have multiple sentences so that we can see what happens there.", + // "we need a really long translation to see what's going to happen with that. it should probably have multiple sentences so that we can see what happens there.", + // "we need a really long translation to see what's going to happen with that. it should probably have multiple sentences so that we can see what happens there.", + // "we need a really long translation to see what's going to happen with that. it should probably have multiple sentences so that we can see what happens there.", + // "we need a really long translation to see what's going to happen with that. it should probably have multiple sentences so that we can see what happens there.", + // ]; + + final ITController controller; + + String? get sourceText { + if ((controller.sourceText == null || controller.sourceText!.isEmpty)) { + ErrorHandler.logError(m: "null source text in ItChoices"); + } + return controller.sourceText; + } + + void showCard( + BuildContext context, + int index, [ + Color? borderColor, + String? choiceFeedback, + ]) => + OverlayUtil.showPositionedCard( + context: context, + cardToShow: WordDataCard( + word: controller.currentITStep!.continuances[index].text, + wordLang: controller.targetLangCode, + fullText: sourceText ?? controller.choreographer.currentText, + fullTextLang: sourceText != null + ? controller.sourceLangCode + : controller.targetLangCode, + hasInfo: controller.currentITStep!.continuances[index].hasInfo, + choiceFeedback: choiceFeedback, + room: controller.choreographer.chatController.room, + ), + cardSize: const Size(300, 300), + borderColor: borderColor, + transformTargetId: controller.choreographer.itBarTransformTargetKey, + backDropToDismiss: false, + ); + + @override + Widget build(BuildContext context) { + try { + if (controller.isEditingSourceText || controller.currentITStep == null) { + return const SizedBox(); + } + return ChoicesArray( + isLoading: controller.isLoading || + controller.choreographer.isFetching || + controller.currentITStep == null, + //TODO - pass current span being translated + originalSpan: "dummy", + choices: controller.currentITStep!.continuances.map((e) { + try { + return Choice(text: e.text.trim(), color: e.color); + } catch (e) { + debugger(when: kDebugMode); + return Choice(text: "error", color: Colors.red); + } + }).toList(), + onPressed: (int index) { + final Continuance continuance = + controller.currentITStep!.continuances[index]; + debugPrint("is gold? ${continuance.gold}"); + if (continuance.level == 1 || continuance.wasClicked) { + Future.delayed( + const Duration(milliseconds: 500), + () => controller.selectTranslation(index), + ); + } else { + showCard( + context, + index, + continuance.level == 2 + ? ChoreoConstants.yellow + : ChoreoConstants.red, + continuance.feedbackText(context), + ); + } + controller.currentITStep!.continuances[index].wasClicked = true; + controller.choreographer.setState(); + }, + onLongPress: (int index) { + showCard(context, index); + }, + uniqueKeyForLayerLink: (int index) => "itChoices$index", + selectedChoiceIndex: null, + ); + } catch (e) { + debugger(when: kDebugMode); + return const SizedBox(); + } + } +} + +class ITError extends StatelessWidget { + final ITController controller; + final Object error; + const ITError({super.key, required this.error, required this.controller}); + + @override + Widget build(BuildContext context) { + final ErrorCopy errorCopy = ErrorCopy(context, error); + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 8), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + ConstrainedBox( + constraints: const BoxConstraints(maxWidth: 300), + child: Text( + // Text( + "${errorCopy.title}\n${errorCopy.body}", + // Haga clic en su mensaje para ver los significados de las palabras. + style: TextStyle( + fontStyle: FontStyle.italic, + color: Theme.of(context).colorScheme.error, + ), + ), + ), + ITRestartButton(controller: controller), + ], + ), + ); + } +} diff --git a/lib/pangea/choreographer/widgets/it_bar_buttons.dart b/lib/pangea/choreographer/widgets/it_bar_buttons.dart new file mode 100644 index 000000000..815020d17 --- /dev/null +++ b/lib/pangea/choreographer/widgets/it_bar_buttons.dart @@ -0,0 +1,79 @@ +import 'package:flutter/material.dart'; + +import 'package:fluffychat/pangea/controllers/pangea_controller.dart'; +import 'package:fluffychat/pangea/utils/instructions.dart'; +import 'package:fluffychat/widgets/matrix.dart'; +import '../../widgets/common/bot_face_svg.dart'; +import '../controllers/choreographer.dart'; +import '../controllers/it_controller.dart'; + +class ITCloseButton extends StatelessWidget { + const ITCloseButton({ + super.key, + required this.choreographer, + }); + + final Choreographer choreographer; + + @override + Widget build(BuildContext context) { + return IconButton( + icon: const Icon(Icons.close_outlined), + onPressed: () { + if (choreographer.itController.isEditingSourceText) { + choreographer.itController.setIsEditingSourceText(false); + } else { + choreographer.itController.closeIT(); + } + }, + ); + } +} + +class ITBotButton extends StatelessWidget { + const ITBotButton({super.key, required this.choreographer}); + + final Choreographer choreographer; + + @override + Widget build(BuildContext context) { + choreographer.pangeaController.instructions.show( + context, + InstructionsEnum.itInstructions, + choreographer.itBotTransformTargetKey, + true, + ); + + return IconButton( + icon: const BotFace(width: 40.0, expression: BotExpression.right), + onPressed: () => choreographer.pangeaController.instructions.show( + context, + InstructionsEnum.itInstructions, + choreographer.itBotTransformTargetKey, + false, + ), + ); + } +} + +class ITRestartButton extends StatelessWidget { + ITRestartButton({ + super.key, + required this.controller, + }); + + final ITController controller; + final PangeaController pangeaController = MatrixState.pangeaController; + + @override + Widget build(BuildContext context) { + return IconButton( + onPressed: () async { + controller.choreographer.errorService.resetError(); + controller.currentITStep = null; + controller.choreographer.getLanguageHelp(); + }, + icon: const Icon(Icons.refresh_outlined), + ); + } +} diff --git a/lib/pangea/choreographer/widgets/it_shimmer.dart b/lib/pangea/choreographer/widgets/it_shimmer.dart new file mode 100644 index 000000000..2710ab57f --- /dev/null +++ b/lib/pangea/choreographer/widgets/it_shimmer.dart @@ -0,0 +1,87 @@ +import 'dart:ui'; + +import 'package:flutter/material.dart'; + +import 'package:fluffychat/config/app_config.dart'; + +class ItShimmer extends StatelessWidget { + const ItShimmer({super.key, required this.originalSpan}); + + final String originalSpan; + + Iterable renderShimmerIfListEmpty( + BuildContext context, { + int noOfBars = 3, + }) { + final List dummyStrings = []; + for (int i = 0; i < noOfBars; i++) { + dummyStrings.add(originalSpan); + } + return dummyStrings.map( + (e) => ITShimmerElement( + text: e, + ), + ); + } + + // PTODO - bring this back, make it shimmer + @override + Widget build(BuildContext context) { + return Wrap( + alignment: WrapAlignment.center, + children: [...renderShimmerIfListEmpty(context, noOfBars: 3)], + ); + } +} + +class ITShimmerElement extends StatelessWidget { + const ITShimmerElement({ + super.key, + required this.text, + }); + + final String text; + + @override + Widget build(BuildContext context) { + return Container( + constraints: const BoxConstraints(minWidth: 50), + margin: const EdgeInsets.all(2), + padding: EdgeInsets.zero, + // decoration: BoxDecoration( + // borderRadius: const BorderRadius.all(Radius.circular(10)), + // border: Border.all( + // color: Theme.of(context).colorScheme.primary, + // style: BorderStyle.solid, + // width: 2.0, + // ), + // ), + child: ImageFiltered( + imageFilter: ImageFilter.blur(sigmaX: 10, sigmaY: 10), + child: TextButton( + style: ButtonStyle( + padding: MaterialStateProperty.all( + const EdgeInsets.symmetric(horizontal: 7), + ), + shape: MaterialStateProperty.all( + RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + ), + ), + backgroundColor: MaterialStateProperty.all( + AppConfig.primaryColor.withOpacity(0.2), + ), + ), + onPressed: () {}, + child: Text( + text, + style: Theme.of(context) + .textTheme + .bodyMedium! + .copyWith(color: Colors.transparent), + ), + ), + ), + ); + } +} diff --git a/lib/pangea/choreographer/widgets/language_display_toggle.dart b/lib/pangea/choreographer/widgets/language_display_toggle.dart new file mode 100644 index 000000000..a399fda44 --- /dev/null +++ b/lib/pangea/choreographer/widgets/language_display_toggle.dart @@ -0,0 +1,57 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; + +import '../../../config/app_config.dart'; +import '../../../pages/chat/chat.dart'; + +class LanguageDisplayToggle extends StatelessWidget { + const LanguageDisplayToggle({ + super.key, + required this.controller, + }); + + final ChatController controller; + + get onPressed => + controller.choreographer.messageOptions.toggleSelectedDisplayLang; + + @override + Widget build(BuildContext context) { + if (!controller.choreographer.translationEnabled) { + return const SizedBox(); + } + return Container( + decoration: BoxDecoration( + shape: BoxShape.circle, + color: controller.choreographer.messageOptions.isTranslationOn + ? AppConfig.primaryColor + : null, + ), + child: IconButton( + tooltip: L10n.of(context)!.toggleLanguages, + onPressed: onPressed, + icon: const Icon(Icons.translate_outlined), + selectedIcon: const Icon(Icons.translate), + isSelected: controller.choreographer.messageOptions.isTranslationOn, + ), + ); + // return Tooltip( + // message: L10n.of(context)!.toggleLanguages, + // waitDuration: const Duration(milliseconds: 1000), + // child: FloatingActionButton( + // onPressed: onPressed, + // backgroundColor: Colors.white, + // mini: false, + // shape: RoundedRectangleBorder( + // borderRadius: BorderRadius.circular(200), // <-- Radius + // ), + // child: LanguageFlag( + // flagUrl: controller + // .choreographer.messageOptions.displayLang?.languageFlag, + // size: 50, + // ), + // ), + // ); + } +} diff --git a/lib/pangea/choreographer/widgets/language_permissions_warning_buttons.dart b/lib/pangea/choreographer/widgets/language_permissions_warning_buttons.dart new file mode 100644 index 000000000..93d441aa4 --- /dev/null +++ b/lib/pangea/choreographer/widgets/language_permissions_warning_buttons.dart @@ -0,0 +1,149 @@ +import 'dart:developer'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/gestures.dart'; +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:go_router/go_router.dart'; +import 'package:matrix/matrix.dart'; + +import 'package:fluffychat/config/app_config.dart'; +import 'package:fluffychat/pangea/choreographer/controllers/choreographer.dart'; +import 'package:fluffychat/pangea/models/class_model.dart'; +import 'package:fluffychat/pangea/utils/error_handler.dart'; +import '../../../widgets/matrix.dart'; + +class _ErrorCopy { + final String title; + final String? description; + + _ErrorCopy(this.title, [this.description]); +} + +class LanguagePermissionsButtons extends StatelessWidget { + final String? roomID; + final Choreographer choreographer; + + const LanguagePermissionsButtons({ + super.key, + required this.roomID, + required this.choreographer, + }); + + @override + Widget build(BuildContext context) { + if (roomID == null) return const SizedBox.shrink(); + final _ErrorCopy? copy = getCopy(context); + if (copy == null) return const SizedBox.shrink(); + + final Widget text = RichText( + text: TextSpan( + children: [ + TextSpan( + text: copy.title, + style: TextStyle( + color: Theme.of(context).brightness == Brightness.light + ? Colors.white + : Colors.black, + ), + ), + if (copy.description != null) + TextSpan( + text: copy.description, + style: const TextStyle(color: AppConfig.primaryColor), + recognizer: TapGestureRecognizer() + ..onTap = () => context.go('/rooms/settings/learning'), + ), + ], + ), + ); + + return Padding( + padding: const EdgeInsets.only(bottom: 56.0), + child: FloatingActionButton( + mini: true, + child: const Icon(Icons.history_edu_outlined), + onPressed: () => showMessage(context, text), + ), + ); + } + + _ErrorCopy? getCopy(BuildContext context) { + final bool itDisabled = !choreographer.itEnabled; + final bool igcDisabled = !choreographer.igcEnabled; + final Room? room = Matrix.of(context).client.getRoomById(roomID!); + + final bool itDisabledByClass = choreographer + .pangeaController.permissionsController + .isToolDisabledByClass(ToolSetting.interactiveTranslator, room); + final bool igcDisabledByClass = choreographer + .pangeaController.permissionsController + .isToolDisabledByClass(ToolSetting.interactiveGrammar, room); + + if (itDisabledByClass && igcDisabledByClass) { + return _ErrorCopy( + L10n.of(context)!.errorDisableLanguageAssistanceClassDesc, + ); + } + + if (itDisabledByClass) { + if (igcDisabled) { + return _ErrorCopy( + "{L10n.of(context)!.errorDisableITClassDesc} ${L10n.of(context)!.errorDisableIGC}", + " ${L10n.of(context)!.errorDisableIGCUserDesc}", + ); + } else { + return _ErrorCopy(L10n.of(context)!.errorDisableITClassDesc); + } + } + + if (igcDisabledByClass) { + if (itDisabled) { + return _ErrorCopy( + "${L10n.of(context)!.errorDisableIGCClassDesc} ${L10n.of(context)!.errorDisableIT}", + " ${L10n.of(context)!.errorDisableITUserDesc}", + ); + } else { + return _ErrorCopy(L10n.of(context)!.errorDisableIGCClassDesc); + } + } + + if (igcDisabled && itDisabled) { + return _ErrorCopy( + L10n.of(context)!.errorDisableLanguageAssistance, + " ${L10n.of(context)!.errorDisableLanguageAssistanceUserDesc}", + ); + } + + if (itDisabled) { + return _ErrorCopy( + L10n.of(context)!.errorDisableIT, + " ${L10n.of(context)!.errorDisableITUserDesc}", + ); + } + + if (igcDisabled) { + return _ErrorCopy( + L10n.of(context)!.errorDisableIGC, + " ${L10n.of(context)!.errorDisableIGCUserDesc}", + ); + } + + debugger(when: kDebugMode); + ErrorHandler.logError( + e: Exception("Unhandled case in language permissions"), + ); + return null; + } + + void showMessage(BuildContext context, Widget text) { + ScaffoldMessenger.of(context).hideCurrentSnackBar(); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + duration: const Duration(seconds: 10), + content: text, + ), + ); + } +} diff --git a/lib/pangea/choreographer/widgets/send_button.dart b/lib/pangea/choreographer/widgets/send_button.dart new file mode 100644 index 000000000..045f0c516 --- /dev/null +++ b/lib/pangea/choreographer/widgets/send_button.dart @@ -0,0 +1,41 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; + +import 'package:fluffychat/pangea/constants/colors.dart'; +import '../../../pages/chat/chat.dart'; + +class ChoreographerSendButton extends StatelessWidget { + const ChoreographerSendButton({ + super.key, + required this.controller, + }); + + final ChatController controller; + + @override + Widget build(BuildContext context) { + // commit for cicd + return controller.choreographer.isFetching + ? Container( + height: 56, + width: 56, + padding: const EdgeInsets.all(13), + child: const CircularProgressIndicator(), + ) + : Container( + height: 56, + alignment: Alignment.center, + child: IconButton( + icon: const Icon(Icons.send_outlined), + color: controller.choreographer.igc.canSendMessage + ? null + : PangeaColors.igcError, + onPressed: () { + controller.choreographer.send(context); + }, + tooltip: L10n.of(context)!.send, + ), + ); + } +} diff --git a/lib/pangea/choreographer/widgets/translation_finished_flow.dart b/lib/pangea/choreographer/widgets/translation_finished_flow.dart new file mode 100644 index 000000000..de49be145 --- /dev/null +++ b/lib/pangea/choreographer/widgets/translation_finished_flow.dart @@ -0,0 +1,87 @@ +import 'package:flutter/material.dart'; + +import '../../utils/bot_style.dart'; +import '../../utils/error_handler.dart'; +import '../controllers/it_controller.dart'; +import 'choice_array.dart'; + +class TranslationFeedback extends StatelessWidget { + final ITController controller; + const TranslationFeedback({super.key, required this.controller}); + + @override + Widget build(BuildContext context) { + String feedbackText; + TextStyle? style; + try { + feedbackText = + controller.choreographer.altTranslator.translationFeedback(context); + style = BotStyle.text(context); + } catch (err, stack) { + feedbackText = "Nice job!"; + style = null; + debugPrint("error getting copy and styles"); + ErrorHandler.logError(e: err, s: stack); + } + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 20), + child: Column( + children: [ + if (controller.choreographer.altTranslator.showTranslationFeedback) + Padding( + padding: const EdgeInsets.symmetric(horizontal: 30), + child: RichText( + textAlign: TextAlign.center, + text: TextSpan( + children: [ + TextSpan( + text: "$feedbackText ", + style: style, + ), + ], + ), + ), + ), + const SizedBox(height: 6), + if (controller + .choreographer.altTranslator.showAlternativeTranslations) + AlternativeTranslations(controller: controller), + // if (!controller + // .choreographer.altTranslator.showAlternativeTranslations && + // !controller.choreographer.isFetching) + // ITRestartButton(controller: controller), + ], + ), + ); + } +} + +class AlternativeTranslations extends StatelessWidget { + const AlternativeTranslations({ + super.key, + required this.controller, + }); + + final ITController controller; + + @override + Widget build(BuildContext context) { + return ChoicesArray( + originalSpan: controller.choreographer.itController.sourceText ?? "dummy", + isLoading: + controller.choreographer.altTranslator.loadingAlternativeTranslations, + // choices: controller.choreographer.altTranslator.similarityResponse.scores + choices: [ + Choice(text: controller.choreographer.altTranslator.translations.first), + ], + // choices: controller.choreographer.altTranslator.translations, + onPressed: (int index) { + controller.choreographer.onSelectAlternativeTranslation( + controller.choreographer.altTranslator.translations[index], + ); + }, + uniqueKeyForLayerLink: (int index) => "altTranslation$index", + selectedChoiceIndex: null, + ); + } +} diff --git a/lib/pangea/config/colors.dart b/lib/pangea/config/colors.dart new file mode 100644 index 000000000..43a3f2e23 --- /dev/null +++ b/lib/pangea/config/colors.dart @@ -0,0 +1,13 @@ +import 'package:flutter/material.dart'; + +class ChoreoColor { + static Color containerBG(BuildContext context) => + Theme.of(context).scaffoldBackgroundColor; + static Color textColor(BuildContext context) => + isLightMode(context) ? Colors.black : Colors.white; + static Color disabled(context) => const Color.fromARGB(255, 211, 211, 211); + static Color removeButtonColor(context) => + Theme.of(context).colorScheme.primary; + static bool isLightMode(BuildContext context) => + Theme.of(context).brightness == Brightness.light ? true : false; +} diff --git a/lib/pangea/config/environment.dart b/lib/pangea/config/environment.dart new file mode 100644 index 000000000..e55f66423 --- /dev/null +++ b/lib/pangea/config/environment.dart @@ -0,0 +1,78 @@ +import 'package:flutter_dotenv/flutter_dotenv.dart'; + +class Environment { + static bool get itIsTime => + DateTime.utc(2023, 1, 25).isBefore(DateTime.now()); + + static String get fileName { + return ".env"; + } + + static bool get isStaging => synapsURL.contains("staging"); + + static String get baseAPI { + return dotenv.env["BASE_API"] ?? 'BASE API not found'; + } + + static String get frontendURL { + return dotenv.env["FRONTEND_URL"] ?? "Frontend URL NOT FOUND"; + } + + static String get synapsURL { + return dotenv.env['SYNAPSE_URL'] ?? 'Synapse Url not found'; + } + + static String get homeServer { + return dotenv.env["HOME_SERVER"] ?? 'Home Server not found'; + } + + static String get choreoApi { + // return "http://localhost:8000/choreo"; + return dotenv.env['CHOREO_API'] ?? 'Not found'; + } + + static String get choreoApiKey { + return dotenv.env['CHOREO_API_KEY'] ?? + 'e6fa9fa97031ba0c852efe78457922f278a2fbc109752fe18e465337699e9873'; + } + + //Question for Jordan - does the client ever pass this to the server? + static String get googleAuthKey { + return dotenv.env['GOOGLE_AUTH_KEY'] ?? + '466850640825-qegdiq3mpj3h5e0e79ud5hnnq2c22mi3.apps.googleusercontent.com'; + } + + static String get sentryDsn { + return dotenv.env["SENTRY_DSN"] ?? + 'https://c2fd19ab2cdc4ebb939a32d01c0e9fa1@o225078.ingest.sentry.io/1376295'; + } + + static String get rcProjectId { + return dotenv.env["RC_PROJECT"] ?? 'a499dc21'; + } + + static String get rcKey { + return dotenv.env["RC_KEY"] ?? 'sk_eVGBdPyInaOfJrKlPBgFVnRynqKJB'; + } + + static String get rcGoogleKey { + return dotenv.env["RC_GOOGLE_KEY"] ?? 'goog_paQMrzFKGzuWZvcMTPkkvIsifJe'; + } + + static String get rcIosKey { + return dotenv.env["RC_IOS_KEY"] ?? 'appl_DUPqnxuLjkBLzhBPTWeDjqNENuv'; + } + + static String get rcStripeKey { + return dotenv.env["RC_STRIPE_KEY"] ?? 'strp_YWZxWUeEfvagiefDNoofinaRCOl'; + } + + static String get rcOfferingName { + return dotenv.env["RC_OFFERING_NAME"] ?? 'default'; + } + + static String get stripeManagementUrl { + return dotenv.env["STRIPE_MANAGEMENT_LINK"] ?? + 'https://billing.stripe.com/p/login/dR6dSkf5p6rBc4EcMM'; + } +} diff --git a/lib/pangea/constants/age_limits.dart b/lib/pangea/constants/age_limits.dart new file mode 100644 index 000000000..9a07840ef --- /dev/null +++ b/lib/pangea/constants/age_limits.dart @@ -0,0 +1,4 @@ +class AgeLimits { + static const int toAccessFeatures = 18; + static const int toUseTheApp = 13; +} diff --git a/lib/pangea/constants/choreo_constants.dart b/lib/pangea/constants/choreo_constants.dart new file mode 100644 index 000000000..cbdfdf7d0 --- /dev/null +++ b/lib/pangea/constants/choreo_constants.dart @@ -0,0 +1,14 @@ +import 'package:flutter/material.dart'; + +class ChoreoConstants { + static const numberOfITChoices = 4; + // static const millisecondsToDisplayFeedback = 2500; + static const millisecondsToDisplayFeedback = 0; + static const commonalityThreshold = 0.9; + static const levelThresholdForGreen = 1; + static const levelThresholdForYellow = 2; + static const levelThresholdForRed = 3; + static const green = Colors.green; + static const yellow = Color.fromARGB(255, 206, 152, 2); + static const red = Colors.red; +} diff --git a/lib/pangea/constants/class_default_values.dart b/lib/pangea/constants/class_default_values.dart new file mode 100644 index 000000000..97522ca4b --- /dev/null +++ b/lib/pangea/constants/class_default_values.dart @@ -0,0 +1,13 @@ +import '../enum/time_span.dart'; + +class ClassDefaultValues { + static const pangeaClassRoomIdDefault = "PANGEA_CLASS_ROOM_ID_DEFAULT"; + static const powerLevelOfAdmin = 100; + static const languageToolPermissions = 1; + static const minutesDelayToUpdateMyAnalytics = -1; + static const minutesDelayToMakeNewChartAnalytics = 1; + static const maxClassName = 40; + static const defaultDominantLanguage = "en"; + static const defaultTargetLanguage = "es"; + static const defaultTimeSpan = TimeSpan.month; +} diff --git a/lib/pangea/constants/colors.dart b/lib/pangea/constants/colors.dart new file mode 100644 index 000000000..16fc7f907 --- /dev/null +++ b/lib/pangea/constants/colors.dart @@ -0,0 +1,5 @@ +import 'package:flutter/material.dart'; + +class PangeaColors { + static const igcError = Colors.red; +} diff --git a/lib/pangea/constants/keys.dart b/lib/pangea/constants/keys.dart new file mode 100644 index 000000000..092b1b0a9 --- /dev/null +++ b/lib/pangea/constants/keys.dart @@ -0,0 +1,4 @@ +class PrefKey { + static const lastFetched = 'LAST_FETCHED'; + static const flags = 'flags'; +} diff --git a/lib/pangea/constants/language_keys.dart b/lib/pangea/constants/language_keys.dart new file mode 100644 index 000000000..cfe0c96c0 --- /dev/null +++ b/lib/pangea/constants/language_keys.dart @@ -0,0 +1,6 @@ +class LanguageKeys { + static const unknownLanguage = "unk"; + static const mixedLanguage = "mixed"; + static const defaultLanguage = "en"; + static const multiLanguage = "multi"; +} diff --git a/lib/pangea/constants/language_level_type.dart b/lib/pangea/constants/language_level_type.dart new file mode 100644 index 000000000..49136ca77 --- /dev/null +++ b/lib/pangea/constants/language_level_type.dart @@ -0,0 +1,3 @@ +class LanguageLevelType { + static List get allInts => [0, 1, 2, 3, 4, 5, 6]; +} diff --git a/lib/pangea/constants/language_list_keys.dart b/lib/pangea/constants/language_list_keys.dart new file mode 100644 index 000000000..7fff924a9 --- /dev/null +++ b/lib/pangea/constants/language_list_keys.dart @@ -0,0 +1,4 @@ +class PrefKey { + static const lastFetched = 'p_lang_lastfetched'; + static const flags = 'p_lang_flag'; +} diff --git a/lib/pangea/constants/local.key.dart b/lib/pangea/constants/local.key.dart new file mode 100644 index 000000000..238a3ecc9 --- /dev/null +++ b/lib/pangea/constants/local.key.dart @@ -0,0 +1,7 @@ +class PLocalKey { + static const String user = 'user'; + + static const String classes = 'classes'; + + static const String cachedClassCodeToJoin = "cachedclasscodetojoin"; +} diff --git a/lib/pangea/constants/match_rule_ids.dart b/lib/pangea/constants/match_rule_ids.dart new file mode 100644 index 000000000..7f3a924de --- /dev/null +++ b/lib/pangea/constants/match_rule_ids.dart @@ -0,0 +1,6 @@ +class MatchRuleIds { + static const interactiveTranslation = "interactive_translation"; + static const tokenNeedsTranslation = "token_needs_translation"; + static const tokenSpanNeedsTranslation = "token_span_needs_translation"; + static const l1SpanAndGrammar = "l1_span_and_grammar"; +} diff --git a/lib/pangea/constants/model_keys.dart b/lib/pangea/constants/model_keys.dart new file mode 100644 index 000000000..66f9d24a8 --- /dev/null +++ b/lib/pangea/constants/model_keys.dart @@ -0,0 +1,79 @@ +class ModelKey { + ///user model keys + static const String userAccess = 'access'; + static const String userRefresh = 'refresh'; + static const String userProfile = 'profile'; + static const String userFullName = 'full_name'; + static const String userCreatedAt = 'created_at'; + static const String userPangeaUserId = 'pangea_user_id'; + static const String userDateOfBirth = 'date_of_birth'; + static const String userTargetLanguage = 'target_language'; + static const String userSourceLanguage = 'source_language'; + static const String userSpeaks = 'speaks'; + static const String userCountry = 'country'; + static const String userInterests = 'interests'; + static const String l2LanguageKey = 'target_language'; + static const String l1LanguageKey = 'source_language'; + static const String publicProfile = 'public'; + static const String userId = 'user_id'; + + static const String clientClassCity = "city"; + static const String clientClassCountry = "country"; + static const String clientClassDominantLanguage = "dominantLanguage"; + static const String clientClassTargetLanguage = "targetLanguage"; + static const String clientClassDescription = "description"; + static const String clientLanguageLevel = "languageLevel"; + static const String clientSchool = "schoolName"; + + static const String clientIsPublic = "isPublic"; + static const String clientIsOpenEnrollment = 'isOpenEnrollment'; + static const String clientIsOpenExchange = 'isOpenExchange'; + static const String clientIsOneToOneChatClass = 'oneToOneChatClass'; + static const String clientIsOneToOneChatExchange = 'oneToOneChatExchange'; + static const String clientIsCreateRooms = 'isCreateRooms'; + static const String clientIsCreateRoomsExchange = 'isCreateRoomsExchange'; + static const String clientIsShareVideo = 'isShareVideo'; + static const String clientIsSharePhoto = 'isSharePhoto'; + static const String clientIsShareFiles = 'isShareFiles'; + static const String clientIsShareLocation = 'isShareLocation'; + static const String clientIsCreateStories = 'isCreateStories'; + static const String clientIsVoiceNotes = 'isVoiceNotes'; + static const String clientIsInviteOnlyStudents = 'isInviteOnlyStudents'; + static const String clientIsInviteOnlyExchanges = 'isInviteOnlyExchanges'; + + static const String userL1 = "user_l1"; + static const String userL2 = "user_l2"; + static const String fullText = "full_text"; + static const String fullTextLang = "full_text_lang"; + static const String tokens = "tokens"; + static const String srcLang = "src_lang"; + static const String tgtLang = "tgt_lang"; + static const String word = "word"; + static const String lang = "lang"; + static const String deepL = "deepl"; + static const String langCode = 'langCode'; + static const String wordLang = "word_lang"; + static const String lemma = "lemma"; + static const String saveVocab = "save_vocab"; + static const String text = "text"; + static const String permissions = "permissions"; + static const String enableIGC = "enable_igc"; + static const String enableIT = "enable_it"; + + static const String originalSent = "original_sent"; + static const String originalWritten = "original_written"; + static const String tokensSent = "tokens_sent"; + static const String tokensWritten = "tokens_written"; + static const String choreoRecord = "choreo_record"; + static const String useType = "use_type"; + + static const String baseDefinition = "base_definition"; + static const String targetDefinition = "target_definition"; + static const String basePartOfSpeech = "base_part_of_speech"; + static const String targetPartOfSpeech = "target_part_of_speech"; + static const String partOfSpeech = "part_of_speech"; + static const String baseWord = "base_word"; + static const String targetWord = "target_word"; + static const String baseExampleSentence = "base_example_sentence"; + static const String targetExampleSentence = "target_example_sentence"; +} diff --git a/lib/pangea/constants/pangea_event_types.dart b/lib/pangea/constants/pangea_event_types.dart new file mode 100644 index 000000000..68e849c88 --- /dev/null +++ b/lib/pangea/constants/pangea_event_types.dart @@ -0,0 +1,16 @@ +class PangeaEventTypes { + static const classSettings = "pangea.class"; + static const pangeaExchange = "p.exchange"; + + static const rules = "p.rules"; + + static const studentAnalyticsSummary = "pangea.usranalytics"; + + static const translation = "pangea.translation"; + static const tokens = "pangea.tokens"; + static const choreoRecord = "pangea.record"; + static const representation = "pangea.representation"; + + static const vocab = "p.vocab"; + static const roomInfo = "pangea.roomtopic"; +} diff --git a/lib/pangea/constants/pangea_message_types.dart b/lib/pangea/constants/pangea_message_types.dart new file mode 100644 index 000000000..23ee52abd --- /dev/null +++ b/lib/pangea/constants/pangea_message_types.dart @@ -0,0 +1,3 @@ +class PangeaMessageTypes { + static String report = 'm.report'; +} diff --git a/lib/pangea/constants/pangea_room_types.dart b/lib/pangea/constants/pangea_room_types.dart new file mode 100644 index 000000000..dcceadd36 --- /dev/null +++ b/lib/pangea/constants/pangea_room_types.dart @@ -0,0 +1,4 @@ +class PangeaRoomTypes { + static const analytics = 'p.analytics'; + static const exchange = 'p.exchange'; +} diff --git a/lib/pangea/constants/url_query_parameter_keys.dart b/lib/pangea/constants/url_query_parameter_keys.dart new file mode 100644 index 000000000..3f5c468db --- /dev/null +++ b/lib/pangea/constants/url_query_parameter_keys.dart @@ -0,0 +1,3 @@ +class UrlQueryParameterKeys { + static const String classCode = 'classcode'; +} diff --git a/lib/pangea/controllers/base_controller.dart b/lib/pangea/controllers/base_controller.dart new file mode 100644 index 000000000..ce41353e8 --- /dev/null +++ b/lib/pangea/controllers/base_controller.dart @@ -0,0 +1,18 @@ +import 'dart:async'; + +class BaseController { + final StreamController stateListener = StreamController(); + late Stream stateStream; + + BaseController() { + stateStream = stateListener.stream.asBroadcastStream(); + } + + dispose() { + stateListener.close(); + } + + setState({dynamic data}) { + stateListener.add(data); + } +} diff --git a/lib/pangea/controllers/class_controller.dart b/lib/pangea/controllers/class_controller.dart new file mode 100644 index 000000000..894498a49 --- /dev/null +++ b/lib/pangea/controllers/class_controller.dart @@ -0,0 +1,160 @@ +import 'dart:async'; +import 'dart:developer'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + +import 'package:collection/collection.dart'; +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:go_router/go_router.dart'; +import 'package:matrix/matrix.dart'; + +import 'package:fluffychat/pangea/constants/local.key.dart'; +import 'package:fluffychat/pangea/controllers/pangea_controller.dart'; +import 'package:fluffychat/pangea/extensions/client_extension.dart'; +import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart'; +import 'package:fluffychat/pangea/utils/class_code.dart'; +import 'package:fluffychat/pangea/utils/error_handler.dart'; +import '../../widgets/matrix.dart'; +import '../utils/bot_name.dart'; +import '../utils/firebase_analytics.dart'; +import 'base_controller.dart'; + +class ClassController extends BaseController { + late PangeaController _pangeaController; + + ClassController(PangeaController pangeaController) : super() { + _pangeaController = pangeaController; + } + + setActiveSpaceIdInChatListController(String classId) { + setState(data: {"activeSpaceId": classId}); + } + + Future fixClassPowerLevels() async { + try { + final List> classFixes = []; + for (final room in _pangeaController + .matrixState.client.classesAndExchangesImTeaching) { + classFixes.add(room.setClassPowerlLevels()); + } + await Future.wait(classFixes); + } catch (err, stack) { + debugger(when: kDebugMode); + ErrorHandler.logError(e: err, s: stack); + } + } + + void checkForClassCodeAndSubscription(BuildContext context) { + final String? classCode = _pangeaController.pStoreService.read( + PLocalKey.cachedClassCodeToJoin, + addClientIdToKey: false, + ); + + if (classCode != null) { + _pangeaController.pStoreService.delete( + PLocalKey.cachedClassCodeToJoin, + addClientIdToKey: false, + ); + joinClasswithCode( + context, + classCode, + ).onError( + (error, stackTrace) => + ClassCodeUtil.messageSnack(context, ErrorCopy(context, error).body), + ); + } else { + try { + //question for gabby: why do we need this in two places? + if (!_pangeaController.subscriptionController.isSubscribed) { + _pangeaController.subscriptionController.showPaywall(context); + } + } catch (err) { + debugger(when: kDebugMode); + } + } + } + + /// if not bot chat return + /// if bot chat, get pangeaClassContext + /// for all classes not in pangeaClassContext, add bot chat to that class + /// PTODO - add analytics bot to all chats and have that do this work + Future> addDirectChatsToClasses(Room room) async { + if (!room.isDirectChat) return []; + final List existingParentsIds = + room.pangeaSpaceParents.map((e) => e.id).toList(); + final List spaces = + _pangeaController.matrixState.client.classesAndExchangesImIn; + + //make sure we have the latest participants + await Future.wait(spaces.map((e) => e.requestParticipants())); + + //get spaces where, + //other chat participant is the bot OR is in the space AND the chat is not + final List spacesToAdd = spaces + .where( + (s) => + (room.directChatMatrixID == BotName.byEnvironment || + s + .getParticipants() + .map( + (u) => u.id, + ) + .contains(room.directChatMatrixID)) && + !existingParentsIds.contains(s.id), + ) + .toList(); + + //set the space child for each space + return Future.wait( + spacesToAdd.map((s) => s.setSpaceChild(room.id, suggested: true)), + ).then((value) => spaces); + } + + Future joinClasswithCode(BuildContext context, String classCode) async { + final QueryPublicRoomsResponse queryPublicRoomsResponse = + await Matrix.of(context).client.queryPublicRooms( + limit: 1, + filter: PublicRoomQueryFilter(genericSearchTerm: classCode), + ); + + final PublicRoomsChunk? classChunk = + queryPublicRoomsResponse.chunk.firstWhereOrNull((element) { + return element.canonicalAlias?.replaceAll("#", "").split(":")[0] == + classCode; + }); + + if (classChunk == null) { + ClassCodeUtil.messageSnack(context, L10n.of(context)!.unableToFindClass); + return; + } + + if (Matrix.of(context) + .client + .rooms + .any((room) => room.id == classChunk.roomId)) { + setActiveSpaceIdInChatListController(classChunk.roomId); + ClassCodeUtil.messageSnack(context, L10n.of(context)!.alreadyInClass); + return; + } + await _pangeaController.matrixState.client.joinRoom(classChunk.roomId); + + setActiveSpaceIdInChatListController(classChunk.roomId); + + GoogleAnalytics.joinClass(classCode); + + ClassCodeUtil.messageSnack( + context, + L10n.of(context)!.welcomeToYourNewClass, + ); + + context.go("/rooms"); + return; + // P-EPIC + // prereq - server needs ability to invite to private room. how? + // does server api have ability with admin token? + // is application service needed? + // BE - check class code and if class code is correct, invite student to room + // FE - look for invite from room and automatically accept + } +} diff --git a/lib/pangea/controllers/contextual_definition_controller.dart b/lib/pangea/controllers/contextual_definition_controller.dart new file mode 100644 index 000000000..c13a428b8 --- /dev/null +++ b/lib/pangea/controllers/contextual_definition_controller.dart @@ -0,0 +1,148 @@ +import 'dart:convert'; + +import 'package:flutter/foundation.dart'; + +import 'package:collection/collection.dart'; +import 'package:http/http.dart'; + +import 'package:fluffychat/pangea/config/environment.dart'; +import 'package:fluffychat/pangea/utils/error_handler.dart'; +import '../constants/model_keys.dart'; +import '../network/requests.dart'; +import '../network/urls.dart'; +import 'pangea_controller.dart'; + +class ContextualDefinitionController { + late PangeaController _pangeaController; + + final List<_ContextualDefinitionCacheItem> _definitions = []; + + ContextualDefinitionController(PangeaController pangeaController) { + _pangeaController = pangeaController; + } + + _ContextualDefinitionCacheItem? _getLocal( + ContextualDefinitionRequestModel req, + ) => + _definitions.firstWhereOrNull( + (e) => e.word == req.word && e.fullText == req.fullText, + ); + + Future get( + ContextualDefinitionRequestModel req, + ) { + final _ContextualDefinitionCacheItem? localItem = _getLocal(req); + + if (localItem != null) return localItem.data; + + _definitions.add( + _ContextualDefinitionCacheItem( + word: req.word, + fullText: req.fullText, + data: _define(req), + ), + ); + + return _definitions.last.data; + } + + Future _define( + ContextualDefinitionRequestModel request, + ) async { + try { + final ContextualDefinitionResponseModel res = + await _ContextualDefinitionRepo.define( + await _pangeaController.userController.accessToken, + request, + ); + return res; + } catch (err, stack) { + debugPrint( + "error getting contextual definition for ${request.word} in '${request.fullText}'", + ); + ErrorHandler.logError(e: err, s: stack, data: request.toJson()); + return null; + } + } +} + +class _ContextualDefinitionCacheItem { + String word; + String fullText; + Future data; + + _ContextualDefinitionCacheItem({ + required this.word, + required this.fullText, + required this.data, + }); +} + +class _ContextualDefinitionRepo { + static Future define( + String accessToken, + ContextualDefinitionRequestModel request, + ) async { + final Requests req = Requests( + choreoApiKey: Environment.choreoApiKey, + accessToken: accessToken, + ); + + final Response res = await req.post( + url: PApiUrls.contextualDefinition, + body: request.toJson(), + ); + + final ContextualDefinitionResponseModel response = + ContextualDefinitionResponseModel.fromJson( + jsonDecode( + utf8.decode(res.bodyBytes).toString(), + ), + ); + + if (response.text.isEmpty) { + ErrorHandler.logError( + e: Exception( + "empty text in contextual definition response", + ), + ); + } + + return response; + } +} + +class ContextualDefinitionRequestModel { + final String fullText; + final String word; + final String feedbackLang; + final String fullTextLang; + final String wordLang; + + ContextualDefinitionRequestModel({ + required this.fullText, + required this.word, + required this.feedbackLang, + required this.fullTextLang, + required this.wordLang, + }); + + Map toJson() => { + ModelKey.fullText: fullText, + ModelKey.word: word, + ModelKey.lang: feedbackLang, + ModelKey.fullTextLang: fullTextLang, + ModelKey.wordLang: wordLang, + }; +} + +class ContextualDefinitionResponseModel { + String text; + + ContextualDefinitionResponseModel({required this.text}); + + factory ContextualDefinitionResponseModel.fromJson( + Map json, + ) => + ContextualDefinitionResponseModel(text: json["response"]); +} diff --git a/lib/pangea/controllers/language_controller.dart b/lib/pangea/controllers/language_controller.dart new file mode 100644 index 000000000..b96c82b8b --- /dev/null +++ b/lib/pangea/controllers/language_controller.dart @@ -0,0 +1,110 @@ +import 'dart:developer'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + +import 'package:matrix/matrix.dart'; +import 'package:sentry_flutter/sentry_flutter.dart'; + +import 'package:fluffychat/pangea/constants/language_keys.dart'; +import 'package:fluffychat/pangea/controllers/language_list_controller.dart'; +import 'package:fluffychat/pangea/controllers/pangea_controller.dart'; +import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart'; +import 'package:fluffychat/pangea/models/class_model.dart'; +import 'package:fluffychat/pangea/models/language_model.dart'; +import '../widgets/user_settings/p_language_dialog.dart'; + +class LanguageController { + late PangeaController _pangeaController; + + LanguageController(PangeaController pangeaController) { + _pangeaController = pangeaController; + } + //show diloag when user does not have languages selected + showDialogOnEmptyLanguage(BuildContext dialogContext, Function callback) { + if (_pangeaController.userController.userModel?.profile == null) { + debugger(when: kDebugMode); + Sentry.addBreadcrumb( + Breadcrumb( + message: 'calling showDialogOnEmptyLanguagae with empty user', + ), + ); + return; + } + if (_userL1Code == null || + _userL2Code == null || + _userL1Code!.isEmpty || + _userL2Code!.isEmpty || + _userL1Code == LanguageKeys.unknownLanguage || + _userL2Code == LanguageKeys.unknownLanguage) { + pLanguageDialog(dialogContext, callback); + } + } + + String? get _userL1Code { + final source = + _pangeaController.userController.userModel?.profile?.sourceLanguage; + return source == null || source.isEmpty ? null : source; + } + + String? get _userL2Code { + final target = + _pangeaController.userController.userModel?.profile?.targetLanguage; + return target == null || target.isEmpty ? null : target; + } + + LanguageModel? get userL1 { + return _userL1Code != null ? PangeaLanguage.byLangCode(_userL1Code!) : null; + } + + LanguageModel? get userL2 { + return _userL2Code != null ? PangeaLanguage.byLangCode(_userL2Code!) : null; + } + + String? activeL1Code({String? roomID}) { + final String? activeL2 = activeL2Code(roomID: roomID); + if (roomID == null || activeL2 != _userL1Code) { + return _userL1Code; + } + final ClassSettingsModel? classContext = _pangeaController + .matrixState.client + .getRoomById(roomID) + ?.firstLanguageSettings; + final String? classL1 = classContext?.dominantLanguage; + if (classL1 == LanguageKeys.mixedLanguage || + classL1 == LanguageKeys.multiLanguage || + classL1 == null) { + if (_userL2Code != _userL1Code) { + return _userL2Code; + } + return LanguageKeys.unknownLanguage; + } + return classL1; + } + + /// Class languages override user languages within a class context + String? activeL2Code({String? roomID}) { + if (roomID == null) { + return _userL2Code; + } + final ClassSettingsModel? classContext = _pangeaController + .matrixState.client + .getRoomById(roomID) + ?.firstLanguageSettings; + return classContext?.targetLanguage ?? _userL2Code; + } + + LanguageModel? activeL1Model({String? roomID}) { + final activeL1 = activeL1Code(roomID: roomID); + return activeL1 != null ? PangeaLanguage.byLangCode(activeL1) : null; + } + + LanguageModel? activeL2Model({String? roomID}) { + final activeL2 = activeL2Code(roomID: roomID); + final model = activeL2 != null ? PangeaLanguage.byLangCode(activeL2) : null; + return model; + } + + bool equalActiveL1AndActiveL2({Room? room}) => + activeL1Code() == activeL2Code(roomID: room?.id); +} diff --git a/lib/pangea/controllers/language_list_controller.dart b/lib/pangea/controllers/language_list_controller.dart new file mode 100644 index 000000000..ef86fead9 --- /dev/null +++ b/lib/pangea/controllers/language_list_controller.dart @@ -0,0 +1,97 @@ +import 'dart:async'; +import 'dart:developer'; + +import 'package:flutter/foundation.dart'; + +import 'package:fluffychat/pangea/constants/language_keys.dart'; +import 'package:fluffychat/pangea/models/language_model.dart'; +import 'package:fluffychat/pangea/repo/language_repo.dart'; +import 'package:fluffychat/pangea/utils/error_handler.dart'; +import '../constants/language_list_keys.dart'; +import '../utils/shared_prefs.dart'; + +class PangeaLanguage { + PangeaLanguage() { + initialize(); + } + + static List _langList = []; + + List get langList => _langList; + + List get targetOptions => + _langList.where((element) => element.languageType == 2).toList(); + + List get baseOptions => + _langList.where((element) => element.languageType == 1).toList(); + + static Future initialize() async { + try { + _langList = await _getCahedFlags(); + if (await _shouldFetch || _langList.isEmpty) { + _langList = await LanguageRepo.fetchLanguages(); + + await _saveFlags(_langList); + await saveLastFetchDate(); + } + _langList.removeWhere( + (element) => + LanguageModel.codeFromNameOrCode(element.langCode) == + LanguageKeys.unknownLanguage, + ); + _langList.sort((a, b) => a.displayName.compareTo(b.displayName)); + _langList.insert(0, LanguageModel.multiLingual()); + } catch (err, stack) { + debugger(when: kDebugMode); + ErrorHandler.logError(e: err, s: stack); + } + } + + static saveLastFetchDate() async { + final String now = DateTime.now().toIso8601String(); + await MyShared.saveString(PrefKey.lastFetched, now); + } + + static Future get _shouldFetch async { + final String? dateString = await MyShared.readString(PrefKey.lastFetched); + if (dateString == null) { + return true; + } + // return true; + final int lastFetched = DateTime.parse(dateString).millisecondsSinceEpoch; + final int now = DateTime.now().millisecondsSinceEpoch; + const int fetchIntervalInMilliseconds = 86534601; + return (now - lastFetched) >= fetchIntervalInMilliseconds ? true : false; + } + + static Future _saveFlags(List langFlags) async { + final Map flagMap = { + PrefKey.flags: langFlags.map((e) => e.toJson()).toList(), + }; + await MyShared.saveJson(PrefKey.flags, flagMap); + } + + static Future> _getCahedFlags() async { + final Map? flagsMap = + await MyShared.readJson(PrefKey.flags); + if (flagsMap == null) { + return []; + } + + final List flags = []; + final List mapList = flagsMap[PrefKey.flags] as List; + for (final element in mapList) { + flags.add(LanguageModel.fromJson(element)); + } + + return flags; + } + + static LanguageModel byLangCode(String langCode) { + final list = _langList; + for (final element in _langList) { + if (element.langCode == langCode) return element; + } + return LanguageModel.unknown; + } +} diff --git a/lib/pangea/controllers/local_settings.dart b/lib/pangea/controllers/local_settings.dart new file mode 100644 index 000000000..5984a7bf5 --- /dev/null +++ b/lib/pangea/controllers/local_settings.dart @@ -0,0 +1,28 @@ +import 'package:fluffychat/pangea/controllers/pangea_controller.dart'; +import 'package:fluffychat/pangea/models/class_model.dart'; + +class LocalSettings { + late PangeaController _pangeaController; + + LocalSettings(PangeaController pangeaController) : super() { + _pangeaController = pangeaController; + } + + bool userLanguageToolSetting(ToolSetting setting) => + _pangeaController.pStoreService.read(setting.toString()) ?? true; + + // bool get userEnableIT => + // _pangeaController.pStoreService.read(ToolSetting.interactiveTranslator.toString()) ?? true; + + // bool get userEnableIGC => + // _pangeaController.pStoreService.read(ToolSetting.interactiveGrammar.toString()) ?? true; + + // bool get userImmersionMode => + // _pangeaController.pStoreService.read(ToolSetting.immersionMode.toString()) ?? true; + + // bool get userTranslationsTool => + // _pangeaController.pStoreService.read(ToolSetting.translations.toString()) ?? true; + + // bool get userDefinitionsTool => + // _pangeaController.pStoreService.read(ToolSetting.definitions.toString()) ?? true; +} diff --git a/lib/pangea/controllers/message_analytics_controller.dart b/lib/pangea/controllers/message_analytics_controller.dart new file mode 100644 index 000000000..78c75b408 --- /dev/null +++ b/lib/pangea/controllers/message_analytics_controller.dart @@ -0,0 +1,451 @@ +import 'dart:developer'; + +import 'package:flutter/foundation.dart'; + +import 'package:matrix/matrix.dart'; + +import 'package:fluffychat/pangea/enum/construct_type_enum.dart'; +import 'package:fluffychat/pangea/enum/time_span.dart'; +import 'package:fluffychat/pangea/models/headwords.dart'; +import 'package:fluffychat/pangea/models/student_analytics_summary_model.dart'; +import 'package:fluffychat/pangea/pages/analytics/base_analytics_page.dart'; +import 'package:fluffychat/pangea/utils/error_handler.dart'; +import '../constants/class_default_values.dart'; +import '../extensions/client_extension.dart'; +import '../extensions/pangea_room_extension.dart'; +import '../models/chart_analytics_model.dart'; +import '../models/construct_analytics_event.dart'; +import '../models/student_analytics_event.dart'; +import 'base_controller.dart'; +import 'pangea_controller.dart'; + +class AnalyticsController extends BaseController { + late PangeaController _pangeaController; + + final List _cachedModels = []; + + AnalyticsController(PangeaController pangeaController) : super() { + _pangeaController = pangeaController; + } + + String get _analyticsTimeSpanKey => "ANALYTICS_TIME_SPAN_KEY"; + + TimeSpan get currentAnalyticsTimeSpan { + try { + final String? str = + _pangeaController.pStoreService.read(_analyticsTimeSpanKey); + return str != null + ? TimeSpan.values.firstWhere((e) { + final spanString = e.toString(); + return spanString == str; + }) + : ClassDefaultValues.defaultTimeSpan; + } catch (err) { + debugger(when: kDebugMode); + return ClassDefaultValues.defaultTimeSpan; + } + } + + Future setCurrentAnalyticsTimeSpan(TimeSpan timeSpan) async { + await _pangeaController.pStoreService + .save(_analyticsTimeSpanKey, timeSpan.toString()); + } + + Future> allClassAnalytics() { + final List> classAnalyticFutures = []; + for (final classRoom + in _pangeaController.matrixState.client.classesAndExchangesImTeaching) { + classAnalyticFutures.add( + getAnalytics(classRoom: classRoom), + ); + } + + return Future.wait(classAnalyticFutures); + } + + ChartAnalyticsModel? getAnalyticsLocal({ + TimeSpan? timeSpan, + String? classId, + String? studentId, + String? chatId, + bool forceUpdate = false, + bool updateExpired = false, + }) { + timeSpan ??= currentAnalyticsTimeSpan; + final int index = _cachedModels.indexWhere( + (e) => + (e.timeSpan == timeSpan) && + (e.classId == classId) && + (e.studentId == studentId) && + (e.chatId == chatId), + ); + + if (index != -1) { + if ((updateExpired && _cachedModels[index].isExpired) || forceUpdate) { + _cachedModels.removeAt(index); + } else { + return _cachedModels[index].chartAnalyticsModel; + } + } + + return null; + } + + Future getAnalytics({ + TimeSpan? timeSpan, + Room? classRoom, + String? studentId, + String? chatId, + bool forceUpdate = false, + }) async { + timeSpan ??= currentAnalyticsTimeSpan; + try { + final cachedModel = getAnalyticsLocal( + classId: classRoom?.id, + studentId: studentId, + chatId: chatId, + updateExpired: true, + forceUpdate: forceUpdate, + ); + if (cachedModel != null) return cachedModel; + // debugger(when: classRoom?.displayname.contains('clizass') ?? false); + late List studentAnalyticsSummaryEvents; + if (classRoom == null) { + if (studentId == null) { + debugger(when: kDebugMode); + ErrorHandler.logError( + m: "studentId should have been defined", + s: StackTrace.current, + ); + } else { + studentAnalyticsSummaryEvents = + await _pangeaController.myAnalytics.allMyAnalyticsEvents(); + } + } else { + if (studentId != null) { + studentAnalyticsSummaryEvents = [ + await classRoom.getStudentAnalytics(studentId), + ]; + } else { + studentAnalyticsSummaryEvents = await classRoom.getClassAnalytics(); + } + if (studentId != null && chatId != null) { + debugger(when: kDebugMode); + ErrorHandler.logError( + m: "studentId and chatId should have both been defined", + s: StackTrace.current, + ); + studentAnalyticsSummaryEvents = []; + } + } + + final List msgs = []; + for (final event in studentAnalyticsSummaryEvents) { + if (event != null) { + msgs.addAll(event.content.messages); + } else { + debugPrint("studentAnalyticsSummaryEvent is null"); + } + } + final newModel = ChartAnalyticsModel( + timeSpan: timeSpan, + msgs: msgs, + chatId: chatId, + ); + + _cachedModels.add( + CacheModel( + timeSpan: timeSpan, + classId: classRoom?.id, + studentId: studentId, + chatId: chatId, + chartAnalyticsModel: newModel, + ), + ); + + return newModel; + } catch (err, s) { + debugger(when: kDebugMode); + ErrorHandler.logError(e: err, s: s); + return ChartAnalyticsModel(msgs: [], timeSpan: timeSpan, chatId: chatId); + } + } + + Future vocabHeadwordsWithTotals( + String langCode, + List vocab, [ + String? chatId, + ]) async { + final VocabHeadwords vocabHeadwords = + await VocabHeadwords.getHeadwords(langCode); + for (final vocabList in vocabHeadwords.lists) { + for (final vocabEvent in vocab) { + vocabList.addVocabUse( + vocabEvent.content.lemma, + vocabEvent.content.uses, + ); + } + } + return vocabHeadwords; + } + + Future getAnalyticsForPrivateChats({ + TimeSpan? timeSpan, + required Room? classRoom, + bool forceUpdate = false, + }) async { + timeSpan ??= currentAnalyticsTimeSpan; + + try { + if (classRoom == null) { + return ChartAnalyticsModel(msgs: [], timeSpan: timeSpan); + } + + final cachedModel = getAnalyticsLocal( + classId: classRoom.id, + studentId: null, + chatId: AnalyticsEntryType.privateChats.toString(), + updateExpired: true, + forceUpdate: forceUpdate, + ); + if (cachedModel != null) return cachedModel; + final List studentAnalyticsSummaryEvents = + await classRoom.getClassAnalytics(); + final List directChatIds = + classRoom.childrenAndGrandChildrenDirectChatIds; + + final List msgs = []; + for (final event in studentAnalyticsSummaryEvents) { + if (event != null) { + msgs.addAll( + event.content.messages + .where((m) => directChatIds.contains(m.chatId)), + ); + } else { + debugPrint("studentAnalyticsSummaryEvent is null"); + } + } + final newModel = ChartAnalyticsModel( + timeSpan: timeSpan, + msgs: msgs, + chatId: null, + ); + + _cachedModels.add( + CacheModel( + timeSpan: timeSpan, + classId: classRoom.id, + studentId: null, + chatId: AnalyticsEntryType.privateChats.toString(), + chartAnalyticsModel: newModel, + ), + ); + + return newModel; + } catch (err, s) { + debugger(when: kDebugMode); + ErrorHandler.logError(e: err, s: s); + return ChartAnalyticsModel(msgs: [], timeSpan: timeSpan); + } + } + + Future myAnalyticsRoom(String langCode) => + _pangeaController.matrixState.client.getMyAnalyticsRoom(langCode); + + Future> myConstructs(String langCode) async { + final Room analyticsRoom = await myAnalyticsRoom(langCode); + + return analyticsRoom.allConstructEvents; + } + + Future> studentConstructs( + String studentId, + String langCode, + ) { + final Room? analyticsRoom = _pangeaController.matrixState.client + .analyticsRoomLocal(langCode, studentId); + return analyticsRoom!.allConstructEvents; + } + + Future> spaceMemberVocab(String spaceId) async { + await _pangeaController.matrixState.client.roomsLoading; + final Room? space = + _pangeaController.matrixState.client.getRoomById(spaceId); + if (space == null) { + throw Exception("space missing in spaceVocab"); + } + final String? langCode = space.firstLanguageSettings?.targetLanguage; + + final List>> vocabEventFutures = []; + await space.requestParticipants(); + for (final student in space.students) { + final Room? room = _pangeaController.matrixState.client + .analyticsRoomLocal(langCode, student.id); + if (room != null) vocabEventFutures.add(room.allConstructEvents); + } + + final List> allVocabLists = + await Future.wait(vocabEventFutures); + + final List allVocab = []; + for (final vocabList in allVocabLists) { + allVocab.addAll(vocabList); + } + return allVocab; + } + + /// in student analytics page, the [defaultSelected] is the student + /// in class analytics page, the [defaultSelected] is the class + /// [defaultSelected] should never be a chat + /// the specific [selected] will be those items in the lists - chat, student or class + Future vocabHeadsByAnalyticsSelected({ + required AnalyticsSelected? selected, + required AnalyticsSelected defaultSelected, + }) async { + Future> eventsFuture; + String langCode; + + if (defaultSelected.type == AnalyticsEntryType.space) { + // as long as a student isn't selected, we want the vocab events for the whole class + final Room? classRoom = + _pangeaController.matrixState.client.getRoomById(defaultSelected.id); + if (classRoom == null) { + throw Exception("classRoom missing in spaceMemberVocab"); + } + langCode = classRoom.classSettings!.targetLanguage; + + if (selected?.type != AnalyticsEntryType.student) { + eventsFuture = spaceMemberVocab(defaultSelected.id); + } else { + eventsFuture = studentConstructs(selected!.id, langCode); + } + } else if (defaultSelected.type == AnalyticsEntryType.student) { + // in this case, we're on an individual's own analytics page + + if (selected?.type == AnalyticsEntryType.space || + selected?.type == AnalyticsEntryType.student) { + langCode = _pangeaController.languageController + .activeL2Code(roomID: selected!.id)!; + eventsFuture = myConstructs(langCode); + } else { + langCode = _pangeaController.languageController.userL2!.langCode; + eventsFuture = myConstructs(langCode); + } + } else { + throw Exception("invalid defaultSelected.type - ${defaultSelected.type}"); + } + + return vocabHeadwordsWithTotals(langCode, await eventsFuture); + } + + /// in student analytics page, the [defaultSelected] is the student + /// in class analytics page, the [defaultSelected] is the class + /// [defaultSelected] should never be a chat + /// the specific [selected] will be those items in the lists - chat, student or class + Future> constuctEventsByAnalyticsSelected({ + required AnalyticsSelected? selected, + required AnalyticsSelected defaultSelected, + required ConstructType constructType, + }) async { + late Future> eventFutures; + String? langCode; + if (defaultSelected.type == AnalyticsEntryType.space) { + // as long as a student isn't selected, we want the vocab events for the whole class + final Room? space = + _pangeaController.matrixState.client.getRoomById(defaultSelected.id); + if (space == null) { + throw "No space available"; + } + langCode = space.firstLanguageSettings?.targetLanguage; + if (langCode == null) { + throw "No target language available"; + } + + if (selected?.type != AnalyticsEntryType.student) { + eventFutures = spaceMemberVocab(defaultSelected.id); + } else { + eventFutures = studentConstructs(selected!.id, langCode); + } + } else if (defaultSelected.type == AnalyticsEntryType.student) { + // in this case, we're on an individual's own analytics page + + if (selected?.type == AnalyticsEntryType.space || + selected?.type == AnalyticsEntryType.student) { + langCode = _pangeaController.languageController + .activeL2Code(roomID: selected!.id)!; + eventFutures = myConstructs(langCode); + } else { + langCode = _pangeaController.languageController.userL2!.langCode; + eventFutures = myConstructs(langCode); + } + } else { + throw "invalid defaultSelected.type - ${defaultSelected.type}"; + } + + final List events = (await eventFutures) + .where( + (element) => element.content.type == constructType, + ) + .toList(); + + final List chatIdsToFilterBy = []; + if (selected?.type == AnalyticsEntryType.room) { + chatIdsToFilterBy.add(selected!.id); + } else if (selected?.type == AnalyticsEntryType.privateChats) { + chatIdsToFilterBy.addAll( + _pangeaController.matrixState.client + .getRoomById(defaultSelected.id) + ?.childrenAndGrandChildrenDirectChatIds ?? + [], + ); + } else if (defaultSelected.type == AnalyticsEntryType.space) { + chatIdsToFilterBy.addAll( + _pangeaController.matrixState.client + .getRoomById(defaultSelected.id) + ?.childrenAndGrandChildren + .where((e) => e.roomId != null) + .map((e) => e.roomId!) ?? + [], + ); + } + if (chatIdsToFilterBy.isNotEmpty) { + for (final event in events) { + event.content.uses + .removeWhere((u) => !chatIdsToFilterBy.contains(u.chatId)); + } + events.removeWhere((e) => e.content.uses.isEmpty); + } + + return events; + } +} + +class CacheModel { + TimeSpan timeSpan; + ChartAnalyticsModel chartAnalyticsModel; + String? classId; + String? chatId; + String? studentId; + late DateTime _createdAt; + + CacheModel({ + required this.timeSpan, + required this.classId, + required this.chartAnalyticsModel, + required this.chatId, + required this.studentId, + }) { + _createdAt = DateTime.now(); + } + + bool get isExpired => + DateTime.now().difference(_createdAt).inMinutes > + ClassDefaultValues.minutesDelayToMakeNewChartAnalytics; +} + +// class ListTotals { +// String listName; +// ConstructUses vocabUse; + +// ListTotals({required this.listName, required this.vocabUse}); +// } diff --git a/lib/pangea/controllers/message_data_controller.dart b/lib/pangea/controllers/message_data_controller.dart new file mode 100644 index 000000000..130afcdfe --- /dev/null +++ b/lib/pangea/controllers/message_data_controller.dart @@ -0,0 +1,236 @@ +import 'dart:developer'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + +import 'package:collection/collection.dart'; +import 'package:matrix/matrix.dart'; +import 'package:sentry_flutter/sentry_flutter.dart'; + +import 'package:fluffychat/pangea/controllers/base_controller.dart'; +import 'package:fluffychat/pangea/controllers/pangea_controller.dart'; +import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart'; +import 'package:fluffychat/pangea/models/message_data_models.dart'; +import 'package:fluffychat/pangea/repo/tokens_repo.dart'; +import '../constants/pangea_event_types.dart'; +import '../enum/use_type.dart'; +import '../models/choreo_record.dart'; +import '../repo/full_text_translation_repo.dart'; +import '../utils/error_handler.dart'; + +class MessageDataController extends BaseController { + late PangeaController _pangeaController; + + final List _cache = []; + + final Map _messageDataToSave = {}; + + MessageDataController(PangeaController pangeaController) { + _pangeaController = pangeaController; + } + + CacheItem? getItem(String parentId, String type, String langCode) => + _cache.firstWhereOrNull( + (e) => + e.parentId == parentId && e.type == type && e.langCode == langCode, + ); + + Future _getTokens( + TokensRequestModel req, + ) async { + final accessToken = await _pangeaController.userController.accessToken; + + final TokensResponseModel igcTextData = + await TokensRepo.tokenize(accessToken, req); + + return PangeaMessageTokens(tokens: igcTextData.tokens); + } + + Future _getTokenEvent({ + required BuildContext context, + required String repEventId, + required TokensRequestModel req, + required Room room, + }) async { + try { + final PangeaMessageTokens? pangeaMessageTokens = await _getTokens( + req, + ); + if (pangeaMessageTokens == null) return null; + + final Event? tokensEvent = await room.sendPangeaEvent( + content: pangeaMessageTokens.toJson(), + parentEventId: repEventId, + type: PangeaEventTypes.tokens, + ); + + return tokensEvent; + } catch (err, stack) { + Sentry.addBreadcrumb( + Breadcrumb( + message: "err in _getTokenEvent with repEventId $repEventId", + ), + ); + Sentry.addBreadcrumb( + Breadcrumb.fromJson({"req": req.toJson()}), + ); + Sentry.addBreadcrumb( + Breadcrumb.fromJson({"room": room.toJson()}), + ); + ErrorHandler.logError(e: err, s: stack); + return null; + } + } + + Future getTokenEvent({ + required BuildContext context, + required String repEventId, + required TokensRequestModel req, + required Room room, + }) async { + final CacheItem? item = + getItem(repEventId, PangeaEventTypes.tokens, req.userL2); + if (item != null) return item.data; + + _cache.add( + CacheItem( + repEventId, + PangeaEventTypes.tokens, + req.userL2, + _getTokenEvent( + context: context, + repEventId: repEventId, + req: req, + room: room, + ), + ), + ); + + return _cache.last.data; + } + + /////// translation //////// + + /// make representation (originalSent and originalWritten always false) + Future _getRepresentationMatrixEvent({ + required BuildContext context, + required String messageEventId, + required FullTextTranslationRequestModel req, + required Room room, + }) async { + try { + final FullTextTranslationResponseModel res = + await FullTextTranslationRepo.translate( + accessToken: await _pangeaController.userController.accessToken, + request: req, + ); + + final PangeaRepresentation representation = PangeaRepresentation( + langCode: req.tgtLang, + text: res.bestTranslation, + originalSent: false, + originalWritten: false, + ); + + final Event? repEvent = await room.sendPangeaEvent( + content: representation.toJson(), + parentEventId: messageEventId, + type: PangeaEventTypes.representation, + ); + + debugger(when: kDebugMode && repEvent == null); + + return repEvent; + } catch (err, stack) { + Sentry.addBreadcrumb( + Breadcrumb( + message: + "err in _getRepresentationMatrixEvent with messageEventId $messageEventId", + ), + ); + Sentry.addBreadcrumb( + Breadcrumb.fromJson({"req": req.toJson()}), + ); + Sentry.addBreadcrumb( + Breadcrumb.fromJson({"room": room.toJson()}), + ); + ErrorHandler.logError(e: err, s: stack); + return null; + } + } + + /// make representation (originalSent and originalWritten always false) + Future getRepresentationMatrixEvent({ + required BuildContext context, + required String messageEventId, + required String text, + required String? source, + required String target, + required Room room, + }) { + final CacheItem? item = + getItem(messageEventId, PangeaEventTypes.representation, target); + if (item != null) return item.data; + + _cache.add( + CacheItem( + messageEventId, + PangeaEventTypes.representation, + target, + _getRepresentationMatrixEvent( + context: context, + messageEventId: messageEventId, + req: FullTextTranslationRequestModel( + text: text, + tgtLang: target, + srcLang: source, + userL2: _pangeaController.languageController + .activeL2Code(roomID: room.id)!, + userL1: _pangeaController.languageController + .activeL1Code(roomID: room.id)!, + ), + room: room, + ), + ), + ); + + return _cache.last.data; + } +} + +class MessageDataQueueItem { + String transactionId; + + List repTokensAndRecords; + + UseType useType; + + MessageDataQueueItem( + this.transactionId, + this.repTokensAndRecords, + this.useType, + // required this.recentMessageRecord, + ); +} + +class RepTokensAndRecord { + PangeaRepresentation representation; + ChoreoRecord? choreoRecord; + PangeaMessageTokens? tokens; + RepTokensAndRecord(this.representation, this.choreoRecord, this.tokens); + + Map toJson() => { + "rep": representation.toJson(), + "choreoRecord": choreoRecord?.toJson(), + "tokens": tokens?.toJson(), + }; +} + +class CacheItem { + String parentId; + String langCode; + String type; + Future data; + + CacheItem(this.parentId, this.type, this.langCode, this.data); +} diff --git a/lib/pangea/controllers/my_analytics_controller.dart b/lib/pangea/controllers/my_analytics_controller.dart new file mode 100644 index 000000000..1fbb15b6f --- /dev/null +++ b/lib/pangea/controllers/my_analytics_controller.dart @@ -0,0 +1,108 @@ +import 'dart:async'; +import 'dart:developer'; + +import 'package:flutter/foundation.dart'; + +import 'package:matrix/matrix.dart'; + +import 'package:fluffychat/pangea/controllers/pangea_controller.dart'; +import 'package:fluffychat/pangea/models/student_analytics_summary_model.dart'; +import 'package:fluffychat/pangea/utils/error_handler.dart'; +import '../extensions/client_extension.dart'; +import '../extensions/pangea_room_extension.dart'; +import '../models/constructs_analytics_model.dart'; +import '../models/student_analytics_event.dart'; + +class MyAnalyticsController { + late PangeaController _pangeaController; + + MyAnalyticsController(PangeaController pangeaController) { + _pangeaController = pangeaController; + } + + String? get _userId => _pangeaController.matrixState.client.userID; + + //PTODO - locally cache and update periodically + Future handleMessage( + Room room, + RecentMessageRecord messageRecord, + ) async { + try { + debugPrint("in handle message with type ${messageRecord.useType}"); + if (_userId == null) { + debugger(when: kDebugMode); + ErrorHandler.logError( + m: "null userId in updateAnalytics", + s: StackTrace.current, + ); + return; + } + + await _pangeaController.classController.addDirectChatsToClasses(room); + //expanding this to all parents of the room + // final List spaces = room.immediateClassParents; + final List spaces = room.pangeaSpaceParents; + // janky but probably stays until we have a class analytics bot added by + // default to all chats + + final List events = await analyticsEvents(spaces); + + for (final event in events) { + debugPrint("adding to total ${event?.content.messages.length}"); + if (event != null) { + event.handleNewMessage(messageRecord); + } + } + } catch (err) { + debugger(when: kDebugMode); + } + } + + Future> analyticsEvents( + List spaces, + ) async { + final List> events = []; + for (final space in spaces) { + events.add(space.getStudentAnalytics(_userId!)); + } + return Future.wait(events); + } + + Future> allMyAnalyticsEvents() => + analyticsEvents( + _pangeaController.matrixState.client.classesAndExchangesImStudyingIn, + ); + + Future saveConstructsMixed( + List allUses, + String langCode, + ) async { + try { + final Map> aggregatedVocabUse = {}; + for (final use in allUses) { + aggregatedVocabUse[use.lemma!] ??= []; + aggregatedVocabUse[use.lemma]!.add(use); + } + final Room analyticsRoom = await _pangeaController.matrixState.client + .getMyAnalyticsRoom(langCode); + analyticsRoom.makeSureTeachersAreInvitedToAnalyticsRoom(); + final List> saveFutures = []; + for (final uses in aggregatedVocabUse.entries) { + debugPrint("saving of type ${uses.value.first.constructType}"); + saveFutures.add( + analyticsRoom.saveConstructUsesSameLemma( + uses.key, + uses.value.first.constructType!, + uses.value, + ), + ); + } + + await Future.wait(saveFutures); + } catch (err, s) { + debugger(when: kDebugMode); + if (!kDebugMode) rethrow; + ErrorHandler.logError(e: err, s: s); + } + } +} diff --git a/lib/pangea/controllers/pangea_controller.dart b/lib/pangea/controllers/pangea_controller.dart new file mode 100644 index 000000000..728f86131 --- /dev/null +++ b/lib/pangea/controllers/pangea_controller.dart @@ -0,0 +1,236 @@ +import 'dart:developer'; +import 'dart:math'; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/foundation.dart'; + +import 'package:matrix/matrix.dart'; +import 'package:sentry_flutter/sentry_flutter.dart'; + +import 'package:fluffychat/pangea/constants/class_default_values.dart'; +import 'package:fluffychat/pangea/controllers/class_controller.dart'; +import 'package:fluffychat/pangea/controllers/contextual_definition_controller.dart'; +import 'package:fluffychat/pangea/controllers/language_controller.dart'; +import 'package:fluffychat/pangea/controllers/language_list_controller.dart'; +import 'package:fluffychat/pangea/controllers/local_settings.dart'; +import 'package:fluffychat/pangea/controllers/message_data_controller.dart'; +import 'package:fluffychat/pangea/controllers/my_analytics_controller.dart'; +import 'package:fluffychat/pangea/controllers/permissions_controller.dart'; +import 'package:fluffychat/pangea/controllers/subscription_controller.dart'; +import 'package:fluffychat/pangea/controllers/user_controller.dart'; +import 'package:fluffychat/pangea/controllers/word_net_controller.dart'; +import 'package:fluffychat/pangea/guard/p_vguard.dart'; +import 'package:fluffychat/pangea/utils/bot_name.dart'; +import 'package:fluffychat/pangea/utils/error_handler.dart'; +import 'package:fluffychat/pangea/utils/instructions.dart'; +import 'package:fluffychat/widgets/matrix.dart'; +import '../../config/app_config.dart'; +import '../utils/firebase_analytics.dart'; +import '../utils/p_store.dart'; +import 'message_analytics_controller.dart'; + +class PangeaController { + ///pangeaControllers + late UserController userController; + late LanguageController languageController; + late ClassController classController; + late PermissionsController permissionsController; + late AnalyticsController analytics; + late MyAnalyticsController myAnalytics; + late WordController wordNet; + late LocalSettings localSettings; + late MessageDataController messageData; + late ContextualDefinitionController definitions; + late InstructionsController instructions; + late SubscriptionController subscriptionController; + + ///store Services + late PLocalStore pStoreService; + final pLanguageStore = PangeaLanguage(); + + ///Matrix Variables + MatrixState matrixState; + Matrix matrix; + + int? randomint; + PangeaController({required this.matrix, required this.matrixState}) { + _setup(); + _subscribeToMatrixStreams(); + randomint = Random().nextInt(2000); + } + + /// Pangea Initialization + void _setup() { + _addRefInObjects(); + } + + void afterSyncAndFirstLoginInitialization(BuildContext context) { + classController.checkForClassCodeAndSubscription(context); + + // startChatWithBotIfNotPresent(); + + classController.fixClassPowerLevels(); + } + + /// Initialize controllers + _addRefInObjects() { + pStoreService = PLocalStore(pangeaController: this); + userController = UserController(this); + languageController = LanguageController(this); + localSettings = LocalSettings(this); + classController = ClassController(this); + permissionsController = PermissionsController(this); + analytics = AnalyticsController(this); + myAnalytics = MyAnalyticsController(this); + messageData = MessageDataController(this); + wordNet = WordController(this); + definitions = ContextualDefinitionController(this); + instructions = InstructionsController(this); + subscriptionController = SubscriptionController(this); + PAuthGaurd.pController = this; + } + + _logOutfromPangea() { + debugPrint("Pangea logout"); + GoogleAnalytics.logout(); + pStoreService.clearStorage(); + } + + Future checkHomeServerAction() async { + if (matrixState.getLoginClient().homeserver != null) { + await Future.delayed(Duration.zero); + return; + } + + final String homeServer = + AppConfig.defaultHomeserver.trim().toLowerCase().replaceAll(' ', '-'); + var homeserver = Uri.parse(homeServer); + if (homeserver.scheme.isEmpty) { + homeserver = Uri.https(homeServer, ''); + } + + matrixState.loginHomeserverSummary = + await matrixState.getLoginClient().checkHomeserver(homeserver); + final ssoSupported = matrixState.loginHomeserverSummary!.loginFlows + .any((flow) => flow.type == 'm.login.sso'); + + try { + await matrixState.getLoginClient().register(); + matrixState.loginRegistrationSupported = true; + } on MatrixException catch (e) { + matrixState.loginRegistrationSupported = + e.requireAdditionalAuthentication; + } + + // setState(() => error = (e).toLocalizedString(context)); + } + + /// check user information if not found then redirect to Date of birth page + _handleLoginStateChange(LoginState state) { + if (state != LoginState.loggedIn) { + _logOutfromPangea(); + } + Sentry.configureScope( + (scope) => scope.setUser(SentryUser(id: matrixState.client.userID)), + ); + GoogleAnalytics.analyticsUserUpdate(matrixState.client.userID); + } + + // void startChatWithBotIfNotPresent() { + // Future.delayed(const Duration(milliseconds: 5000), () async { + // try { + // if (pStoreService.read("started_bot_chat", addClientIdToKey: false) ?? + // false) { + // return; + // } + // await pStoreService.save("started_bot_chat", true, + // addClientIdToKey: false); + // final rooms = matrixState.client.rooms; + + // await matrixState.client.startDirectChat( + // BotName.byEnvironment, + // enableEncryption: false, + // ); + // } catch (err, stack) { + // debugger(when: kDebugMode); + // ErrorHandler.logError(e: err, s: stack); + // } + // }); + // } + + void startChatWithBotIfNotPresent() { + Future.delayed(const Duration(milliseconds: 10000), () async { + try { + await matrixState.client.startDirectChat( + BotName.byEnvironment, + enableEncryption: false, + ); + } catch (err, stack) { + debugger(when: kDebugMode); + ErrorHandler.logError(e: err, s: stack); + } + }); + } + + _handleJoinEvent(SyncUpdate syncUpdate) { + // for (final joinedRoomUpdate in syncUpdate.rooms!.join!.entries) { + // debugPrint( + // "room update for ${joinedRoomUpdate.key} - ${joinedRoomUpdate.value}"); + // } + } + + _handleOnSyncUpdate(SyncUpdate syncUpdate) { + // debugPrint(syncUpdate.toString()); + } + + _handleSyncStatusFinished(SyncStatusUpdate event) { + //might be useful to do something periodically, probably be overkill + } + + void _subscribeToMatrixStreams() { + matrixState.client.onLoginStateChanged.stream + .listen(_handleLoginStateChange); + + // matrixState.client.onSyncStatus.stream + // .where((SyncStatusUpdate event) => event.status == SyncStatus.finished) + // .listen(_handleSyncStatusFinished); + + //PTODO - listen to incoming invites and autojoin if in class + // matrixState.client.onSync.stream + // .where((event) => event.rooms?.invite?.isNotEmpty ?? false) + // .listen((SyncUpdate event) { + // }); + + // matrixState.client.onSync.stream.listen(_handleOnSyncUpdate); + } + + Future inviteBotToExistingSpaces() async { + final List spaces = + matrixState.client.rooms.where((room) => room.isSpace).toList(); + for (final Room space in spaces) { + List participants; + try { + participants = await space.requestParticipants(); + } catch (err) { + ErrorHandler.logError( + e: "Failed to fetch participants for space ${space.id}", + ); + continue; + } + final List userIds = participants.map((user) => user.id).toList(); + if (space.canInvite && !userIds.contains(BotName.byEnvironment)) { + try { + await space.invite(BotName.byEnvironment); + await space.setPower( + BotName.byEnvironment, + ClassDefaultValues.powerLevelOfAdmin, + ); + } catch (err) { + ErrorHandler.logError( + e: "Failed to invite pangea bot to space ${space.id}", + ); + } + } + } + } +} diff --git a/lib/pangea/controllers/permissions_controller.dart b/lib/pangea/controllers/permissions_controller.dart new file mode 100644 index 000000000..6dcf64388 --- /dev/null +++ b/lib/pangea/controllers/permissions_controller.dart @@ -0,0 +1,142 @@ +import 'package:matrix/matrix.dart'; + +import 'package:fluffychat/pangea/constants/age_limits.dart'; +import 'package:fluffychat/pangea/constants/pangea_event_types.dart'; +import 'package:fluffychat/pangea/controllers/base_controller.dart'; +import 'package:fluffychat/pangea/controllers/pangea_controller.dart'; +import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart'; +import 'package:fluffychat/pangea/models/class_model.dart'; +import 'package:fluffychat/pangea/utils/p_extension.dart'; + +class PermissionsController extends BaseController { + late PangeaController _pangeaController; + + PermissionsController(PangeaController pangeaController) : super() { + _pangeaController = pangeaController; + } + + Room? _getRoomById(String? roomId) => roomId == null + ? null + : _pangeaController.matrixState.client.getRoomById(roomId); + + PangeaRoomRules? _getRoomRules(String? roomId) => + roomId == null ? null : _getRoomById(roomId)?.firstRules; + + Room? firstRoomWithState({required String? roomID, required String type}) { + final Room? room = _getRoomById(roomID); + + return room?.pangeaRoomRules != null + ? room + : room?.firstParentWithState(type); + } + + /// Returns false if user is null + bool isUser18() { + final dob = + _pangeaController.userController.userModel?.profile?.dateOfBirth; + return dob != null + ? DateTime.parse(dob).isAtLeastYearsOld(AgeLimits.toAccessFeatures) + : false; + } + + /// A user can private chat if + /// 1) they are 18 and outside a class context or + /// 2) they are in a class context and the class rules permit it + /// If no class is passed, uses classController.activeClass + bool canUserPrivateChat({String? roomID}) { + final Room? classContext = + firstRoomWithState(roomID: roomID, type: PangeaEventTypes.rules); + return classContext?.pangeaRoomRules == null + ? isUser18() + : classContext!.pangeaRoomRules!.oneToOneChatClass || + classContext.isRoomAdmin; + } + + bool canUserGroupChat({String? roomID}) { + final Room? classContext = + firstRoomWithState(roomID: roomID, type: PangeaEventTypes.rules); + + return classContext?.pangeaRoomRules == null + ? isUser18() + : classContext!.pangeaRoomRules!.isCreateRooms || + classContext.isRoomAdmin; + } + + bool showChatInputAddButton(String roomId) { + final PangeaRoomRules? perms = _getRoomRules(roomId); + if (perms == null) return isUser18(); + return perms.isShareFiles || + perms.isShareLocation || + perms.isSharePhoto || + perms.isShareVideo; + } + + /// works for both roomID of chat and class + bool canShareVideo(String? roomID) => + _getRoomRules(roomID)?.isShareVideo ?? isUser18(); + + /// works for both roomID of chat and class + bool canSharePhoto(String? roomID) => + _getRoomRules(roomID)?.isSharePhoto ?? isUser18(); + + /// works for both roomID of chat and class + bool canShareFile(String? roomID) => + _getRoomRules(roomID)?.isShareFiles ?? isUser18(); + + /// works for both roomID of chat and class + bool canShareLocation(String? roomID) => + _getRoomRules(roomID)?.isShareLocation ?? isUser18(); + + int? classLanguageToolPermission(Room room, ToolSetting setting) => + room.firstRules?.getToolSettings(setting); + + //what happens if a room isn't in a class? + bool isToolDisabledByClass(ToolSetting setting, Room? room) { + if (room?.isSpaceAdmin ?? false) return false; + final int? classPermission = + room != null ? classLanguageToolPermission(room, setting) : 1; + return classPermission == 0; + } + + bool userToolSetting(ToolSetting setting) => + _pangeaController.localSettings.userLanguageToolSetting(setting); + + bool isToolEnabled(ToolSetting setting, Room? room) { + if (room?.isSpaceAdmin ?? false) { + return userToolSetting(setting); + } + final int? classPermission = + room != null ? classLanguageToolPermission(room, setting) : 1; + if (classPermission == 0) return false; + if (classPermission == 2) return true; + return userToolSetting(setting); + } + + bool isWritingAssistanceEnabled(Room? room) { + return isToolEnabled(ToolSetting.interactiveTranslator, room) && + isToolEnabled(ToolSetting.interactiveGrammar, room); + } + + // bool get showChatListStartChatFloatingActionButton { + // //for now, I'm turning off chat button when not in the context of a clas + // //it will still be possible to private chat outside of a class + // //need to investigate if private chats can be put in a space. i suppose they can + // //if so, do we want that? + // try { + // if (_pangeaController.classController.activeClass == null) return false; + + // // final isExchange = + // // (_pangeaController.classController.activeClass?.isExchange ?? false); + // const isExchange = false; + // final regular = (canUserPrivateChat() || canUserGroupChat()); + // final inExchange = + // (canUserPrivateChatExchanges() || canUserGroupChatExchanges()); + // final theAnswer = isExchange ? inExchange : regular; + // // debugger(when: kDebugMode && !theAnswer); + // return theAnswer; + // } catch (e, s) { + // ErrorHandler.logError(e: e, s: s); + // return false; + // } + // } +} diff --git a/lib/pangea/controllers/space_rules_edit_controller.dart b/lib/pangea/controllers/space_rules_edit_controller.dart new file mode 100644 index 000000000..5f5a2ed72 --- /dev/null +++ b/lib/pangea/controllers/space_rules_edit_controller.dart @@ -0,0 +1,20 @@ +import 'package:matrix/matrix.dart'; + +import 'package:fluffychat/pangea/constants/pangea_event_types.dart'; +import '../extensions/pangea_room_extension.dart'; +import '../models/class_model.dart'; + +class RoomRulesEditController { + final Room? room; + + late PangeaRoomRules rules; + + RoomRulesEditController([this.room]) { + rules = room?.pangeaRoomRules ?? PangeaRoomRules(); + } + + StateEvent get toStateEvent => StateEvent( + content: rules.toJson(), + type: PangeaEventTypes.rules, + ); +} diff --git a/lib/pangea/controllers/subscription_controller.dart b/lib/pangea/controllers/subscription_controller.dart new file mode 100644 index 000000000..34619e676 --- /dev/null +++ b/lib/pangea/controllers/subscription_controller.dart @@ -0,0 +1,265 @@ +import 'dart:async'; +import 'dart:convert'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + +import 'package:adaptive_dialog/adaptive_dialog.dart'; +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:http/http.dart'; +import 'package:purchases_flutter/purchases_flutter.dart'; +import 'package:url_launcher/url_launcher_string.dart'; + +import 'package:fluffychat/config/app_config.dart'; +import 'package:fluffychat/pangea/controllers/base_controller.dart'; +import 'package:fluffychat/pangea/controllers/pangea_controller.dart'; +import 'package:fluffychat/pangea/models/base_subscription_info.dart'; +import 'package:fluffychat/pangea/models/mobile_subscriptions.dart'; +import 'package:fluffychat/pangea/models/web_subscriptions.dart'; +import 'package:fluffychat/pangea/network/requests.dart'; +import 'package:fluffychat/pangea/network/urls.dart'; +import 'package:fluffychat/pangea/utils/error_handler.dart'; +import 'package:fluffychat/pangea/utils/firebase_analytics.dart'; +import 'package:fluffychat/pangea/widgets/subscription/subscription_paywall.dart'; +import 'package:fluffychat/utils/platform_infos.dart'; + +class SubscriptionController extends BaseController { + late PangeaController _pangeaController; + SubscriptionInfo? subscription; + + //convert this logic to use completer + bool initialized = false; + + SubscriptionController(PangeaController pangeaController) : super() { + _pangeaController = pangeaController; + } + + bool get isSubscribed => + subscription != null && + (subscription!.currentSubscriptionId != null || + subscription!.currentSubscription != null); + + bool get currentSubscriptionAvailable => + isSubscribed && subscription?.currentSubscription != null; + + bool get currentSubscriptionIsTrial => + subscription?.currentSubscription?.isTrial ?? false; + + Future initialize() async { + try { + if (_pangeaController.matrixState.client.userID == null) { + debugPrint( + "Attempted to initalize subscription information with null userId", + ); + return; + } + + subscription = kIsWeb + ? WebSubscriptionInfo(pangeaController: _pangeaController) + : MobileSubscriptionInfo(pangeaController: _pangeaController); + + await subscription!.configure(); + + initialized = true; + + if (!kIsWeb) { + Purchases.addCustomerInfoUpdateListener( + (CustomerInfo info) => updateCustomerInfo(), + ); + } + setState(); + } catch (e, s) { + debugPrint("Failed to initialize subscription controller"); + ErrorHandler.logError(e: e, s: s); + } + } + + Future updateCustomerInfo() async { + if (subscription == null) { + ErrorHandler.logError( + m: "Null subscription info in subscription settings", + s: StackTrace.current, + ); + return; + } + await subscription!.setCustomerInfo(); + + setState(); + } + + Future showPaywall( + BuildContext context, [ + bool forceShow = false, + ]) async { + try { + if (!initialized) { + await initialize(); + } + if (subscription?.availableSubscriptions.isEmpty ?? true) { + return; + } + if (!forceShow && isSubscribed) return; + await showModalBottomSheet( + isScrollControlled: true, + useRootNavigator: !PlatformInfos.isMobile, + clipBehavior: Clip.hardEdge, + context: context, + constraints: BoxConstraints( + maxHeight: PlatformInfos.isMobile ? 600 : 480, + ), + builder: (_) => SubscriptionPaywall( + pangeaController: _pangeaController, + ), + ); + } catch (e, s) { + ErrorHandler.logError(e: e, s: s); + } + } + + Future fetchSubscriptionStatus() async { + final Requests req = Requests(baseUrl: PApiUrls.baseAPI); + final String reqUrl = Uri.encodeFull( + "${PApiUrls.subscriptionExpiration}?pangea_user_id=${_pangeaController.matrixState.client.userID}", + ); + + DateTime? expiration; + try { + final Response res = await req.get(url: reqUrl); + final json = jsonDecode(res.body); + if (json["premium_expires_date"] != null) { + expiration = DateTime.parse(json["premium_expires_date"]); + } + } catch (err) { + ErrorHandler.logError( + e: "Failed to fetch subscripton status for user ${_pangeaController.matrixState.client.userID}", + s: StackTrace.current, + ); + } + final bool subscribed = + expiration == null ? false : DateTime.now().isBefore(expiration); + GoogleAnalytics.updateUserSubscriptionStatus(subscribed); + return subscribed; + } + + Future getPaymentLink(String duration, {bool isPromo = false}) async { + final Requests req = Requests(baseUrl: PApiUrls.baseAPI); + final String reqUrl = Uri.encodeFull( + "${PApiUrls.paymentLink}?pangea_user_id=${_pangeaController.matrixState.client.userID}&duration=$duration&redeem=$isPromo", + ); + final Response res = await req.get(url: reqUrl); + final json = jsonDecode(res.body); + String paymentLink = json["link"]["url"]; + + final String? email = await _pangeaController.userController.userEmail; + if (email != null) { + paymentLink += "?prefilled_email=${Uri.encodeComponent(email)}"; + } + return paymentLink; + } + + void submitSubscriptionChange( + SubscriptionDetails? selectedSubscription, + BuildContext context, { + bool isPromo = false, + }) async { + if (selectedSubscription != null) { + if (kIsWeb) { + if (selectedSubscription.duration == null) { + ErrorHandler.logError( + m: "Tried to subscribe to web SubscriptionDetails with Null duration", + s: StackTrace.current, + ); + return; + } + final String paymentLink = await getPaymentLink( + selectedSubscription.duration!, + isPromo: isPromo, + ); + setState(); + launchUrlString( + paymentLink, + webOnlyWindowName: "_self", + ); + return; + } + if (selectedSubscription.package == null) { + ErrorHandler.logError( + m: "Tried to subscribe to SubscriptionDetails with Null revenuecat Package", + s: StackTrace.current, + ); + return; + } + try { + GoogleAnalytics.beginPurchaseSubscription( + selectedSubscription, + context, + ); + await Purchases.purchasePackage(selectedSubscription.package!); + GoogleAnalytics.updateUserSubscriptionStatus(true); + } catch (err) { + ErrorHandler.logError( + m: "Failed to purchase revenuecat package for user ${_pangeaController.matrixState.client.userID}", + s: StackTrace.current, + ); + return; + } + } + } + + Future redeemPromoCode(BuildContext context) async { + final List? promoCode = await showTextInputDialog( + useRootNavigator: false, + context: context, + title: L10n.of(context)!.enterPromoCode, + okLabel: L10n.of(context)!.ok, + cancelLabel: L10n.of(context)!.cancel, + textFields: [const DialogTextField()], + ); + if (promoCode == null || promoCode.single.isEmpty) return; + launchUrlString( + "${AppConfig.iosPromoCode}${promoCode.single}", + ); + } +} + +class SubscriptionDetails { + double price; + String? duration; + Package? package; + String? appId; + final String id; + String? periodType = "normal"; + + SubscriptionDetails({ + required this.price, + required this.id, + this.duration, + this.package, + this.appId, + this.periodType, + }); + + void makeTrial() => periodType = 'trial'; + bool get isTrial => periodType == 'trial'; + + String displayPrice(BuildContext context) { + if (isTrial || price <= 0) { + return L10n.of(context)!.freeTrial; + } + return "\$${price.toStringAsFixed(2)}"; + } + + String displayName(BuildContext context) { + if (isTrial) { + return L10n.of(context)!.oneWeekTrial; + } + switch (duration) { + case ('month'): + return L10n.of(context)!.monthlySubscription; + case ('year'): + return L10n.of(context)!.yearlySubscription; + default: + return L10n.of(context)!.defaultSubscription; + } + } +} diff --git a/lib/pangea/controllers/user_controller.dart b/lib/pangea/controllers/user_controller.dart new file mode 100644 index 000000000..aeec7a5dc --- /dev/null +++ b/lib/pangea/controllers/user_controller.dart @@ -0,0 +1,220 @@ +import 'dart:async'; +import 'dart:developer'; + +import 'package:collection/collection.dart'; +import 'package:jwt_decode/jwt_decode.dart'; +import 'package:matrix/matrix.dart' as matrix; + +import 'package:fluffychat/pangea/constants/language_keys.dart'; +import 'package:fluffychat/pangea/constants/model_keys.dart'; +import 'package:fluffychat/pangea/controllers/base_controller.dart'; +import 'package:fluffychat/pangea/controllers/pangea_controller.dart'; +import 'package:fluffychat/widgets/fluffy_chat_app.dart'; +import '../constants/local.key.dart'; +import '../models/user_model.dart'; +import '../repo/user_repo.dart'; + +class UserController extends BaseController { + late PangeaController _pangeaController; + final Completer _completer = Completer(); + UserController(PangeaController pangeaController) : super() { + _pangeaController = pangeaController; + } + + Future fetchUserModel() async { + try { + if (_matrixAccessToken == null) { + throw Exception( + "calling fetchUserModel with matrixAccesstoken == null", + ); + } + final PUserModel? newUserModel = await PUserRepo.fetchPangeaUserInfo( + userID: userId!, + matrixAccessToken: _matrixAccessToken!, + ); + + if (newUserModel != null) { + _savePUserModel(newUserModel); + } + _completeCompleter(); + + return newUserModel; + } catch (err) { + log("User model not found. Probably first signup and needs Pangea account"); + rethrow; + } + } + + void _completeCompleter() { + if (!_completer.isCompleted) { + _completer.complete(null); + } + } + + Future get completer async { + if (await isPUserDataAvailable) { + _completeCompleter(); + } + return _completer; + } + + bool get needNewJWT => + userModel?.access != null ? Jwt.isExpired(userModel!.access) : true; + + Future get accessToken async { + await (await completer).future; + // if userModel null or access token expired then fetchUserModel + final PUserModel? useThisOne = + needNewJWT ? await fetchUserModel() : userModel; + + if (useThisOne == null) { + //debugger(when: kDebugMode); + throw Exception("trying to get accessToken with userModel = null"); + } + return useThisOne.access; + } + + String? get userId { + return _pangeaController.matrixState.client.userID; + } + + String get fullname { + final String? userID = userId; + if (userID == null) { + throw Exception('User ID not found'); + } + return userID.substring(0, userID.indexOf(":")).replaceAll("@", ""); + } + + PUserModel? get userModel { + final data = _pangeaController.pStoreService.read(PLocalKey.user); + return data != null ? PUserModel.fromJson(data) : null; + } + + Future get isPUserDataAvailable async { + try { + final PUserModel? toCheck = userModel ?? (await fetchUserModel()); + return toCheck != null ? true : false; + } catch (err) { + return false; + } + } + + Future get isUserDataAvailableAndDateOfBirthSet async { + try { + final PUserModel? toCheck = userModel ?? (await fetchUserModel()); + return toCheck?.profile?.dateOfBirth != null ? true : false; + } catch (err) { + return false; + } + } + + Future get areUserLanguagesSet async { + try { + final PUserModel? toCheck = userModel ?? (await fetchUserModel()); + if (toCheck?.profile == null) { + return false; + } + final String? srcLang = toCheck!.profile!.sourceLanguage; + final String? tgtLang = toCheck.profile!.targetLanguage; + return srcLang != null && + tgtLang != null && + srcLang.isNotEmpty && + tgtLang.isNotEmpty && + srcLang != LanguageKeys.unknownLanguage && + tgtLang != LanguageKeys.unknownLanguage; + } catch (err) { + return false; + } + } + + redirectToUserInfo() { + // _pangeaController.matrix.router!.currentState!.to( + // "/home/connect/user_age", + // queryParameters: + // _pangeaController.matrix.router!.currentState!.queryParameters, + // ); + FluffyChatApp.router.go("/rooms/user_age"); + } + + _savePUserModel(PUserModel? pUserModel) { + final jsonUser = pUserModel!.toJson(); + _pangeaController.pStoreService.save(PLocalKey.user, jsonUser); + + setState(data: pUserModel); + } + + Future updateUserProfile({ + String? dateOfBirth, + String? targetLanguage, + String? sourceLanguage, + String? country, + List? interests, + List? speaks, + bool? publicProfile, + }) async { + if (userModel == null) throw Exception("Local userModel not defined"); + final profileJson = userModel!.profile!.toJson(); + + if (dateOfBirth != null) { + profileJson[ModelKey.userDateOfBirth] = dateOfBirth; + } + if (targetLanguage != null) { + profileJson[ModelKey.userTargetLanguage] = targetLanguage; + } + if (sourceLanguage != null) { + profileJson[ModelKey.userSourceLanguage] = sourceLanguage; + } + if (interests != null) { + profileJson[ModelKey.userInterests] = interests.toString(); + } + if (speaks != null) { + profileJson[ModelKey.userSpeaks] = speaks.toString(); + } + if (country != null) { + profileJson[ModelKey.userCountry] = country; + } + if (publicProfile != null) { + profileJson[ModelKey.publicProfile] = publicProfile; + } + final Profile updatedUserProfile = await PUserRepo.updateUserProfile( + Profile.fromJson(profileJson), + await accessToken, + ); + + await _savePUserModel( + PUserModel( + access: await accessToken, + refresh: userModel!.refresh, + profile: updatedUserProfile, + ), + ); + } + + Future createPangeaUser({required String dob}) async { + final PUserModel newUserModel = await PUserRepo.repoCreatePangeaUser( + userID: userId!, + dateOfBirth: dob, + fullName: fullname, + matrixAccessToken: _matrixAccessToken!, + ); + await _savePUserModel(newUserModel); + } + + String? get _matrixAccessToken => + _pangeaController.matrixState.client.accessToken; + + bool get isPublic => + _pangeaController.userController.userModel?.profile?.publicProfile ?? + false; + + Future get userEmail async { + final List? identifiers = + await _pangeaController.matrixState.client.getAccount3PIDs(); + final matrix.ThirdPartyIdentifier? email = identifiers?.firstWhereOrNull( + (identifier) => + identifier.medium == matrix.ThirdPartyIdentifierMedium.email, + ); + return email?.address; + } +} diff --git a/lib/pangea/controllers/word_net_controller.dart b/lib/pangea/controllers/word_net_controller.dart new file mode 100644 index 000000000..ce8324ebe --- /dev/null +++ b/lib/pangea/controllers/word_net_controller.dart @@ -0,0 +1,83 @@ +import 'package:collection/collection.dart'; +import 'package:http/http.dart' as http; + +import 'package:fluffychat/pangea/constants/language_keys.dart'; +import 'package:fluffychat/pangea/repo/word_repo.dart'; +import '../models/word_data_model.dart'; +import 'base_controller.dart'; +import 'pangea_controller.dart'; + +class WordController extends BaseController { + late PangeaController _pangeaController; + + final List _wordData = []; + + WordController(PangeaController pangeaController) : super() { + _pangeaController = pangeaController; + } + + WordData? getWordDataLocal({ + required String word, + required String fullText, + required String? userL1, + required String? userL2, + }) => + _wordData.firstWhereOrNull( + (e) => e.isMatch( + w: word, + f: fullText, + l1: userL1, + l2: userL2, + ), + ); + + Future getWordDataGlobal({ + required String word, + required String fullText, + required String? userL1, + required String? userL2, + }) async { + if (userL1 == null || + userL2 == null || + userL1 == LanguageKeys.unknownLanguage || + userL2 == LanguageKeys.unknownLanguage) { + throw http.Response("", 405); + } + + final WordData? local = getWordDataLocal( + word: word, + fullText: fullText, + userL1: userL1, + userL2: userL2, + ); + + if (local != null) return local; + + final WordData remote = await WordRepo.getWordNetData( + accessToken: await _pangeaController.userController.accessToken, + fullText: fullText, + word: word, + userL1: userL1, + userL2: userL2, + ); + + _addWordData(remote); + + return remote; + } + + _addWordData(WordData w) { + final WordData? local = getWordDataLocal( + word: w.word, + fullText: w.fullText, + userL1: w.userL1, + userL2: w.userL2, + ); + + if (local == null) { + if (_wordData.length > 100) _wordData.clear(); + _wordData.add(w); + setState(); + } + } +} diff --git a/lib/pangea/enum/ReactDialogAlignment.dart b/lib/pangea/enum/ReactDialogAlignment.dart new file mode 100644 index 000000000..959ec429a --- /dev/null +++ b/lib/pangea/enum/ReactDialogAlignment.dart @@ -0,0 +1 @@ +enum DialogAlignment { center, left, right } diff --git a/lib/pangea/enum/bar_chart_view_enum.dart b/lib/pangea/enum/bar_chart_view_enum.dart new file mode 100644 index 000000000..d59f34d9a --- /dev/null +++ b/lib/pangea/enum/bar_chart_view_enum.dart @@ -0,0 +1,33 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; + +enum BarChartViewSelection { + messages, + // vocab, + grammar, +} + +extension BarChartViewSelectionExtension on BarChartViewSelection { + String string(BuildContext context) { + switch (this) { + case BarChartViewSelection.messages: + return L10n.of(context)!.messages; + // case BarChartViewSelection.vocab: + // return L10n.of(context)!.vocab; + case BarChartViewSelection.grammar: + return L10n.of(context)!.grammarAnalytics; + } + } + + IconData get icon { + switch (this) { + case BarChartViewSelection.messages: + return Icons.chat_bubble; + // case BarChartViewSelection.vocab: + // return Icons.abc; + case BarChartViewSelection.grammar: + return Icons.spellcheck_outlined; + } + } +} diff --git a/lib/pangea/enum/construct_type_enum.dart b/lib/pangea/enum/construct_type_enum.dart new file mode 100644 index 000000000..2a7d5583d --- /dev/null +++ b/lib/pangea/enum/construct_type_enum.dart @@ -0,0 +1,30 @@ +enum ConstructType { + grammar, + vocab, +} + +extension ConstructExtension on ConstructType { + String get string { + switch (this) { + case ConstructType.grammar: + return 'grammar'; + case ConstructType.vocab: + return 'vocab'; + } + } +} + +class ConstructTypeUtil { + static ConstructType fromString(String? string) { + switch (string) { + case 'g': + case 'grammar': + return ConstructType.grammar; + case 'v': + case 'vocab': + return ConstructType.vocab; + default: + return ConstructType.vocab; + } + } +} diff --git a/lib/pangea/enum/direction.dart b/lib/pangea/enum/direction.dart new file mode 100644 index 000000000..9b1f9736a --- /dev/null +++ b/lib/pangea/enum/direction.dart @@ -0,0 +1 @@ +enum EditDirection { append, remove } diff --git a/lib/pangea/enum/edit_type.dart b/lib/pangea/enum/edit_type.dart new file mode 100644 index 000000000..5d0a43932 --- /dev/null +++ b/lib/pangea/enum/edit_type.dart @@ -0,0 +1,8 @@ +enum EditType { + itStandard, + igc, + keyboard, + alternativeTranslation, + itGold, + itStart, +} diff --git a/lib/pangea/enum/pop-for.dart b/lib/pangea/enum/pop-for.dart new file mode 100644 index 000000000..77b75b5ac --- /dev/null +++ b/lib/pangea/enum/pop-for.dart @@ -0,0 +1 @@ +enum PopupFor { ownMessage, notOwnMessage, inputBar } diff --git a/lib/pangea/enum/span_choice_type.dart b/lib/pangea/enum/span_choice_type.dart new file mode 100644 index 000000000..7ba748d09 --- /dev/null +++ b/lib/pangea/enum/span_choice_type.dart @@ -0,0 +1,55 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; + +enum SpanChoiceType { + bestCorrection, + distractor, + bestAnswer, +} + +extension SpanChoiceExt on SpanChoiceType { + String get name { + switch (this) { + case SpanChoiceType.bestCorrection: + return "bestCorrection"; + case SpanChoiceType.distractor: + return "distractor"; + case SpanChoiceType.bestAnswer: + return "bestAnswer"; + } + } + + String defaultFeedback(BuildContext context) { + switch (this) { + case SpanChoiceType.bestCorrection: + return L10n.of(context)!.bestCorrectionFeedback; + case SpanChoiceType.distractor: + return L10n.of(context)!.distractorFeedback; + case SpanChoiceType.bestAnswer: + return L10n.of(context)!.bestAnswerFeedback; + } + } + + IconData get icon { + switch (this) { + case SpanChoiceType.bestCorrection: + return Icons.check_circle; + case SpanChoiceType.distractor: + return Icons.cancel; + case SpanChoiceType.bestAnswer: + return Icons.check_circle; + } + } + + Color get color { + switch (this) { + case SpanChoiceType.bestCorrection: + return Colors.green; + case SpanChoiceType.distractor: + return Colors.red; + case SpanChoiceType.bestAnswer: + return Colors.green; + } + } +} diff --git a/lib/pangea/enum/span_data_type.dart b/lib/pangea/enum/span_data_type.dart new file mode 100644 index 000000000..5e4fdf8cb --- /dev/null +++ b/lib/pangea/enum/span_data_type.dart @@ -0,0 +1,38 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; + +enum SpanDataTypeEnum { + definition, + practice, + correction, + itStart, +} + +extension SpanDataTypeEnumExt on SpanDataTypeEnum { + String get name { + switch (this) { + case SpanDataTypeEnum.definition: + return "definition"; + case SpanDataTypeEnum.practice: + return "practice"; + case SpanDataTypeEnum.correction: + return "correction"; + case SpanDataTypeEnum.itStart: + return "itStart"; + } + } + + String defaultPrompt(BuildContext context) { + switch (this) { + case SpanDataTypeEnum.definition: + return L10n.of(context)!.definitionDefaultPrompt; + case SpanDataTypeEnum.practice: + return L10n.of(context)!.practiceDefaultPrompt; + case SpanDataTypeEnum.correction: + return L10n.of(context)!.correctionDefaultPrompt; + case SpanDataTypeEnum.itStart: + return L10n.of(context)!.needsItMessage; + } + } +} diff --git a/lib/pangea/enum/time_span.dart b/lib/pangea/enum/time_span.dart new file mode 100644 index 000000000..23a54e4ea --- /dev/null +++ b/lib/pangea/enum/time_span.dart @@ -0,0 +1,109 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; + +import '../models/chart_analytics_model.dart'; + +enum TimeSpan { day, week, month, sixmonths, year } + +extension TimeSpanFunctions on TimeSpan { + String string(BuildContext context) { + switch (this) { + case TimeSpan.day: + return L10n.of(context)!.oneday; + case TimeSpan.week: + return L10n.of(context)!.oneweek; + case TimeSpan.month: + return L10n.of(context)!.onemonth; + case TimeSpan.sixmonths: + return L10n.of(context)!.sixmonth; + case TimeSpan.year: + return L10n.of(context)!.oneyear; + default: + return "Invalid time span"; + } + } + + int get numberOfIntervals { + switch (this) { + case TimeSpan.day: + return 24; + case TimeSpan.week: + return 7; + case TimeSpan.month: + return DateTime.now().month == 2 ? 26 : 28; + case TimeSpan.sixmonths: + return 6; + case TimeSpan.year: + return 12; + } + } + + Duration timeAgo(int index) { + switch (this) { + case TimeSpan.day: + return Duration(hours: index); + case TimeSpan.week: + case TimeSpan.month: + return Duration(days: index); + case TimeSpan.year: + case TimeSpan.sixmonths: + return Duration(days: index * 32); + } + } + + DateTime get cutOffDate { + switch (this) { + case TimeSpan.day: + return DateTime.now().subtract(Duration(hours: numberOfIntervals)); + case TimeSpan.week: + return DateTime.now().subtract(Duration(days: numberOfIntervals)); + case TimeSpan.month: + //PTODO - get onee month agoo + return DateTime.now().subtract(Duration(days: numberOfIntervals)); + case TimeSpan.sixmonths: + //PTODO - get six months ago + return DateTime.now().subtract(Duration(days: numberOfIntervals * 30)); + case TimeSpan.year: + return DateTime.now().subtract(const Duration(days: 365)); + } + } + + String getMapKey(DateTime date) { + switch (this) { + case TimeSpan.day: + return date.hour.toString(); + case TimeSpan.week: + return date.weekday.toString(); + case TimeSpan.month: + return date.day.toString(); + case TimeSpan.sixmonths: + case TimeSpan.year: + return date.month.toString(); + } + } + + /// Note: end is same as start!! + Map get emptyIntervals { + final DateTime now = DateTime.now(); + final List numbers = + List.generate(numberOfIntervals, (index) => index); + final Map map = {}; + + // debugger(when: kDebugMode); + for (final index in numbers) { + final timeAgos = timeAgo(index); + final DateTime end = now.subtract(timeAgos); + // debugger(when: end.isBefore(now.subtract(const Duration(days: 30)))); + final String mapKey = getMapKey(end); + // debugger(when: mapKey.toString() == "5"); + map[mapKey] = TimeSeriesInterval( + start: end, + end: end, + totals: TimeSeriesTotals.empty, + ); + } + // debugger(when: kDebugMode); + return map; + } +} diff --git a/lib/pangea/enum/use_type.dart b/lib/pangea/enum/use_type.dart new file mode 100644 index 000000000..771b26220 --- /dev/null +++ b/lib/pangea/enum/use_type.dart @@ -0,0 +1,109 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; + +import '../models/choreo_record.dart'; +import '../utils/bot_style.dart'; + +enum UseType { wa, ta, ga, un } + +extension UseTypeMethods on UseType { + String get string => toString().split(".").last; + + String tooltipString(BuildContext context) { + final l10n = L10n.of(context); + if (l10n == null) return string; + switch (this) { + case UseType.ga: + return l10n.gaTooltip; + case UseType.ta: + return l10n.taTooltip; + case UseType.wa: + return l10n.waTooltip; + default: + return l10n.unTooltip; + } + } + + IconData get iconData { + switch (this) { + case UseType.ga: + return Icons.spellcheck_outlined; + case UseType.ta: + return Icons.translate; + case UseType.wa: + return Icons.thumb_up; + default: + return Icons.question_mark_outlined; + } + } + + Widget iconView(BuildContext context, Color color, [int size = 14]) => + Tooltip( + message: tooltipString(context), + child: Icon( + iconData, + color: color, + size: size.toDouble(), + ), + ); + + Widget iconButtonView(BuildContext context, Color color, [int size = 14]) => + Tooltip( + message: tooltipString(context), + child: Icon( + iconData, + color: color, + size: size.toDouble(), + ), + ); + + Widget textView(BuildContext context, [TextStyle? existingStyle]) => Tooltip( + message: tooltipString(context), + child: Text( + string, + style: BotStyle.text( + context, + existingStyle: existingStyle, + italics: true, + ), + textAlign: TextAlign.end, + ), + ); + + static bool isDarkMode(BuildContext context) => + Theme.of(context).brightness == Brightness.dark; + + Color color(BuildContext context) { + switch (this) { + case UseType.ga: + return isDarkMode(context) + ? const Color.fromARGB(255, 157, 234, 172) + : const Color.fromARGB(255, 31, 146, 54); + case UseType.ta: + return isDarkMode(context) + ? const Color.fromARGB(255, 169, 183, 237) + : const Color.fromARGB(255, 38, 59, 141); + case UseType.wa: + return isDarkMode(context) + ? const Color.fromARGB(255, 212, 144, 216) + : const Color.fromARGB(255, 163, 39, 169); + default: + return Theme.of(context).textTheme.bodyLarge!.color ?? Colors.blueGrey; + } + } +} + +UseType useTypeCalculator( + ChoreoRecord? choreoRecord, +) { + if (choreoRecord == null) { + return UseType.un; + } else if (choreoRecord.includedIT) { + return UseType.ta; + } else if (choreoRecord.hasAcceptedMatches) { + return UseType.ga; + } else { + return UseType.wa; + } +} diff --git a/lib/pangea/enum/vocab_proficiency_enum.dart b/lib/pangea/enum/vocab_proficiency_enum.dart new file mode 100644 index 000000000..73187dbf7 --- /dev/null +++ b/lib/pangea/enum/vocab_proficiency_enum.dart @@ -0,0 +1,45 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; + +enum VocabProficiencyEnum { low, medium, high, unk } + +extension Copy on VocabProficiencyEnum { + String toolTipString(BuildContext context) { + switch (this) { + case VocabProficiencyEnum.low: + return L10n.of(context)!.low; + case VocabProficiencyEnum.medium: + return L10n.of(context)!.medium; + case VocabProficiencyEnum.high: + return L10n.of(context)!.high; + case VocabProficiencyEnum.unk: + return L10n.of(context)!.unknownProficiency; + } + } + + IconData get iconData { + switch (this) { + case VocabProficiencyEnum.low: + return Icons.sentiment_dissatisfied_outlined; + case VocabProficiencyEnum.medium: + return Icons.sentiment_neutral_outlined; + case VocabProficiencyEnum.high: + return Icons.sentiment_satisfied_outlined; + case VocabProficiencyEnum.unk: + return Icons.question_mark_outlined; + } + } +} + +class VocabProficiencyUtil { + static VocabProficiencyEnum proficiency(num numeric) { + if (numeric > 1) { + return VocabProficiencyEnum.high; + } + if (numeric < -1) { + return VocabProficiencyEnum.low; + } + return VocabProficiencyEnum.medium; + } +} diff --git a/lib/pangea/extensions/client_extension.dart b/lib/pangea/extensions/client_extension.dart new file mode 100644 index 000000000..d226c78a7 --- /dev/null +++ b/lib/pangea/extensions/client_extension.dart @@ -0,0 +1,155 @@ +import 'dart:developer'; + +import 'package:flutter/foundation.dart'; + +import 'package:collection/collection.dart'; +import 'package:matrix/matrix.dart'; + +import 'package:fluffychat/pangea/constants/class_default_values.dart'; +import 'package:fluffychat/pangea/constants/model_keys.dart'; +import 'package:fluffychat/pangea/constants/pangea_room_types.dart'; +import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart'; +import 'package:fluffychat/pangea/utils/bot_name.dart'; +import 'package:fluffychat/pangea/utils/error_handler.dart'; +import '../utils/p_store.dart'; + +extension PangeaClient on Client { + List get classes => rooms.where((e) => e.isPangeaClass).toList(); + + List get classesImTeaching => rooms + .where( + (e) => + e.isPangeaClass && + e.ownPowerLevel == ClassDefaultValues.powerLevelOfAdmin, + ) + .toList(); + + List get classesAndExchangesImTeaching => rooms + .where( + (e) => + (e.isPangeaClass || e.isExchange) && + e.ownPowerLevel == ClassDefaultValues.powerLevelOfAdmin, + ) + .toList(); + + List get classesImIn => rooms + .where( + (e) => + e.isPangeaClass && + e.ownPowerLevel < ClassDefaultValues.powerLevelOfAdmin, + ) + .toList(); + + List get classesAndExchangesImStudyingIn => rooms + .where( + (e) => + (e.isPangeaClass || e.isExchange) && + e.ownPowerLevel < ClassDefaultValues.powerLevelOfAdmin, + ) + .toList(); + + List get classesAndExchangesImIn => + rooms.where((e) => e.isPangeaClass || e.isExchange).toList(); + + Future> get myTeachers async { + final List teachers = []; + for (final classRoom in classesImIn) { + for (final teacher in await classRoom.teachers) { + if (!teachers.any((e) => e.id == teacher.id)) { + teachers.add(teacher); + } + } + } + return teachers; + } + + Future updateMyLearningAnalyticsForAllClassesImIn([ + PLocalStore? storageService, + ]) async { + try { + final List> updateFutures = []; + for (final classRoom in classesImIn) { + updateFutures + .add(classRoom.updateMyLearningAnalyticsForClass(storageService)); + } + await Future.wait(updateFutures); + } catch (err, s) { + if (kDebugMode) rethrow; + // debugger(when: kDebugMode); + ErrorHandler.logError(e: err, s: s); + } + } + + // get analytics room matching targetlanguage + // if not present, create it and invite teachers of that language + // set description to let people know what the hell it is + Future getMyAnalyticsRoom(String langCode) async { + await roomsLoading; + + final Room? analyticsRoom = analyticsRoomLocal(langCode); + + if (analyticsRoom != null) return analyticsRoom; + + return _makeAnalyticsRoom(langCode); + } + + //note: if langCode is null and user has >1 analyticsRooms then this could + //return the wrong one. this is to account for when an exchange might not + //be in a class. + Room? analyticsRoomLocal(String? langCode, [String? userIdParam]) { + final Room? analyticsRoom = rooms.firstWhereOrNull((e) { + return e.isAnalyticsRoom && + e.isAnalyticsRoomOfUser(userIdParam ?? userID!) && + (langCode != null ? e.isMadeForLang(langCode) : true); + }); + if (analyticsRoom != null && + analyticsRoom.membership == Membership.invite) { + final membership = analyticsRoom.membership; + debugger(when: kDebugMode); + analyticsRoom + .join() + .onError( + (error, stackTrace) => + ErrorHandler.logError(e: error, s: stackTrace), + ) + .then((value) => analyticsRoom.postLoad()); + return analyticsRoom; + } + return analyticsRoom; + } + + Future _makeAnalyticsRoom(String langCode) async { + final String roomID = await createRoom( + creationContent: { + 'type': PangeaRoomTypes.analytics, + ModelKey.langCode: langCode, + }, + name: "$userID $langCode Analytics", + topic: "This room stores learning analytics for $userID.", + invite: [ + ...(await myTeachers).map((e) => e.id), + // BotName.localBot, + BotName.byEnvironment, + ], + visibility: Visibility.private, + roomAliasName: "${userID!.localpart}_${langCode}_analytics", + ); + if (getRoomById(roomID) == null) { + // Wait for room actually appears in sync + await waitForRoomInSync(roomID, join: true); + } + + return getRoomById(roomID)!; + } + + Future getReportsDM(User teacher, Room space) async { + final String roomId = await teacher.startDirectChat( + enableEncryption: false, + ); + space.setSpaceChild( + roomId, + suggested: false, + ); + return getRoomById(roomId)!; + } +} diff --git a/lib/pangea/extensions/my_list_extionsion.dart b/lib/pangea/extensions/my_list_extionsion.dart new file mode 100644 index 000000000..2527c1eb8 --- /dev/null +++ b/lib/pangea/extensions/my_list_extionsion.dart @@ -0,0 +1,8 @@ +extension ReturnShuffle on List { + List shuffleReturn() { + // final List copyList = toList(); + shuffle(); + return this; + // return copyList; + } +} diff --git a/lib/pangea/extensions/pangea_event_extension.dart b/lib/pangea/extensions/pangea_event_extension.dart new file mode 100644 index 000000000..9d4556721 --- /dev/null +++ b/lib/pangea/extensions/pangea_event_extension.dart @@ -0,0 +1,34 @@ +import 'dart:developer'; + +import 'package:flutter/foundation.dart'; + +import 'package:matrix/matrix.dart'; + +import 'package:fluffychat/pangea/constants/pangea_event_types.dart'; +import 'package:fluffychat/pangea/models/choreo_record.dart'; +import 'package:fluffychat/pangea/models/message_data_models.dart'; + +extension PangeaEvent on Event { + V getPangeaContent() { + final Map? json = content[type] as Map?; + + if (json == null) { + debugger(when: kDebugMode); + throw Exception("$type event with null content $eventId"); + } + + //PTODO - how does this work? abstract class? + // return V.fromJson(json); + + switch (type) { + case PangeaEventTypes.tokens: + return PangeaMessageTokens.fromJson(json) as V; + case PangeaEventTypes.representation: + return PangeaRepresentation.fromJson(json) as V; + case PangeaEventTypes.choreoRecord: + return ChoreoRecord.fromJson(json) as V; + default: + throw Exception("$type events do not have pangea content"); + } + } +} diff --git a/lib/pangea/extensions/pangea_room_extension.dart b/lib/pangea/extensions/pangea_room_extension.dart new file mode 100644 index 000000000..f599a5c64 --- /dev/null +++ b/lib/pangea/extensions/pangea_room_extension.dart @@ -0,0 +1,984 @@ +import 'dart:async'; +import 'dart:developer'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + +import 'package:matrix/matrix.dart'; +import 'package:matrix/src/utils/space_child.dart'; +import 'package:sentry_flutter/sentry_flutter.dart'; + +import 'package:fluffychat/pangea/constants/class_default_values.dart'; +import 'package:fluffychat/pangea/constants/model_keys.dart'; +import 'package:fluffychat/pangea/constants/pangea_room_types.dart'; +import 'package:fluffychat/pangea/models/class_model.dart'; +import 'package:fluffychat/pangea/models/pangea_message_event.dart'; +import 'package:fluffychat/pangea/utils/bot_name.dart'; +import 'package:fluffychat/pangea/utils/error_handler.dart'; +import '../../config/app_config.dart'; +import '../constants/pangea_event_types.dart'; +import '../enum/construct_type_enum.dart'; +import '../enum/use_type.dart'; +import '../models/choreo_record.dart'; +import '../models/construct_analytics_event.dart'; +import '../models/constructs_analytics_model.dart'; +import '../models/message_data_models.dart'; +import '../models/student_analytics_event.dart'; +import '../models/student_analytics_summary_model.dart'; +import '../utils/p_store.dart'; +import 'client_extension.dart'; + +extension PangeaRoom on Room { + /// the pangeaClass event is listed an importantStateEvent so, if event exists, + /// it's already local. If it's an old class and doesn't, then the class_controller + /// should automatically migrate during this same session, when the space is first loaded + ClassSettingsModel? get classSettings { + try { + if (!isSpace) { + return null; + } + final Map? content = languageSettingsStateEvent?.content; + if (content != null) { + final ClassSettingsModel classSettings = + ClassSettingsModel.fromJson(content); + return classSettings; + } + return null; + } catch (err, s) { + Sentry.addBreadcrumb( + Breadcrumb( + message: "Error in classSettings", + data: {"room": toJson()}, + ), + ); + ErrorHandler.logError(e: err, s: s); + return null; + } + } + + PangeaRoomRules? get pangeaRoomRules { + try { + final Map? content = pangeaRoomRulesStateEvent?.content; + if (content != null) { + final PangeaRoomRules roomRules = PangeaRoomRules.fromJson(content); + return roomRules; + } + return null; + } catch (err, s) { + Sentry.addBreadcrumb( + Breadcrumb( + message: "Error in pangeaRoomRules", + data: {"room": toJson()}, + ), + ); + ErrorHandler.logError(e: err, s: s); + return null; + } + } + + String? get creatorId => getState(EventTypes.RoomCreate)?.senderId; + + ClassSettingsModel? get firstLanguageSettings => + classSettings ?? + firstParentWithState(PangeaEventTypes.classSettings)?.classSettings; + + PangeaRoomRules? get firstRules => + pangeaRoomRules ?? + firstParentWithState(PangeaEventTypes.rules)?.pangeaRoomRules; + + //resolve somehow if multiple rooms have the state? + //check logic + Room? firstParentWithState(String stateType) { + if (![PangeaEventTypes.classSettings, PangeaEventTypes.rules] + .contains(stateType)) { + return null; + } + + for (final parent in pangeaSpaceParents) { + if (parent.getState(stateType) != null) { + return parent; + } + } + for (final parent in pangeaSpaceParents) { + final parentFirstRoom = parent.firstParentWithState(stateType); + if (parentFirstRoom != null) return parentFirstRoom; + } + return null; + } + + IconData? get roomTypeIcon { + if (membership == Membership.invite) return Icons.add; + if (isPangeaClass) return Icons.school; + if (isExchange) return Icons.connecting_airports; + if (isAnalyticsRoom) return Icons.analytics; + if (isDirectChat) return Icons.forum; + return Icons.group; + } + + Text nameAndRoomTypeIcon([TextStyle? textStyle]) => Text.rich( + style: textStyle, + TextSpan( + children: [ + WidgetSpan( + child: Icon(roomTypeIcon), + ), + TextSpan( + text: ' $name', + ), + ], + ), + ); + + /// find any parents and return the rooms + List get immediateClassParents => pangeaSpaceParents + .where( + (element) => element.isPangeaClass, + ) + .toList(); + + List get pangeaSpaceParents => client.rooms + .where( + (r) => r.isSpace, + ) + .where( + (space) => space.spaceChildren.any( + (room) => room.roomId == id, + ), + ) + .toList(); + + bool isChild(String roomId) => + isSpace && spaceChildren.any((room) => room.roomId == roomId); + + bool isFirstOrSecondChild(String roomId) => + isSpace && spaceChildren.any((room) => room.roomId == roomId) || + spaceChildren + .where( + (sc) => sc.roomId != null, + ) + .map( + (sc) => client.getRoomById(sc.roomId!), + ) + .any( + (room) => + room != null && + room.spaceChildren.any((room) => room.roomId == roomId), + ); + + //note this only will return rooms that the user has joined or been invited to + List get childrenAndGrandChildren { + if (!isSpace) return []; + final List kids = []; + for (final child in spaceChildren) { + kids.add(child); + if (child.roomId != null) { + final Room? childRoom = client.getRoomById(child.roomId!); + if (childRoom != null && childRoom.isSpace) { + kids.addAll(childRoom.spaceChildren); + } + } + } + return kids.where((element) => element.roomId != null).toList(); + } + + //this assumes that a user has been invited to all group chats in a space + //it is a janky workaround for determining whether a spacechild is a direct chat + //since the spaceChild object doesn't contain this info. this info is only accessible + //when the user has joined or been invited to the room. direct chats included in + //a space show up in spaceChildren but the user has not been invited to them. + List get childrenAndGrandChildrenDirectChatIds { + final List nonDirectChatRoomIds = childrenAndGrandChildren + .map((e) => client.getRoomById(e.roomId!)) + .where((r) => r != null && !r.isDirectChat) + .map((e) => e!.id) + .toList(); + + return childrenAndGrandChildren + .where( + (child) => + child.roomId != null && + !nonDirectChatRoomIds.contains(child.roomId), + ) + .map((e) => e.roomId) + .cast() + .toList(); + + // return childrenAndGrandChildren + // .where((element) => element.roomId != null) + // .where( + // (child) { + // final room = client.getRoomById(child.roomId!); + // return room == null || room.isDirectChat; + // }, + // ) + // .map((e) => e.roomId) + // .cast() + // .toList(); + } + + //if the user is an admin of the room or any immediate parent of the room + //Question: check parents of parents? + //check logic + bool get isSpaceAdmin { + if (isSpace) return isRoomAdmin; + + for (final parent in pangeaSpaceParents) { + if (parent.isRoomAdmin) { + return true; + } + } + for (final parent in pangeaSpaceParents) { + for (final parent2 in parent.pangeaSpaceParents) { + if (parent2.isRoomAdmin) { + return true; + } + } + } + return false; + } + + bool isUserRoomAdmin(String userId) => getParticipants().any( + (e) => + e.id == userId && + e.powerLevel == ClassDefaultValues.powerLevelOfAdmin, + ); + + bool isUserSpaceAdmin(String userId) { + if (isSpace) return isUserRoomAdmin(userId); + + for (final parent in pangeaSpaceParents) { + if (parent.isUserRoomAdmin(userId)) { + return true; + } + } + return false; + } + + Event? get languageSettingsStateEvent => + getState(PangeaEventTypes.classSettings); + + Event? get pangeaRoomRulesStateEvent => getState(PangeaEventTypes.rules); + + bool get isPangeaClass => isSpace && languageSettingsStateEvent != null; + + bool get isAnalyticsRoom => + getState(EventTypes.RoomCreate)?.content.tryGet('type') == + PangeaRoomTypes.analytics; + + bool get isExchange => + isSpace && + languageSettingsStateEvent == null && + pangeaRoomRulesStateEvent != null; + + bool get isDirectChatWithoutMe => + isDirectChat && !getParticipants().any((e) => e.id == client.userID); + + bool isMadeByUser(String userId) => + getState(EventTypes.RoomCreate)?.senderId == userId; + + bool isMadeForLang(String langCode) => + getState(EventTypes.RoomCreate) + ?.content + .tryGet(ModelKey.langCode) == + langCode; + + bool isAnalyticsRoomOfUser(String userId) => + isAnalyticsRoom && isMadeByUser(userId); + + String get domainString => + AppConfig.defaultHomeserver.replaceAll("matrix.", ""); + + String get classCode { + if (!isSpace) { + for (final Room potentialClassRoom in pangeaSpaceParents) { + if (potentialClassRoom.isPangeaClass) { + return potentialClassRoom.classCode; + } + } + return "Not in a class!"; + } + + return canonicalAlias.replaceAll(":$domainString", "").replaceAll("#", ""); + } + + StudentAnalyticsEvent? _getStudentAnalyticsLocal(String studentId) { + if (!isSpace) { + debugger(when: kDebugMode); + ErrorHandler.logError( + m: "calling getStudentAnalyticsLocal on non-space room", + s: StackTrace.current, + ); + return null; + } + + final Event? matrixEvent = getState( + PangeaEventTypes.studentAnalyticsSummary, + studentId, + ); + + return matrixEvent != null + ? StudentAnalyticsEvent(event: matrixEvent) + : null; + } + + Future getStudentAnalytics( + String studentId, { + bool forcedUpdate = false, + }) async { + try { + debugPrint("getStudentAnalytics $studentId"); + if (!isSpace) { + debugger(when: kDebugMode); + throw Exception("calling getStudentAnalyticsLocal on non-space room"); + } + StudentAnalyticsEvent? localEvent = _getStudentAnalyticsLocal(studentId); + + if (localEvent == null) { + await postLoad(); + localEvent = _getStudentAnalyticsLocal(studentId); + } + + if (studentId == client.userID && localEvent == null) { + final Event? matrixEvent = await _createStudentAnalyticsEvent(); + if (matrixEvent != null) { + localEvent = StudentAnalyticsEvent(event: matrixEvent); + } + } + + return localEvent; + } catch (err) { + debugger(when: kDebugMode); + rethrow; + } + } + + void checkClass() { + if (!isSpace) { + debugger(when: kDebugMode); + Sentry.addBreadcrumb( + Breadcrumb(message: "calling room.students with non-class room"), + ); + } + } + + List get students { + checkClass(); + return isSpace + ? getParticipants() + .where( + (e) => + e.powerLevel < ClassDefaultValues.powerLevelOfAdmin && + e.id != BotName.byEnvironment, + ) + .toList() + : getParticipants(); + } + + Future> get teachers async { + checkClass(); + final List participants = await requestParticipants(); + return isSpace + ? participants + .where( + (e) => + e.powerLevel == ClassDefaultValues.powerLevelOfAdmin && + e.id != BotName.byEnvironment, + ) + .toList() + : participants; + } + + /// if [studentIds] is null, returns all students + Future> getClassAnalytics([ + List? studentIds, + ]) async { + await postLoad(); + await requestParticipants(); + final List> sassFutures = []; + final List filteredIds = students + .where( + (element) => studentIds == null || studentIds.contains(element.id), + ) + .map((e) => e.id) + .toList(); + for (final id in filteredIds) { + sassFutures.add( + getStudentAnalytics( + id, + ), + ); + } + return Future.wait(sassFutures); + } + + /// if [isSpace] + /// for all child chats, call _getChatAnalyticsGlobal and merge results + /// else + /// get analytics from pangea chat server + /// do any needed conversion work + /// save RoomAnalytics object to PangeaEventTypes.analyticsSummary event + Future _createStudentAnalyticsEvent() async { + try { + if (!pangeaCanSendEvent(PangeaEventTypes.studentAnalyticsSummary)) { + ErrorHandler.logError( + m: "null powerLevels in createStudentAnalytics", + s: StackTrace.current, + ); + return null; + } + if (client.userID == null) { + debugger(when: kDebugMode); + throw Exception("null userId in createStudentAnalytics"); + } + await postLoad(); + final String eventId = await client.setRoomStateWithKey( + id, + PangeaEventTypes.studentAnalyticsSummary, + client.userID!, + StudentAnalyticsSummary( + // studentId: client.userID!, + lastUpdated: DateTime.now(), + messages: [], + ).toJson(), + ); + final Event? event = await getEventById(eventId); + + if (event == null) { + debugger(when: kDebugMode); + throw Exception( + "null event after creation with eventId $eventId in createStudentAnalytics", + ); + } + return event; + } catch (err, stack) { + ErrorHandler.logError(e: err, s: stack, data: powerLevels); + return null; + } + } + + /// for each chat in class + /// get timeline back to january 15 + /// get messages + /// discard timeline + /// save messages to StudentAnalyticsSummary + Future updateMyLearningAnalyticsForClass([ + PLocalStore? storageService, + ]) async { + try { + final String migratedAnalyticsKey = + "MIGRATED_ANALYTICS_KEY${id.localpart}"; + + if (storageService?.read(migratedAnalyticsKey) ?? false) return; + + if (!isPangeaClass) { + throw Exception( + "In updateMyLearningAnalyticsForClass with room that is not not a class", + ); + } + + if (client.userID == null) { + debugger(when: kDebugMode); + return; + } + + final StudentAnalyticsEvent? myAnalEvent = + await getStudentAnalytics(client.userID!); + + if (myAnalEvent == null) { + debugPrint("null analytcs event for $id"); + if (pangeaCanSendEvent(PangeaEventTypes.studentAnalyticsSummary)) { + // debugger(when: kDebugMode); + } + return; + } + + myAnalEvent.bulkUpdate(await _messageListForAllChildChats); + + storageService?.save(migratedAnalyticsKey, true); + } catch (err, s) { + if (kDebugMode) rethrow; + // debugger(when: kDebugMode); + ErrorHandler.logError(e: err, s: s); + } + } + + Future> get _messageListForAllChildChats async { + try { + if (!isSpace) return []; + final List spaceChats = spaceChildren + .where((e) => e.roomId != null) + .map((e) => client.getRoomById(e.roomId!)) + .where((element) => element != null) + .cast() + .where((element) => !element.isSpace) + .toList(); + + if (spaceChildren.length != spaceChats.length) { + // debugger(when: kDebugMode); + ErrorHandler.logError( + m: "spaceChildren.length > chats.length in updateMyLearningAnalyticsForClass", + ); + } + + final List>> msgListFutures = []; + for (final chat in spaceChats) { + msgListFutures.add(chat._messageListForChat); + } + final List> msgLists = + await Future.wait(msgListFutures); + + final List joined = []; + for (final msgList in msgLists) { + joined.addAll(msgList); + } + return joined; + } catch (err) { + // debugger(when: kDebugMode); + rethrow; + } + } + + Future> get _messageListForChat async { + try { + int numberOfSearches = 0; + + if (isSpace) { + throw Exception( + "In messageListForChat with room that is not a chat", + ); + } + final Timeline timeline = await getTimeline(); + + while (timeline.canRequestHistory && numberOfSearches < 50) { + await timeline.requestHistory(historyCount: 100); + numberOfSearches += 1; + } + if (timeline.canRequestHistory) { + debugger(when: kDebugMode); + } + + final List msgs = []; + for (final event in timeline.events) { + if (event.senderId == client.userID && + event.type == EventTypes.Message) { + if (event.content['msgtype'] == MessageTypes.Text) { + final PangeaMessageEvent pMsgEvent = PangeaMessageEvent( + event: event, + timeline: timeline, + ownMessage: true, + selected: false, + ); + msgs.add( + RecentMessageRecord( + eventId: event.eventId, + chatId: id, + useType: pMsgEvent.useType, + time: event.originServerTs, + ), + ); + } else { + debugger(when: kDebugMode); + } + } + } + return msgs; + } catch (err, s) { + if (kDebugMode) rethrow; + debugger(when: kDebugMode); + ErrorHandler.logError(e: err, s: s); + return []; + } + } + + Future sendPangeaEvent({ + required Map content, + required String parentEventId, + required String type, + }) async { + try { + debugPrint("creating $type child for $parentEventId"); + Sentry.addBreadcrumb(Breadcrumb.fromJson(content)); + if (parentEventId.contains("web")) { + debugger(when: kDebugMode); + Sentry.addBreadcrumb( + Breadcrumb( + message: + "sendPangeaEvent with likely invalid parentEventId $parentEventId", + ), + ); + } + final Map repContent = { + // what is the functionality of m.reference? + "m.relates_to": {"rel_type": type, "event_id": parentEventId}, + type: content, + }; + + final String? newEventId = await sendEvent(repContent, type: type); + + if (newEventId == null) { + debugger(when: kDebugMode); + } + + //PTODO - handle the frequent case of a null newEventId + final Event? newEvent = await getEventById(newEventId!); + + if (newEvent == null) { + debugger(when: kDebugMode); + } + + return newEvent; + } catch (err, stack) { + debugger(when: kDebugMode); + ErrorHandler.logError( + e: err, + s: stack, + data: { + "type": type, + "parentEventId": parentEventId, + "content": content, + }, + ); + return null; + } + } + + ConstructEvent? _vocabEventLocal(String lemma) { + if (!isAnalyticsRoom) throw Exception("not an analytics room"); + + final Event? matrixEvent = getState(PangeaEventTypes.vocab, lemma); + + return matrixEvent != null ? ConstructEvent(event: matrixEvent) : null; + } + + bool get isRoomOwner => + getState(EventTypes.RoomCreate)?.senderId == client.userID; + + Future vocabEvent( + String lemma, + ConstructType type, [ + bool makeIfNull = false, + ]) async { + try { + if (!isAnalyticsRoom) throw Exception("not an analytics room"); + + ConstructEvent? localEvent = _vocabEventLocal(lemma); + + if (localEvent != null) return localEvent; + + await postLoad(); + localEvent = _vocabEventLocal(lemma); + + if (localEvent == null && isRoomOwner && makeIfNull) { + final Event matrixEvent = await _createVocabEvent(lemma, type); + localEvent = ConstructEvent(event: matrixEvent); + } + + return localEvent!; + } catch (err) { + debugger(when: kDebugMode); + rethrow; + } + } + + Future saveConstructUsesSameLemma( + String lemma, + ConstructType type, + List lemmaUses, + ) async { + final ConstructEvent? localEvent = _vocabEventLocal(lemma); + + if (localEvent == null) { + final json = + ConstructUses(lemma: lemma, type: type, uses: lemmaUses).toJson(); + await client.setRoomStateWithKey( + id, + PangeaEventTypes.vocab, + lemma, + ConstructUses(lemma: lemma, type: type, uses: lemmaUses).toJson(), + ); + } else { + localEvent.addAll(lemmaUses); + await updateStateEvent(localEvent.event); + } + } + + Future> get allConstructEvents async { + await postLoad(); + + return states[PangeaEventTypes.vocab] + ?.values + .map((Event event) => ConstructEvent(event: event)) + .toList() + .cast() ?? + []; + } + + Future _createVocabEvent(String lemma, ConstructType type) async { + try { + if (!isRoomOwner) { + throw Exception( + "Tried to create vocab event in room where user is not owner", + ); + } + final String eventId = await client.setRoomStateWithKey( + id, + PangeaEventTypes.vocab, + lemma, + ConstructUses(lemma: lemma, type: type).toJson(), + ); + final Event? event = await getEventById(eventId); + + if (event == null) { + debugger(when: kDebugMode); + throw Exception( + "null event after creation with eventId $eventId in _createVocabEvent", + ); + } + return event; + } catch (err, stack) { + debugger(when: kDebugMode); + ErrorHandler.logError(e: err, s: stack, data: powerLevels); + rethrow; + } + } + + Future makeSureTeachersAreInvitedToAnalyticsRoom() async { + try { + if (!isAnalyticsRoom) { + throw Exception("not an analytics room"); + } + if (!participantListComplete) { + await requestParticipants(); + } + final toAdd = [ + ...getParticipants([Membership.invite, Membership.join]) + .map((e) => e.id), + BotName.byEnvironment, + ]; + for (final teacher in await client.myTeachers) { + if (!toAdd.contains(teacher.id)) { + debugPrint("inviting ${teacher.id} to analytics room"); + await invite(teacher.id); + } + } + } catch (err, stack) { + debugger(when: kDebugMode); + ErrorHandler.logError(e: err, s: stack); + } + } + + /// update state event and return eventId + Future updateStateEvent(Event stateEvent) { + return client.setRoomStateWithKey( + id, + stateEvent.type, + stateEvent.stateKey!, + stateEvent.content, + ); + } + + bool canIAddSpaceChild(Room? room) { + if (!isSpace) { + ErrorHandler.logError( + m: "should not call canIAddSpaceChildren on non-space room", + data: toJson(), + s: StackTrace.current, + ); + return false; + } + if (!pangeaCanSendEvent(EventTypes.spaceChild) && !isRoomAdmin) { + return false; + } + if (room == null) { + return isRoomAdmin || (pangeaRoomRules?.isCreateRooms ?? false); + } + if (room.isExchange) { + return isRoomAdmin; + } + if (!room.isSpace) { + return pangeaRoomRules?.isCreateRooms ?? false; + } + if (room.isPangeaClass) { + ErrorHandler.logError( + m: "should not call canIAddSpaceChild with class", + data: room.toJson(), + s: StackTrace.current, + ); + return false; + } + return false; + } + + bool get canIAddSpaceParents => + isRoomAdmin || pangeaCanSendEvent(EventTypes.spaceParent); + + bool get showClassEditOptions => isSpace && isRoomAdmin; + + bool get canDelete => isSpaceAdmin; + + bool get isRoomAdmin => ownPowerLevel == ClassDefaultValues.powerLevelOfAdmin; + + //overriding the default canSendEvent to check power levels + bool pangeaCanSendEvent(String eventType) { + final powerLevelsMap = getState(EventTypes.RoomPowerLevels)?.content; + if (powerLevelsMap == null) return 0 <= ownPowerLevel; + final pl = powerLevelsMap + .tryGetMap('events') + ?.tryGet(eventType) ?? + 100; + return ownPowerLevel >= pl; + } + + Future setClassPowerlLevels() async { + try { + if (ownPowerLevel < ClassDefaultValues.powerLevelOfAdmin) { + return; + } + final currentPower = getState(EventTypes.RoomPowerLevels); + final Map? currentPowerContent = + currentPower!.content["events"] as Map?; + final spaceChildPower = currentPowerContent?[EventTypes.spaceChild]; + final studentAnalyticsPower = + currentPowerContent?[PangeaEventTypes.studentAnalyticsSummary]; + + if (spaceChildPower == null || studentAnalyticsPower == null) { + currentPowerContent!["events"][EventTypes.spaceChild] = 0; + currentPowerContent["events"] + [PangeaEventTypes.studentAnalyticsSummary] = 0; + + await client.setRoomStateWithKey( + id, + EventTypes.RoomPowerLevels, + currentPower.stateKey ?? "", + currentPowerContent, + ); + } + } catch (err, s) { + debugger(when: kDebugMode); + ErrorHandler.logError(e: err, s: s, data: toJson()); + } + } + + Future pangeaSendTextEvent( + String message, { + String? txid, + Event? inReplyTo, + String? editEventId, + bool parseMarkdown = false, + bool parseCommands = false, + String msgtype = MessageTypes.Text, + String? threadRootEventId, + String? threadLastEventId, + PangeaRepresentation? originalSent, + PangeaRepresentation? originalWritten, + PangeaMessageTokens? tokensSent, + PangeaMessageTokens? tokensWritten, + ChoreoRecord? choreo, + UseType? useType, + }) { + // if (parseCommands) { + // return client.parseAndRunCommand(this, message, + // inReplyTo: inReplyTo, + // editEventId: editEventId, + // txid: txid, + // threadRootEventId: threadRootEventId, + // threadLastEventId: threadLastEventId); + // } + final event = { + 'msgtype': msgtype, + 'body': message, + ModelKey.choreoRecord: choreo?.toJson(), + ModelKey.originalSent: originalSent?.toJson(), + ModelKey.originalWritten: originalWritten?.toJson(), + ModelKey.tokensSent: tokensSent?.toJson(), + ModelKey.tokensWritten: tokensWritten?.toJson(), + ModelKey.useType: useType?.string, + }; + // if (parseMarkdown) { + // final html = markdown(event['body'], + // getEmotePacks: () => getImagePacksFlat(ImagePackUsage.emoticon), + // getMention: getMention); + // // if the decoded html is the same as the body, there is no need in sending a formatted message + // if (HtmlUnescape().convert(html.replaceAll(RegExp(r'
\n?'), '\n')) != + // event['body']) { + // event['format'] = 'org.matrix.custom.html'; + // event['formatted_body'] = html; + // } + // } + return sendEvent( + event, + txid: txid, + inReplyTo: inReplyTo, + editEventId: editEventId, + threadRootEventId: threadRootEventId, + threadLastEventId: threadLastEventId, + ); + } + + bool get locked { + final Event? powerLevels = getState(EventTypes.RoomPowerLevels); + if (powerLevels == null) { + return false; + } + final Map powerLevelsContent = Map.from( + powerLevels.content, + ); + + if (!isSpace) { + return powerLevelsContent['events_default'] != null && + powerLevelsContent['events_default'] >= 100; + } + + final List children = spaceChildren + .map( + (child) => + child.roomId != null ? client.getRoomById(child.roomId!) : null, + ) + .toList(); + + for (final Room? child in children) { + if (child != null && !child.locked) { + return false; + } + } + return true; + } + + Future suggestedInSpace(Room space) async { + try { + final Map resp = + await client.getRoomStateWithKey(space.id, EventTypes.spaceChild, id); + return resp.containsKey('suggested') ? resp['suggested'] as bool : true; + } catch (err) { + ErrorHandler.logError( + e: "Failed to fetch suggestion status of room $id in space ${space.id}", + s: StackTrace.current, + ); + return true; + } + } + + Future setSuggestedInSpace(bool suggest, Room space) async { + try { + await space.setSpaceChild(id, suggested: suggest); + } catch (err) { + ErrorHandler.logError( + e: "Failed to set suggestion status of room $id in space ${space.id}", + s: StackTrace.current, + ); + return; + } + } + + Future> getChildRooms() async { + final List children = []; + for (final child in spaceChildren) { + if (child.roomId == null) continue; + final Room? room = client.getRoomById(child.roomId!); + if (room != null) { + children.add(room); + } + } + return children; + } +} diff --git a/lib/pangea/guard/p_vguard.dart b/lib/pangea/guard/p_vguard.dart new file mode 100644 index 000000000..20ddd35d6 --- /dev/null +++ b/lib/pangea/guard/p_vguard.dart @@ -0,0 +1,151 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; + +import 'package:go_router/go_router.dart'; + +import 'package:fluffychat/widgets/matrix.dart'; +import '../controllers/pangea_controller.dart'; + +class PAuthGaurd { + static bool isPublicLeaving = false; + static PangeaController? pController; + + static FutureOr loggedInRedirect( + BuildContext context, + GoRouterState state, + ) async { + if (pController != null) { + final bool setDob = await pController! + .userController.isUserDataAvailableAndDateOfBirthSet; + if (Matrix.of(context).client.isLogged()) { + return !setDob ? '/rooms/user_age' : '/rooms'; + } + return null; + } else { + debugPrint("controller is null in pguard check"); + Matrix.of(context).client.isLogged() ? '/rooms' : null; + } + return null; + } + + static FutureOr loggedOutRedirect( + BuildContext context, + GoRouterState state, + ) async { + if (pController != null) { + final bool setDob = await pController! + .userController.isUserDataAvailableAndDateOfBirthSet; + return !Matrix.of(context).client.isLogged() + ? '/home' + : !setDob + ? '/rooms/user_age' + : null; + } else { + debugPrint("controller is null in pguard check"); + return Matrix.of(context).client.isLogged() ? null : '/home'; + } + } + + // static const defaultRoute = '/home'; + + // static Future onPublicEnter() async { + // final bool setDob = + // await pController!.userController.isUserDataAvailableAndDateOfBirthSet; + // if (_isLogged != null && _isLogged! && setDob) { + // vRedirector.to('/rooms'); + // } + // } + + // static Future onPublicUpdate(VRedirector vRedirector) async { + // final bool setDob = + // await pController!.userController.isUserDataAvailableAndDateOfBirthSet; + // if (_isLogged != null && _isLogged! && setDob) { + // vRedirector.to('/rooms'); + // } + // bool oldHaveParms = false; + + // final bool haveData = vRedirector.previousVRouterData != null; + // if (haveData) { + // final bool isPublicRoute = + // vRedirector.newVRouterData!.url!.startsWith(defaultRoute); + // if (!isPublicRoute) { + // return; + // } + // oldHaveParms = + // vRedirector.previousVRouterData!.queryParameters.isNotEmpty; + // if (oldHaveParms) { + // if (vRedirector.newVRouterData!.queryParameters.isEmpty) { + // vRedirector.to( + // vRedirector.toUrl!, + // queryParameters: vRedirector.previousVRouterData!.queryParameters, + // ); + // } + // } + // } + + // return; + // } + + // static Future onPublicLeave( + // VRedirector vRedirector, + // Function(Map onLeave) callback, + // ) async { + // final bool haveData = vRedirector.previousVRouterData != null; + + // if (haveData) { + // try { + // if (vRedirector.previousVRouterData!.queryParameters['redirect'] == + // 'true') { + // if (!isPublicLeaving) { + // isPublicLeaving = true; + // vRedirector.to( + // vRedirector.previousVRouterData!.queryParameters['redirectPath']!, + // ); + // } + // } + // } catch (e, s) { + // ErrorHandler.logError(e: e, s: s); + // } + // } + // return; + // } + + // static Future onPrivateUpdate(VRedirector vRedirector) async { + // if (_isLogged == null) { + // return; + // } + // final Map redirectParm = {}; + // final bool haveData = vRedirector.newVRouterData != null; + // if (haveData) { + // if (vRedirector.newVRouterData!.queryParameters.isNotEmpty) { + // redirectParm['redirect'] = 'true'; + // redirectParm['redirectPath'] = vRedirector.newVRouterData!.url!; + // } + // } + // if (!_isLogged!) { + // debugPrint("onPrivateUpdate with user not logged in"); + // ErrorHandler.logError( + // e: Exception("onPrivateUpdate with user not logged in"), + // s: StackTrace.current, + // ); + // // vRedirector.to(defaultRoute, queryParameters: redirectParm); + // } else { + // if (pController != null) { + // if (!await pController! + // .userController.isUserDataAvailableAndDateOfBirthSet) { + // debugPrint("reroute to user_age"); + // vRedirector.to( + // '/home/connect/user_age', + // queryParameters: redirectParm, + // ); + // } + // } else { + // debugPrint("controller is null in pguard check"); + // } + // } + + // isPublicLeaving = false; + // return; + // } +} diff --git a/lib/pangea/models/analytics_model_old.dart b/lib/pangea/models/analytics_model_old.dart new file mode 100644 index 000000000..8dc5159da --- /dev/null +++ b/lib/pangea/models/analytics_model_old.dart @@ -0,0 +1,100 @@ +// import 'dart:convert'; + +// class UserTimeSeriesInterval { +// String? userId; +// int? taTotal; +// int? gaTotal; +// int? waTotal; + +// UserTimeSeriesInterval({ +// required this.userId, +// required this.taTotal, +// required this.gaTotal, +// required this.waTotal, +// }); + +// Map toJson() => +// {"usr": userId, "ta": taTotal, "ga": gaTotal, "wa": waTotal}; + +// factory UserTimeSeriesInterval.fromJson(json) => UserTimeSeriesInterval( +// userId: json["usr"], +// taTotal: json["ta"], +// gaTotal: json["ga"], +// waTotal: json["wa"], +// ); +// } + +// class TimeSeriesInterval { +// DateTime start; +// DateTime end; +// List users; + +// TimeSeriesInterval({ +// required this.start, +// required this.end, +// required this.users, +// }); + +// Map toJson() => { +// "strt": start, +// "end": end, +// "usrs": jsonEncode(users.map((e) => e.toJson()).toList()) +// }; + +// factory TimeSeriesInterval.fromJson(json) => TimeSeriesInterval( +// start: json["strt"], +// end: json["end"], +// users: ((jsonDecode(json["usrs"]) as Iterable) +// .map((e) => UserTimeSeriesInterval.fromJson(e)) +// .toList() +// .cast()), +// ); +// } + +// class RoomAnalyticsSummary { +// List monthlyTotalsForAllTime; +// List dailyTotalsForLast30Days; +// List hourlyTotalsForLast24Hours; + +// DateTime? updatedAt; + +// RoomAnalyticsSummary({ +// required this.monthlyTotalsForAllTime, +// required this.dailyTotalsForLast30Days, +// required this.hourlyTotalsForLast24Hours, +// }); + +// Map toJson() => { +// "mnths": +// jsonEncode(monthlyTotalsForAllTime.map((e) => e.toJson()).toList()), +// "dys": jsonEncode( +// dailyTotalsForLast30Days.map((e) => e.toJson()).toList()), +// "hrs": jsonEncode( +// hourlyTotalsForLast24Hours.map((e) => e.toJson()).toList()), +// }; + +// factory RoomAnalyticsSummary.fromJson(json) => RoomAnalyticsSummary( +// monthlyTotalsForAllTime: (jsonDecode(json["mnths"]) as Iterable) +// .map((e) => TimeSeriesInterval.fromJson(e)) +// .toList() +// .cast(), +// dailyTotalsForLast30Days: (jsonDecode(json["dys"]) as Iterable) +// .map((e) => TimeSeriesInterval.fromJson(e)) +// .toList() +// .cast(), +// hourlyTotalsForLast24Hours: (jsonDecode(json["hrs"]) as Iterable) +// .map((e) => TimeSeriesInterval.fromJson(e)) +// .toList() +// .cast(), +// ); +// } + +// class UserDirectChatAnalyticsSummary { +// // directChatRoomIds and analytics for those rooms +// // updated by user; +// Map? directChatSummaries; + +// Map toJson() => {}; +// } + +// // maybe search how to do date ranges in dart diff --git a/lib/pangea/models/analytics_model_older.dart b/lib/pangea/models/analytics_model_older.dart new file mode 100644 index 000000000..2ee817f0b --- /dev/null +++ b/lib/pangea/models/analytics_model_older.dart @@ -0,0 +1,124 @@ +// import 'dart:convert'; + +// class ChatTimeSeriesInterval { +// String? chatId; +// int? taTotal; +// int? gaTotal; +// int? waTotal; + +// ChatTimeSeriesInterval({ +// required this.chatId, +// required this.taTotal, +// required this.gaTotal, +// required this.waTotal, +// }); + +// Map toJson() => +// {"id": chatId, "ta": taTotal, "ga": gaTotal, "wa": waTotal}; + +// factory ChatTimeSeriesInterval.fromJson(json) => ChatTimeSeriesInterval( +// chatId: json["id"], +// taTotal: json["ta"], +// gaTotal: json["ga"], +// waTotal: json["wa"], +// ); +// } + +// class TimeSeriesInterval { +// DateTime start; +// DateTime end; +// List chats; + +// TimeSeriesInterval({ +// required this.start, +// required this.end, +// required this.chats, +// }); + +// Map toJson() => { +// "strt": start, +// "end": end, +// "usrs": jsonEncode(chats.map((e) => e.toJson()).toList()) +// }; + +// factory TimeSeriesInterval.fromJson(json) => TimeSeriesInterval( +// start: DateTime(json["strt"]), +// end: DateTime(json["end"]), +// chats: ((jsonDecode(json["usrs"]) as Iterable) +// .map((e) => ChatTimeSeriesInterval.fromJson(e)) +// .toList() +// .cast()), +// ); +// } + +// // class RecentMessageRecord { +// // String eventId; +// // String typeOfUse; +// // String time; +// // } + +// class StudentAnalyticsSummary { +// /// event statekey = studentId +// // String studentId; + +// List monthlyTotalsForAllTime; +// List dailyTotalsForLast30Days; +// List hourlyTotalsForLast24Hours; + +// // List messages; + +// DateTime lastLogin; +// DateTime lastMessage; + +// DateTime lastUpdated; + +// StudentAnalyticsSummary({ +// // required this.studentId, +// required this.monthlyTotalsForAllTime, +// required this.dailyTotalsForLast30Days, +// required this.hourlyTotalsForLast24Hours, +// required this.lastLogin, +// required this.lastMessage, +// required this.lastUpdated, +// }); + +// // static const _studentIdKey = 'usr'; +// static const _monthKey = "mnths"; +// static const _dayKey = "dys"; +// static const _hoursKey = "hrs"; +// static const _lastLoginKey = "lgn"; +// static const _lastMessageKey = "msg"; +// static const _lastUpdated = "lupt"; + +// Map toJson() => { +// _monthKey: +// jsonEncode(monthlyTotalsForAllTime.map((e) => e.toJson()).toList()), +// _dayKey: jsonEncode( +// dailyTotalsForLast30Days.map((e) => e.toJson()).toList()), +// _hoursKey: jsonEncode( +// hourlyTotalsForLast24Hours.map((e) => e.toJson()).toList()), +// // _studentIdKey: studentId, +// _lastLoginKey: lastLogin.toIso8601String(), +// _lastMessageKey: lastMessage.toIso8601String(), +// _lastUpdated: lastUpdated.toIso8601String() +// }; + +// factory StudentAnalyticsSummary.fromJson(json) => StudentAnalyticsSummary( +// // studentId: json[_studentIdKey], +// monthlyTotalsForAllTime: (jsonDecode(json[_monthKey]) as Iterable) +// .map((e) => TimeSeriesInterval.fromJson(e)) +// .toList() +// .cast(), +// dailyTotalsForLast30Days: (jsonDecode(json[_dayKey]) as Iterable) +// .map((e) => TimeSeriesInterval.fromJson(e)) +// .toList() +// .cast(), +// hourlyTotalsForLast24Hours: (jsonDecode(json[_hoursKey]) as Iterable) +// .map((e) => TimeSeriesInterval.fromJson(e)) +// .toList() +// .cast(), +// lastLogin: DateTime(json[_lastLoginKey]), +// lastUpdated: DateTime(json[_lastLoginKey]), +// lastMessage: DateTime(json[_lastMessageKey]), +// ); +// } diff --git a/lib/pangea/models/analytics_model_oldest.dart b/lib/pangea/models/analytics_model_oldest.dart new file mode 100644 index 000000000..f075c1fe4 --- /dev/null +++ b/lib/pangea/models/analytics_model_oldest.dart @@ -0,0 +1,77 @@ +// import 'dart:convert'; + +// class BaseDataModel { +// late int spanTotal; +// late int spanIT; +// late int spanIGC; +// late int spanDirect; + +// BaseDataModel(Map json) { +// fromJson(json); +// } + +// fromJson(Map json) { +// spanTotal = json["total"]; +// spanIT = json["it"]; +// spanIGC = json["igc"]; +// spanDirect = json["direct"]; +// } +// } + +// class TimeSeriesInterval extends BaseDataModel { +// //note: always in UTC +// late DateTime start; +// late DateTime end; + +// TimeSeriesInterval(Map json) : super(json) { +// fromJsonTimeSeriesInterval(json); +// } + +// fromJsonTimeSeriesInterval(Map json) { +// start = DateTime.parse(json["start"]); +// end = DateTime.parse(json["end"]); +// } +// } + +// class chartAnalytics extends BaseDataModel { +// late String id; +// late int allTotal; +// late int allIT; +// late int allIGC; +// late int allDirect; +// late String timeSpan; +// late DateTime fetchedAt; +// late List? chatIds; +// late List? userIds; +// late List? classIds; +// late List timeSeries; + +// chartAnalytics(Map json) : super(json) { +// fromJsonchartAnalytics(json); +// fetchedAt = DateTime.now(); +// } + +// fromJsonchartAnalytics(Map json) { +// id = json["id"]; +// timeSpan = json["timespan"]; +// allTotal = json["alltime"]["total"]; +// allIT = json["alltime"]["it"]; +// allIGC = json["alltime"]["igc"]; +// allDirect = json["alltime"]["direct"]; +// timeSeries = (json["timeseries"] as Iterable) +// .map( +// (timeSeriesJsonEntry) => TimeSeriesInterval(timeSeriesJsonEntry), +// ) +// .toList() +// .cast(); +// chatIds = json["chats"] != null && json["chats"] != [] +// ? (json["chats"] as List).cast() +// : null; +// userIds = json["users"] != null && json["userIds"] != [] +// ? (json["users"] as List).cast() +// : null; +// classIds = json["classes"] != null && json["classes"] != [] +// ? (json["classes"] as List).cast() +// : null; +// } +// } diff --git a/lib/pangea/models/base_subscription_info.dart b/lib/pangea/models/base_subscription_info.dart new file mode 100644 index 000000000..604abf6e9 --- /dev/null +++ b/lib/pangea/models/base_subscription_info.dart @@ -0,0 +1,74 @@ +import 'package:fluffychat/pangea/controllers/pangea_controller.dart'; +import 'package:fluffychat/pangea/controllers/subscription_controller.dart'; +import 'package:fluffychat/pangea/repo/subscription_repo.dart'; +import 'package:fluffychat/pangea/utils/subscription_app_id.dart'; + +class SubscriptionInfo { + PangeaController pangeaController; + List availableSubscriptions = []; + String? currentSubscriptionId; + SubscriptionDetails? currentSubscription; + // Gabby - is it necessary to store appIds for each platform? + SubscriptionAppIds? appIds; + List? allProducts; + final SubscriptionPlatform platform = SubscriptionPlatform(); + List allEntitlements = []; + DateTime? expirationDate; + + bool get hasSubscribed => allEntitlements.isNotEmpty; + + SubscriptionInfo({ + required this.pangeaController, + }) : super(); + + Future configure() async {} + + //TO-DO - hey Gabby this file feels like it could be reorganized. i'd like to + // 1) move these api calls to a class in a file in repo and + // 2) move the url to the urls file. + // 3) any stateful info to the subscription controller + // let's discuss before you make the changes though + // maybe you had some reason for this organization + + /* + Fetch App Ids for each RC app (iOS, Android, and Stripe). Used to determine which app a user + with an active subscription purchased that subscription. + */ + Future setAppIds() async { + if (appIds != null) return; + appIds = await SubscriptionRepo.getAppIds(); + } + + Future setAllProducts() async { + if (allProducts != null) return; + allProducts = await SubscriptionRepo.getAllProducts(); + } + + bool get currentSubscriptionIsPromotional => + currentSubscriptionId?.startsWith("rc_promo") ?? false; + + bool get isLifetimeSubscription => + currentSubscriptionIsPromotional && + expirationDate != null && + expirationDate!.isAfter(DateTime(2100)); + + String? get purchasePlatformDisplayName { + if (currentSubscription?.appId == null) return null; + return appIds?.appDisplayName(currentSubscription!.appId!); + } + + bool get purchasedOnWeb => + (currentSubscription != null && appIds != null) && + (currentSubscription?.appId == appIds?.stripeId); + + bool get currentPlatformMatchesPurchasePlatform => + (currentSubscription != null && appIds != null) && + (currentSubscription?.appId == appIds?.currentAppId); + + void resetSubscription() { + currentSubscription = null; + currentSubscriptionId = null; + } + + Future setCustomerInfo() async {} +} diff --git a/lib/pangea/models/chart_analytics_model.dart b/lib/pangea/models/chart_analytics_model.dart new file mode 100644 index 000000000..af06a0958 --- /dev/null +++ b/lib/pangea/models/chart_analytics_model.dart @@ -0,0 +1,140 @@ +import 'dart:developer'; + +import 'package:flutter/foundation.dart'; + +import 'package:fluffychat/pangea/enum/time_span.dart'; +import 'package:fluffychat/pangea/models/student_analytics_summary_model.dart'; +import '../enum/use_type.dart'; + +class TimeSeriesTotals { + int ta; + int ga; + int wa; + int un; + + int get all => ta + ga + wa + un; + + TimeSeriesTotals({ + required this.ta, + required this.ga, + required this.wa, + required this.un, + }); + + Map toJson() => { + UseType.ta.string: ta, + UseType.ga.string: ga, + UseType.wa.string: wa, + UseType.un.string: un, + }; + + factory TimeSeriesTotals.fromJson(json) => TimeSeriesTotals( + ta: json[UseType.ta.string], + ga: json[UseType.ga.string], + wa: json[UseType.wa.string], + un: json[UseType.un.string], + ); + + static get empty => TimeSeriesTotals(ta: 0, ga: 0, wa: 0, un: 0); + + int get taPercent => all != 0 ? (ta / all * 100).round() : 0; + int get gaPercent => all != 0 ? (ga / all * 100).round() : 0; + int get waPercent => all != 0 ? (wa / all * 100).round() : 0; + int get unPercent => all != 0 ? (un / all * 100).round() : 0; + + void increment(RecentMessageRecord msg) { + switch (msg.useType) { + case UseType.ta: + ta += 1; + break; + case UseType.wa: + wa += 1; + break; + case UseType.ga: + ga += 1; + break; + case UseType.un: + un += 1; + break; + default: + debugger(when: kDebugMode); + debugPrint("message with bad type ${msg.toJson()}"); + } + } +} + +class TimeSeriesInterval { + DateTime start; + DateTime end; + TimeSeriesTotals totals; + + TimeSeriesInterval({ + required this.start, + required this.end, + required this.totals, + }); + + Map toJson() => { + "strt": start.toIso8601String(), + "end": end.toIso8601String(), + "totals": totals.toJson(), + }; + + factory TimeSeriesInterval.fromJson(json) => TimeSeriesInterval( + start: DateTime.parse(json["strt"]), + end: DateTime.parse(json["end"]), + totals: TimeSeriesTotals.fromJson(json["totals"]), + ); +} + +class ChartAnalyticsModel { + final TimeSpan timeSpan; + final TimeSeriesTotals totals = TimeSeriesTotals.empty; + final List msgs; + final String? chatId; + + late DateTime fetchedAt; + late List timeSeries; + DateTime? lastMessage; + + ChartAnalyticsModel({ + required this.timeSpan, + required this.msgs, + this.chatId, + }) { + fetchedAt = DateTime.now(); + calculate(); + } + + bool get isEmpty => (totals.ga + totals.ta + totals.wa == 0); + + void calculate() { + final Map intervals = timeSpan.emptyIntervals; + final DateTime cutOff = timeSpan.cutOffDate; + + final filtered = msgs.where( + (msg) => + (chatId == null || msg.chatId == chatId) && msg.time.isAfter(cutOff), + ); + + //remove msgs with duplicate ids + final Map unique = {}; + for (final msg in filtered) { + if (unique[msg.eventId] == null) { + unique[msg.eventId] = msg; + } + } + + for (final msg in unique.values) { + final String key = timeSpan.getMapKey(msg.time); + if (intervals[key] == null) { + debugger(when: kDebugMode); + } else { + intervals[key]!.totals.increment(msg); + totals.increment(msg); + lastMessage = msg.time; + } + } + timeSeries = intervals.values.toList().reversed.toList(); + } +} diff --git a/lib/pangea/models/chat_topic_model.dart b/lib/pangea/models/chat_topic_model.dart new file mode 100644 index 000000000..c83e3f7c6 --- /dev/null +++ b/lib/pangea/models/chat_topic_model.dart @@ -0,0 +1,124 @@ +import 'lemma.dart'; + +class ChatTopic { + String name; + String description; + String langCode; + String languageLevel; + List discussionPrompts; + List vocab; + + ChatTopic({ + this.name = "", + this.description = "", + required this.langCode, + this.languageLevel = "Pre-A1", + this.discussionPrompts = const [], + this.vocab = const [], + }); + + factory ChatTopic.fromJson(Map json) { + return ChatTopic( + name: json['name'], + description: json['description'], + langCode: json['lang_code'], + languageLevel: json['language_level'], + discussionPrompts: (json['discussion_prompts'] as Iterable) + .map((e) => DiscussionPrompt.fromJson(e)) + .toList(), + vocab: (json['vocab'] as Iterable) + .map((e) => Lemma.fromJson(e)) + .toList(), + ); + } + + Map toJson() { + return { + 'name': name, + 'description': description, + 'lang_code': langCode, + 'language_level': languageLevel, + 'discussion_prompts': discussionPrompts, + 'vocab': vocab, + }; + } + + static ChatTopic get empty => ChatTopic( + name: '', + description: '', + langCode: '', + languageLevel: '', + discussionPrompts: [], + vocab: [], + ); + + /// set equals operator + @override + bool operator ==(Object other) => + identical(this, other) || + other is ChatTopic && + runtimeType == other.runtimeType && + name == other.name && + description == other.description && + langCode == other.langCode && + languageLevel == other.languageLevel && + discussionPrompts == other.discussionPrompts && + vocab == other.vocab; + + /// set hashcode + @override + int get hashCode => + name.hashCode ^ + description.hashCode ^ + langCode.hashCode ^ + languageLevel.hashCode ^ + discussionPrompts.hashCode ^ + vocab.hashCode; + + /// mock data + static ChatTopic get mockTopic => ChatTopic( + name: 'Mock Topic', + description: 'Mock Description', + langCode: 'en', + languageLevel: 'A1', + discussionPrompts: [ + DiscussionPrompt(text: 'Mock Prompt 1'), + DiscussionPrompt(text: 'Mock Prompt 2'), + ], + vocab: [ + Lemma(text: 'Mock Lemma 1', saveVocab: true, form: 'Mock Form 1'), + Lemma(text: 'Mock Lemma 2', saveVocab: true, form: 'Mock Form 2'), + ], + ); +} + +/// just one parameter, text +class DiscussionPrompt { + final String text; + + DiscussionPrompt({required this.text}); + + factory DiscussionPrompt.fromJson(Map json) { + return DiscussionPrompt( + text: json['text'], + ); + } + + Map toJson() { + return { + 'text': text, + }; + } + + /// set equals operator + @override + bool operator ==(Object other) => + identical(this, other) || + other is DiscussionPrompt && + runtimeType == other.runtimeType && + text == other.text; + + /// set hashcode + @override + int get hashCode => text.hashCode; +} diff --git a/lib/pangea/models/choreo_init_response.model.dart b/lib/pangea/models/choreo_init_response.model.dart new file mode 100644 index 000000000..45274bca5 --- /dev/null +++ b/lib/pangea/models/choreo_init_response.model.dart @@ -0,0 +1,85 @@ +class ChoreoResponseModel { + GrammarData? grammarData; + String? detectedLang; + String? route; + String? feedbackMessage; + int? payloadId; + ChoreoResponseModel({ + this.grammarData, + this.detectedLang, + this.route, + this.feedbackMessage, + }); + + ChoreoResponseModel.fromJson(Map json) { + grammarData = json['grammar_data'] != null + ? GrammarData.fromJson(json['grammar_data']) + : null; + detectedLang = json['detected_lang']; + route = json['route']; + feedbackMessage = json['feedback_message']; + payloadId = json['payload_id']; + } + + Map toJson() { + final Map data = {}; + if (grammarData != null) { + data['grammar_data'] = grammarData!.toJson(); + } + data['detected_lang'] = detectedLang; + data['route'] = route; + data['feedback_message'] = feedbackMessage; + return data; + } +} + +class GrammarData { + String? text; + List? tokens; + double? slor; + + GrammarData({this.text, this.tokens, this.slor}); + + GrammarData.fromJson(Map json) { + text = json['text']; + if (json['tokens'] != null) { + tokens = []; + json['tokens'].forEach((v) { + tokens!.add(Tokens.fromJson(v)); + }); + } + slor = json['slor']; + } + + Map toJson() { + final Map data = {}; + data['text'] = text; + if (tokens != null) { + data['tokens'] = tokens!.map((v) => v.toJson()).toList(); + } + data['slor'] = slor; + return data; + } +} + +class Tokens { + String? token; + int? category; + String? feedbackMessage; + + Tokens({this.token, this.category, this.feedbackMessage}); + + Tokens.fromJson(Map json) { + token = json['token']; + category = json['category']; + feedbackMessage = json['feedback_message']; + } + + Map toJson() { + final Map data = {}; + data['token'] = token; + data['category'] = category; + data['feedback_message'] = feedbackMessage; + return data; + } +} diff --git a/lib/pangea/models/choreo_record.dart b/lib/pangea/models/choreo_record.dart new file mode 100644 index 000000000..d3612f8f4 --- /dev/null +++ b/lib/pangea/models/choreo_record.dart @@ -0,0 +1,330 @@ +import 'dart:convert'; + +import 'package:fluffychat/pangea/models/pangea_match_model.dart'; +import 'package:fluffychat/pangea/models/pangea_token_model.dart'; +import '../constants/choreo_constants.dart'; +import '../enum/construct_type_enum.dart'; +import 'constructs_analytics_model.dart'; +import 'it_step.dart'; +import 'lemma.dart'; + +/// this class lives within a [PangeaIGCEvent] +/// it always has a [RepresentationEvent] parent +/// These live as separate event so that anyone can add and edit grammar checks +/// to a representation +/// It represents the real-time changes to a text +/// TODO - start saving senderL2Code in choreoRecord to be able better decide the useType + +class ChoreoRecord { + /// ordered versions of the representation, with first being original and last + /// being the final sent text + /// there is not a 1-to-1 map from steps to matches + List choreoSteps; + + // String current; + + List openMatches; + + ChoreoRecord({ + required this.choreoSteps, + required this.openMatches, + // required this.current, + }); + + factory ChoreoRecord.fromJson(Map json) { + final stepsRaw = json[_stepsKey]; + return ChoreoRecord( + choreoSteps: (jsonDecode(stepsRaw ?? "[]") as Iterable) + .map((e) { + return ChoreoRecordStep.fromJson(e); + }) + .toList() + .cast(), + openMatches: (jsonDecode(json[_openMatchesKey] ?? "[]") as Iterable) + .map((e) { + return PangeaMatch.fromJson(e); + }) + .toList() + .cast(), + // current: json[_currentKey], + ); + } + + static const _stepsKey = "stps"; + static const _openMatchesKey = "mtchs"; + // static const _currentKey = "crnt"; + + Map toJson() { + final data = {}; + data[_stepsKey] = jsonEncode(choreoSteps.map((e) => e.toJson()).toList()); + data[_openMatchesKey] = + jsonEncode(openMatches.map((e) => e.toJson()).toList()); + // data[_currentKey] = current; + return data; + } + + addRecord(String text, {PangeaMatch? match, ITStep? step}) { + if (match != null && step != null) { + throw Exception("match and step should not both be defined"); + } + choreoSteps.add( + ChoreoRecordStep( + text: text, + acceptedOrIgnoredMatch: match, + itStep: step, + ), + ); + } + + bool get hasAcceptedMatches => choreoSteps.any( + (element) => + element.acceptedOrIgnoredMatch?.status == + PangeaMatchStatus.accepted, + ); + + bool get hasIgnoredMatches => choreoSteps.any( + (element) => + element.acceptedOrIgnoredMatch?.status == PangeaMatchStatus.ignored, + ); + + // bool get includedIT => choreoSteps.any((step) { + // return step.acceptedOrIgnoredMatch?.status == + // PangeaMatchStatus.accepted && + // (step.acceptedOrIgnoredMatch?.isITStart ?? false); + // }); + + bool get includedIT => choreoSteps.any((step) { + return step.acceptedOrIgnoredMatch?.status == + PangeaMatchStatus.accepted && + (step.acceptedOrIgnoredMatch?.isOutOfTargetMatch ?? false); + }); + + bool get includedIGC => choreoSteps.any((step) { + return step.acceptedOrIgnoredMatch?.status == + PangeaMatchStatus.accepted && + (step.acceptedOrIgnoredMatch?.isGrammarMatch ?? false); + }); + + static ChoreoRecord get newRecord => ChoreoRecord( + choreoSteps: [], + openMatches: [], + ); + + /// [tokens] is the final list of tokens that were sent + /// if no ga or ta, + /// make wa use for each and return + /// else + /// for each saveable vocab in the final message + /// if vocab is contained in an accepted replacement, make ga use + /// if vocab is contained in ta choice, + /// if selected as choice, corIt + /// if written as customInput, corIt? (account for score in this) + /// for each it step + /// for each continuance + /// if not within the final message, save ignIT/incIT + List toVocabUse( + List tokens, + String chatId, + String msgId, + ) { + final List uses = []; + final DateTime now = DateTime.now(); + List lemmasToVocabUses( + List lemmas, + ConstructUseType type, + ) { + final List uses = []; + for (final lemma in lemmas) { + if (lemma.saveVocab) { + uses.add( + OneConstructUse( + useType: type, + chatId: chatId, + timeStamp: now, + lemma: lemma.text, + form: lemma.form, + msgId: msgId, + constructType: ConstructType.vocab, + ), + ); + } + } + return uses; + } + + List getVocabUseForToken(PangeaToken token) { + for (final step in choreoSteps) { + /// if 1) accepted match 2) token is in the replacement and 3) replacement + /// is in the overall step text, then token was a ga + if (step.acceptedOrIgnoredMatch?.status == PangeaMatchStatus.accepted && + (step.acceptedOrIgnoredMatch!.match.choices?.any( + (r) => + r.value.contains(token.text.content) && + step.text.contains(r.value), + ) ?? + false)) { + return lemmasToVocabUses(token.lemmas, ConstructUseType.ga); + } + if (step.itStep != null) { + final bool pickedThroughIT = step.itStep!.chosenContinuance?.text + .contains(token.text.content) ?? + false; + if (pickedThroughIT) { + return lemmasToVocabUses(token.lemmas, ConstructUseType.corIt); + //PTODO - check if added via custom input in IT flow + } + } + } + return lemmasToVocabUses(token.lemmas, ConstructUseType.wa); + } + + /// for each token, record whether selected in ga, ta, or wa + for (final token in tokens) { + uses.addAll(getVocabUseForToken(token)); + } + + for (final itStep in itSteps) { + for (final continuance in itStep.continuances) { + // this seems to always be false for continuances right now + + if (finalMessage.contains(continuance.text)) { + continue; + } + if (continuance.wasClicked) { + //PTODO - account for end of flow score + if (continuance.level != ChoreoConstants.levelThresholdForGreen) { + uses.addAll( + lemmasToVocabUses(continuance.lemmas, ConstructUseType.incIt), + ); + } + } else { + if (continuance.level != ChoreoConstants.levelThresholdForGreen) { + uses.addAll( + lemmasToVocabUses(continuance.lemmas, ConstructUseType.ignIt), + ); + } + } + } + } + + return uses; + } + + List toGrammarConstructUse(String msgId, String chatId) { + final List uses = []; + final DateTime now = DateTime.now(); + for (final step in choreoSteps) { + if (step.acceptedOrIgnoredMatch?.status == PangeaMatchStatus.accepted) { + final String name = step.acceptedOrIgnoredMatch!.match.rule?.id ?? + step.acceptedOrIgnoredMatch!.match.shortMessage ?? + step.acceptedOrIgnoredMatch!.match.type.typeName.name; + uses.add( + OneConstructUse( + useType: ConstructUseType.ga, + chatId: chatId, + timeStamp: now, + lemma: name, + form: name, + msgId: msgId, + constructType: ConstructType.grammar, + ), + ); + } + } + return uses; + } + + List get itSteps => + choreoSteps.where((e) => e.itStep != null).map((e) => e.itStep!).toList(); + + String get finalMessage => + choreoSteps.isNotEmpty ? choreoSteps.last.text : ""; +} + +/// new step are saved +/// 1) before every system-provided text is accepted, if final text is different +/// from last step +/// 2) on the acceptance of system-provided text +/// 3) on message send, if final text is different from last step +/// +/// user edit +/// "hey ther" +/// user accepts "there" correction +/// "hey there" +/// step made for user edits and step made for system suggestion +/// user goes through IT, chooses "hola" +/// "hola" +/// step saved +/// adds "amigo" +/// step saved +class ChoreoRecordStep { + /// text after changes have been made + String text; + + /// all matches throughout edit process, + /// including those open, accepted and ignored + /// last step in list may contain open + PangeaMatch? acceptedOrIgnoredMatch; + + ITStep? itStep; + + ChoreoRecordStep({ + required this.text, + this.acceptedOrIgnoredMatch, + this.itStep, + }) { + if (itStep != null && acceptedOrIgnoredMatch != null) { + throw Exception( + "itStep and acceptedOrIgnoredMatch should not both be defined", + ); + } + } + + factory ChoreoRecordStep.fromJson(Map json) { + return ChoreoRecordStep( + text: json[_textKey], + acceptedOrIgnoredMatch: json[_acceptedOrIgnoredMatchKey] != null + ? PangeaMatch.fromJson(json[_acceptedOrIgnoredMatchKey]) + : null, + itStep: json[_stepKey] != null ? ITStep.fromJson(json[_stepKey]) : null, + ); + } + + static const _textKey = "txt"; + static const _acceptedOrIgnoredMatchKey = "mtch"; + static const _stepKey = "stp"; + + Map toJson() { + final data = {}; + data[_textKey] = text; + data[_acceptedOrIgnoredMatchKey] = acceptedOrIgnoredMatch?.toJson(); + data[_stepKey] = itStep?.toJson(); + return data; + } +} + +// Example flow +// hello my name is Jordan! Im typing a message + +// igc called, step saved with matchIndex = null + +// click Im and fixed + +// hello my name is Jordan! I'm typing a message + +// igc called, step saved with matchIndex equal to i'm index + +// hello my name is Jordan! I'm typing a message + +// igc called, step saved with matchIndex = null + +// class ITStepRecord { +// List allContinuances; + +// /// continuances that were clicked but not selected +// List clicked; + +// ITStepRecord({required this.continuances}); +// } + +// class ContinuanceRecord {} diff --git a/lib/pangea/models/class_analytics_model.dart b/lib/pangea/models/class_analytics_model.dart new file mode 100644 index 000000000..3e37ee4d1 --- /dev/null +++ b/lib/pangea/models/class_analytics_model.dart @@ -0,0 +1,100 @@ +import 'package:intl/intl.dart'; + +class ClassAnalyticsModel { + ClassAnalyticsModel(); + late final Null classId; + late final List userIds; + late final List analytics; + get tableView {} + ClassAnalyticsModel.fromJson(Map json) { + classId = null; + userIds = List.castFrom(json['user_ids']); + analytics = + List.from(json['analytics']).map((e) => Analytics.fromJson(e)).toList(); + } + + Map toJson() { + final data = {}; + data['class_id'] = classId; + data['user_ids'] = userIds; + data['analytics'] = analytics.map((e) => e.toJson()).toList(); + return data; + } +} + +class Analytics { + Analytics({ + required this.title, + required this.section, + }); + late final String title; + late final List
section; + + Analytics.fromJson(Map json) { + title = json['title']; + section = + List.from(json['section']).map((e) => Section.fromJson(e)).toList(); + } + + Map toJson() { + final data = {}; + data['title'] = title; + data['section'] = section.map((e) => e.toJson()).toList(); + return data; + } +} + +class Section { + Section({ + required this.title, + required this.classTotal, + required this.data, + }); + late final String title; + late final String classTotal; + late final List data; + + Section.fromJson(Map json) { + title = json['title']; + classTotal = json['class_total']; + data = List.from(json['data']).map((e) => Data.fromJson(e)).toList(); + } + + Map toJson() { + final data = {}; + data['title'] = title; + data['class_total'] = classTotal; + data['data'] = data.map((e) => e.toJson()).toList(); + return data; + } +} + +class Data { + Data(); + set value(String val) => _value = val; + String get value { + if (value_type == 'date') { + return DateFormat('yyyy/M/dd hh:mm a') + .format(DateTime.parse(_value).toLocal()) + .toString(); + } + return _value; + } + + late final String userId; + late final String _value; + late final String value_type; + Data.fromJson(Map json) { + userId = json['user_id']; + _value = json['value']; + value_type = json['value_type']; + } + + Map toJson() { + final data = {}; + data['user_id'] = userId; + data['value'] = _value; + data['value_type'] = value_type; + return data; + } +} diff --git a/lib/pangea/models/class_email_invite_model.dart b/lib/pangea/models/class_email_invite_model.dart new file mode 100644 index 000000000..31d6b2472 --- /dev/null +++ b/lib/pangea/models/class_email_invite_model.dart @@ -0,0 +1,47 @@ +class PClassEmailInviteModel { + List? data; + String? pangeaClassRoomId; + String? teacherName; + + PClassEmailInviteModel({this.data, this.pangeaClassRoomId, this.teacherName}); + + PClassEmailInviteModel.fromJson(Map json) { + if (json['data'] != null) { + data = []; + json['data'].forEach((v) { + data!.add(ClassEmailInviteData.fromJson(v)); + }); + } + pangeaClassRoomId = json['pangea_class_room_id']; + teacherName = json['teacher_name']; + } + + Map toJson() { + final Map data = {}; + if (this.data != null) { + data['data'] = this.data!.map((v) => v.toJson()).toList(); + } + data['pangea_class_room_id'] = pangeaClassRoomId; + data['teacher_name'] = teacherName; + return data; + } +} + +class ClassEmailInviteData { + String? name; + String? email; + + ClassEmailInviteData({this.name, this.email}); + + ClassEmailInviteData.fromJson(Map json) { + name = json['name']; + email = json['email']; + } + + Map toJson() { + final Map data = {}; + data['name'] = name; + data['email'] = email; + return data; + } +} diff --git a/lib/pangea/models/class_model.dart b/lib/pangea/models/class_model.dart new file mode 100644 index 000000000..1f588980c --- /dev/null +++ b/lib/pangea/models/class_model.dart @@ -0,0 +1,335 @@ +import 'dart:developer'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:matrix/matrix.dart'; + +import 'package:fluffychat/pangea/constants/model_keys.dart'; +import 'package:fluffychat/pangea/utils/error_handler.dart'; +import '../constants/class_default_values.dart'; +import '../constants/language_keys.dart'; +import '../constants/pangea_event_types.dart'; +import 'language_model.dart'; + +class ClassSettingsModel { + String? city; + String? country; + String? schoolName; + int? languageLevel; + String dominantLanguage; + String targetLanguage; + + ClassSettingsModel({ + this.dominantLanguage = ClassDefaultValues.defaultDominantLanguage, + this.targetLanguage = ClassDefaultValues.defaultTargetLanguage, + this.languageLevel, + this.city, + this.country, + this.schoolName, + }); + + static ClassSettingsModel get newClass => ClassSettingsModel( + city: null, + country: null, + dominantLanguage: ClassDefaultValues.defaultDominantLanguage, + languageLevel: null, + schoolName: null, + targetLanguage: ClassDefaultValues.defaultTargetLanguage, + ); + + factory ClassSettingsModel.fromJson(Map json) { + return ClassSettingsModel( + city: json['city'], + country: json['country'], + dominantLanguage: LanguageModel.codeFromNameOrCode( + json['dominant_language'] ?? LanguageKeys.unknownLanguage, + ), + targetLanguage: LanguageModel.codeFromNameOrCode( + json['target_language'] ?? LanguageKeys.unknownLanguage, + ), + languageLevel: json['language_level'], + schoolName: json['school_name'], + ); + } + + Map toJson() { + final data = {}; + try { + data['city'] = city; + data['country'] = country; + //check for and do "english" => en and "spanish" => es + data['dominant_language'] = dominantLanguage; + //check for and do "english" => en and "spanish" => es + data['target_language'] = targetLanguage; + data['language_level'] = languageLevel; + data['school_name'] = schoolName; + return data; + } catch (e, s) { + debugger(when: kDebugMode); + ErrorHandler.logError(e: e, s: s); + return data; + } + } + + //TODO: define enum with all possible values + updateEditableClassField(String key, dynamic value) { + switch (key) { + case ModelKey.clientClassCity: + city = value; + break; + case ModelKey.clientClassCountry: + country = value; + break; + case ModelKey.clientClassDominantLanguage: + dominantLanguage = value; + break; + case ModelKey.clientClassTargetLanguage: + targetLanguage = value; + break; + case ModelKey.clientLanguageLevel: + languageLevel = value; + break; + case ModelKey.clientSchool: + schoolName = value; + break; + default: + throw Exception('Invalid key for setting permissions - $key'); + } + } + + StateEvent get toStateEvent => StateEvent( + content: toJson(), + type: PangeaEventTypes.classSettings, + ); +} + +class PangeaRoomRules { + // int? pangeaClassID; // this is id our database + bool isPublic; + bool isOpenEnrollment; + bool oneToOneChatClass; + bool isCreateRooms; + bool isShareVideo; + bool isSharePhoto; + bool isShareFiles; + bool isShareLocation; + bool isCreateStories; + bool isVoiceNotes; + bool isInviteOnlyStudents; + // 0 = forbidden, 1 = allow individual to choose, 2 = require + int interactiveTranslator; + int interactiveGrammar; + int immersionMode; + int definitions; + int translations; + + PangeaRoomRules({ + this.isPublic = false, + this.isOpenEnrollment = false, + this.oneToOneChatClass = true, + this.isCreateRooms = true, + this.isShareVideo = true, + this.isSharePhoto = true, + this.isShareFiles = true, + this.isShareLocation = false, + this.isCreateStories = false, + this.isVoiceNotes = true, + this.isInviteOnlyStudents = true, + this.interactiveTranslator = ClassDefaultValues.languageToolPermissions, + this.interactiveGrammar = ClassDefaultValues.languageToolPermissions, + this.immersionMode = ClassDefaultValues.languageToolPermissions, + this.definitions = ClassDefaultValues.languageToolPermissions, + this.translations = ClassDefaultValues.languageToolPermissions, + }); + + updatePermission(String key, bool value) { + switch (key) { + case 'isPublic': + isPublic = value; + break; + case 'isOpenEnrollment': + isOpenEnrollment = value; + break; + case 'oneToOneChatClass': + oneToOneChatClass = value; + break; + case 'isCreateRooms': + isCreateRooms = value; + break; + case 'isShareVideo': + isShareVideo = value; + break; + case 'isSharePhoto': + isSharePhoto = value; + break; + case 'isShareFiles': + isShareFiles = value; + break; + case 'isShareLocation': + isShareLocation = value; + break; + case 'isCreateStories': + isCreateStories = value; + break; + case 'isVoiceNotes': + isVoiceNotes = value; + break; + case 'isInviteOnlyStudents': + isInviteOnlyStudents = value; + break; + default: + throw Exception('Invalid key for setting permissions - $key'); + } + } + + setLanguageToolSetting(ToolSetting setting, int value) { + switch (setting) { + case ToolSetting.interactiveTranslator: + interactiveTranslator = value; + break; + case ToolSetting.interactiveGrammar: + interactiveGrammar = value; + break; + case ToolSetting.immersionMode: + immersionMode = value; + break; + case ToolSetting.definitions: + definitions = value; + break; + case ToolSetting.translations: + translations = value; + break; + default: + throw Exception('Invalid key for setting permissions - $setting'); + } + } + + StateEvent get toStateEvent => StateEvent( + content: toJson(), + type: PangeaEventTypes.rules, + ); + + factory PangeaRoomRules.fromJson(Map json) => + PangeaRoomRules( + // pangeaClassID: json['pangea_class']; + isPublic: json['is_public'], + isOpenEnrollment: json['is_open_enrollment'], + oneToOneChatClass: json['one_to_one_chat_class'], + isCreateRooms: json['is_create_rooms'], + isShareVideo: json['is_share_video'], + isSharePhoto: json['is_share_photo'], + isShareFiles: json['is_share_files'], + isShareLocation: json['is_share_location'], + isCreateStories: json['is_create_stories'], + isVoiceNotes: json['is_voice_notes'], + isInviteOnlyStudents: json['is_invite_only_students'] ?? true, + interactiveTranslator: json['interactive_translator'] ?? + ClassDefaultValues.languageToolPermissions, + interactiveGrammar: json['interactive_grammar'] ?? + ClassDefaultValues.languageToolPermissions, + immersionMode: json['immersion_mode'] ?? + ClassDefaultValues.languageToolPermissions, + definitions: + json['definitions'] ?? ClassDefaultValues.languageToolPermissions, + translations: + json['translations'] ?? ClassDefaultValues.languageToolPermissions, + ); + + Map toJson() { + final data = {}; + // data['pangea_class'] = pangeaClassID; + data['is_public'] = isPublic; + data['is_open_enrollment'] = isOpenEnrollment; + data['one_to_one_chat_class'] = oneToOneChatClass; + data['is_create_rooms'] = isCreateRooms; + data['is_share_video'] = isShareVideo; + data['is_share_photo'] = isSharePhoto; + data['is_share_files'] = isShareFiles; + data['is_share_location'] = isShareLocation; + data['is_create_stories'] = isCreateStories; + data['is_voice_notes'] = isVoiceNotes; + data['is_invite_only_students'] = isInviteOnlyStudents; + data['interactive_translator'] = interactiveTranslator; + data['interactive_grammar'] = interactiveGrammar; + data['immersion_mode'] = immersionMode; + data['definitions'] = definitions; + data['translations'] = translations; + return data; + } + + int getToolSettings(ToolSetting setting) { + switch (setting) { + case ToolSetting.interactiveTranslator: + return interactiveTranslator; + case ToolSetting.interactiveGrammar: + return interactiveGrammar; + case ToolSetting.immersionMode: + return immersionMode; + case ToolSetting.definitions: + return definitions; + case ToolSetting.translations: + return translations; + default: + throw Exception('Invalid key for setting permissions - $setting'); + } + } + + String languageToolPermissionsText( + BuildContext context, + ToolSetting setting, + ) { + switch (getToolSettings(setting)) { + case 0: + return L10n.of(context)!.interactiveTranslatorNotAllowed; + case 1: + return L10n.of(context)!.interactiveTranslatorAllowed; + case 2: + return L10n.of(context)!.interactiveTranslatorRequired; + default: + return L10n.of(context)!.notYetSet; + } + } +} + +enum ToolSetting { + interactiveTranslator, + interactiveGrammar, + immersionMode, + definitions, + translations, +} + +extension SettingCopy on ToolSetting { + String toolName(BuildContext context) { + switch (this) { + case ToolSetting.interactiveTranslator: + return L10n.of(context)!.interactiveTranslatorSliderHeader; + case ToolSetting.interactiveGrammar: + return L10n.of(context)!.interactiveGrammarSliderHeader; + case ToolSetting.immersionMode: + return L10n.of(context)!.toggleImmersionMode; + case ToolSetting.definitions: + return L10n.of(context)!.definitionsToolName; + case ToolSetting.translations: + return L10n.of(context)!.messageTranslationsToolName; + } + } + + //use l10n to get tool name + String toolDescription(BuildContext context) { + switch (this) { + case ToolSetting.interactiveTranslator: + return L10n.of(context)!.itToggleDescription; + case ToolSetting.interactiveGrammar: + return L10n.of(context)!.igcToggleDescription; + case ToolSetting.immersionMode: + return L10n.of(context)!.toggleImmersionModeDesc; + case ToolSetting.definitions: + return L10n.of(context)!.definitionsToolDescription; + case ToolSetting.translations: + return L10n.of(context)!.translationsToolDescrption; + } + } +} diff --git a/lib/pangea/models/construct_analytics_event.dart b/lib/pangea/models/construct_analytics_event.dart new file mode 100644 index 000000000..66921b8a2 --- /dev/null +++ b/lib/pangea/models/construct_analytics_event.dart @@ -0,0 +1,33 @@ +import 'package:matrix/matrix.dart'; + +import 'package:fluffychat/pangea/models/constructs_analytics_model.dart'; +import '../constants/pangea_event_types.dart'; + +class ConstructEvent { + late Event _event; + ConstructUses? _contentCache; + + ConstructEvent({required Event event}) { + if (event.type != PangeaEventTypes.vocab) { + throw Exception( + "${event.type} should not be used to make a StudentAnalyticsEvent", + ); + } + _event = event; + } + + Event get event => _event; + + ConstructUses get content { + _contentCache ??= ConstructUses.fromJson(event.content); + if (_contentCache!.lemma.isEmpty) { + _contentCache!.lemma = event.stateKey!; + } + return _contentCache!; + } + + void addAll(List uses) { + content.uses.addAll(uses); + event.content = content.toJson(); + } +} diff --git a/lib/pangea/models/constructs_analytics_model.dart b/lib/pangea/models/constructs_analytics_model.dart new file mode 100644 index 000000000..672467d56 --- /dev/null +++ b/lib/pangea/models/constructs_analytics_model.dart @@ -0,0 +1,181 @@ +import 'dart:developer'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + +import 'package:fluffychat/pangea/constants/model_keys.dart'; +import '../enum/construct_type_enum.dart'; + +class ConstructUses { + String lemma; + ConstructType type; + + List uses; + + //PTODO - how to incorporate semantic similarity score into this? + + //PTODO - add variables for saving requests for + // 1) definitions + // 2) translations + // 3) examples??? (gpt suggested) + + ConstructUses({ + required this.lemma, + required this.type, + this.uses = const [], + }); + + factory ConstructUses.fromJson(Map json) { + // try { + debugger( + when: + kDebugMode && (json['uses'] == null || json[ModelKey.lemma] == null), + ); + return ConstructUses( + lemma: json[ModelKey.lemma], + uses: (json['uses'] as Iterable) + .map( + (use) => use != null ? OneConstructUse.fromJson(use) : null, + ) + .where((element) => element != null) + .cast() + .toList(), + type: ConstructTypeUtil.fromString(json['type']), + ); + // } catch (err) { + // debugger(when: kDebugMode); + // rethrow; + // } + } + + toJson() { + return { + ModelKey.lemma: lemma, + 'uses': uses.map((use) => use.toJson()).toList(), + 'type': type.string, + }; + } + + void addUsesByUseType(List uses) { + for (final use in uses) { + if (use.lemma != lemma) { + throw Exception('lemma mismatch'); + } + uses.add(use); + } + } +} + +enum ConstructUseType { + /// encountered match and accepted it + ga, + + /// used without assistance + wa, + + /// selected correctly in IT flow + corIt, + + /// encountered as it distractor and selected it + incIt, + + /// encountered as IT distractor and correctly ignored it + ignIt, + + /// encountered in igc match and ignored match + ignIGC, + + /// encountered in igc match and ignored match + corIGC, +} + +extension on ConstructUseType { + String get string { + switch (this) { + case ConstructUseType.ga: + return 'ga'; + case ConstructUseType.wa: + return 'wa'; + case ConstructUseType.corIt: + return 'corIt'; + case ConstructUseType.incIt: + return 'incIt'; + case ConstructUseType.ignIt: + return 'ignIt'; + case ConstructUseType.ignIGC: + return 'ignIGC'; + case ConstructUseType.corIGC: + return 'corIGC'; + } + } + + IconData get icon { + switch (this) { + case ConstructUseType.ga: + return Icons.check; + case ConstructUseType.wa: + return Icons.thumb_up_sharp; + case ConstructUseType.corIt: + return Icons.check; + case ConstructUseType.incIt: + return Icons.close; + case ConstructUseType.ignIt: + return Icons.close; + case ConstructUseType.ignIGC: + return Icons.close; + case ConstructUseType.corIGC: + return Icons.check; + } + } +} + +class OneConstructUse { + String? lemma; + ConstructType? constructType; + String? form; + ConstructUseType useType; + String chatId; + String? msgId; + DateTime timeStamp; + + OneConstructUse({ + required this.useType, + required this.chatId, + required this.timeStamp, + required this.lemma, + required this.form, + required this.msgId, + required this.constructType, + }); + + factory OneConstructUse.fromJson(Map json) { + return OneConstructUse( + useType: ConstructUseType.values + .firstWhere((e) => e.string == json['useType']), + chatId: json['chatId'], + timeStamp: DateTime.parse(json['timeStamp']), + lemma: json['lemma'], + form: json['form'], + msgId: json['msgId'], + constructType: json['constructType'] != null + ? ConstructTypeUtil.fromString(json['constructType']) + : null, + ); + } + + Map toJson([bool condensed = true]) { + final Map data = { + 'useType': useType.string, + 'chatId': chatId, + 'timeStamp': timeStamp.toIso8601String(), + 'form': form, + 'msgId': msgId, + }; + if (!condensed && lemma != null) data['lemma'] = lemma!; + if (!condensed && constructType != null) { + data['constructType'] = constructType!.string; + } + + return data; + } +} diff --git a/lib/pangea/models/custom_input_translation_model.dart b/lib/pangea/models/custom_input_translation_model.dart new file mode 100644 index 000000000..7d2989d73 --- /dev/null +++ b/lib/pangea/models/custom_input_translation_model.dart @@ -0,0 +1,41 @@ +import 'package:fluffychat/pangea/constants/model_keys.dart'; + +class CustomInputRequestModel { + String text; + String customInput; + String sourceLangCode; + String targetLangCode; + String userId; + String roomId; + String? classId; + + CustomInputRequestModel({ + required this.text, + required this.customInput, + required this.sourceLangCode, + required this.targetLangCode, + required this.userId, + required this.roomId, + required this.classId, + }); + + factory CustomInputRequestModel.fromJson(json) => CustomInputRequestModel( + text: json['text'], + customInput: json['custom_input'], + sourceLangCode: json[ModelKey.srcLang], + targetLangCode: json[ModelKey.tgtLang], + userId: json['user_id'], + roomId: json['room_id'], + classId: json['class_id'], + ); + + toJson() => { + 'text': text, + 'custom_input': customInput, + ModelKey.srcLang: sourceLangCode, + ModelKey.tgtLang: targetLangCode, + 'user_id': userId, + 'room_id': roomId, + 'class_id': classId, + }; +} diff --git a/lib/pangea/models/exchange_model.dart b/lib/pangea/models/exchange_model.dart new file mode 100644 index 000000000..42ce2a175 --- /dev/null +++ b/lib/pangea/models/exchange_model.dart @@ -0,0 +1,40 @@ +import 'dart:developer'; + +import 'package:flutter/foundation.dart'; + +import 'package:fluffychat/pangea/constants/model_keys.dart'; +import 'package:fluffychat/pangea/utils/error_handler.dart'; +import 'class_model.dart'; + +class ExchangeModel { + PangeaRoomRules permissions; + + ExchangeModel({ + required this.permissions, + }); + + factory ExchangeModel.fromJson(Map json) { + return ExchangeModel( + permissions: PangeaRoomRules.fromJson(json[ModelKey.permissions]), + ); + } + + Map toJson() { + final data = {}; + try { + data[ModelKey.permissions] = permissions.toJson(); + return data; + } catch (e, s) { + debugger(when: kDebugMode); + ErrorHandler.logError(e: e, s: s); + return data; + } + } + + updateEditableClassField(String key, dynamic value) { + switch (key) { + default: + throw Exception('Invalid key for setting permissions - $key'); + } + } +} diff --git a/lib/pangea/models/headwords.dart b/lib/pangea/models/headwords.dart new file mode 100644 index 000000000..cd0a68108 --- /dev/null +++ b/lib/pangea/models/headwords.dart @@ -0,0 +1,182 @@ +import 'dart:convert'; +import 'dart:developer'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/services.dart'; + +import 'package:fluffychat/pangea/models/constructs_analytics_model.dart'; +import '../enum/vocab_proficiency_enum.dart'; + +class VocabHeadwords { + List lists; + + VocabHeadwords({ + required this.lists, + }); + + /// in json parameter, keys are the names of the VocabList + /// values are the words in the VocabList + factory VocabHeadwords.fromJson(Map json) { + final List lists = []; + for (final entry in json.entries) { + lists.add( + VocabList( + name: entry.key, + lemmas: (entry.value as Iterable).cast().toList(), + ), + ); + } + return VocabHeadwords(lists: lists); + } + + static Future getHeadwords(String langCode) async { + final String data = + await rootBundle.loadString('${langCode}_headwords.json'); + final decoded = jsonDecode(data); + final VocabHeadwords headwords = VocabHeadwords.fromJson(decoded); + return headwords; + } +} + +class VocabList { + String name; + + /// key is lemma + Map words = {}; + + VocabList({ + required this.name, + required List lemmas, + }) { + for (final lemma in lemmas) { + words[lemma] = VocabTotals.newTotals; + } + } + + void addVocabUse(String lemma, List use) { + words[lemma.toUpperCase()]?.addVocabUseBasedOnUseType(use); + } + + ListTotals calculuateTotals() { + final ListTotals listTotals = ListTotals.empty; + for (final word in words.entries) { + debugger(when: kDebugMode && word.key == "baloncesto".toLowerCase()); + listTotals.addByType(word.value.proficiencyLevel); + } + return listTotals; + } +} + +class ListTotals { + int low; + int medium; + int high; + int unknown; + + ListTotals({ + required this.low, + required this.medium, + required this.high, + required this.unknown, + }); + + static get empty => ListTotals(low: 0, medium: 0, high: 0, unknown: 0); + + void addByType(VocabProficiencyEnum prof) { + switch (prof) { + case VocabProficiencyEnum.low: + low++; + break; + case VocabProficiencyEnum.medium: + medium++; + break; + case VocabProficiencyEnum.high: + high++; + break; + case VocabProficiencyEnum.unk: + unknown++; + break; + } + } +} + +class VocabTotals { + num ga; + + num wa; + + num corIt; + + num incIt; + + num ignIt; + + VocabTotals({ + required this.ga, + required this.wa, + required this.corIt, + required this.incIt, + required this.ignIt, + }); + + num get calculateEstimatedVocabProficiency { + const num gaWeight = -1; + const num waWeight = 1; + const num corItWeight = 0.5; + const num incItWeight = -0.5; + const num ignItWeight = 0.1; + + final num gaScore = ga * gaWeight; + final num waScore = wa * waWeight; + final num corItScore = corIt * corItWeight; + final num incItScore = incIt * incItWeight; + final num ignItScore = ignIt * ignItWeight; + + final num totalScore = + gaScore + waScore + corItScore + incItScore + ignItScore; + + return totalScore; + } + + VocabProficiencyEnum get proficiencyLevel => + VocabProficiencyUtil.proficiency(calculateEstimatedVocabProficiency); + + static VocabTotals get newTotals { + return VocabTotals( + ga: 0, + wa: 0, + corIt: 0, + incIt: 0, + ignIt: 0, + ); + } + + void addVocabUseBasedOnUseType(List uses) { + for (final use in uses) { + switch (use.useType) { + case ConstructUseType.ga: + ga++; + break; + case ConstructUseType.wa: + wa++; + break; + case ConstructUseType.corIt: + corIt++; + break; + case ConstructUseType.incIt: + incIt++; + break; + case ConstructUseType.ignIt: + ignIt++; + break; + //TODO - these shouldn't be counted as such + case ConstructUseType.ignIGC: + ignIt++; + break; + case ConstructUseType.corIGC: + corIt++; + break; + } + } + } +} diff --git a/lib/pangea/models/igc_text_data_model.dart b/lib/pangea/models/igc_text_data_model.dart new file mode 100644 index 000000000..04be9b485 --- /dev/null +++ b/lib/pangea/models/igc_text_data_model.dart @@ -0,0 +1,335 @@ +import 'dart:developer'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/gestures.dart'; +import 'package:flutter/material.dart'; + +import 'package:matrix/matrix.dart'; +import 'package:sentry_flutter/sentry_flutter.dart'; + +import 'package:fluffychat/pangea/models/pangea_match_model.dart'; +import 'package:fluffychat/pangea/models/pangea_token_model.dart'; +import 'package:fluffychat/pangea/models/span_card_model.dart'; +import 'package:fluffychat/pangea/utils/error_handler.dart'; +import '../constants/model_keys.dart'; +import '../utils/overlay.dart'; +import '../widgets/igc/span_card.dart'; +import '../widgets/igc/word_data_card.dart'; +import 'language_detection_model.dart'; + +// import 'package:language_tool/language_tool.dart'; + +class IGCTextData { + List detections; + String originalInput; + String? fullTextCorrection; + List tokens; + List matches; + String userL1; + String userL2; + bool enableIT; + bool enableIGC; + bool loading = false; + + IGCTextData({ + required this.detections, + required this.originalInput, + required this.fullTextCorrection, + required this.tokens, + required this.matches, + required this.userL1, + required this.userL2, + required this.enableIT, + required this.enableIGC, + }); + + factory IGCTextData.fromJson(Map json) { + return IGCTextData( + tokens: (json[_tokensKey] as Iterable) + .map( + (e) => PangeaToken.fromJson(e as Map), + ) + .toList() + .cast(), + matches: json[_matchesKey] != null + ? (json[_matchesKey] as Iterable) + .map( + (e) { + return PangeaMatch.fromJson(e as Map); + }, + ) + .toList() + .cast() + : [], + detections: (json[_detectionsKey] as Iterable) + .map( + (e) => LanguageDetection.fromJson(e as Map), + ) + .toList() + .cast(), + originalInput: json["original_input"], + fullTextCorrection: json["full_text_correction"], + userL1: json[ModelKey.userL1], + userL2: json[ModelKey.userL2], + enableIT: json["enable_it"], + enableIGC: json["enable_igc"], + ); + } + + static const String _tokensKey = "tokens"; + static const String _matchesKey = "matches"; + static const String _detectionsKey = "detections"; + + Map toJson() => { + _detectionsKey: detections.map((e) => e.toJson()).toList(), + "original_input": originalInput, + "full_text_correction": fullTextCorrection, + _tokensKey: tokens.map((e) => e.toJson()).toList(), + _matchesKey: matches.map((e) => e.toJson()).toList(), + ModelKey.userL1: userL1, + ModelKey.userL2: userL2, + "enable_it": enableIT, + "enable_igc": enableIGC, + }; + + // reconstruct fullText based on accepted match + //update offsets in existing matches to reflect the change + //if existing matches overlap with the accepted one, remove them?? + void acceptReplacement( + int matchIndex, + int choiceIndex, + ) async { + //should be already added to choreoRecord + //TODO - that should be done in the same function to avoid error potential + final PangeaMatch pangeaMatch = matches[matchIndex]; + + if (pangeaMatch.match.choices == null) { + debugger(when: kDebugMode); + ErrorHandler.logError( + m: "pangeaMatch.match.choices is null in acceptReplacement", + ); + return; + } + + final String replacement = pangeaMatch.match.choices![choiceIndex].value; + + originalInput = originalInput.replaceRange( + pangeaMatch.match.offset, + pangeaMatch.match.offset + pangeaMatch.match.length, + replacement, + ); + + //update offsets in existing matches to reflect the change + //Question - remove matches that overlap with the accepted one? + // see case of "quiero ver un fix" + matches.removeAt(matchIndex); + + for (final match in matches) { + final matchOffset = match.match.offset; + final matchLength = match.match.length; + match.match.fullText = originalInput; + if (match.match.offset > pangeaMatch.match.offset) { + match.match.offset += replacement.length - pangeaMatch.match.length; + } + } + //quiero ver un fix + //match offset zero and length of full text or 16 + //fix is repplaced by arreglo and now the length needs to be 20 + //if the accepted span is within another span, then the length of that span needs + //needs to be increased by the difference between the new and old length + //if the two spans are overlapping, what happens? + //------ + // ----- -> --- + //if there is any overlap, maybe igc needs to run again? + } + + void removeMatchByOffset(int offset) { + final int index = getTopMatchIndexForOffset(offset); + if (index != -1) { + matches.removeAt(index); + } + } + + int tokenIndexByOffset( + cursorOffset, + ) => + tokens.indexWhere( + (token) => + token.text.offset <= cursorOffset && + cursorOffset <= token.text.offset + token.text.length, + ); + + List getMatchIndicesForToken(PangeaToken token) => + matchIndicesByOffset(token.text.offset); + + int getTopMatchIndexForOffset(int offset) { + final List matchesForToken = matchIndicesByOffset(offset); + if (matchesForToken.isEmpty) return -1; + for (final matchIndex in matchesForToken) { + final match = matches[matchIndex]; + if (enableIT) { + if (match.isITStart || match.isl1SpanMatch) { + return matchIndex; + } + } + if (enableIGC) { + if (match.isGrammarMatch) { + return matchIndex; + } + } + } + return -1; + } + + PangeaMatch? getTopMatchForToken(PangeaToken token) { + final int topMatchIndex = getTopMatchIndexForOffset(token.text.offset); + if (topMatchIndex == -1) return null; + return matches[topMatchIndex]; + } + + List matchIndicesByOffset(int offset) { + final List matchesForOffset = []; + + for (final (index, match) in matches.indexed) { + if (match.isOffsetInMatchSpan(offset)) { + matchesForOffset.add(index); + } + } + + return matchesForOffset; + } + + int getAfterTokenSpacingByIndex( + int tokenIndex, + ) { + final int endOfToken = + tokens[tokenIndex].text.offset + tokens[tokenIndex].text.length; + + if (tokenIndex + 1 < tokens.length) { + final spaceBetween = tokens[tokenIndex + 1].text.offset - endOfToken; + + if (spaceBetween < 0) { + Sentry.addBreadcrumb( + Breadcrumb.fromJson( + { + "fullText": originalInput, + "tokens": tokens.map((e) => e.toJson()).toString(), + }, + ), + ); + ErrorHandler.logError( + m: "wierd token lengths for ${tokens[tokenIndex].text.content} and ${tokens[tokenIndex + 1].text.content}", + ); + return 0; + } + return spaceBetween; + } else { + return originalInput.length - endOfToken; + } + } + + static TextStyle underlineStyle(Color color) => TextStyle( + decoration: TextDecoration.underline, + decorationColor: color, + decorationThickness: 5, + ); + + static const _hasDefinitionStyle = TextStyle( + decoration: TextDecoration.underline, + decorationColor: Color.fromARGB(148, 83, 97, 255), + decorationThickness: 4, + ); + static TextStyle hasDefinitionStyle(TextStyle? existingStyle) => + existingStyle?.merge(_hasDefinitionStyle) ?? _hasDefinitionStyle; + + //PTODO - handle multitoken spans + List constructTokenSpan({ + required BuildContext context, + TextStyle? defaultStyle, + required SpanCardModel? spanCardModel, + required bool showTokens, + required bool handleClick, + required String transformTargetId, + required Room room, + }) { + final List items = []; + + if (loading) { + return [ + TextSpan( + text: originalInput, + style: defaultStyle, + ), + ]; + } + + // or could make big strings for non-match text and therefore make less textspans. + // would that be more performant? + tokens.asMap().forEach( + (index, token) { + final PangeaMatch? topTokenMatch = getTopMatchForToken( + tokens[index], + ); + // if (index == 3) { + // debugPrint( + // "constructing span with topTokenMatch: ${topTokenMatch?.match.rule.id}"); + // } + + final Widget cardToShow = spanCardModel != null && topTokenMatch != null + ? SpanCard( + scm: spanCardModel, + ) + : WordDataCard( + fullText: originalInput, + fullTextLang: detections.first.langCode, + word: token.text.content, + wordLang: detections.first.langCode, + hasInfo: token.hasInfo, + room: room, + ); + + final TextStyle tokenStyle = topTokenMatch != null + ? topTokenMatch.textStyle(defaultStyle) + : hasDefinitionStyle(defaultStyle); + + items.add( + TextSpan( + text: token.text.content, + style: tokenStyle, + recognizer: handleClick + ? (TapGestureRecognizer() + ..onTapDown = (details) => OverlayUtil.showPositionedCard( + context: context, + cardToShow: cardToShow, + cardSize: topTokenMatch?.isITStart ?? false + ? const Size(350, 220) + : const Size(350, 400), + transformTargetId: transformTargetId, + )) + : null, + ), + ); + + final int charBetween = getAfterTokenSpacingByIndex( + index, + ); + + if (charBetween > 0) { + items.add( + TextSpan( + text: " " * charBetween, + style: topTokenMatch != null && + token.text.offset + token.text.length + charBetween <= + topTokenMatch.match.offset + + topTokenMatch.match.length + ? tokenStyle + : defaultStyle, + ), + ); + } + }, + ); + + return items; + } +} diff --git a/lib/pangea/models/it_response_model.dart b/lib/pangea/models/it_response_model.dart new file mode 100644 index 000000000..86a9c7a4c --- /dev/null +++ b/lib/pangea/models/it_response_model.dart @@ -0,0 +1,178 @@ +import 'package:flutter/material.dart'; + +import 'package:collection/collection.dart'; +import 'package:flutter_gen/gen_l10n/l10n.dart'; + +import 'package:fluffychat/pangea/constants/choreo_constants.dart'; +import 'package:fluffychat/pangea/constants/model_keys.dart'; +import 'package:fluffychat/pangea/extensions/my_list_extionsion.dart'; +import 'lemma.dart'; + +class ITResponseModel { + String fullTextTranslation; + List continuances; + List? goldContinuances; + bool isFinal; + String? translationId; + int payloadId; + + ITResponseModel({ + required this.fullTextTranslation, + required this.continuances, + required this.translationId, + required this.goldContinuances, + required this.isFinal, + required this.payloadId, + }); + + factory ITResponseModel.fromJson(Map json) { + //PTODO - is continuances a variable type? can we change that? + if (json['continuances'].runtimeType == String) { + debugPrint("continuances was string - ${json['continuances']}"); + json['continuances'] = []; + json['finished'] = true; + } + + final List interimCont = (json['continuances'] as List) + .mapIndexed((index, e) { + e["index"] = index; + return Continuance.fromJson(e); + }) + .toList() + .take(ChoreoConstants.numberOfITChoices) + .toList() + .shuffleReturn() + .cast() + //can't do this on the backend because step translation can't filter them out + .where((element) => element.inDictionary) + .toList(); + + return ITResponseModel( + fullTextTranslation: json["full_text_translation"] ?? json["translation"], + continuances: interimCont, + translationId: json['translation_id'], + payloadId: json['payload_id'] ?? 0, + isFinal: json['finished'] ?? false, + goldContinuances: json['gold_continuances'] != null + ? (json['gold_continuances'] as Iterable).map((e) { + e["gold"] = true; + return Continuance.fromJson(e); + }).toList() + : null, + ); + } + + Map toJson() { + final Map data = {}; + data['full_text_translation'] = fullTextTranslation; + data['continuances'] = continuances.map((v) => v.toJson()).toList(); + if (translationId != null) { + data['translation_id'] = translationId; + } + data['payload_id'] = payloadId; + data["finished"] = isFinal; + return data; + } +} + +class Continuance { + /// only saving this top set in a condensed json form + double probability; + int level; + String text; + List lemmas; + + /// saving this in a full json form + String description; + int? indexSavedByServer; + bool wasClicked; + bool inDictionary; + bool hasInfo; + bool gold; + + Continuance({ + required this.probability, + required this.level, + required this.text, + required this.description, + required this.indexSavedByServer, + required this.wasClicked, + required this.inDictionary, + required this.hasInfo, + required this.gold, + required this.lemmas, + }); + + factory Continuance.fromJson(Map json) { + final List lemmaInternal = + (json[ModelKey.lemma] != null && json[ModelKey.lemma] is Iterable) + ? (json[ModelKey.lemma] as Iterable) + .map( + (e) => Lemma.fromJson(e as Map), + ) + .toList() + .cast() + : []; + return Continuance( + probability: json['probability'], + level: json['level'], + text: json['text'], + description: json['description'] ?? "", + indexSavedByServer: json["index"], + inDictionary: json['in_dictionary'] ?? true, + wasClicked: json['clkd'] ?? false, + hasInfo: json['has_info'] ?? false, + gold: json['gold'] ?? false, + lemmas: lemmaInternal, + ); + } + + Map toJson([bool condensed = false]) { + final Map data = {}; + data['probability'] = probability; + data['level'] = level; + data['text'] = text; + data['clkd'] = wasClicked; + data[ModelKey.lemma] = lemmas.map((e) => e.toJson()).toList(); + + if (!condensed) { + data['description'] = description; + data['in_dictionary'] = inDictionary; + data['has_info'] = hasInfo; + data["index"] = indexSavedByServer; + data['gold'] = gold; + } + return data; + } + + Color? get color { + if (!wasClicked) return null; + switch (level) { + case ChoreoConstants.levelThresholdForGreen: + return ChoreoConstants.green; + case ChoreoConstants.levelThresholdForYellow: + return ChoreoConstants.yellow; + case ChoreoConstants.levelThresholdForRed: + return ChoreoConstants.red; + default: + return null; + } + } + + String? feedbackText(BuildContext context) { + final L10n? l10n = L10n.of(context); + if (l10n == null) { + return null; + } + switch (level) { + case ChoreoConstants.levelThresholdForGreen: + return l10n.greenFeedback; + case ChoreoConstants.levelThresholdForYellow: + return l10n.yellowFeedback; + case ChoreoConstants.levelThresholdForRed: + return l10n.redFeedback; + default: + return null; + } + } +} diff --git a/lib/pangea/models/it_step.dart b/lib/pangea/models/it_step.dart new file mode 100644 index 000000000..f06bd7401 --- /dev/null +++ b/lib/pangea/models/it_step.dart @@ -0,0 +1,70 @@ +import 'package:flutter/material.dart'; + +import '../constants/choreo_constants.dart'; +import 'it_response_model.dart'; + +class ITStep { + List continuances; + int? chosen; + String? customInput; + bool showAlternativeTranslationOption = false; + + ITStep( + this.continuances, { + this.chosen, + this.customInput, + }) { + if (chosen == null && customInput == null) { + throw Exception("ITStep must have either chosen or customInput"); + } + if (chosen != null && customInput != null) { + throw Exception("ITStep must have only chosen or customInput"); + } + } + + Continuance? get chosenContinuance { + if (chosen == null) return null; + return continuances[chosen!]; + } + + String choiceFeedback(BuildContext context) { + if (continuances.length == 1) return ''; + return chosenContinuance?.feedbackText(context) ?? ""; + } + + bool get isCorrect => + chosenContinuance != null && + (chosenContinuance!.level == ChoreoConstants.levelThresholdForGreen || + chosenContinuance!.gold); + + bool get isYellow => + chosenContinuance != null && + chosenContinuance!.level == ChoreoConstants.levelThresholdForYellow; + + bool get isWrong { + return chosenContinuance != null && + chosenContinuance!.level == ChoreoConstants.levelThresholdForRed; + } + + bool get isCustom => chosenContinuance == null; + + Map toJson() { + final Map data = {}; + data['continuances'] = continuances.map((e) => e.toJson(true)).toList(); + data['chosen'] = chosen; + data['custom_input'] = customInput; + return data; + } + + factory ITStep.fromJson(Map json) { + final List continuances = []; + for (final Map continuance in json['continuances']) { + continuances.add(Continuance.fromJson(continuance)); + } + return ITStep( + continuances, + chosen: json['chosen'], + customInput: json['custom_input'], + ); + } +} diff --git a/lib/pangea/models/language_detection_model.dart b/lib/pangea/models/language_detection_model.dart new file mode 100644 index 000000000..6fa3d7299 --- /dev/null +++ b/lib/pangea/models/language_detection_model.dart @@ -0,0 +1,19 @@ +class LanguageDetection { + String langCode; + + LanguageDetection({ + required this.langCode, + }); + + factory LanguageDetection.fromJson(Map json) { + return LanguageDetection( + langCode: json[_langCodeKey], + ); + } + + static const _langCodeKey = "lang_code"; + + Map toJson() => { + _langCodeKey: langCode, + }; +} diff --git a/lib/pangea/models/language_model.dart b/lib/pangea/models/language_model.dart new file mode 100644 index 000000000..d7b6409b5 --- /dev/null +++ b/lib/pangea/models/language_model.dart @@ -0,0 +1,741 @@ +import 'dart:developer'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; + +import 'package:fluffychat/pangea/constants/language_keys.dart'; +import '../utils/error_handler.dart'; + +class LanguageModel { + final String langCode; + final int languageType; + final String languageFlag; + final String displayName; + final bool l2; + final bool l1; + + LanguageModel({ + required this.langCode, + required this.languageType, + required this.languageFlag, + required this.displayName, + required this.l2, + required this.l1, + }); + + factory LanguageModel.fromJson(json) { + final String code = json['language_code'] ?? + codeFromNameOrCode( + json['language_name'], + json['language_flag'], + ); + + return LanguageModel( + langCode: code, + languageType: json['language_type'] is String && + (json['language_type'] as String).isNotEmpty + ? int.parse(json['language_type']) + : json['language_type'], + languageFlag: json['language_flag'] ?? "", + displayName: _LanguageLocal.getDisplayName( + code != LanguageKeys.unknownLanguage ? code : json['language_name'], + ), + l2: json["l2"] ?? code.contains("es") || code.contains("en"), + l1: json["l1"] ?? !code.contains("es") && !code.contains("en"), + ); + } + + toJson() => { + 'language_code': langCode, + 'language_name': displayName, + 'language_type': languageType, + 'language_flag': languageFlag, + 'l2': l2, + 'l1': l1, + }; + + // Discuss with Jordan - adding langCode field to language objects as separate from displayName + static String codeFromNameOrCode(String codeOrName, [String? url]) { + if (codeOrName.isEmpty) return LanguageKeys.unknownLanguage; + if (codeOrName == LanguageKeys.unknownLanguage) return codeOrName; + + if (_LanguageLocal.isoLangs.containsKey(codeOrName)) return codeOrName; + + final String code = _LanguageLocal.langCodeFromName(codeOrName); + if (code != LanguageKeys.unknownLanguage) return code; + + if (url == null) return LanguageKeys.unknownLanguage; + + final List split = url.split('/'); + return split.last.split('.').first; + } + + //PTODO - add flag for unknown + static LanguageModel get unknown => LanguageModel( + langCode: LanguageKeys.unknownLanguage, + languageType: 1, + languageFlag: "", + displayName: "Unknown", + l2: false, + l1: false, + ); + + static LanguageModel multiLingual([BuildContext? context]) => LanguageModel( + displayName: context != null + ? L10n.of(context)!.multiLingualClass + : "Multilingual Class", + l2: false, + l1: false, + langCode: LanguageKeys.multiLanguage, + languageFlag: 'assets/colors.png', + languageType: 3, + ); + + // Discuss with Jordan + bool get hasContextualDefinitionSupport => languageType == 2; + + String? getDisplayName(BuildContext context) { + switch (langCode) { + case 'ab': + return L10n.of(context)!.abDisplayName; + case 'aa': + return L10n.of(context)!.aaDisplayName; + case 'af': + return L10n.of(context)!.afDisplayName; + case 'ak': + return L10n.of(context)!.akDisplayName; + case 'sq': + return L10n.of(context)!.sqDisplayName; + case 'am': + return L10n.of(context)!.amDisplayName; + case 'ar': + return L10n.of(context)!.arDisplayName; + case 'an': + return L10n.of(context)!.anDisplayName; + case 'hy': + return L10n.of(context)!.hyDisplayName; + case 'as': + return L10n.of(context)!.asDisplayName; + case 'av': + return L10n.of(context)!.avDisplayName; + case 'ae': + return L10n.of(context)!.aeDisplayName; + case 'ay': + return L10n.of(context)!.ayDisplayName; + case 'az': + return L10n.of(context)!.azDisplayName; + case 'bm': + return L10n.of(context)!.bmDisplayName; + case 'ba': + return L10n.of(context)!.baDisplayName; + case 'eu': + return L10n.of(context)!.euDisplayName; + case 'be': + return L10n.of(context)!.beDisplayName; + case 'bn': + return L10n.of(context)!.bnDisplayName; + case 'bh': + return L10n.of(context)!.bhDisplayName; + case 'bi': + return L10n.of(context)!.biDisplayName; + case 'bs': + return L10n.of(context)!.bsDisplayName; + case 'br': + return L10n.of(context)!.brDisplayName; + case 'bg': + return L10n.of(context)!.bgDisplayName; + case 'my': + return L10n.of(context)!.myDisplayName; + case 'ca': + return L10n.of(context)!.caDisplayName; + case 'ch': + return L10n.of(context)!.chDisplayName; + case 'ce': + return L10n.of(context)!.ceDisplayName; + case 'ny': + return L10n.of(context)!.nyDisplayName; + case 'zh': + return L10n.of(context)!.zhDisplayName; + case 'cv': + return L10n.of(context)!.cvDisplayName; + case 'kw': + return L10n.of(context)!.kwDisplayName; + case 'co': + return L10n.of(context)!.coDisplayName; + case 'cr': + return L10n.of(context)!.crDisplayName; + case 'hr': + return L10n.of(context)!.hrDisplayName; + case 'cs': + return L10n.of(context)!.csDisplayName; + case 'da': + return L10n.of(context)!.daDisplayName; + case 'dv': + return L10n.of(context)!.dvDisplayName; + case 'nl': + return L10n.of(context)!.nlDisplayName; + case 'en': + return L10n.of(context)!.enDisplayName; + case 'eo': + return L10n.of(context)!.eoDisplayName; + case 'et': + return L10n.of(context)!.etDisplayName; + case 'ee': + return L10n.of(context)!.eeDisplayName; + case 'fo': + return L10n.of(context)!.foDisplayName; + case 'fj': + return L10n.of(context)!.fjDisplayName; + case 'fi': + return L10n.of(context)!.fiDisplayName; + case 'fr': + return L10n.of(context)!.frDisplayName; + case 'ff': + return L10n.of(context)!.ffDisplayName; + case 'gl': + return L10n.of(context)!.glDisplayName; + case 'ka': + return L10n.of(context)!.kaDisplayName; + case 'de': + return L10n.of(context)!.deDisplayName; + case 'el': + return L10n.of(context)!.elDisplayName; + case 'gn': + return L10n.of(context)!.gnDisplayName; + case 'gu': + return L10n.of(context)!.guDisplayName; + case 'ht': + return L10n.of(context)!.htDisplayName; + case 'ha': + return L10n.of(context)!.haDisplayName; + case 'he': + return L10n.of(context)!.heDisplayName; + case 'hz': + return L10n.of(context)!.hzDisplayName; + case 'hi': + return L10n.of(context)!.hiDisplayName; + case 'ho': + return L10n.of(context)!.hoDisplayName; + case 'hu': + return L10n.of(context)!.huDisplayName; + case 'ia': + return L10n.of(context)!.iaDisplayName; + case 'id': + return L10n.of(context)!.idDisplayName; + case 'ie': + return L10n.of(context)!.ieDisplayName; + case 'ga': + return L10n.of(context)!.gaDisplayName; + case 'ig': + return L10n.of(context)!.igDisplayName; + case 'ik': + return L10n.of(context)!.ikDisplayName; + case 'io': + return L10n.of(context)!.ioDisplayName; + case 'is': + return L10n.of(context)!.isDisplayName; + case 'it': + return L10n.of(context)!.itDisplayName; + case 'iu': + return L10n.of(context)!.iuDisplayName; + case 'ja': + return L10n.of(context)!.jaDisplayName; + case 'jv': + return L10n.of(context)!.jvDisplayName; + case 'kl': + return L10n.of(context)!.klDisplayName; + case 'kn': + return L10n.of(context)!.knDisplayName; + case 'kr': + return L10n.of(context)!.krDisplayName; + case 'ks': + return L10n.of(context)!.ksDisplayName; + case 'kk': + return L10n.of(context)!.kkDisplayName; + case 'km': + return L10n.of(context)!.kmDisplayName; + case 'ki': + return L10n.of(context)!.kiDisplayName; + case 'rw': + return L10n.of(context)!.rwDisplayName; + case 'ky': + return L10n.of(context)!.kyDisplayName; + case 'kv': + return L10n.of(context)!.kvDisplayName; + case 'kg': + return L10n.of(context)!.kgDisplayName; + case 'ko': + return L10n.of(context)!.koDisplayName; + case 'ku': + return L10n.of(context)!.kuDisplayName; + case 'kj': + return L10n.of(context)!.kjDisplayName; + case 'la': + return L10n.of(context)!.laDisplayName; + case 'lb': + return L10n.of(context)!.lbDisplayName; + case 'lg': + return L10n.of(context)!.lgDisplayName; + case 'li': + return L10n.of(context)!.liDisplayName; + case 'ln': + return L10n.of(context)!.lnDisplayName; + case 'lo': + return L10n.of(context)!.loDisplayName; + case 'lt': + return L10n.of(context)!.ltDisplayName; + case 'lu': + return L10n.of(context)!.luDisplayName; + case 'lv': + return L10n.of(context)!.lvDisplayName; + case 'gv': + return L10n.of(context)!.gvDisplayName; + case 'mk': + return L10n.of(context)!.mkDisplayName; + case 'mg': + return L10n.of(context)!.mgDisplayName; + case 'ms': + return L10n.of(context)!.msDisplayName; + case 'ml': + return L10n.of(context)!.mlDisplayName; + case 'mt': + return L10n.of(context)!.mtDisplayName; + case 'mi': + return L10n.of(context)!.miDisplayName; + case 'mr': + return L10n.of(context)!.mrDisplayName; + case 'mh': + return L10n.of(context)!.mhDisplayName; + case 'mn': + return L10n.of(context)!.mnDisplayName; + case 'na': + return L10n.of(context)!.naDisplayName; + case 'nv': + return L10n.of(context)!.nvDisplayName; + case 'nb': + return L10n.of(context)!.nbDisplayName; + case 'nd': + return L10n.of(context)!.ndDisplayName; + case 'ne': + return L10n.of(context)!.neDisplayName; + case 'ng': + return L10n.of(context)!.ngDisplayName; + case 'nn': + return L10n.of(context)!.nnDisplayName; + case 'no': + return L10n.of(context)!.noDisplayName; + case 'ii': + return L10n.of(context)!.iiDisplayName; + case 'nr': + return L10n.of(context)!.nrDisplayName; + case 'oc': + return L10n.of(context)!.ocDisplayName; + case 'oj': + return L10n.of(context)!.ojDisplayName; + case 'cu': + return L10n.of(context)!.cuDisplayName; + case 'om': + return L10n.of(context)!.omDisplayName; + case 'or': + return L10n.of(context)!.orDisplayName; + case 'os': + return L10n.of(context)!.osDisplayName; + case 'pa': + return L10n.of(context)!.paDisplayName; + case 'pi': + return L10n.of(context)!.piDisplayName; + case 'fa': + return L10n.of(context)!.faDisplayName; + case 'pl': + return L10n.of(context)!.plDisplayName; + case 'ps': + return L10n.of(context)!.psDisplayName; + case 'pt': + return L10n.of(context)!.ptDisplayName; + case 'qu': + return L10n.of(context)!.quDisplayName; + case 'rm': + return L10n.of(context)!.rmDisplayName; + case 'rn': + return L10n.of(context)!.rnDisplayName; + case 'ro': + return L10n.of(context)!.roDisplayName; + case 'ru': + return L10n.of(context)!.ruDisplayName; + case 'sa': + return L10n.of(context)!.saDisplayName; + case 'sc': + return L10n.of(context)!.scDisplayName; + case 'sd': + return L10n.of(context)!.sdDisplayName; + case 'se': + return L10n.of(context)!.seDisplayName; + case 'sm': + return L10n.of(context)!.smDisplayName; + case 'sg': + return L10n.of(context)!.sgDisplayName; + case 'sr': + return L10n.of(context)!.srDisplayName; + case 'gd': + return L10n.of(context)!.gdDisplayName; + case 'sn': + return L10n.of(context)!.snDisplayName; + case 'si': + return L10n.of(context)!.siDisplayName; + case 'sk': + return L10n.of(context)!.skDisplayName; + case 'sl': + return L10n.of(context)!.slDisplayName; + case 'so': + return L10n.of(context)!.soDisplayName; + case 'st': + return L10n.of(context)!.stDisplayName; + case 'es': + return L10n.of(context)!.esDisplayName; + case 'su': + return L10n.of(context)!.suDisplayName; + case 'sw': + return L10n.of(context)!.swDisplayName; + case 'ss': + return L10n.of(context)!.ssDisplayName; + case 'sv': + return L10n.of(context)!.svDisplayName; + case 'ta': + return L10n.of(context)!.taDisplayName; + case 'te': + return L10n.of(context)!.teDisplayName; + case 'tg': + return L10n.of(context)!.tgDisplayName; + case 'th': + return L10n.of(context)!.thDisplayName; + case 'ti': + return L10n.of(context)!.tiDisplayName; + case 'bo': + return L10n.of(context)!.boDisplayName; + case 'tk': + return L10n.of(context)!.tkDisplayName; + case 'tl': + return L10n.of(context)!.tlDisplayName; + case 'tn': + return L10n.of(context)!.tnDisplayName; + case 'to': + return L10n.of(context)!.toDisplayName; + case 'tr': + return L10n.of(context)!.trDisplayName; + case 'ts': + return L10n.of(context)!.tsDisplayName; + case 'tt': + return L10n.of(context)!.ttDisplayName; + case 'tw': + return L10n.of(context)!.twDisplayName; + case 'ty': + return L10n.of(context)!.tyDisplayName; + case 'ug': + return L10n.of(context)!.ugDisplayName; + case 'uk': + return L10n.of(context)!.ukDisplayName; + case 'ur': + return L10n.of(context)!.urDisplayName; + case 'uz': + return L10n.of(context)!.uzDisplayName; + case 've': + return L10n.of(context)!.veDisplayName; + case 'vi': + return L10n.of(context)!.viDisplayName; + case 'vo': + return L10n.of(context)!.voDisplayName; + case 'wa': + return L10n.of(context)!.waDisplayName; + case 'cy': + return L10n.of(context)!.cyDisplayName; + case 'wo': + return L10n.of(context)!.woDisplayName; + case 'fy': + return L10n.of(context)!.fyDisplayName; + case 'xh': + return L10n.of(context)!.xhDisplayName; + case 'yi': + return L10n.of(context)!.yiDisplayName; + case 'yo': + return L10n.of(context)!.yoDisplayName; + case 'za': + return L10n.of(context)!.zaDisplayName; + case 'unk': + return L10n.of(context)!.unkDisplayName; + case 'zu': + return L10n.of(context)!.zuDisplayName; + case 'haw': + return L10n.of(context)!.hawDisplayName; + case 'hmn': + return L10n.of(context)!.hmnDisplayName; + case 'multi': + return L10n.of(context)!.multiDisplayName; + case 'ceb': + return L10n.of(context)!.cebDisplayName; + case 'dz': + return L10n.of(context)!.dzDisplayName; + case 'iw': + return L10n.of(context)!.iwDisplayName; + case 'jw': + return L10n.of(context)!.jwDisplayName; + case 'mo': + return L10n.of(context)!.moDisplayName; + case 'sh': + return L10n.of(context)!.shDisplayName; + } + debugger(when: kDebugMode); + ErrorHandler.logError(m: "No Display name found", s: StackTrace.current); + return null; + } +} + +class _LanguageLocal { + static const isoLangs = { + "ab": {"name": "Abkhaz", "nativeName": "аҧсуа"}, + "aa": {"name": "Afar", "nativeName": "Afaraf"}, + "af": {"name": "Afrikaans", "nativeName": "Afrikaans"}, + "ak": {"name": "Akan", "nativeName": "Akan"}, + "sq": {"name": "Albanian", "nativeName": "Shqip"}, + "am": {"name": "Amharic", "nativeName": "አማርኛ"}, + "ar": {"name": "Arabic", "nativeName": "العربية"}, + "an": {"name": "Aragonese", "nativeName": "Aragonés"}, + "hy": {"name": "Armenian", "nativeName": "Հայերեն"}, + "as": {"name": "Assamese", "nativeName": "অসমীয়া"}, + "av": {"name": "Avaric", "nativeName": "авар мацӀ, магӀарул мацӀ"}, + "ae": {"name": "Avestan", "nativeName": "avesta"}, + "ay": {"name": "Aymara", "nativeName": "aymar aru"}, + "az": {"name": "Azerbaijani", "nativeName": "azərbaycan dili"}, + "bm": {"name": "Bambara", "nativeName": "bamanankan"}, + "ba": {"name": "Bashkir", "nativeName": "башҡорт теле"}, + "eu": {"name": "Basque", "nativeName": "euskara, euskera"}, + "be": {"name": "Belarusian", "nativeName": "Беларуская"}, + "bn": {"name": "Bengali", "nativeName": "বাংলা"}, + "bh": {"name": "Bihari", "nativeName": "भोजपुरी"}, + "bi": {"name": "Bislama", "nativeName": "Bislama"}, + "bs": {"name": "Bosnian", "nativeName": "bosanski jezik"}, + "br": {"name": "Breton", "nativeName": "brezhoneg"}, + "bg": {"name": "Bulgarian", "nativeName": "български език"}, + "my": {"name": "Burmese", "nativeName": "ဗမာစာ"}, + "ca": {"name": "Catalan, Valencian", "nativeName": "Català"}, + "ch": {"name": "Chamorro", "nativeName": "Chamoru"}, + "ce": {"name": "Chechen", "nativeName": "нохчийн мотт"}, + "ny": { + "name": "Chichewa, Chewa, Nyanja", + "nativeName": "chiCheŵa, chinyanja", + }, + "zh": {"name": "Chinese", "nativeName": "中文 (Zhōngwén), 汉语, 漢語"}, + "cv": {"name": "Chuvash", "nativeName": "чӑваш чӗлхи"}, + "kw": {"name": "Cornish", "nativeName": "Kernewek"}, + "co": {"name": "Corsican", "nativeName": "corsu, lingua corsa"}, + "cr": {"name": "Cree", "nativeName": "ᓀᐦᐃᔭᐍᐏᐣ"}, + "hr": {"name": "Croatian", "nativeName": "hrvatski"}, + "cs": {"name": "Czech", "nativeName": "česky, čeština"}, + "da": {"name": "Danish", "nativeName": "dansk"}, + "dv": {"name": "Divehi; Dhivehi; Maldivian;", "nativeName": "ދިވެހި"}, + "nl": {"name": "Dutch", "nativeName": "Nederlands, Vlaams"}, + "en": {"name": "English", "nativeName": "English"}, + "eo": {"name": "Esperanto", "nativeName": "Esperanto"}, + "et": {"name": "Estonian", "nativeName": "eesti, eesti keel"}, + "ee": {"name": "Ewe", "nativeName": "Evegbe"}, + "fo": {"name": "Faroese", "nativeName": "føroyskt"}, + "fj": {"name": "Fijian", "nativeName": "vosa Vakaviti"}, + "fi": {"name": "Finnish", "nativeName": "suomi, suomen kieli"}, + "fr": {"name": "French", "nativeName": "français, langue française"}, + "ff": { + "name": "Fula; Fulah; Pulaar; Pular", + "nativeName": "Fulfulde, Pulaar, Pular", + }, + "gl": {"name": "Galician", "nativeName": "Galego"}, + "ka": {"name": "Georgian", "nativeName": "ქართული"}, + "de": {"name": "German", "nativeName": "Deutsch"}, + "el": {"name": "Greek, Modern", "nativeName": "Ελληνικά"}, + "gn": {"name": "Guaraní", "nativeName": "Avañeẽ"}, + "gu": {"name": "Gujarati", "nativeName": "ગુજરાતી"}, + "ht": {"name": "Haitian, Haitian Creole", "nativeName": "Kreyòl ayisyen"}, + "ha": {"name": "Hausa", "nativeName": "Hausa, هَوُسَ"}, + "he": {"name": "Hebrew (modern)", "nativeName": "עברית"}, + "hz": {"name": "Herero", "nativeName": "Otjiherero"}, + "hi": {"name": "Hindi", "nativeName": "हिन्दी, हिंदी"}, + "ho": {"name": "Hiri Motu", "nativeName": "Hiri Motu"}, + "hu": {"name": "Hungarian", "nativeName": "Magyar"}, + "ia": {"name": "Interlingua", "nativeName": "Interlingua"}, + "id": {"name": "Indonesian", "nativeName": "Bahasa Indonesia"}, + "ie": { + "name": "Interlingue", + "nativeName": "Originally called Occidental; then Interlingue after WWII", + }, + "ga": {"name": "Irish", "nativeName": "Gaeilge"}, + "ig": {"name": "Igbo", "nativeName": "Asụsụ Igbo"}, + "ik": {"name": "Inupiaq", "nativeName": "Iñupiaq, Iñupiatun"}, + "io": {"name": "Ido", "nativeName": "Ido"}, + "is": {"name": "Icelandic", "nativeName": "Íslenska"}, + "it": {"name": "Italian", "nativeName": "Italiano"}, + "iu": {"name": "Inuktitut", "nativeName": "ᐃᓄᒃᑎᑐᑦ"}, + "ja": {"name": "Japanese", "nativeName": "日本語 (にほんご/にっぽんご)"}, + "jv": {"name": "Javanese", "nativeName": "basa Jawa"}, + "kl": { + "name": "Kalaallisut, Greenlandic", + "nativeName": "kalaallisut, kalaallit oqaasii", + }, + "kn": {"name": "Kannada", "nativeName": "ಕನ್ನಡ"}, + "kr": {"name": "Kanuri", "nativeName": "Kanuri"}, + "ks": {"name": "Kashmiri", "nativeName": "कश्मीरी, كشميري"}, + "kk": {"name": "Kazakh", "nativeName": "Қазақ тілі"}, + "km": {"name": "Khmer", "nativeName": "ភាសាខ្មែរ"}, + "ki": {"name": "Kikuyu, Gikuyu", "nativeName": "Gĩkũyũ"}, + "rw": {"name": "Kinyarwanda", "nativeName": "Ikinyarwanda"}, + "ky": {"name": "Kirghiz, Kyrgyz", "nativeName": "кыргыз тили"}, + "kv": {"name": "Komi", "nativeName": "коми кыв"}, + "kg": {"name": "Kongo", "nativeName": "KiKongo"}, + "ko": {"name": "Korean", "nativeName": "한국어 (韓國語), 조선말 (朝鮮語)"}, + "ku": {"name": "Kurdish", "nativeName": "Kurdî, كوردی"}, + "kj": {"name": "Kwanyama, Kuanyama", "nativeName": "Kuanyama"}, + "la": {"name": "Latin", "nativeName": "latine, lingua latina"}, + "lb": { + "name": "Luxembourgish, Letzeburgesch", + "nativeName": "Lëtzebuergesch", + }, + "lg": {"name": "Luganda", "nativeName": "Luganda"}, + "li": { + "name": "Limburgish, Limburgan, Limburger", + "nativeName": "Limburgs", + }, + "ln": {"name": "Lingala", "nativeName": "Lingála"}, + "lo": {"name": "Lao", "nativeName": "ພາສາລາວ"}, + "lt": {"name": "Lithuanian", "nativeName": "lietuvių kalba"}, + "lu": {"name": "Luba-Katanga", "nativeName": ""}, + "lv": {"name": "Latvian", "nativeName": "latviešu valoda"}, + "gv": {"name": "Manx", "nativeName": "Gaelg, Gailck"}, + "mk": {"name": "Macedonian", "nativeName": "македонски јазик"}, + "mg": {"name": "Malagasy", "nativeName": "Malagasy fiteny"}, + "ms": {"name": "Malay", "nativeName": "bahasa Melayu, بهاس ملايو"}, + "ml": {"name": "Malayalam", "nativeName": "മലയാളം"}, + "mt": {"name": "Maltese", "nativeName": "Malti"}, + "mi": {"name": "Māori", "nativeName": "te reo Māori"}, + "mr": {"name": "Marathi (Marāṭhī)", "nativeName": "मराठी"}, + "mh": {"name": "Marshallese", "nativeName": "Kajin M̧ajeļ"}, + "mn": {"name": "Mongolian", "nativeName": "монгол"}, + "na": {"name": "Nauru", "nativeName": "Ekakairũ Naoero"}, + "nv": {"name": "Navajo, Navaho", "nativeName": "Diné bizaad, Dinék'ehǰí"}, + "nb": {"name": "Norwegian Bokmål", "nativeName": "Norsk bokmål"}, + "nd": {"name": "North Ndebele", "nativeName": "isiNdebele"}, + "ne": {"name": "Nepali", "nativeName": "नेपाली"}, + "ng": {"name": "Ndonga", "nativeName": "Owambo"}, + "nn": {"name": "Norwegian Nynorsk", "nativeName": "Norsk nynorsk"}, + "no": {"name": "Norwegian", "nativeName": "Norsk"}, + "ii": {"name": "Nuosu", "nativeName": "ꆈꌠ꒿ Nuosuhxop"}, + "nr": {"name": "South Ndebele", "nativeName": "isiNdebele"}, + "oc": {"name": "Occitan", "nativeName": "Occitan"}, + "oj": {"name": "Ojibwe, Ojibwa", "nativeName": "ᐊᓂᔑᓈᐯᒧᐎᓐ"}, + "cu": { + "name": + "Old Church Slavonic, Church Slavic, Church Slavonic, Old Bulgarian, Old Slavonic", + "nativeName": "ѩзыкъ словѣньскъ", + }, + "om": {"name": "Oromo", "nativeName": "Afaan Oromoo"}, + "or": {"name": "Oriya", "nativeName": "ଓଡ଼ିଆ"}, + "os": {"name": "Ossetian, Ossetic", "nativeName": "ирон æвзаг"}, + "pa": {"name": "Panjabi, Punjabi", "nativeName": "ਪੰਜਾਬੀ, پنجابی"}, + "pi": {"name": "Pāli", "nativeName": "पाऴि"}, + "fa": {"name": "Persian", "nativeName": "فارسی"}, + "pl": {"name": "Polish", "nativeName": "polski"}, + "ps": {"name": "Pashto, Pushto", "nativeName": "پښتو"}, + "pt": {"name": "Portuguese", "nativeName": "Português"}, + "qu": {"name": "Quechua", "nativeName": "Runa Simi, Kichwa"}, + "rm": {"name": "Romansh", "nativeName": "rumantsch grischun"}, + "rn": {"name": "Kirundi", "nativeName": "kiRundi"}, + "ro": {"name": "Romanian, Moldavian, Moldovan", "nativeName": "română"}, + "ru": {"name": "Russian", "nativeName": "русский язык"}, + "sa": {"name": "Sanskrit (Saṁskṛta)", "nativeName": "संस्कृतम्"}, + "sc": {"name": "Sardinian", "nativeName": "sardu"}, + "sd": {"name": "Sindhi", "nativeName": "सिन्धी, سنڌي، سندھی"}, + "se": {"name": "Northern Sami", "nativeName": "Davvisámegiella"}, + "sm": {"name": "Samoan", "nativeName": "gagana faa Samoa"}, + "sg": {"name": "Sango", "nativeName": "yângâ tî sängö"}, + "sr": {"name": "Serbian", "nativeName": "српски језик"}, + "gd": {"name": "Scottish Gaelic, Gaelic", "nativeName": "Gàidhlig"}, + "sn": {"name": "Shona", "nativeName": "chiShona"}, + "si": {"name": "Sinhala, Sinhalese", "nativeName": "සිංහල"}, + "sk": {"name": "Slovak", "nativeName": "Slovenčina"}, + "sl": {"name": "Slovene", "nativeName": "Slovenščina"}, + "so": {"name": "Somali", "nativeName": "Soomaaliga, af Soomaali"}, + "st": {"name": "Southern Sotho", "nativeName": "Sesotho"}, + "es": {"name": "Spanish, Castilian", "nativeName": "Español, Castellano"}, + "su": {"name": "Sundanese", "nativeName": "Basa Sunda"}, + "sw": {"name": "Swahili", "nativeName": "Kiswahili"}, + "ss": {"name": "Swati", "nativeName": "SiSwati"}, + "sv": {"name": "Swedish", "nativeName": "svenska"}, + "ta": {"name": "Tamil", "nativeName": "தமிழ்"}, + "te": {"name": "Telugu", "nativeName": "తెలుగు"}, + "tg": {"name": "Tajik", "nativeName": "тоҷикӣ, toğikī, تاجیکی"}, + "th": {"name": "Thai", "nativeName": "ไทย"}, + "ti": {"name": "Tigrinya", "nativeName": "ትግርኛ"}, + "bo": { + "name": "Tibetan Standard, Tibetan, Central", + "nativeName": "བོད་ཡིག", + }, + "tk": {"name": "Turkmen", "nativeName": "Türkmen, Түркмен"}, + "tl": {"name": "Tagalog", "nativeName": "Wikang Tagalog, ᜏᜒᜃᜅ᜔ ᜆᜄᜎᜓᜄ᜔"}, + "tn": {"name": "Tswana", "nativeName": "Setswana"}, + "to": {"name": "Tonga (Tonga Islands)", "nativeName": "faka Tonga"}, + "tr": {"name": "Turkish", "nativeName": "Türkçe"}, + "ts": {"name": "Tsonga", "nativeName": "Xitsonga"}, + "tt": {"name": "Tatar", "nativeName": "татарча, tatarça, تاتارچا"}, + "tw": {"name": "Twi", "nativeName": "Twi"}, + "ty": {"name": "Tahitian", "nativeName": "Reo Tahiti"}, + "ug": {"name": "Uighur, Uyghur", "nativeName": "Uyƣurqə, ئۇيغۇرچە"}, + "uk": {"name": "Ukrainian", "nativeName": "українська"}, + "ur": {"name": "Urdu", "nativeName": "اردو"}, + "uz": {"name": "Uzbek", "nativeName": "zbek, Ўзбек, أۇزبېك"}, + "ve": {"name": "Venda", "nativeName": "Tshivenḓa"}, + "vi": {"name": "Vietnamese", "nativeName": "Tiếng Việt"}, + "vo": {"name": "Volapük", "nativeName": "Volapük"}, + "wa": {"name": "Walloon", "nativeName": "Walon"}, + "cy": {"name": "Welsh", "nativeName": "Cymraeg"}, + "wo": {"name": "Wolof", "nativeName": "Wollof"}, + "fy": {"name": "Western Frisian", "nativeName": "Frysk"}, + "xh": {"name": "Xhosa", "nativeName": "isiXhosa"}, + "yi": {"name": "Yiddish", "nativeName": "ייִדיש"}, + "yo": {"name": "Yoruba", "nativeName": "Yorùbá"}, + "za": {"name": "Zhuang, Chuang", "nativeName": "Saw cueŋƅ, Saw cuengh"}, + "unk": {"name": "Unknown", "nativeName": "Saw cueŋƅ, Saw cuengh"}, + "zu": {"name": "Zulu", "nativeName": "Zulu"}, + "haw": {"name": "Hawaiian", "nativeName": "Hawaiian"}, + "hmn": {"name": "Hmong", "nativeName": "Hmong"}, + 'multi': {"name": "Multi", "nativeName": "Multi"}, + "ceb": {"name": "Cebuano", "nativeName": "Cebuano"}, + "dz": {"name": "Dzongkha", "nativeName": "Dzongkha"}, + "iw": {"name": "Hebrew", "nativeName": "Hebrew"}, + "jw": {"name": "Javanese", "nativeName": "Javanese"}, + "mo": {"name": "Moldavian", "nativeName": "Moldavian"}, + "sh": {"name": "Serbo-Croatian", "nativeName": "Serbo-Croatian"}, + }; + + static String getDisplayName(String key, [native = false]) { + final Map? item = isoLangs[key]; + if (item == null) { + // debugger(when: kDebugMode); + // ErrorHandler.logError(m: "Bad language key $key", s: StackTrace.current); + } + if (item == null) return key; + + return (native ? item["nativeName"]! : item["name"]!).split(",")[0]; + } + + static String langCodeFromName(String? name) { + if (name == null) return LanguageKeys.unknownLanguage; + if (isoLangs.containsKey(name)) return name; + + final String searchName = name.toLowerCase().split(" ")[0]; + for (final entry in isoLangs.entries) { + if (entry.value["name"]!.toLowerCase().contains(searchName)) { + return entry.key; + } + } + // debugger(when: kDebugMode); + // ErrorHandler.logError(m: "Bad language name $name", s: StackTrace.current); + return LanguageKeys.unknownLanguage; + } +} diff --git a/lib/pangea/models/lemma.dart b/lib/pangea/models/lemma.dart new file mode 100644 index 000000000..2ad0b2950 --- /dev/null +++ b/lib/pangea/models/lemma.dart @@ -0,0 +1,24 @@ +class Lemma { + final String text; + final String form; + final bool saveVocab; + + Lemma({required this.text, required this.saveVocab, required this.form}); + + factory Lemma.fromJson(Map json) { + return Lemma( + text: json['text'], + saveVocab: json['save_vocab'] ?? json['saveVocab'] ?? false, + form: json["form"] ?? json['text'], + ); + } + + toJson() { + return {'text': text, 'save_vocab': saveVocab, 'form': form}; + } + + static Lemma get empty => Lemma(text: '', saveVocab: true, form: ''); + + static Lemma create(String form) => + Lemma(text: '', saveVocab: true, form: form); +} diff --git a/lib/pangea/models/message_data_models.dart b/lib/pangea/models/message_data_models.dart new file mode 100644 index 000000000..1ed2f36ce --- /dev/null +++ b/lib/pangea/models/message_data_models.dart @@ -0,0 +1,104 @@ +import 'dart:convert'; + +import 'package:matrix/matrix.dart'; + +import 'package:fluffychat/pangea/models/pangea_token_model.dart'; + +/// this class is contained within a [RepresentationEvent] +/// this event is the child of a [EventTypes.Message] +/// the event has two potential children events - +/// [PangeaTokensEvent] and [PangeaIGCEvent] +/// these events contain [PangeaMessageTokens] and [ChoreoRecord], respectively. +class PangeaRepresentation { + /// system-detected language, possibly condensed from a list, + /// but only with high certainty + /// cannot be "unk" + String langCode; + + /// final sent text + /// if this was a process, a [PangeaIGCEvent] will contain changes + String text; + + bool originalSent; + bool originalWritten; + + // how do we know which representation was sent by author? + // RepresentationEvent.text == PangeaMessageEvent.event.body + // use: to know whether directUse + + // how do we know which representation was original L1 message that was translated (if it exists)? + // (of l2 rep) RepresentationEvent.igc.steps.first.text = RepresentationEvent.text (of L1 rep) + // use: for base text for future translations + + // os = true and ow = false + // rep that went through IGC/IT + + // os = false and ow = false + // rep added by other user + + // os = true and ow = true + // potentially L1 language use, maybe with limited IGC, and ignored out of target cries + // potentially perfect L2 use + + // os = false and ow = true + // L1 message that then went through significant IGC and/or IT + // L2 message with errors that went through IGC + + PangeaRepresentation({ + required this.langCode, + required this.text, + required this.originalSent, + required this.originalWritten, + }); + + factory PangeaRepresentation.fromJson(Map json) => + PangeaRepresentation( + langCode: json[_langCodeKey], + text: json[_textKey], + originalSent: json[_originalSentKey] ?? false, + originalWritten: json[_originalWrittenKey] ?? false, + ); + + static const _textKey = "txt"; + static const _langCodeKey = "lang"; + static const _originalSentKey = "snt"; + static const _originalWrittenKey = "wrttn"; + + Map toJson() { + final data = {}; + data[_textKey] = text; + data[_langCodeKey] = langCode; + if (originalSent) data[_originalSentKey] = originalSent; + if (originalWritten) data[_originalWrittenKey] = originalWritten; + return data; + } +} + +/// this class lives within a [PangeaTokensEvent] +/// it always has a [RepresentationEvent] parent +/// These live as separate event so that anyone can add and edit tokens to +/// representation +class PangeaMessageTokens { + List tokens; + + PangeaMessageTokens({ + required this.tokens, + }); + + factory PangeaMessageTokens.fromJson(Map json) { + return PangeaMessageTokens( + tokens: (jsonDecode(json[_tokensKey] ?? "[]") as Iterable) + .map((e) => PangeaToken.fromJson(e)) + .toList() + .cast(), + ); + } + + static const _tokensKey = "tkns"; + + Map toJson() { + final data = {}; + data[_tokensKey] = jsonEncode(tokens.map((e) => e.toJson()).toList()); + return data; + } +} diff --git a/lib/pangea/models/mobile_subscriptions.dart b/lib/pangea/models/mobile_subscriptions.dart new file mode 100644 index 000000000..128724b9e --- /dev/null +++ b/lib/pangea/models/mobile_subscriptions.dart @@ -0,0 +1,219 @@ +import 'dart:io'; + +import 'package:flutter/material.dart'; + +import 'package:collection/collection.dart'; +import 'package:purchases_flutter/purchases_flutter.dart'; +import 'package:sentry_flutter/sentry_flutter.dart'; + +import 'package:fluffychat/pangea/config/environment.dart'; +import 'package:fluffychat/pangea/controllers/subscription_controller.dart'; +import 'package:fluffychat/pangea/models/base_subscription_info.dart'; +import 'package:fluffychat/pangea/utils/error_handler.dart'; + +class MobileSubscriptionInfo extends SubscriptionInfo { + MobileSubscriptionInfo({required super.pangeaController}) : super(); + + @override + Future configure() async { + final PurchasesConfiguration configuration = Platform.isAndroid + ? PurchasesConfiguration(Environment.rcGoogleKey) + : PurchasesConfiguration(Environment.rcIosKey); + try { + await Purchases.configure( + configuration..appUserID = pangeaController.userController.userId, + ); + } catch (err) { + ErrorHandler.logError( + m: "Failed to configure revenuecat SDK for user ${pangeaController.userController.userId}", + s: StackTrace.current, + ); + debugPrint( + "Failed to configure revenuecat SDK for user ${pangeaController.userController.userId}", + ); + return; + } + await setAppIds(); + await setAllProducts(); + await setCustomerInfo(); + await setMobilePackages(); + if (allProducts != null && appIds != null) { + availableSubscriptions = allProducts! + .where((product) => product.appId == appIds!.currentAppId) + .toList(); + availableSubscriptions.sort((a, b) => a.price.compareTo(b.price)); + + if (currentSubscriptionId == null && !hasSubscribed) { + //@Gabby - temporary solution to add trial to list + final id = availableSubscriptions[0].id; + final package = availableSubscriptions[0].package; + final duration = availableSubscriptions[0].duration; + availableSubscriptions.insert( + 0, + SubscriptionDetails( + price: 0, + id: id, + duration: duration, + package: package, + periodType: 'trial', + ), + ); + } + } else { + ErrorHandler.logError(e: Exception("allProducts null || appIds null")); + } + } + + Future setMobilePackages() async { + if (allProducts == null) { + ErrorHandler.logError( + m: "Null appProducts in setMobilePrices", + s: StackTrace.current, + ); + debugPrint( + "Null appProducts in setMobilePrices", + ); + return; + } + Offerings offerings; + try { + offerings = await Purchases.getOfferings(); + } catch (err) { + ErrorHandler.logError( + m: "Failed to fetch revenuecat offerings from revenuecat", + s: StackTrace.current, + ); + debugPrint( + "Failed to fetch revenuecat offerings from revenuecat", + ); + return; + } + final Offering? offering = offerings.all[Environment.rcOfferingName]; + if (offering != null) { + final List mobileSubscriptions = + offering.availablePackages + .map( + (package) { + return SubscriptionDetails( + price: package.storeProduct.price, + id: package.storeProduct.identifier, + package: package, + ); + }, + ) + .toList() + .cast(); + for (final SubscriptionDetails mobileSub in mobileSubscriptions) { + final int productIndex = allProducts! + .indexWhere((product) => product.id.contains(mobileSub.id)); + if (productIndex >= 0) { + final SubscriptionDetails updated = allProducts![productIndex]; + updated.package = mobileSub.package; + allProducts![productIndex] = updated; + } + } + } + } + + @override + Future setCustomerInfo() async { + if (allProducts == null) { + ErrorHandler.logError( + m: "Null appProducts in setCustomerInfo", + s: StackTrace.current, + ); + debugPrint( + "Null appProducts in setCustomerInfo", + ); + return; + } + + CustomerInfo info; + try { + // await Purchases.syncPurchases(); + info = await Purchases.getCustomerInfo(); + } catch (err) { + ErrorHandler.logError( + m: "Failed to fetch revenuecat customer info for user ${pangeaController.userController.userId}", + s: StackTrace.current, + ); + debugPrint( + "Failed to fetch revenuecat customer info for user ${pangeaController.userController.userId}", + ); + return; + } + final List noExpirations = + getEntitlementsWithoutExpiration(info); + + if (noExpirations.isNotEmpty) { + Sentry.addBreadcrumb( + Breadcrumb( + message: + "Found revenuecat entitlement(s) without expiration date for user ${pangeaController.userController.userId}: ${noExpirations.map( + (entry) => + "Entitlement Id: ${entry.identifier}, Purchase Date: ${entry.originalPurchaseDate}", + )}", + ), + ); + } + + final List activeEntitlements = + info.entitlements.all.entries + .where( + (MapEntry entry) => + entry.value.expirationDate == null || + DateTime.parse(entry.value.expirationDate!) + .isAfter(DateTime.now()), + ) + .map((MapEntry entry) => entry.value) + .toList(); + + allEntitlements = info.entitlements.all.entries + .map( + (MapEntry entry) => + entry.value.productIdentifier, + ) + .cast() + .toList(); + + if (activeEntitlements.length > 1) { + debugPrint( + "User has more than one active entitlement.", + ); + } else if (activeEntitlements.isEmpty) { + debugPrint("User has no active entitlements"); + resetSubscription(); + return; + } + final EntitlementInfo activeEntitlement = activeEntitlements[0]; + currentSubscriptionId = activeEntitlement.productIdentifier; + currentSubscription = allProducts!.firstWhereOrNull( + (SubscriptionDetails sub) => + sub.id.contains(currentSubscriptionId!) || + currentSubscriptionId!.contains(sub.id), + ); + expirationDate = activeEntitlement.expirationDate != null + ? DateTime.parse(activeEntitlement.expirationDate!) + : null; + + if (activeEntitlement.periodType == PeriodType.trial) { + currentSubscription?.makeTrial(); + } + if (currentSubscriptionId != null && currentSubscription == null) { + Sentry.addBreadcrumb( + Breadcrumb(message: "mismatch of productIds and currentSubscriptionID"), + ); + } + } + + List getEntitlementsWithoutExpiration(CustomerInfo info) { + final List noExpirations = info.entitlements.all.entries + .where( + (MapEntry entry) => + entry.value.expirationDate == null, + ) + .map((MapEntry entry) => entry.value) + .toList(); + return noExpirations; + } +} diff --git a/lib/pangea/models/pangea_choreo_event.dart b/lib/pangea/models/pangea_choreo_event.dart new file mode 100644 index 000000000..f28f04b04 --- /dev/null +++ b/lib/pangea/models/pangea_choreo_event.dart @@ -0,0 +1,55 @@ +import 'package:flutter/foundation.dart'; + +import 'package:matrix/matrix.dart'; + +import 'package:fluffychat/pangea/extensions/pangea_event_extension.dart'; +import 'package:fluffychat/pangea/utils/error_handler.dart'; +import '../constants/pangea_event_types.dart'; +import 'choreo_record.dart'; + +class ChoreoEvent { + Event event; + ChoreoRecord? _content; + + ChoreoEvent({required this.event}) { + if (event.type != PangeaEventTypes.choreoRecord) { + throw Exception( + "${event.type} should not be used to make a ChoreoEvent", + ); + } + } + + ChoreoRecord? get content { + try { + _content ??= event.getPangeaContent(); + return _content; + } catch (err, s) { + if (kDebugMode) rethrow; + ErrorHandler.logError(e: err, s: s); + return null; + } + } + + // bool get hasAcceptedMatches => + // content?.steps.any( + // (element) => + // element.acceptedOrIgnoredMatch?.status == + // PangeaMatchStatus.accepted, + // ) ?? + // false; + + // bool get hasIgnoredMatches => + // content?.steps.any( + // (element) => + // element.acceptedOrIgnoredMatch?.status == PangeaMatchStatus.ignored, + // ) ?? + // false; + + // bool get includedIT => + // content?.steps.any((step) { + // return step.acceptedOrIgnoredMatch?.status == + // PangeaMatchStatus.accepted && + // (step.acceptedOrIgnoredMatch?.isITStart ?? false); + // }) ?? + // false; +} diff --git a/lib/pangea/models/pangea_match_model.dart b/lib/pangea/models/pangea_match_model.dart new file mode 100644 index 000000000..c7e97f4c0 --- /dev/null +++ b/lib/pangea/models/pangea_match_model.dart @@ -0,0 +1,130 @@ +import 'dart:developer'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + +import 'package:fluffychat/pangea/enum/span_data_type.dart'; +import 'package:fluffychat/pangea/utils/error_handler.dart'; +import '../constants/match_rule_ids.dart'; +import 'igc_text_data_model.dart'; +import 'span_data.dart'; + +enum PangeaMatchStatus { open, ignored, accepted, unknown } + +class PangeaMatch { + SpanData match; + + PangeaMatchStatus status; + + // String source; + + PangeaMatch({ + required this.match, + required this.status, + // required this.source, + }); + + factory PangeaMatch.fromJson(Map json) { + // try { + return PangeaMatch( + match: SpanData.fromJson(json[_matchKey] as Map), + status: json[_statusKey] != null + ? _statusStringToEnum(json[_statusKey]) + : PangeaMatchStatus.open, + // source: json[_matchKey]["source"] ?? "unk", + ); + // } catch (err) { + // debugger(when: kDebugMode); + // ErrorHandler.logError( + // m: "unknown error in PangeaMatch.fromJson", data: json); + // rethrow; + // } + } + + String _statusEnumToString(dynamic status) => + status.toString().split('.').last; + + static PangeaMatchStatus _statusStringToEnum(String status) { + final String lastPart = status.toString().split('.').last; + switch (lastPart) { + case 'open': + return PangeaMatchStatus.open; + case 'ignored': + return PangeaMatchStatus.ignored; + case 'accepted': + return PangeaMatchStatus.accepted; + default: + return PangeaMatchStatus.unknown; + } + } + + static const _matchKey = "match"; + static const _statusKey = "status"; + + bool get isl1SpanMatch => needsTranslation; + + bool get isITStart => + match.rule?.id == MatchRuleIds.interactiveTranslation || + match.type.typeName == SpanDataTypeEnum.itStart; + + bool get needsTranslation => match.rule?.id != null + ? [ + MatchRuleIds.tokenNeedsTranslation, + MatchRuleIds.tokenSpanNeedsTranslation, + ].contains(match.rule!.id) + : false; + + bool get isOutOfTargetMatch => isITStart || needsTranslation; + + bool get isGrammarMatch => !isOutOfTargetMatch; + + Map toJson() => { + _matchKey: match.toJson(), + // _detectionsKey: detections.map((e) => e.toJson()).toList(), + _statusKey: _statusEnumToString(status), + }; + + String get matchContent { + late int beginning; + late int end; + if (match.offset < 0) { + beginning = 0; + debugger(when: kDebugMode); + ErrorHandler.logError(m: "match.offset < 0", data: match.toJson()); + } else { + beginning = match.offset; + } + if (match.offset + match.length > match.fullText.length) { + end = match.fullText.length; + debugger(when: kDebugMode); + ErrorHandler.logError( + m: "match.offset + match.length > match.fullText.length", + data: match.toJson(), + ); + } else { + end = match.offset + match.length; + } + return match.fullText.substring(beginning, end); + } + + bool isOffsetInMatchSpan(int offset) => + offset >= match.offset && offset <= match.offset + match.length; + + Color get underlineColor { + switch (match.rule?.id ?? "unknown") { + case MatchRuleIds.interactiveTranslation: + return const Color.fromARGB(187, 132, 96, 224); + case MatchRuleIds.tokenNeedsTranslation: + case MatchRuleIds.tokenSpanNeedsTranslation: + return const Color.fromARGB(186, 255, 132, 0); + default: + return const Color.fromARGB(149, 255, 17, 0); + } + } + + TextStyle textStyle(TextStyle? existingStyle) => + existingStyle?.merge(IGCTextData.underlineStyle(underlineColor)) ?? + IGCTextData.underlineStyle(underlineColor); + + PangeaMatch get copyWith => PangeaMatch.fromJson(toJson()); +} diff --git a/lib/pangea/models/pangea_message_event.dart b/lib/pangea/models/pangea_message_event.dart new file mode 100644 index 000000000..b56402c08 --- /dev/null +++ b/lib/pangea/models/pangea_message_event.dart @@ -0,0 +1,270 @@ +import 'package:flutter/material.dart'; + +import 'package:collection/collection.dart'; +import 'package:matrix/matrix.dart'; + +import 'package:fluffychat/pangea/constants/pangea_message_types.dart'; +import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart'; +import 'package:fluffychat/pangea/models/choreo_record.dart'; +import 'package:fluffychat/pangea/models/message_data_models.dart'; +import 'package:fluffychat/pangea/models/pangea_representation_event.dart'; +import 'package:fluffychat/pangea/utils/bot_name.dart'; +import '../../widgets/matrix.dart'; +import '../constants/language_keys.dart'; +import '../constants/model_keys.dart'; +import '../constants/pangea_event_types.dart'; +import '../enum/use_type.dart'; +import '../utils/error_handler.dart'; + +class PangeaMessageEvent { + late Event _event; + final Timeline timeline; + final bool ownMessage; + final bool selected; + bool _isValidPangeaMessageEvent = true; + + PangeaMessageEvent({ + required Event event, + required this.timeline, + required this.ownMessage, + required this.selected, + }) { + if (event.type != EventTypes.Message) { + _isValidPangeaMessageEvent = false; + ErrorHandler.logError( + m: "${event.type} should not be used to make a PangeaMessageEvent", + ); + } + _event = event; + } + + //the timeline filters the edits and uses the original events + //so this event will always be the original and the sdk getter body + //handles getting the latest text from the aggregated events + String get body => _event.body; + + String get senderId => _event.senderId; + + DateTime get originServerTs => _event.originServerTs; + + String get eventId => _event.eventId; + + Room get room => _event.room; + + Event? _latestEditCache; + Event get _latestEdit => _latestEditCache ??= _event + .aggregatedEvents( + timeline, + RelationshipTypes.edit, + ) + //sort by event.originServerTs to get the most recent first + .sorted( + (a, b) => b.originServerTs.compareTo(a.originServerTs), + ) + .firstOrNull ?? + _event; + + bool get showRichText { + if (!_isValidPangeaMessageEvent) { + return false; + } + // if (URLFinder.getMatches(event.body).isNotEmpty) { + // return false; + // } + if ([EventStatus.error, EventStatus.sending].contains(_event.status)) { + return false; + } + if (ownMessage && !selected) return false; + + return true; + } + + List? _representations; + List get representations { + if (_representations != null) return _representations!; + + _representations = []; + + if (_latestEdit.content[ModelKey.originalSent] != null) { + try { + _representations!.add( + RepresentationEvent( + content: PangeaRepresentation.fromJson( + _latestEdit.content[ModelKey.originalSent] + as Map, + ), + tokens: _latestEdit.content[ModelKey.tokensSent] != null + ? PangeaMessageTokens.fromJson( + _latestEdit.content[ModelKey.tokensSent] + as Map, + ) + : null, + choreo: _latestEdit.content[ModelKey.choreoRecord] != null + ? ChoreoRecord.fromJson( + _latestEdit.content[ModelKey.choreoRecord] + as Map, + ) + : null, + timeline: timeline, + ), + ); + } catch (err, s) { + ErrorHandler.logError( + e: err, + s: s, + ); + } + } + + if (_latestEdit.content[ModelKey.originalWritten] != null) { + _representations!.add( + RepresentationEvent( + content: PangeaRepresentation.fromJson( + _latestEdit.content[ModelKey.originalWritten] + as Map, + ), + tokens: _latestEdit.content[ModelKey.tokensWritten] != null + ? PangeaMessageTokens.fromJson( + _latestEdit.content[ModelKey.tokensWritten] + as Map, + ) + : null, + timeline: timeline, + ), + ); + } + + _representations!.addAll( + _latestEdit + .aggregatedEvents( + timeline, + PangeaEventTypes.representation, + ) + .map( + (e) => RepresentationEvent(event: e, timeline: timeline), + ) + .sorted( + (a, b) { + //TODO - test with edited events to make sure this is working + if (a.event == null) return -1; + if (b.event == null) return 1; + return b.event!.originServerTs.compareTo(a.event!.originServerTs); + }, + ).toList(), + ); + + return _representations!; + } + + RepresentationEvent? representationByLanguage(String langCode) => + representations.firstWhereOrNull( + (element) => element.langCode == langCode, + ); + + int translationIndex(String langCode) => representations.indexWhere( + (element) => element.langCode == langCode, + ); + + String translationTextSafe(String langCode) { + return representationByLanguage(langCode)?.text ?? body; + } + + bool get isNew => + DateTime.now().difference(originServerTs.toLocal()).inSeconds < 8; + + Future _repLocal(String langCode) async { + int tries = 0; + + RepresentationEvent? rep = representationByLanguage(langCode); + + while ((isNew || eventId.contains("web")) && tries < 20) { + if (rep != null) return rep; + await Future.delayed(const Duration(milliseconds: 500)); + rep = representationByLanguage(langCode); + tries += 1; + } + return rep; + } + + Future representationByLanguageGlobal({ + required BuildContext context, + required String langCode, + }) async { + // try { + final RepresentationEvent? repLocal = await _repLocal(langCode); + + if (repLocal != null || + langCode == LanguageKeys.unknownLanguage || + langCode == LanguageKeys.mixedLanguage || + langCode == LanguageKeys.multiLanguage) return repLocal; + + if (eventId.contains("web")) return null; + + // should this just be the original event body? + // worth a conversation with the team + final PangeaRepresentation? basis = + (originalWritten ?? originalSent)?.content; + + final Event? repEvent = await MatrixState.pangeaController.messageData + .getRepresentationMatrixEvent( + context: context, + messageEventId: _latestEdit.eventId, + text: basis?.text ?? _latestEdit.body, + target: langCode, + source: basis?.langCode, + room: _latestEdit.room, + ); + + // PTODO - if res.source different from langCode, save rep for source + + return repEvent != null + ? RepresentationEvent( + event: repEvent, + timeline: timeline, + ) + : null; + // } catch (err, s) { + // debugger(when: kDebugMode); + // ErrorHandler.logError( + // e: err, + // s: s, + // ); + // return null; + // } + } + + RepresentationEvent? get originalSent => representations + .firstWhereOrNull((element) => element.content.originalSent); + + RepresentationEvent? get originalWritten => representations + .firstWhereOrNull((element) => element.content.originalWritten); + + PangeaRepresentation get defaultRepresentation => PangeaRepresentation( + langCode: LanguageKeys.unknownLanguage, + text: body, + originalSent: false, + originalWritten: false, + ); + + UseType get useType => useTypeCalculator(originalSent?.choreo); + + bool get showUseType => + !ownMessage && + _event.room.isSpaceAdmin && + _event.senderId != BotName.byEnvironment && + !room.isUserSpaceAdmin(_event.senderId) && + _event.messageType != PangeaMessageTypes.report; + + // List get activities => + //each match is turned into an activity that other students can access + //they're not told the answer but have to find it themselves + //the message has a blank piece which they fill in themselves +} + +class URLFinder { + static Iterable getMatches(String text) { + final RegExp exp = + RegExp(r'(?:(?:https?|ftp):\/\/)?[\w/\-?=%.]+\.[\w/\-?=%.]+'); + return exp.allMatches(text); + } +} diff --git a/lib/pangea/models/pangea_representation_event.dart b/lib/pangea/models/pangea_representation_event.dart new file mode 100644 index 000000000..49e0f9358 --- /dev/null +++ b/lib/pangea/models/pangea_representation_event.dart @@ -0,0 +1,161 @@ +import 'dart:developer'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + +import 'package:matrix/matrix.dart'; +import 'package:sentry_flutter/sentry_flutter.dart'; + +import 'package:fluffychat/pangea/extensions/pangea_event_extension.dart'; +import 'package:fluffychat/pangea/models/pangea_choreo_event.dart'; +import 'package:fluffychat/pangea/models/pangea_token_model.dart'; +import 'package:fluffychat/pangea/repo/tokens_repo.dart'; +import '../../widgets/matrix.dart'; +import '../constants/language_keys.dart'; +import '../constants/pangea_event_types.dart'; +import '../utils/error_handler.dart'; +import 'choreo_record.dart'; +import 'message_data_models.dart'; +import 'pangea_tokens_event.dart'; + +class RepresentationEvent { + Event? _event; + PangeaRepresentation? _content; + PangeaMessageTokens? _tokens; + ChoreoRecord? _choreo; + Timeline timeline; + + RepresentationEvent({ + required this.timeline, + Event? event, + PangeaRepresentation? content, + PangeaMessageTokens? tokens, + ChoreoRecord? choreo, + }) { + if (event != null && event.type != PangeaEventTypes.representation) { + throw Exception( + "${event.type} should not be used to make a RepresentationEvent", + ); + } + _event = event; + _content = content; + _tokens = tokens; + _choreo = choreo; + } + + Event? get event => _event; + + PangeaRepresentation get content { + if (_content != null) return _content!; + _content = _event?.getPangeaContent(); + return _content!; + } + + String get text => content.text; + + String get langCode => content.langCode; + + bool get botAuthored => + content.originalSent == false && content.originalWritten == false; + + List? get tokens { + if (_tokens != null) return _tokens!.tokens; + + if (_event == null) { + debugger(when: kDebugMode); + ErrorHandler.logError( + m: '_event and _tokens both null', + s: StackTrace.current, + ); + return null; + } + + final Set tokenEvents = + _event!.aggregatedEvents(timeline, PangeaEventTypes.tokens); + + if (tokenEvents.isEmpty) return null; + + if (tokenEvents.length > 1) { + debugger(when: kDebugMode); + Sentry.addBreadcrumb( + Breadcrumb( + message: "Token events for representation ${_event!.eventId}: " + "Content: ${tokenEvents.map((e) => e.content).toString()}" + "Type: ${tokenEvents.map((e) => e.type).toString()}", + ), + ); + ErrorHandler.logError( + m: 'should not have more than one tokenEvent per representation ${_event!.eventId}', + s: StackTrace.current, + ); + } + + _tokens = tokenEvents.first.getPangeaContent(); + + return _tokens!.tokens; + } + + Future?> tokensGlobal(BuildContext context) async { + if (tokens != null) return tokens!; + if (_event == null) { + debugger(when: kDebugMode); + ErrorHandler.logError( + m: '_event and _tokens both null', + s: StackTrace.current, + ); + return null; + } + + final Event? tokensEvent = + await MatrixState.pangeaController.messageData.getTokenEvent( + context: context, + repEventId: _event!.eventId, + room: _event!.room, + // Jordan - for just tokens, it's not clear which languages to pass + req: TokensRequestModel( + fullText: text, + userL1: + MatrixState.pangeaController.languageController.userL1?.langCode ?? + LanguageKeys.unknownLanguage, + userL2: langCode, + ), + ); + + if (tokensEvent == null) return null; + + _tokens = TokensEvent(event: tokensEvent).tokens; + + return _tokens?.tokens; + } + + ChoreoRecord? get choreo { + if (_choreo != null) return _choreo; + + if (_event == null) { + // debugger(when: kDebugMode); + ErrorHandler.logError( + m: '_event and _choreo both null', + s: StackTrace.current, + ); + return null; + } + + final Set choreoMatrixEvents = + _event!.aggregatedEvents(timeline, PangeaEventTypes.choreoRecord); + + if (choreoMatrixEvents.isEmpty) return null; + + if (choreoMatrixEvents.length > 1) { + debugger(when: kDebugMode); + ErrorHandler.logError( + m: 'should not have more than one choreoEvent per representation ${_event!.eventId}', + s: StackTrace.current, + data: _event!.toJson(), + ); + } + + _choreo = ChoreoEvent(event: choreoMatrixEvents.first).content; + + return _choreo; + } +} diff --git a/lib/pangea/models/pangea_text_tap.dart b/lib/pangea/models/pangea_text_tap.dart new file mode 100644 index 000000000..013082ce6 --- /dev/null +++ b/lib/pangea/models/pangea_text_tap.dart @@ -0,0 +1,20 @@ +class PTextTapModel { + late int cursorOffset; + late String word; + late bool isHighLighted; + late int textAtOffSet; + PTextTapModel({ + required this.cursorOffset, + required this.isHighLighted, + required this.textAtOffSet, + required this.word, + }); + toJson() { + return { + 'cursorOffset': cursorOffset, + 'word': word, + 'isHighlighted': isHighLighted, + 'textAtOffSet': textAtOffSet, + }; + } +} diff --git a/lib/pangea/models/pangea_token_model.dart b/lib/pangea/models/pangea_token_model.dart new file mode 100644 index 000000000..217cdc55b --- /dev/null +++ b/lib/pangea/models/pangea_token_model.dart @@ -0,0 +1,96 @@ +import 'dart:developer'; + +import 'package:flutter/foundation.dart'; + +import 'package:sentry_flutter/sentry_flutter.dart'; + +import '../constants/model_keys.dart'; +import '../utils/error_handler.dart'; +import 'lemma.dart'; + +class PangeaToken { + PangeaTokenText text; + bool hasInfo; + List lemmas; + + PangeaToken({ + required this.text, + required this.hasInfo, + required this.lemmas, + }); + + static getLemmas(String text, Iterable? json) { + if (json != null) { + return json + .map( + (e) => Lemma.fromJson(e as Map), + ) + .toList() + .cast(); + } else { + return [Lemma(text: text, saveVocab: false, form: text)]; + } + } + + factory PangeaToken.fromJson(Map json) { + try { + final PangeaTokenText text = + PangeaTokenText.fromJson(json[_textKey] as Map); + return PangeaToken( + text: text, + hasInfo: json[_hasInfoKey] ?? text.length > 2, + lemmas: getLemmas(text.content, json[_lemmaKey]), + ); + } catch (err, s) { + debugger(when: kDebugMode); + Sentry.addBreadcrumb( + Breadcrumb( + message: "PangeaToken.fromJson error", + data: { + "json": json, + }, + ), + ); + ErrorHandler.logError(e: err, s: s); + rethrow; + } + } + + static const String _textKey = "text"; + static const String _hasInfoKey = "has_info"; + static const String _lemmaKey = ModelKey.lemma; + + Map toJson() => { + _textKey: text, + _hasInfoKey: hasInfo, + _lemmaKey: lemmas.map((e) => e.toJson()).toList(), + }; +} + +class PangeaTokenText { + int offset; + String content; + int length; + + PangeaTokenText({ + required this.offset, + required this.content, + required this.length, + }); + + factory PangeaTokenText.fromJson(Map json) { + debugger(when: kDebugMode && json[_offsetKey] == null); + return PangeaTokenText( + offset: json[_offsetKey], + content: json[_contentKey], + length: json[_lengthKey] ?? (json[_contentKey] as String).length, + ); + } + + static const String _offsetKey = "offset"; + static const String _contentKey = "content"; + static const String _lengthKey = "length"; + + Map toJson() => + {_offsetKey: offset, _contentKey: content, _lengthKey: length}; +} diff --git a/lib/pangea/models/pangea_tokens_event.dart b/lib/pangea/models/pangea_tokens_event.dart new file mode 100644 index 000000000..244455766 --- /dev/null +++ b/lib/pangea/models/pangea_tokens_event.dart @@ -0,0 +1,31 @@ +import 'package:matrix/matrix.dart'; + +import 'package:fluffychat/pangea/extensions/pangea_event_extension.dart'; +import 'package:fluffychat/pangea/utils/error_handler.dart'; +import '../constants/pangea_event_types.dart'; +import 'message_data_models.dart'; + +class TokensEvent { + Event event; + PangeaMessageTokens? _content; + + TokensEvent({required this.event}) { + if (event.type != PangeaEventTypes.tokens) { + throw Exception( + "${event.type} should not be used to make a TokensEvent", + ); + } + } + + PangeaMessageTokens? get _pangeaMessageTokens { + try { + _content ??= event.getPangeaContent(); + return _content!; + } catch (err, s) { + ErrorHandler.logError(e: err, s: s); + return null; + } + } + + PangeaMessageTokens? get tokens => _pangeaMessageTokens; +} diff --git a/lib/pangea/models/removed_translation.dart b/lib/pangea/models/removed_translation.dart new file mode 100644 index 000000000..6887476fe --- /dev/null +++ b/lib/pangea/models/removed_translation.dart @@ -0,0 +1,6 @@ +import 'it_response_model.dart'; + +class RemovedTranslation { + List lastSelectedContinuance = []; + Continuance? removedContinuance; +} diff --git a/lib/pangea/models/span_card_model.dart b/lib/pangea/models/span_card_model.dart new file mode 100644 index 000000000..8a252e67b --- /dev/null +++ b/lib/pangea/models/span_card_model.dart @@ -0,0 +1,26 @@ +import 'package:fluffychat/pangea/choreographer/controllers/choreographer.dart'; +import 'package:fluffychat/pangea/models/pangea_match_model.dart'; + +class SpanCardModel { + // IGCTextData igcTextData; + int matchIndex; + Future Function({required int matchIndex, required int choiceIndex}) + onReplacementSelect; + Future Function(String) onSentenceRewrite; + void Function() onIgnore; + void Function() onITStart; + Choreographer choreographer; + + SpanCardModel({ + // required this.igcTextData, + required this.matchIndex, + required this.onReplacementSelect, + required this.onSentenceRewrite, + required this.onIgnore, + required this.onITStart, + required this.choreographer, + }); + + PangeaMatch? get pangeaMatch => + choreographer.igc.igcTextData?.matches[matchIndex]; +} diff --git a/lib/pangea/models/span_data.dart b/lib/pangea/models/span_data.dart new file mode 100644 index 000000000..186e2834e --- /dev/null +++ b/lib/pangea/models/span_data.dart @@ -0,0 +1,185 @@ +//Possible actions/effects from cards +// Nothing +// useType of viewed definitions +// SpanChoice of text in message from options +// Call to server for additional/followup info + +import 'package:flutter/material.dart'; + +import 'package:collection/collection.dart'; + +import '../enum/span_choice_type.dart'; +import '../enum/span_data_type.dart'; + +class SpanData { + SpanData({ + required this.message, + required this.shortMessage, + required this.choices, + required this.offset, + required this.length, + required this.context, + required this.fullText, + required this.type, + required this.rule, + }); + + factory SpanData.fromJson(Map json) { + final Iterable? choices = json['choices'] ?? json['replacements']; + return SpanData( + message: json['message'], + shortMessage: json['shortMessage'] ?? json['short_message'], + choices: choices + ?.map( + (e) => SpanChoice.fromJson(e as Map), + ) + .toList(), + offset: json['offset'] as int, + length: json['length'] as int, + context: + json['context'] != null ? Context.fromJson(json['context']) : null, + fullText: + json['sentence'] ?? json['full_text'] ?? json['fullText'] as String, + type: SpanDataType.fromJson(json['type'] as Map), + rule: json['rule'] != null + ? Rule.fromJson(json['rule'] as Map) + : null, + ); + } + + String? message; + String? shortMessage; + List? choices; + int offset; + int length; + Context? context; + String fullText; + SpanDataType type; + Rule? rule; + + Map toJson() => { + 'message': message, + 'short_message': shortMessage, + 'choices': choices != null + ? List.from(choices!.map((x) => x.toJson())) + : null, + 'offset': offset, + 'length': length, + 'context': context?.toJson(), + 'full_text': fullText, + 'type': type.toJson(), + 'rule': rule?.toJson(), + }; +} + +class Context { + Context({ + required this.text, + required this.offset, + required this.length, + }); + + factory Context.fromJson(Map json) { + return Context( + text: json['text'] as String, + offset: json['offset'] as int, + length: json['length'] as int, + ); + } + + /// full text of the message + String text; + int offset; + int length; + + Map toJson() => { + 'text': text, + 'offset': offset, + 'length': length, + }; +} + +class SpanChoice { + SpanChoice({ + required this.value, + required this.type, + this.feedback, + this.selected = false, + }); + factory SpanChoice.fromJson(Map json) { + return SpanChoice( + value: json['value'] as String, + type: json['type'] != null + ? SpanChoiceType.values.firstWhereOrNull( + (element) => element.name == json['type'], + ) ?? + SpanChoiceType.bestCorrection + : SpanChoiceType.bestCorrection, + feedback: json['feedback'], + selected: json['selected'] ?? false, + ); + } + + String value; + SpanChoiceType type; + bool selected; + String? feedback; + + Map toJson() => { + 'value': value, + 'type': type.name, + 'selected': selected, + 'feedback': feedback, + }; + + String feedbackToDisplay(BuildContext context) { + if (feedback == null) { + return type.defaultFeedback(context); + } + return feedback!; + } + + bool get isDistractor => type == SpanChoiceType.distractor; + + bool get isBestCorrection => type == SpanChoiceType.bestCorrection; + + Color get color => type.color; +} + +class Rule { + Rule({ + required this.id, + }); + factory Rule.fromJson(Map json) => Rule( + id: json['id'] as String, + ); + + String id; + + Map toJson() => { + 'id': id, + }; +} + +class SpanDataType { + SpanDataType({ + required this.typeName, + }); + + factory SpanDataType.fromJson(Map json) { + final String? type = + json['typeName'] ?? json['type'] ?? json['type_name'] as String?; + return SpanDataType( + typeName: type != null + ? SpanDataTypeEnum.values + .firstWhereOrNull((element) => element.name == type) ?? + SpanDataTypeEnum.correction + : SpanDataTypeEnum.correction, + ); + } + SpanDataTypeEnum typeName; + + Map toJson() => { + 'type_name': typeName.name, + }; +} diff --git a/lib/pangea/models/student_analytics_event.dart b/lib/pangea/models/student_analytics_event.dart new file mode 100644 index 000000000..738014bb8 --- /dev/null +++ b/lib/pangea/models/student_analytics_event.dart @@ -0,0 +1,133 @@ +import 'dart:developer'; + +import 'package:flutter/foundation.dart'; + +import 'package:matrix/matrix.dart'; + +import 'package:fluffychat/pangea/constants/class_default_values.dart'; +import 'package:fluffychat/pangea/models/student_analytics_summary_model.dart'; +import 'package:fluffychat/pangea/utils/error_handler.dart'; +import '../constants/pangea_event_types.dart'; +import 'chart_analytics_model.dart'; + +class StudentAnalyticsEvent { + late Event _event; + StudentAnalyticsSummary? _contentCache; + List _messagesToSave = []; + + StudentAnalyticsEvent({required Event event}) { + if (event.type != PangeaEventTypes.studentAnalyticsSummary) { + throw Exception( + "${event.type} should not be used to make a StudentAnalyticsEvent", + ); + } + _event = event; + if (!classRoom.isSpace) { + throw Exception( + "non-class room should not be used to make a StudentAnalyticsEvent", + ); + } + _event = event; + + _messagesToSave = []; + } + + Room get classRoom => _event.room; + + Event get event => _event; + + StudentAnalyticsSummary get content { + _contentCache ??= StudentAnalyticsSummary.fromJson(event.content); + return _contentCache!; + } + + Future handleNewMessage(RecentMessageRecord message) async { + debugPrint("handle new message"); + if (classRoom.client.userID != _event.stateKey) { + debugger(when: kDebugMode); + ErrorHandler.logError( + m: "should not be in handleNewMessage ${classRoom.client.userID} != ${_event.stateKey}", + ); + return; + } + _addMessage(message); + + if (DateTime.now().difference(content.lastUpdated).inMinutes > + ClassDefaultValues.minutesDelayToUpdateMyAnalytics) { + _updateStudentAnalytics(); + } + } + + Future bulkUpdate(List messages) async { + if (classRoom.client.userID != _event.stateKey) { + debugger(when: kDebugMode); + ErrorHandler.logError( + m: "should not be in bulkUpdate ${classRoom.client.userID} != ${_event.stateKey}", + ); + return; + } + _messagesToSave.addAll(messages); + _updateStudentAnalytics(); + } + + Future _updateStudentAnalytics() async { + content.lastUpdated = DateTime.now(); + content.addAll(_messagesToSave); + debugPrint("updating student analytics"); + _clearMessages(); + await classRoom.client.setRoomStateWithKey( + classRoom.id, + _event.type, + _event.stateKey!, + content.toJson(), + ); + } + + _addMessage(RecentMessageRecord message) { + if (_messagesToSave.every((e) => e.eventId != message.eventId)) { + _messagesToSave.add(message); + } else { + debugger(when: kDebugMode); + ErrorHandler.logError( + m: "adding message twice in StudentAnalyticsEvent._addMessage", + ); + } + //PTODO - save to local storagge + } + + _clearMessages() { + _messagesToSave.clear(); + //PTODO - clear local storagge + } + + Future getTotals(String? chatId) async { + final TimeSeriesTotals totals = TimeSeriesTotals.empty; + final msgs = chatId == null + ? content.messages + : content.messages.where((msg) => msg.chatId == chatId); + for (final msg in msgs) { + totals.increment(msg); + } + return totals; + } + + Future getTimeServiesInterval( + DateTime start, + DateTime end, + String? chatId, + ) async { + final TimeSeriesInterval interval = TimeSeriesInterval( + start: start, + end: end, + totals: TimeSeriesTotals.empty, + ); + for (final msg in content.messages) { + if (msg.time.isAfter(start) && + msg.time.isBefore(end) && + (chatId == null || chatId == msg.chatId)) { + interval.totals.increment(msg); + } + } + return interval; + } +} diff --git a/lib/pangea/models/student_analytics_event_old.dart b/lib/pangea/models/student_analytics_event_old.dart new file mode 100644 index 000000000..d2696eb01 --- /dev/null +++ b/lib/pangea/models/student_analytics_event_old.dart @@ -0,0 +1,51 @@ +// import 'package:fluffychat/pangea/extensions/pangea_event_extension.dart'; +// import 'package:fluffychat/pangea/models/analytics_model_older.dart'; +// import 'package:matrix/matrix.dart'; + +// import '../constants/pangea_event_types.dart'; + +// class StudentAnalyticsEvent { +// late Event _event; +// StudentAnalyticsSummary? _contentCache; + +// StudentAnalyticsEvent({required Event event}) { +// if (event.type != PangeaEventTypes.studentAnalyticsSummary) { +// throw Exception( +// "${event.type} should not be used to make a StudentAnalyticsEvent", +// ); +// } +// _event = event; +// } + +// Event get event => _event; + +// StudentAnalyticsSummary get _content { +// _contentCache ??= event.getPangeaContent(); +// return _contentCache!; +// } + +// List get monthly => _content.monthlyTotalsForAllTime; +// List get daily => _content.dailyTotalsForLast30Days; +// List get hourly => _content.hourlyTotalsForLast24Hours; + +// // updateLocal +// // updateServer +// handleNewMessage() {} + +// /// if monthly.isNotEmpty && last.end.month < now.month +// /// push empty intervals until last.end.month >= now.month +// /// if daily.isEmpty +// /// push empty intervals until last.end.day >= now.day +// /// else if daily.where(e => e.month < now.month) +// /// sum and add to monthly +// /// +// /// if hourly.isEmpty || last.end.hour < now.hour +// /// push empty intervals until last.end.hour >= now.hour +// /// increment hourly + +// updateLocal() {} + +// // if server copy is older than x, push local version +// // get new server copy, local version = server copy +// updateServer() {} +// } diff --git a/lib/pangea/models/student_analytics_summary_model.dart b/lib/pangea/models/student_analytics_summary_model.dart new file mode 100644 index 000000000..682768b28 --- /dev/null +++ b/lib/pangea/models/student_analytics_summary_model.dart @@ -0,0 +1,109 @@ +import 'dart:convert'; + +import 'package:flutter/foundation.dart'; + +import 'package:fluffychat/pangea/utils/error_handler.dart'; +import '../enum/use_type.dart'; + +class RecentMessageRecord { + String eventId; + String chatId; + UseType useType; + DateTime time; + + RecentMessageRecord({ + required this.eventId, + required this.chatId, + required this.useType, + required this.time, + }); + + factory RecentMessageRecord.fromJson(Map json) => + RecentMessageRecord( + eventId: json[_eventIdKey], + chatId: json[_chatIdKey], + useType: _typeStringToEnum(json[_typeOfUseKey]), + time: DateTime.parse(json[_timeKey]), + ); + + Map toJson() => { + _eventIdKey: eventId, + _chatIdKey: chatId, + _typeOfUseKey: _typeEnumToString(useType), + _timeKey: time.toIso8601String(), + }; + + String _typeEnumToString(dynamic status) => status.toString().split('.').last; + + static UseType _typeStringToEnum(String useType) { + final String lastPart = useType.toString().split('.').last; + switch (lastPart) { + case 'ta': + return UseType.ta; + case 'ga': + return UseType.ga; + case 'wa': + return UseType.wa; + default: + return UseType.un; + } + } + + static const _eventIdKey = "m.id"; + static const _chatIdKey = "c.id"; + static const _typeOfUseKey = "typ"; + static const _timeKey = "t"; +} + +class StudentAnalyticsSummary { + late List _messages; + DateTime lastUpdated; + + StudentAnalyticsSummary({ + required List messages, + required this.lastUpdated, + }) { + _messages = messages; + } + + void addAll(List msgs) { + for (final msg in msgs) { + if (_messages.any((element) => element.eventId == msg.eventId)) { + ErrorHandler.logError( + m: "adding message twice in StudentAnalyticsSummary.add", + ); + } else { + _messages.add(msg); + } + } + } + + List get messages => _messages; + + static const _messagesKey = "msgs"; + static const _lastUpdatedKey = "lupt"; + + Map toJson() => { + _messagesKey: jsonEncode(_messages.map((e) => e.toJson()).toList()), + _lastUpdatedKey: lastUpdated.toIso8601String(), + }; + + factory StudentAnalyticsSummary.fromJson(json) { + List savedMessages = []; + try { + savedMessages = json[_messagesKey] != null + ? (jsonDecode(json[_messagesKey] ?? "[]") as Iterable) + .map((e) => RecentMessageRecord.fromJson(e)) + .toList() + .cast() + : []; + } catch (err, stack) { + if (kDebugMode) rethrow; + ErrorHandler.logError(e: err, s: stack); + } + return StudentAnalyticsSummary( + messages: savedMessages, + lastUpdated: DateTime.parse(json[_lastUpdatedKey]), + ); + } +} diff --git a/lib/pangea/models/system_choice_translation_model.dart b/lib/pangea/models/system_choice_translation_model.dart new file mode 100644 index 000000000..6914044d3 --- /dev/null +++ b/lib/pangea/models/system_choice_translation_model.dart @@ -0,0 +1,45 @@ +import '../constants/model_keys.dart'; + +class SystemChoiceRequestModel { + String translationId; + int? nextWordIndex; + String? customInput; + String userId; + String roomId; + String targetLangCode; + String sourceLangCode; + String? classId; + + SystemChoiceRequestModel({ + required this.translationId, + this.nextWordIndex, + this.customInput, + required this.userId, + required this.roomId, + required this.targetLangCode, + required this.sourceLangCode, + this.classId, + }); + + toJson() => { + 'translation_id': translationId, + 'next_word_index': nextWordIndex, + 'custom_input': customInput, + 'user_id': userId, + 'room_id': roomId, + ModelKey.tgtLang: targetLangCode, + ModelKey.srcLang: sourceLangCode, + 'class_id': classId, + }; + + factory SystemChoiceRequestModel.fromJson(json) => SystemChoiceRequestModel( + translationId: json['translation_id'], + nextWordIndex: json['next_word_index'], + customInput: json['custom_input'], + userId: json['user_id'], + roomId: json['room_id'], + targetLangCode: json[ModelKey.tgtLang], + sourceLangCode: json[ModelKey.srcLang], + classId: json['class_id'], + ); +} diff --git a/lib/pangea/models/textChangeModel.dart b/lib/pangea/models/textChangeModel.dart new file mode 100644 index 000000000..38a988df8 --- /dev/null +++ b/lib/pangea/models/textChangeModel.dart @@ -0,0 +1,11 @@ +import '../enum/direction.dart'; +import '../enum/edit_type.dart'; + +class TextChangeModel { + EditType? editType; + EditDirection? editDirection; + String? text; + + toJson() => + {'editType': editType, 'editDirection': editDirection, 'text': text}; +} diff --git a/lib/pangea/models/user_model.dart b/lib/pangea/models/user_model.dart new file mode 100644 index 000000000..cd8fa3aac --- /dev/null +++ b/lib/pangea/models/user_model.dart @@ -0,0 +1,609 @@ +import 'dart:convert'; + +import 'package:flutter/material.dart'; + +import 'package:country_picker/country_picker.dart'; +import 'package:flutter_gen/gen_l10n/l10n.dart'; + +import 'package:fluffychat/pangea/constants/model_keys.dart'; +import '../constants/language_keys.dart'; +import 'language_model.dart'; + +PUserModel pUserModelFromJson(String str) => + PUserModel.fromJson(json.decode(str)); + +String pUserModelToJson(PUserModel data) => json.encode(data.toJson()); + +class PUserModel { + String access; + String refresh; + Profile? profile; + + PUserModel({required this.access, required this.refresh, this.profile}); + + factory PUserModel.fromJson(Map json) => PUserModel( + access: json[ModelKey.userAccess], + refresh: json[ModelKey.userRefresh], + profile: json[ModelKey.userProfile] != null + ? Profile.fromJson(json[ModelKey.userProfile]) + : null, + ); + + Map toJson() { + final Map data = {}; + data[ModelKey.userAccess] = access; + data[ModelKey.userRefresh] = refresh; + if (profile != null) { + data[ModelKey.userProfile] = profile!.toJson(); + } + return data; + } +} + +class Profile { + // i'm considering removing this field because it's duplicating info in the + // matrix database + // String? fullName; + final String createdAt; + final String pangeaUserId; + String? dateOfBirth; + String? targetLanguage; + String? sourceLanguage; + + String? country; + bool publicProfile; + + Profile({ + // this.fullName, + required this.createdAt, + required this.pangeaUserId, + this.dateOfBirth, + this.targetLanguage, + this.sourceLanguage, + this.country, + this.publicProfile = false, + }); + + factory Profile.fromJson(Map json) { + final l2 = LanguageModel.codeFromNameOrCode( + json[ModelKey.l2LanguageKey] ?? LanguageKeys.unknownLanguage, + ); + final l1 = LanguageModel.codeFromNameOrCode( + json[ModelKey.l1LanguageKey] ?? LanguageKeys.unknownLanguage, + ); + + return Profile( + // fullName: json[ModelKey.userFullName], + createdAt: json[ModelKey.userCreatedAt], + pangeaUserId: json[ModelKey.userPangeaUserId], + dateOfBirth: json[ModelKey.userDateOfBirth], + targetLanguage: l2, + sourceLanguage: l1, + publicProfile: json[ModelKey.publicProfile] ?? false, + country: json[ModelKey.userCountry], + ); + } + + Map toJson() { + final Map data = {}; + // data[ModelKey.userFullName] = fullName; + data[ModelKey.userCreatedAt] = createdAt; + data[ModelKey.userPangeaUserId] = pangeaUserId; + data[ModelKey.userDateOfBirth] = dateOfBirth; + data[ModelKey.l2LanguageKey] = targetLanguage; + data[ModelKey.l1LanguageKey] = sourceLanguage; + data[ModelKey.publicProfile] = publicProfile; + data[ModelKey.userCountry] = country; + return data; + } + + /// used in find a partner page for display partner's country + String get flagEmoji { + final String? countryName = this.country?.split(' (')[0]; + final Country? country = CountryService().findByName(countryName); + return country?.flagEmoji ?? ""; + } + + String? countryDisplayName(BuildContext context) { + final String? countryName = this.country?.split(' (')[0]; + final Country? country = CountryService().findByName(countryName); + if (country?.countryCode == null) return null; + switch (country!.countryCode) { + case 'WW': + return L10n.of(context)!.wwCountryDisplayName; + case 'AF': + return L10n.of(context)!.afCountryDisplayName; + case 'AX': + return L10n.of(context)!.axCountryDisplayName; + case 'AL': + return L10n.of(context)!.alCountryDisplayName; + case 'DZ': + return L10n.of(context)!.dzCountryDisplayName; + case 'AS': + return L10n.of(context)!.asCountryDisplayName; + case 'AD': + return L10n.of(context)!.adCountryDisplayName; + case 'AO': + return L10n.of(context)!.aoCountryDisplayName; + case 'AI': + return L10n.of(context)!.aiCountryDisplayName; + case 'AG': + return L10n.of(context)!.agCountryDisplayName; + case 'AR': + return L10n.of(context)!.arCountryDisplayName; + case 'AM': + return L10n.of(context)!.amCountryDisplayName; + case 'AW': + return L10n.of(context)!.awCountryDisplayName; + case 'AC': + return L10n.of(context)!.acCountryDisplayName; + case 'AU': + return L10n.of(context)!.auCountryDisplayName; + case 'AT': + return L10n.of(context)!.atCountryDisplayName; + case 'AZ': + return L10n.of(context)!.azCountryDisplayName; + case 'BS': + return L10n.of(context)!.bsCountryDisplayName; + case 'BH': + return L10n.of(context)!.bhCountryDisplayName; + case 'BD': + return L10n.of(context)!.bdCountryDisplayName; + case 'BB': + return L10n.of(context)!.bbCountryDisplayName; + case 'BY': + return L10n.of(context)!.byCountryDisplayName; + case 'BE': + return L10n.of(context)!.beCountryDisplayName; + case 'BZ': + return L10n.of(context)!.bzCountryDisplayName; + case 'BJ': + return L10n.of(context)!.bjCountryDisplayName; + case 'BM': + return L10n.of(context)!.bmCountryDisplayName; + case 'BT': + return L10n.of(context)!.btCountryDisplayName; + case 'BO': + return L10n.of(context)!.boCountryDisplayName; + case 'BA': + return L10n.of(context)!.baCountryDisplayName; + case 'BW': + return L10n.of(context)!.bwCountryDisplayName; + case 'BR': + return L10n.of(context)!.brCountryDisplayName; + case 'IO': + return L10n.of(context)!.ioCountryDisplayName; + case 'VG': + return L10n.of(context)!.vgCountryDisplayName; + case 'BN': + return L10n.of(context)!.bnCountryDisplayName; + case 'BG': + return L10n.of(context)!.bgCountryDisplayName; + case 'BF': + return L10n.of(context)!.bfCountryDisplayName; + case 'BI': + return L10n.of(context)!.biCountryDisplayName; + case 'KH': + return L10n.of(context)!.khCountryDisplayName; + case 'CM': + return L10n.of(context)!.cmCountryDisplayName; + case 'CA': + return L10n.of(context)!.caCountryDisplayName; + case 'CV': + return L10n.of(context)!.cvCountryDisplayName; + case 'BQ': + return L10n.of(context)!.bqCountryDisplayName; + case 'KY': + return L10n.of(context)!.kyCountryDisplayName; + case 'CF': + return L10n.of(context)!.cfCountryDisplayName; + case 'TD': + return L10n.of(context)!.tdCountryDisplayName; + case 'CL': + return L10n.of(context)!.clCountryDisplayName; + case 'CN': + return L10n.of(context)!.cnCountryDisplayName; + case 'CX': + return L10n.of(context)!.cxCountryDisplayName; + case 'CC': + return L10n.of(context)!.ccCountryDisplayName; + case 'CO': + return L10n.of(context)!.coCountryDisplayName; + case 'KM': + return L10n.of(context)!.kmCountryDisplayName; + case 'CD': + return L10n.of(context)!.cdCountryDisplayName; + case 'CG': + return L10n.of(context)!.cgCountryDisplayName; + case 'CK': + return L10n.of(context)!.ckCountryDisplayName; + case 'CR': + return L10n.of(context)!.crCountryDisplayName; + case 'CI': + return L10n.of(context)!.ciCountryDisplayName; + case 'HR': + return L10n.of(context)!.hrCountryDisplayName; + case 'CU': + return L10n.of(context)!.cuCountryDisplayName; + case 'CW': + return L10n.of(context)!.cwCountryDisplayName; + case 'CY': + return L10n.of(context)!.cyCountryDisplayName; + case 'CZ': + return L10n.of(context)!.czCountryDisplayName; + case 'DK': + return L10n.of(context)!.dkCountryDisplayName; + case 'DJ': + return L10n.of(context)!.djCountryDisplayName; + case 'DM': + return L10n.of(context)!.dmCountryDisplayName; + case 'DO': + return L10n.of(context)!.doCountryDisplayName; + case 'TL': + return L10n.of(context)!.tlCountryDisplayName; + case 'EC': + return L10n.of(context)!.ecCountryDisplayName; + case 'EG': + return L10n.of(context)!.egCountryDisplayName; + case 'SV': + return L10n.of(context)!.svCountryDisplayName; + case 'GQ': + return L10n.of(context)!.gqCountryDisplayName; + case 'ER': + return L10n.of(context)!.erCountryDisplayName; + case 'EE': + return L10n.of(context)!.eeCountryDisplayName; + case 'SZ': + return L10n.of(context)!.szCountryDisplayName; + case 'ET': + return L10n.of(context)!.etCountryDisplayName; + case 'FK': + return L10n.of(context)!.fkCountryDisplayName; + case 'FO': + return L10n.of(context)!.foCountryDisplayName; + case 'FJ': + return L10n.of(context)!.fjCountryDisplayName; + case 'FI': + return L10n.of(context)!.fiCountryDisplayName; + case 'FR': + return L10n.of(context)!.frCountryDisplayName; + case 'GF': + return L10n.of(context)!.gfCountryDisplayName; + case 'PF': + return L10n.of(context)!.pfCountryDisplayName; + case 'GA': + return L10n.of(context)!.gaCountryDisplayName; + case 'GM': + return L10n.of(context)!.gmCountryDisplayName; + case 'GE': + return L10n.of(context)!.geCountryDisplayName; + case 'DE': + return L10n.of(context)!.deCountryDisplayName; + case 'GH': + return L10n.of(context)!.ghCountryDisplayName; + case 'GI': + return L10n.of(context)!.giCountryDisplayName; + case 'GR': + return L10n.of(context)!.grCountryDisplayName; + case 'GL': + return L10n.of(context)!.glCountryDisplayName; + case 'GD': + return L10n.of(context)!.gdCountryDisplayName; + case 'GP': + return L10n.of(context)!.gpCountryDisplayName; + case 'GU': + return L10n.of(context)!.guCountryDisplayName; + case 'GT': + return L10n.of(context)!.gtCountryDisplayName; + case 'GG': + return L10n.of(context)!.ggCountryDisplayName; + case 'GN': + return L10n.of(context)!.gnCountryDisplayName; + case 'GW': + return L10n.of(context)!.gwCountryDisplayName; + case 'GY': + return L10n.of(context)!.gyCountryDisplayName; + case 'HT': + return L10n.of(context)!.htCountryDisplayName; + case 'HM': + return L10n.of(context)!.hmCountryDisplayName; + case 'HN': + return L10n.of(context)!.hnCountryDisplayName; + case 'HK': + return L10n.of(context)!.hkCountryDisplayName; + case 'HU': + return L10n.of(context)!.huCountryDisplayName; + case 'IS': + return L10n.of(context)!.isCountryDisplayName; + case 'IN': + return L10n.of(context)!.inCountryDisplayName; + case 'ID': + return L10n.of(context)!.idCountryDisplayName; + case 'IR': + return L10n.of(context)!.irCountryDisplayName; + case 'IQ': + return L10n.of(context)!.iqCountryDisplayName; + case 'IE': + return L10n.of(context)!.ieCountryDisplayName; + case 'IM': + return L10n.of(context)!.imCountryDisplayName; + case 'IL': + return L10n.of(context)!.ilCountryDisplayName; + case 'IT': + return L10n.of(context)!.itCountryDisplayName; + case 'JM': + return L10n.of(context)!.jmCountryDisplayName; + case 'JP': + return L10n.of(context)!.jpCountryDisplayName; + case 'JE': + return L10n.of(context)!.jeCountryDisplayName; + case 'JO': + return L10n.of(context)!.joCountryDisplayName; + case 'KZ': + return L10n.of(context)!.kzCountryDisplayName; + case 'KE': + return L10n.of(context)!.keCountryDisplayName; + case 'KI': + return L10n.of(context)!.kiCountryDisplayName; + case 'XK': + return L10n.of(context)!.xkCountryDisplayName; + case 'KW': + return L10n.of(context)!.kwCountryDisplayName; + case 'KG': + return L10n.of(context)!.kgCountryDisplayName; + case 'LA': + return L10n.of(context)!.laCountryDisplayName; + case 'LV': + return L10n.of(context)!.lvCountryDisplayName; + case 'LB': + return L10n.of(context)!.lbCountryDisplayName; + case 'LS': + return L10n.of(context)!.lsCountryDisplayName; + case 'LR': + return L10n.of(context)!.lrCountryDisplayName; + case 'LY': + return L10n.of(context)!.lyCountryDisplayName; + case 'LI': + return L10n.of(context)!.liCountryDisplayName; + case 'LT': + return L10n.of(context)!.ltCountryDisplayName; + case 'LU': + return L10n.of(context)!.luCountryDisplayName; + case 'MO': + return L10n.of(context)!.moCountryDisplayName; + case 'MK': + return L10n.of(context)!.mkCountryDisplayName; + case 'MG': + return L10n.of(context)!.mgCountryDisplayName; + case 'MW': + return L10n.of(context)!.mwCountryDisplayName; + case 'MY': + return L10n.of(context)!.myCountryDisplayName; + case 'MV': + return L10n.of(context)!.mvCountryDisplayName; + case 'ML': + return L10n.of(context)!.mlCountryDisplayName; + case 'MT': + return L10n.of(context)!.mtCountryDisplayName; + case 'MH': + return L10n.of(context)!.mhCountryDisplayName; + case 'MQ': + return L10n.of(context)!.mqCountryDisplayName; + case 'MR': + return L10n.of(context)!.mrCountryDisplayName; + case 'MU': + return L10n.of(context)!.muCountryDisplayName; + case 'YT': + return L10n.of(context)!.ytCountryDisplayName; + case 'MX': + return L10n.of(context)!.mxCountryDisplayName; + case 'FM': + return L10n.of(context)!.fmCountryDisplayName; + case 'MD': + return L10n.of(context)!.mdCountryDisplayName; + case 'MC': + return L10n.of(context)!.mcCountryDisplayName; + case 'MN': + return L10n.of(context)!.mnCountryDisplayName; + case 'ME': + return L10n.of(context)!.meCountryDisplayName; + case 'MS': + return L10n.of(context)!.msCountryDisplayName; + case 'MA': + return L10n.of(context)!.maCountryDisplayName; + case 'MZ': + return L10n.of(context)!.mzCountryDisplayName; + case 'MM': + return L10n.of(context)!.mmCountryDisplayName; + case 'NA': + return L10n.of(context)!.naCountryDisplayName; + case 'NR': + return L10n.of(context)!.nrCountryDisplayName; + case 'NP': + return L10n.of(context)!.npCountryDisplayName; + case 'NL': + return L10n.of(context)!.nlCountryDisplayName; + case 'NC': + return L10n.of(context)!.ncCountryDisplayName; + case 'NZ': + return L10n.of(context)!.nzCountryDisplayName; + case 'NI': + return L10n.of(context)!.niCountryDisplayName; + case 'NE': + return L10n.of(context)!.neCountryDisplayName; + case 'NG': + return L10n.of(context)!.ngCountryDisplayName; + case 'NU': + return L10n.of(context)!.nuCountryDisplayName; + case 'NF': + return L10n.of(context)!.nfCountryDisplayName; + case 'KP': + return L10n.of(context)!.kpCountryDisplayName; + case 'MP': + return L10n.of(context)!.mpCountryDisplayName; + case 'NO': + return L10n.of(context)!.noCountryDisplayName; + case 'OM': + return L10n.of(context)!.omCountryDisplayName; + case 'PK': + return L10n.of(context)!.pkCountryDisplayName; + case 'PW': + return L10n.of(context)!.pwCountryDisplayName; + case 'PS': + return L10n.of(context)!.psCountryDisplayName; + case 'PA': + return L10n.of(context)!.paCountryDisplayName; + case 'PG': + return L10n.of(context)!.pgCountryDisplayName; + case 'PY': + return L10n.of(context)!.pyCountryDisplayName; + case 'PE': + return L10n.of(context)!.peCountryDisplayName; + case 'PH': + return L10n.of(context)!.phCountryDisplayName; + case 'PL': + return L10n.of(context)!.plCountryDisplayName; + case 'PT': + return L10n.of(context)!.ptCountryDisplayName; + case 'PR': + return L10n.of(context)!.prCountryDisplayName; + case 'QA': + return L10n.of(context)!.qaCountryDisplayName; + case 'RE': + return L10n.of(context)!.reCountryDisplayName; + case 'RO': + return L10n.of(context)!.roCountryDisplayName; + case 'RU': + return L10n.of(context)!.ruCountryDisplayName; + case 'RW': + return L10n.of(context)!.rwCountryDisplayName; + case 'BL': + return L10n.of(context)!.blCountryDisplayName; + case 'SH': + return L10n.of(context)!.shCountryDisplayName; + case 'KN': + return L10n.of(context)!.knCountryDisplayName; + case 'LC': + return L10n.of(context)!.lcCountryDisplayName; + case 'MF': + return L10n.of(context)!.mfCountryDisplayName; + case 'PM': + return L10n.of(context)!.pmCountryDisplayName; + case 'VC': + return L10n.of(context)!.vcCountryDisplayName; + case 'WS': + return L10n.of(context)!.wsCountryDisplayName; + case 'SM': + return L10n.of(context)!.smCountryDisplayName; + case 'ST': + return L10n.of(context)!.stCountryDisplayName; + case 'SA': + return L10n.of(context)!.saCountryDisplayName; + case 'SN': + return L10n.of(context)!.snCountryDisplayName; + case 'RS': + return L10n.of(context)!.rsCountryDisplayName; + case 'SC': + return L10n.of(context)!.scCountryDisplayName; + case 'SL': + return L10n.of(context)!.slCountryDisplayName; + case 'SG': + return L10n.of(context)!.sgCountryDisplayName; + case 'SX': + return L10n.of(context)!.sxCountryDisplayName; + case 'SK': + return L10n.of(context)!.skCountryDisplayName; + case 'SI': + return L10n.of(context)!.siCountryDisplayName; + case 'SB': + return L10n.of(context)!.sbCountryDisplayName; + case 'SO': + return L10n.of(context)!.soCountryDisplayName; + case 'ZA': + return L10n.of(context)!.zaCountryDisplayName; + case 'GS': + return L10n.of(context)!.gsCountryDisplayName; + case 'KR': + return L10n.of(context)!.krCountryDisplayName; + case 'SS': + return L10n.of(context)!.ssCountryDisplayName; + case 'ES': + return L10n.of(context)!.esCountryDisplayName; + case 'LK': + return L10n.of(context)!.lkCountryDisplayName; + case 'SD': + return L10n.of(context)!.sdCountryDisplayName; + case 'SR': + return L10n.of(context)!.srCountryDisplayName; + case 'SJ': + return L10n.of(context)!.sjCountryDisplayName; + case 'SE': + return L10n.of(context)!.seCountryDisplayName; + case 'CH': + return L10n.of(context)!.chCountryDisplayName; + case 'SY': + return L10n.of(context)!.syCountryDisplayName; + case 'TW': + return L10n.of(context)!.twCountryDisplayName; + case 'TJ': + return L10n.of(context)!.tjCountryDisplayName; + case 'TZ': + return L10n.of(context)!.tzCountryDisplayName; + case 'TH': + return L10n.of(context)!.thCountryDisplayName; + case 'TG': + return L10n.of(context)!.tgCountryDisplayName; + case 'TK': + return L10n.of(context)!.tkCountryDisplayName; + case 'TO': + return L10n.of(context)!.toCountryDisplayName; + case 'TT': + return L10n.of(context)!.ttCountryDisplayName; + case 'TN': + return L10n.of(context)!.tnCountryDisplayName; + case 'TR': + return L10n.of(context)!.trCountryDisplayName; + case 'TM': + return L10n.of(context)!.tmCountryDisplayName; + case 'TC': + return L10n.of(context)!.tcCountryDisplayName; + case 'TV': + return L10n.of(context)!.tvCountryDisplayName; + case 'VI': + return L10n.of(context)!.viCountryDisplayName; + case 'UG': + return L10n.of(context)!.ugCountryDisplayName; + case 'UA': + return L10n.of(context)!.uaCountryDisplayName; + case 'AE': + return L10n.of(context)!.aeCountryDisplayName; + case 'GB': + return L10n.of(context)!.gbCountryDisplayName; + case 'US': + return L10n.of(context)!.usCountryDisplayName; + case 'UY': + return L10n.of(context)!.uyCountryDisplayName; + case 'UZ': + return L10n.of(context)!.uzCountryDisplayName; + case 'VU': + return L10n.of(context)!.vuCountryDisplayName; + case 'VA': + return L10n.of(context)!.vaCountryDisplayName; + case 'VE': + return L10n.of(context)!.veCountryDisplayName; + case 'VN': + return L10n.of(context)!.vnCountryDisplayName; + case 'WF': + return L10n.of(context)!.wfCountryDisplayName; + case 'EH': + return L10n.of(context)!.ehCountryDisplayName; + case 'YE': + return L10n.of(context)!.yeCountryDisplayName; + case 'ZM': + return L10n.of(context)!.zmCountryDisplayName; + case 'ZW': + return L10n.of(context)!.zwCountryDisplayName; + } + return null; + } +} diff --git a/lib/pangea/models/user_profile_search_model.dart b/lib/pangea/models/user_profile_search_model.dart new file mode 100644 index 000000000..de8822b04 --- /dev/null +++ b/lib/pangea/models/user_profile_search_model.dart @@ -0,0 +1,27 @@ +import 'user_model.dart'; + +class UserProfileSearchResponse { + int count; + String? next; + String? previous; + List results; + + UserProfileSearchResponse({ + required this.count, + required this.next, + required this.previous, + required this.results, + }); + + factory UserProfileSearchResponse.fromJson(Map json) { + return UserProfileSearchResponse( + count: json["count"], + next: json["next"], + previous: json["previous"], + results: json["results"] + .map((p) => Profile.fromJson(p)) + .toList() + .cast(), + ); + } +} diff --git a/lib/pangea/models/web_subscriptions.dart b/lib/pangea/models/web_subscriptions.dart new file mode 100644 index 000000000..788465916 --- /dev/null +++ b/lib/pangea/models/web_subscriptions.dart @@ -0,0 +1,59 @@ +import 'package:sentry_flutter/sentry_flutter.dart'; + +import 'package:fluffychat/pangea/controllers/subscription_controller.dart'; +import 'package:fluffychat/pangea/models/base_subscription_info.dart'; +import 'package:fluffychat/pangea/repo/subscription_repo.dart'; + +class WebSubscriptionInfo extends SubscriptionInfo { + WebSubscriptionInfo({required super.pangeaController}) : super(); + + @override + Future configure() async { + await setAppIds(); + await setAllProducts(); + await setCustomerInfo(); + availableSubscriptions = allProducts! + .where((product) => product.appId == appIds!.currentAppId) + .toList(); + availableSubscriptions.sort((a, b) => a.price.compareTo(b.price)); + //@Gabby - temporary solution to add trial to list + if (currentSubscriptionId == null && !hasSubscribed) { + final id = availableSubscriptions[0].id; + final package = availableSubscriptions[0].package; + final duration = availableSubscriptions[0].duration; + availableSubscriptions.insert( + 0, + SubscriptionDetails( + price: 0, + id: id, + duration: duration, + package: package, + periodType: 'trial', + ), + ); + } + } + + @override + Future setCustomerInfo() async { + if (currentSubscriptionId != null && currentSubscription != null) { + return; + } + final RCSubscriptionResponseModel currentSubscriptionInfo = + await SubscriptionRepo.getCurrentSubscriptionInfo( + pangeaController.matrixState.client.userID, + allProducts, + ); + + currentSubscriptionId = currentSubscriptionInfo.currentSubscriptionId; + currentSubscription = currentSubscriptionInfo.currentSubscription; + allEntitlements = currentSubscriptionInfo.allEntitlements ?? []; + expirationDate = currentSubscriptionInfo.expirationDate; + + if (currentSubscriptionId != null && currentSubscription == null) { + Sentry.addBreadcrumb( + Breadcrumb(message: "mismatch of productIds and currentSubscriptionID"), + ); + } + } +} diff --git a/lib/pangea/models/widget_measurement.dart b/lib/pangea/models/widget_measurement.dart new file mode 100644 index 000000000..7229c219a --- /dev/null +++ b/lib/pangea/models/widget_measurement.dart @@ -0,0 +1,29 @@ +import 'package:flutter/material.dart'; + +class WidgetMeasurements { + static final Map _fromKey = {}; + static dispose() => _fromKey.clear(); + static WidgetMeasurements defaultFromKey(String key) { + if (_fromKey[key] == null) { + _fromKey[key] = WidgetMeasurements( + position: const Offset(0, 0), + size: const Size(0, 0), + uid: key, + ); + } + + final WidgetMeasurements? weg = _fromKey[key]; + return _fromKey[key]!; + } + + Offset? position; + Size? size; + String? uid; + WidgetMeasurements({ + required this.position, + required this.size, + required this.uid, + }); + + toJson() => {'position': position, 'size': size, 'uid': uid}; +} diff --git a/lib/pangea/models/word_data_model.dart b/lib/pangea/models/word_data_model.dart new file mode 100644 index 000000000..838240725 --- /dev/null +++ b/lib/pangea/models/word_data_model.dart @@ -0,0 +1,201 @@ +import 'dart:developer'; + +import 'package:flutter/foundation.dart'; + +import 'package:fluffychat/pangea/constants/model_keys.dart'; +import 'package:fluffychat/pangea/widgets/igc/word_data_card.dart'; + +class WordData { + final String word; + final String fullText; + final String? userL1; + final String? userL2; + // final List languageSenses; + + final String targetPartOfSpeech; + final String basePartOfSpeech; + final String partOfSpeech; + final String targetDefinition; + final String baseDefinition; + final String targetWord; + final String baseWord; + final String baseExampleSentence; + final String targetExampleSentence; + + WordData({ + // required this.languageSenses, + required this.fullText, + required this.word, + required this.userL1, + required this.userL2, + required this.baseDefinition, + required this.targetDefinition, + required this.basePartOfSpeech, + required this.targetPartOfSpeech, + required this.partOfSpeech, + required this.baseWord, + required this.targetWord, + required this.baseExampleSentence, + required this.targetExampleSentence, + }); + + // static const String _languageSensesKey = 'sense_responses'; + static const String _dataFullKey = 'data_full'; + + Map toJson() => { + // _languageSensesKey: languageSenses.map((e) => e.toJson()).toList(), + ModelKey.word: word, + ModelKey.userL1: userL1, + ModelKey.userL2: userL2, + ModelKey.baseDefinition: baseDefinition, + ModelKey.targetDefinition: targetDefinition, + ModelKey.basePartOfSpeech: basePartOfSpeech, + ModelKey.targetPartOfSpeech: targetPartOfSpeech, + ModelKey.partOfSpeech: partOfSpeech, + ModelKey.baseWord: baseWord, + ModelKey.targetWord: targetWord, + ModelKey.baseExampleSentence: baseExampleSentence, + ModelKey.targetExampleSentence: targetExampleSentence, + }; + + factory WordData.fromJson( + Map json, { + required String word, + required String fullText, + required String userL1, + required String userL2, + }) { + try { + return WordData( + // languageSenses: (json[_languageSensesKey] as List) + // .map( + // (e) => LanguageSense.fromJson(e as Map), + // ) + // .toList() + // .cast(), + baseDefinition: json[_dataFullKey][ModelKey.baseDefinition], + targetDefinition: json[_dataFullKey][ModelKey.targetDefinition], + basePartOfSpeech: json[_dataFullKey][ModelKey.basePartOfSpeech], + targetPartOfSpeech: json[_dataFullKey][ModelKey.targetPartOfSpeech], + partOfSpeech: json[_dataFullKey][ModelKey.partOfSpeech], + baseWord: json[_dataFullKey][ModelKey.baseWord], + targetWord: json[_dataFullKey][ModelKey.targetWord], + baseExampleSentence: json[_dataFullKey][ModelKey.baseExampleSentence], + targetExampleSentence: json[_dataFullKey] + [ModelKey.targetExampleSentence], + word: word, + userL1: userL1, + userL2: userL2, + fullText: fullText, + ); + } catch (err) { + debugger(when: kDebugMode); + return [] as WordData; + } + } + + bool isMatch({ + required String w, + required String f, + required String? l1, + required String? l2, + }) => + word == w && userL1 == l1 && userL2 == l2 && fullText == f; + + String formattedPartOfSpeech(LanguageType languageType) { + final String pos = languageType == LanguageType.base + ? basePartOfSpeech + : targetPartOfSpeech; + return pos[0].toUpperCase() + pos.substring(1); + } + + // List sensesForLanguage(String code) => + // languageSenses.where((langSense) => langSense.langCode == code).toList(); +} + +// class LanguageSense { +// List senses; +// String langCode; + +// LanguageSense({ +// required this.senses, +// required this.langCode, +// }); + +// static const String _sensesKey = "senses"; +// static const String _langCodeKey = "lang_code"; + +// Map toJson() => { +// _sensesKey: senses.map((e) => e.toJson()).toList(), +// _langCodeKey: langCode, +// }; + +// factory LanguageSense.fromJson(Map json) => LanguageSense( +// senses: (json[_sensesKey] as List) +// .map( +// (e) => Sense.fromJson(e as Map), +// ) +// .toList() +// .cast(), +// langCode: json[_langCodeKey], +// ); + +// List get partsOfSpeech => +// senses.map((sense) => sense.partOfSpeech).toSet().toList(); + +// List definitionsForPartOfSpeech(String partOfSpeech) { +// final List definitions = []; +// for (final Sense sense in senses) { +// if (sense.partOfSpeech == partOfSpeech && +// sense.definition != null && +// sense.definition!.isNotEmpty) { +// definitions.add(sense.definition!); +// } +// } +// return definitions; +// } + +// // List partOfSpeechSense(partOfSpeech) { +// // return senses +// // .where((sense) => sense.partOfSpeech == partOfSpeech) +// // .map((sense) => sense.lemmas.join(', ')) +// // .toSet() +// // .toList(); +// // } + +// // Map> get partOfSpeechSenses { +// // final Map> senses = {}; +// // for (final partOfSpeech in partsOfSpeech) { +// // senses[partOfSpeech] = partOfSpeechSense(partOfSpeech); +// // } +// // return senses; +// // } +// } + +// class Sense { +// String partOfSpeech; +// List lemmas; +// String? definition; + +// Sense({ +// required this.partOfSpeech, +// required this.lemmas, +// required this.definition, +// }); + +// static const String _posKey = "pos"; +// static const String _lemmasKey = "lemmas"; +// static const String _definitionKey = "definition"; + +// Map toJson() => { +// _posKey: partOfSpeech, +// _lemmasKey: lemmas.toString(), +// _definitionKey: definition +// }; + +// factory Sense.fromJson(Map json) => Sense( +// partOfSpeech: json[_posKey], +// lemmas: (json[_lemmasKey] as List).cast(), +// definition: json[_definitionKey], +// ); +// } diff --git a/lib/pangea/network/p_api_exception.dart b/lib/pangea/network/p_api_exception.dart new file mode 100644 index 000000000..66c54dd51 --- /dev/null +++ b/lib/pangea/network/p_api_exception.dart @@ -0,0 +1,91 @@ +import 'package:flutter/foundation.dart'; + +import '../utils/p_toast.dart'; + +class ApiException { + static exception({required int statusCode, required String body}) { + switch (statusCode) { + case 400: + if (kDebugMode) { + debugPrint(body); + debugPrint(statusCode.toString()); + } + PToastController.toastMsg(msg: "Unknown error accrued", success: false); + return; + case 401: + if (kDebugMode) { + debugPrint(body); + debugPrint(statusCode.toString()); + } + PToastController.toastMsg( + msg: "Exception: Unauthorized access", + success: false, + ); + + return; + case 403: + if (kDebugMode) { + debugPrint(body); + debugPrint(statusCode.toString()); + } + PToastController.toastMsg( + msg: "Exception: Don't have permissions!", + success: false, + ); + return; + case 500: + if (kDebugMode) { + debugPrint(body); + debugPrint(statusCode.toString()); + } + PToastController.toastMsg( + msg: "Exception: Internal Server Error", + success: false, + ); + return; + case 502: + if (kDebugMode) { + debugPrint(body); + debugPrint(statusCode.toString()); + } + PToastController.toastMsg( + msg: "Exception: Bad Gateway", + success: false, + ); + + return; + case 503: + if (kDebugMode) { + debugPrint(body); + debugPrint(statusCode.toString()); + } + PToastController.toastMsg( + msg: "Exception: Service Unavailable", + success: false, + ); + + return; + case 504: + if (kDebugMode) { + debugPrint(body); + debugPrint(statusCode.toString()); + } + PToastController.toastMsg( + msg: "Exception: Gateway timeout error!", + success: false, + ); + + return; + default: + if (kDebugMode) { + debugPrint(body); + debugPrint(statusCode.toString()); + } + PToastController.toastMsg( + msg: "Unknown exception accrued!", + success: false, + ); + return; + } + } +} diff --git a/lib/pangea/network/requests.dart b/lib/pangea/network/requests.dart new file mode 100644 index 000000000..5cad3cf6c --- /dev/null +++ b/lib/pangea/network/requests.dart @@ -0,0 +1,146 @@ +import 'dart:convert'; + +import 'package:flutter/material.dart'; + +import 'package:http/http.dart' as http; +import 'package:sentry_flutter/sentry_flutter.dart'; + +class Requests { + late String? baseUrl; + late String? accessToken; + late String? matrixAccessToken; + late String? choreoApiKey; + //Question: How can we make baseUrl optional? + Requests({ + this.accessToken, + this.baseUrl = '', + this.matrixAccessToken, + this.choreoApiKey, + }); + + Future post({ + required String url, + required Map body, + }) async { + dynamic encoded; + encoded = jsonEncode(body); + + debugPrint(baseUrl! + url); + + final http.Response response = await http.post( + _uriBuilder(url), + body: encoded, + headers: _headers, + ); + handleError(response, body: body); + + return response; + } + + Future put({ + required String url, + required Map body, + }) async { + dynamic encoded; + encoded = jsonEncode(body); + + debugPrint(baseUrl! + url); + + final http.Response response = await http.put( + _uriBuilder(url), + body: encoded, + headers: _headers, + ); + + handleError(response, body: body); + + return response; + } + + Future get({required String url, String objectId = ""}) async { + final http.Response response = + await http.get(_uriBuilder(url + objectId), headers: _headers); + + handleError(response, objectId: objectId); + + return response; + } + + Uri _uriBuilder(url) => + baseUrl != null ? Uri.parse(baseUrl! + url) : Uri.parse(url); + + Map _parseEachToString(Map json) { + for (final String key in json.keys) { + if (json[key].runtimeType != String) { + if (json[key].runtimeType == List) { + json[key].forEach((item) { + _parseEachToString(json[key]); + }); + } + if (json[key].runtimeType == Map) { + _parseEachToString(json[key]); + } + if (json[key].runtimeType == int || json[key].runtimeType == double) { + json[key] = json[key].toString(); + } + } + } + + return json; + } + + void handleError( + http.Response response, { + Map? body, + String? objectId, + }) { + //PTODO - handle 401 error - unauthorized call + //kick them back to login? + + addBreadcrumb() { + debugPrint("Error - code: ${response.statusCode}"); + debugPrint("api: ${response.request?.url}"); + debugPrint("request body: ${body ?? objectId}"); + Sentry.addBreadcrumb( + Breadcrumb.http( + url: response.request?.url ?? Uri(path: "not available"), + method: response.request?.method ?? "not available", + statusCode: response.statusCode, + ), + ); + Sentry.addBreadcrumb( + Breadcrumb.fromJson({"body": body, "objectId": objectId}), + ); + } + + switch (response.statusCode) { + case 200: + case 201: + break; + case 502: + case 504: + addBreadcrumb(); + throw response; + default: + addBreadcrumb(); + throw response; + } + } + + get _headers { + final Map headers = { + "Content-Type": "application/json", + "Accept": "application/json", + }; + if (accessToken != null) { + headers["Authorization"] = 'Bearer ${accessToken!}'; + } + if (matrixAccessToken != null) { + headers["Matrix-Access-Token"] = matrixAccessToken!; + } + if (choreoApiKey != null) { + headers['api_key'] = choreoApiKey!; + } + return headers; + } +} diff --git a/lib/pangea/network/urls.dart b/lib/pangea/network/urls.dart new file mode 100644 index 000000000..0cd4c2e9c --- /dev/null +++ b/lib/pangea/network/urls.dart @@ -0,0 +1,74 @@ +//TODO move baseAPI addition to request function + +import 'package:fluffychat/pangea/config/environment.dart'; + +/// autodocs +/// https://api.staging.pangea.chat/choreo/docs +/// username: admin +/// password: admin +/// +/// https://api.staging.pangea.chat/api/v1/ +class PApiUrls { + static String baseAPI = Environment.baseAPI; + static String choreoBaseApi = Environment.choreoApi; + + /// ---------------------- Languages -------------------------------------- + static String getLanguages = "/language/list"; + + /// ---------------------- Users -------------------------------------- + static String createUser = "/account/create"; + static String userDetails = "/account/get_user_access_token?pangea_user_id="; + static String updateUserProfile = "/account/update"; + static String paymentLink = "/account/payment_link"; + static String subscriptionExpiration = "/account/premium_expires_date"; + + /// ---------------------- Conversation Partner ------------------------- + static String searchUserProfiles = "/account/search"; + + /// ---------------------- Deprecated Class API ------------------------- + static String classListBySpaceIds = "/class/listbyspaceids"; + static String getClassByClassCode = "/class/class_by_code?class_code="; + + /// ---------------------- Exchange ----------------------------------- + static String exchangeClassValidate = "/class/validate_exchange"; + static String exchangeClass = "/class/class_exchange"; + static String isExchange = "/class/get_exchange?exchange_pangea_id="; + static String exchangeParticipantsStore = "/class/exchange/participant"; + static String exchangeInfoStore = "/class/exchange/create"; + static String fetchExchangeInfo = "/class/exchange/data?exchange_pangea_id="; + static String exchangeAcceptRequest = "/class/exchange/accept"; + static String makeAdminInExchange = "/class/exchange/admin/create"; + + ///-------------------------------- Deprecated analytics -------------------- + static String classAnalytics = "${Environment.choreoApi}/class_analytics"; + static String messageService = "/message_service"; + + ///-------------------------------- choreo -------------------------- + static String igc = "${Environment.choreoApi}/grammar"; + + static String igcLite = "${Environment.choreoApi}/grammar_lite"; + static String spanDetails = "${Environment.choreoApi}/span_details"; + + static String wordNet = "${Environment.choreoApi}/wordnet"; + static String contextualizedTranslation = + "${Environment.choreoApi}/translation/contextual"; + static String simpleTranslation = + "${Environment.choreoApi}/translation/direct"; + static String tokenize = "${Environment.choreoApi}/tokenize"; + static String contextualDefinition = + "${Environment.choreoApi}/contextual_definition"; + static String similarity = "${Environment.choreoApi}/similarity"; + static String topicInfo = "${Environment.choreoApi}/vocab_list"; + + static String firstStep = "/it_initialstep"; + static String subseqStep = "/it_step"; + + ///-------------------------------- revenue cat -------------------------- + static String rcApiV1 = "https://api.revenuecat.com/v1"; + static String rcApiV2 = + "https://api.revenuecat.com/v2/projects/${Environment.rcProjectId}"; + + static String rcApps = "$rcApiV2/apps"; + static String rcProducts = "$rcApiV2/offerings?expand=items.package.product"; + static String rcSubscribers = "$rcApiV1/subscribers"; +} diff --git a/lib/pangea/pages/analytics/analytics_list_tile.dart b/lib/pangea/pages/analytics/analytics_list_tile.dart new file mode 100644 index 000000000..1120d31d5 --- /dev/null +++ b/lib/pangea/pages/analytics/analytics_list_tile.dart @@ -0,0 +1,108 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:go_router/go_router.dart'; +import 'package:matrix/matrix.dart'; + +import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart'; +import '../../../../utils/date_time_extension.dart'; +import '../../../widgets/avatar.dart'; +import '../../../widgets/matrix.dart'; +import '../../models/chart_analytics_model.dart'; +import 'base_analytics_page.dart'; +import 'list_summary_analytics.dart'; + +class AnalyticsListTile extends StatelessWidget { + const AnalyticsListTile({ + super.key, + required this.model, + required this.displayName, + required this.avatar, + required this.type, + required this.id, + required this.selected, + required this.onTap, + required this.allowNavigateOnSelect, + }); + + final Uri? avatar; + final String displayName; + final AnalyticsEntryType type; + final String id; + final ChartAnalyticsModel? model; + final bool selected; + final bool allowNavigateOnSelect; + + final void Function(AnalyticsSelected) onTap; + + @override + Widget build(BuildContext context) { + final Room? room = Matrix.of(context).client.getRoomById(id); + return Material( + color: selected + ? Theme.of(context).colorScheme.secondaryContainer + : Colors.transparent, + child: ListTile( + leading: type == AnalyticsEntryType.privateChats + ? CircleAvatar( + backgroundColor: Theme.of(context).primaryColor, + foregroundColor: Colors.white, + radius: Avatar.defaultSize / 2, + child: const Icon(Icons.forum), + ) + : Avatar( + mxContent: avatar, + name: displayName, + littleIcon: room?.roomTypeIcon, + ), + title: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Text( + displayName, + maxLines: 1, + overflow: TextOverflow.ellipsis, + softWrap: false, + style: TextStyle( + fontWeight: FontWeight.bold, + color: Theme.of(context).textTheme.bodyLarge!.color, + ), + ), + ), + Tooltip( + message: L10n.of(context)!.timeOfLastMessage, + child: Text( + model?.lastMessage?.localizedTimeShort(context) ?? "", + style: TextStyle( + fontSize: 13, + color: Theme.of(context).textTheme.bodyMedium!.color, + ), + ), + ), + ], + ), + subtitle: ListSummaryAnalytics( + chartAnalytics: model, + ), + selected: selected, + onTap: () => (room?.isSpace ?? false) && allowNavigateOnSelect + ? context.go( + '/rooms/analytics/${room!.id}', + ) + : onTap( + AnalyticsSelected( + id, + type, + displayName, + ), + ), + trailing: (room?.isSpace ?? false) && + type != AnalyticsEntryType.privateChats && + allowNavigateOnSelect + ? const Icon(Icons.chevron_right) + : null, + ), + ); + } +} diff --git a/lib/pangea/pages/analytics/bar_chart_card.dart b/lib/pangea/pages/analytics/bar_chart_card.dart new file mode 100644 index 000000000..a81f3e5c5 --- /dev/null +++ b/lib/pangea/pages/analytics/bar_chart_card.dart @@ -0,0 +1,52 @@ +import 'package:flutter/material.dart'; + +import 'package:fl_chart/fl_chart.dart'; + +class BarChartCard extends StatelessWidget { + const BarChartCard({ + super.key, + required this.barChartTitle, + required this.barChart, + required this.legend, + required this.loadingData, + }); + + final String barChartTitle; + final BarChart? barChart; + final Widget legend; + final bool loadingData; + + @override + Widget build(BuildContext context) { + return Card( + elevation: 0, + shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(6)), + color: Theme.of(context).scaffoldBackgroundColor, + child: Padding( + padding: const EdgeInsets.all(8), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + const SizedBox(height: 6), + Text( + barChartTitle, + style: Theme.of(context).textTheme.bodyMedium, + ), + const SizedBox(height: 14), + Expanded( + child: loadingData || barChart == null + ? const Center( + child: CircularProgressIndicator(), + ) + : barChart!, + ), + const SizedBox(height: 10), + legend, + const SizedBox(height: 6), + ], + ), + ), + ); + } +} diff --git a/lib/pangea/pages/analytics/bar_chart_placeholder_data.dart b/lib/pangea/pages/analytics/bar_chart_placeholder_data.dart new file mode 100644 index 000000000..113d34af1 --- /dev/null +++ b/lib/pangea/pages/analytics/bar_chart_placeholder_data.dart @@ -0,0 +1,293 @@ +import 'package:flutter/material.dart'; + +import 'package:fl_chart/fl_chart.dart'; + +import '../../enum/use_type.dart'; + +class BarChartPlaceHolderData { + static BarChartRodData randomBarChartRodData( + BuildContext context, + int index, + ) { + // final total = Random().nextInt(100); + // final it = total != 0 ? Random().nextInt(max(total - index, 1)) : 0; + // final igc = total != 0 ? Random().nextInt(max(total - it - index, 1)) : 0; + // // final direct = Random().nextInt(total - it - igc); + // final y1 = it.toDouble(); + // final y2 = y1 + igc.toDouble(); + // final y3 = total.toDouble(); + // final y4 = y3; + const total = 0; + const double y1 = 0; + const double y2 = 0; + const double y3 = 0; + const double y4 = 0; + + return BarChartRodData( + toY: total.toDouble(), + rodStackItems: [ + BarChartRodStackItem(0, y1, UseType.ta.color(context)), + BarChartRodStackItem(y1, y2, UseType.ga.color(context)), + BarChartRodStackItem(y2, y3, UseType.wa.color(context)), + BarChartRodStackItem(y3, y4, UseType.un.color(context)), + ], + borderRadius: BorderRadius.zero, + ); + } + + static List getRandomData(BuildContext context) { + const double barSpace = 16; + + const indices = [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + ]; + + final List barChartGroupData = []; + + indices.asMap().forEach((key, value) { + barChartGroupData.add( + BarChartGroupData( + x: key, + barsSpace: barSpace, + barRods: [ + randomBarChartRodData(context, value), + ], + ), + ); + }); + + return barChartGroupData; + } + + static List getData( + Color dark, + Color normal, + Color light, + ) { + const double barSpace = 16; + + return [ + BarChartGroupData( + x: 0, + barsSpace: barSpace, + barRods: [ + BarChartRodData( + toY: 17, + rodStackItems: [ + BarChartRodStackItem(0, 2, dark), + BarChartRodStackItem(2, 12, normal), + BarChartRodStackItem(12, 17, light), + ], + borderRadius: BorderRadius.zero, + ), + BarChartRodData( + toY: 24, + rodStackItems: [ + BarChartRodStackItem(0, 13, dark), + BarChartRodStackItem(13, 14, normal), + BarChartRodStackItem(14, 24, light), + ], + borderRadius: BorderRadius.zero, + ), + BarChartRodData( + toY: 23, + rodStackItems: [ + BarChartRodStackItem(0, 6, dark), + BarChartRodStackItem(6, 18, normal), + BarChartRodStackItem(18, 23, light), + ], + borderRadius: BorderRadius.zero, + ), + BarChartRodData( + toY: 29, + rodStackItems: [ + BarChartRodStackItem(0, 9, dark), + BarChartRodStackItem(9, 15, normal), + BarChartRodStackItem(15, 29, light), + ], + borderRadius: BorderRadius.zero, + ), + BarChartRodData( + toY: 32, + rodStackItems: [ + BarChartRodStackItem(0, 2, dark), + BarChartRodStackItem(2, 17, normal), + BarChartRodStackItem(17, 32, light), + ], + borderRadius: BorderRadius.zero, + ), + ], + ), + BarChartGroupData( + x: 1, + barsSpace: barSpace, + barRods: [ + BarChartRodData( + toY: 31, + rodStackItems: [ + BarChartRodStackItem(0, 11, dark), + BarChartRodStackItem(11, 18, normal), + BarChartRodStackItem(18, 31, light), + ], + borderRadius: BorderRadius.zero, + ), + BarChartRodData( + toY: 35, + rodStackItems: [ + BarChartRodStackItem(0, 14, dark), + BarChartRodStackItem(14, 27, normal), + BarChartRodStackItem(27, 35, light), + ], + borderRadius: BorderRadius.zero, + ), + BarChartRodData( + toY: 31, + rodStackItems: [ + BarChartRodStackItem(0, 8, dark), + BarChartRodStackItem(8, 24, normal), + BarChartRodStackItem(24, 31, light), + ], + borderRadius: BorderRadius.zero, + ), + BarChartRodData( + toY: 15, + rodStackItems: [ + BarChartRodStackItem(0, 6, dark), + BarChartRodStackItem(6, 12, normal), + BarChartRodStackItem(12, 15, light), + ], + borderRadius: BorderRadius.zero, + ), + BarChartRodData( + toY: 17, + rodStackItems: [ + BarChartRodStackItem(0, 9, dark), + BarChartRodStackItem(9, 15, normal), + BarChartRodStackItem(15, 17, light), + ], + borderRadius: BorderRadius.zero, + ), + ], + ), + BarChartGroupData( + x: 2, + barsSpace: barSpace, + barRods: [ + BarChartRodData( + toY: 34, + rodStackItems: [ + BarChartRodStackItem(0, 6, dark), + BarChartRodStackItem(6, 23, normal), + BarChartRodStackItem(23, 34, light), + ], + borderRadius: BorderRadius.zero, + ), + BarChartRodData( + toY: 32, + rodStackItems: [ + BarChartRodStackItem(0, 7, dark), + BarChartRodStackItem(7, 24, normal), + BarChartRodStackItem(24, 32, light), + ], + borderRadius: BorderRadius.zero, + ), + BarChartRodData( + toY: 14, + rodStackItems: [ + BarChartRodStackItem(0, 1, dark), + BarChartRodStackItem(1, 12, normal), + BarChartRodStackItem(12, 14, light), + ], + borderRadius: BorderRadius.zero, + ), + BarChartRodData( + toY: 20, + rodStackItems: [ + BarChartRodStackItem(0, 4, dark), + BarChartRodStackItem(4, 15, normal), + BarChartRodStackItem(15, 20, light), + ], + borderRadius: BorderRadius.zero, + ), + BarChartRodData( + toY: 24, + rodStackItems: [ + BarChartRodStackItem(0, 4, dark), + BarChartRodStackItem(4, 15, normal), + BarChartRodStackItem(15, 24, light), + ], + borderRadius: BorderRadius.zero, + ), + ], + ), + BarChartGroupData( + x: 3, + barsSpace: barSpace, + barRods: [ + BarChartRodData( + toY: 14, + rodStackItems: [ + BarChartRodStackItem(0, 1, dark), + BarChartRodStackItem(1, 12, normal), + BarChartRodStackItem(12, 14, light), + ], + borderRadius: BorderRadius.zero, + ), + BarChartRodData( + toY: 27, + rodStackItems: [ + BarChartRodStackItem(0, 7, dark), + BarChartRodStackItem(7, 25, normal), + BarChartRodStackItem(25, 27, light), + ], + borderRadius: BorderRadius.zero, + ), + BarChartRodData( + toY: 29, + rodStackItems: [ + BarChartRodStackItem(0, 6, dark), + BarChartRodStackItem(6, 23, normal), + BarChartRodStackItem(23, 29, light), + ], + borderRadius: BorderRadius.zero, + ), + BarChartRodData( + toY: 16, + rodStackItems: [ + BarChartRodStackItem(0, 9, dark), + BarChartRodStackItem(9, 15, normal), + BarChartRodStackItem(15, 16, light), + ], + borderRadius: BorderRadius.zero, + ), + BarChartRodData( + toY: 15, + rodStackItems: [ + BarChartRodStackItem(0, 7, dark), + BarChartRodStackItem(7, 12, normal), + BarChartRodStackItem(12, 15, light), + ], + borderRadius: BorderRadius.zero, + ), + ], + ), + ]; + } +} diff --git a/lib/pangea/pages/analytics/base_analytics_page.dart b/lib/pangea/pages/analytics/base_analytics_page.dart new file mode 100644 index 000000000..f17c12e53 --- /dev/null +++ b/lib/pangea/pages/analytics/base_analytics_page.dart @@ -0,0 +1,365 @@ +import 'dart:math'; + +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; + +import 'package:fluffychat/config/app_config.dart'; +import 'package:fluffychat/pangea/enum/construct_type_enum.dart'; +import '../../../widgets/layouts/max_width_body.dart'; +import '../../../widgets/matrix.dart'; +import '../../controllers/pangea_controller.dart'; +import '../../enum/bar_chart_view_enum.dart'; +import '../../enum/time_span.dart'; +import '../../models/chart_analytics_model.dart'; +import 'analytics_list_tile.dart'; +import 'construct_list.dart'; +import 'messages_bar_chart.dart'; +import 'time_span_menu_button.dart'; + +class BaseAnalyticsPage extends StatefulWidget { + final String pageTitle; + final TabData tabData1; + final TabData tabData2; + final Future Function(BuildContext) refreshData; + + final AnalyticsSelected defaultAnalyticsSelected; + final AnalyticsSelected? alwaysSelected; + + const BaseAnalyticsPage({ + super.key, + required this.pageTitle, + required this.tabData1, + required this.tabData2, + required this.defaultAnalyticsSelected, + required this.refreshData, + required this.alwaysSelected, + }); + + @override + State createState() => BaseAnalyticsController(); +} + +class BaseAnalyticsController extends State { + final PangeaController _pangeaController = MatrixState.pangeaController; + AnalyticsSelected? selected; + BarChartViewSelection selectedView = BarChartViewSelection.grammar; + + @override + void initState() { + super.initState(); + } + + bool isSelected(String chatOrStudentId) => chatOrStudentId == selected?.id; + + ChartAnalyticsModel? chartData( + BuildContext context, + AnalyticsSelected? selectedParam, + ) { + final AnalyticsSelected analyticsSelected = + selectedParam ?? widget.defaultAnalyticsSelected; + + if (analyticsSelected.type == AnalyticsEntryType.privateChats) { + return _pangeaController.analytics.getAnalyticsLocal( + classId: analyticsSelected.id, + chatId: AnalyticsEntryType.privateChats.toString(), + ); + } + + String? chatId = analyticsSelected.type == AnalyticsEntryType.room + ? analyticsSelected.id + : null; + chatId ??= widget.alwaysSelected?.type == AnalyticsEntryType.room + ? widget.alwaysSelected?.id + : null; + + String? studentId = analyticsSelected.type == AnalyticsEntryType.student + ? analyticsSelected.id + : null; + studentId ??= widget.alwaysSelected?.type == AnalyticsEntryType.student + ? widget.alwaysSelected?.id + : null; + + String? classId = analyticsSelected.type == AnalyticsEntryType.space + ? analyticsSelected.id + : null; + classId ??= widget.alwaysSelected?.type == AnalyticsEntryType.space + ? widget.alwaysSelected?.id + : null; + + final data = _pangeaController.analytics.getAnalyticsLocal( + classId: classId, + chatId: chatId, + studentId: studentId, + ); + return data; + } + + String barTitle(BuildContext context) => + "${selectedView.string(context)}: ${selected == null ? widget.defaultAnalyticsSelected.displayName : selected!.displayName}"; + + TimeSpan get currentTimeSpan => + _pangeaController.analytics.currentAnalyticsTimeSpan; + + void toggleSelection(AnalyticsSelected selectedParam) { + setState(() { + debugPrint("selectedParam.id is ${selectedParam.id}"); + selected = isSelected(selectedParam.id) ? null : selectedParam; + }); + Future.delayed(Duration.zero, () => setState(() {})); + } + + void toggleTimeSpan(BuildContext context, TimeSpan timeSpan) { + _pangeaController.analytics.setCurrentAnalyticsTimeSpan(timeSpan); + setState(() {}); + widget.refreshData(context).then((value) => setState(() {})); + } + + void toggleSelectedView(BarChartViewSelection view) { + selectedView = view; + setState(() {}); + } + + @override + Widget build(BuildContext context) => BaseAnalyticsView(controller: this); +} + +class BaseAnalyticsView extends StatelessWidget { + const BaseAnalyticsView({ + super.key, + required this.controller, + }); + + final BaseAnalyticsController controller; + + Widget chartView(BuildContext context) { + switch (controller.selectedView) { + case BarChartViewSelection.messages: + return MessagesBarChart( + chartAnalytics: controller.chartData(context, controller.selected), + barChartTitle: controller.barTitle(context), + ); + // case BarChartViewSelection.vocab: + // return ConstructList( + // selected: controller.selected, + // defaultSelected: controller.widget.defaultAnalyticsSelected, + // constructType: ConstructType.vocab, + // ); + case BarChartViewSelection.grammar: + return ConstructList( + selected: controller.selected, + defaultSelected: controller.widget.defaultAnalyticsSelected, + constructType: ConstructType.grammar, + title: controller.barTitle(context), + ); + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + centerTitle: true, + title: Text( + controller.widget.pageTitle, + style: TextStyle( + color: Theme.of(context).textTheme.bodyLarge!.color, + fontSize: 18, + fontWeight: FontWeight.w700, + ), + overflow: TextOverflow.clip, + textAlign: TextAlign.center, + ), + actions: [ + for (final view in BarChartViewSelection.values) + Container( + decoration: BoxDecoration( + shape: BoxShape.circle, + color: controller.selectedView == view + ? AppConfig.primaryColor + : null, + ), + child: IconButton( + isSelected: controller.selectedView == view, + icon: Icon(view.icon), + tooltip: view.string(context), + onPressed: () => controller.toggleSelectedView(view), + ), + ), + TimeSpanMenuButton( + value: controller.currentTimeSpan, + onChange: (TimeSpan value) => + controller.toggleTimeSpan(context, value), + ), + // ChartViewPickerButton( + // selected: controller.selectedView, + // onChange: controller.toggleSelectedView, + // ), + ], + ), + body: MaxWidthBody( + withScrolling: false, + child: Column( + children: [ + Expanded( + flex: 1, + child: chartView(context), + ), + Expanded( + flex: 1, + child: DefaultTabController( + length: 2, + child: Column( + children: [ + TabBar( + tabs: [ + Tab( + icon: Icon( + controller.widget.tabData1.icon, + color: + Theme.of(context).colorScheme.onSurfaceVariant, + ), + ), + Tab( + icon: Icon( + controller.widget.tabData2.icon, + color: + Theme.of(context).colorScheme.onSurfaceVariant, + ), + ), + ], + ), + Expanded( + child: SingleChildScrollView( + child: SizedBox( + height: max( + controller.widget.tabData1.items.length + 1, + controller.widget.tabData2.items.length, + ) * + 72, + child: TabBarView( + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + ...controller.widget.tabData1.items.map( + (item) => AnalyticsListTile( + avatar: item.avatar, + model: controller.chartData( + context, + AnalyticsSelected( + item.id, + controller.widget.tabData1.type, + "", + ), + ), + displayName: item.displayName, + id: item.id, + type: controller.widget.tabData1.type, + selected: controller.isSelected(item.id), + onTap: controller.toggleSelection, + allowNavigateOnSelect: controller.widget + .tabData1.allowNavigateOnSelect, + ), + ), + if (controller.widget.defaultAnalyticsSelected + .type == + AnalyticsEntryType.space) + AnalyticsListTile( + avatar: null, + model: controller.chartData( + context, + AnalyticsSelected( + controller.widget + .defaultAnalyticsSelected.id, + AnalyticsEntryType.privateChats, + L10n.of(context)!.allPrivateChats, + ), + ), + displayName: + L10n.of(context)!.allPrivateChats, + id: controller + .widget.defaultAnalyticsSelected.id, + type: AnalyticsEntryType.privateChats, + selected: controller.isSelected( + controller + .widget.defaultAnalyticsSelected.id, + ), + onTap: controller.toggleSelection, + allowNavigateOnSelect: false, + ), + ], + ), + Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: controller.widget.tabData2.items + .map( + (item) => AnalyticsListTile( + avatar: item.avatar, + model: controller.chartData( + context, + AnalyticsSelected( + item.id, + controller.widget.tabData2.type, + "", + ), + ), + displayName: item.displayName, + id: item.id, + type: controller.widget.tabData2.type, + selected: + controller.isSelected(item.id), + onTap: controller.toggleSelection, + allowNavigateOnSelect: controller.widget + .tabData2.allowNavigateOnSelect, + ), + ) + .toList(), + ), + ], + ), + ), + ), + ), + ], + ), + ), + ), + ], + ), + ), + ); + } +} + +class TabData { + AnalyticsEntryType type; + IconData icon; + List items; + bool allowNavigateOnSelect; + + TabData({ + required this.type, + required this.items, + required this.icon, + this.allowNavigateOnSelect = true, + }); +} + +class TabItem { + Uri? avatar; + String displayName; + String id; + + TabItem({required this.avatar, required this.displayName, required this.id}); +} + +enum AnalyticsEntryType { student, room, space, privateChats } + +class AnalyticsSelected { + String id; + AnalyticsEntryType type; + String displayName; + + AnalyticsSelected(this.id, this.type, this.displayName); +} diff --git a/lib/pangea/pages/analytics/chart_view_picker_button.dart b/lib/pangea/pages/analytics/chart_view_picker_button.dart new file mode 100644 index 000000000..125b107af --- /dev/null +++ b/lib/pangea/pages/analytics/chart_view_picker_button.dart @@ -0,0 +1,39 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; + +import '../../enum/bar_chart_view_enum.dart'; + +class ChartViewPickerButton extends StatelessWidget { + final BarChartViewSelection selected; + final void Function(BarChartViewSelection) onChange; + const ChartViewPickerButton({ + super.key, + required this.selected, + required this.onChange, + }); + + @override + Widget build(BuildContext context) { + return PopupMenuButton( + icon: Icon(selected.icon), + tooltip: L10n.of(context)!.changeView, + initialValue: selected, + onSelected: (BarChartViewSelection? barChartView) { + if (barChartView == null) { + debugPrint("when is barChartView null?"); + return; + } + onChange(barChartView); + }, + itemBuilder: (BuildContext context) => BarChartViewSelection.values + .map>( + (BarChartViewSelection barChartView) { + return PopupMenuItem( + value: barChartView, + child: Text(barChartView.string(context)), + ); + }).toList(), + ); + } +} diff --git a/lib/pangea/pages/analytics/class_analytics/class_analytics.dart b/lib/pangea/pages/analytics/class_analytics/class_analytics.dart new file mode 100644 index 000000000..39acca938 --- /dev/null +++ b/lib/pangea/pages/analytics/class_analytics/class_analytics.dart @@ -0,0 +1,171 @@ +import 'dart:async'; +import 'dart:developer'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + +import 'package:go_router/go_router.dart'; +import 'package:matrix/matrix.dart'; + +import 'package:fluffychat/pangea/constants/pangea_event_types.dart'; +import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart'; +import 'package:fluffychat/pangea/models/chart_analytics_model.dart'; +import 'package:fluffychat/pangea/utils/error_handler.dart'; +import 'package:fluffychat/pangea/widgets/common/list_placeholder.dart'; +import 'package:fluffychat/pangea/widgets/common/p_circular_loader.dart'; +import '../../../../widgets/matrix.dart'; +import '../../../controllers/pangea_controller.dart'; +import '../../../utils/sync_status_util_v2.dart'; +import 'class_analytics_view.dart'; + +enum AnalyticsPageType { classList, student, classDetails } + +class ClassAnalyticsPage extends StatefulWidget { + // final AnalyticsPageType type; + const ClassAnalyticsPage({super.key}); + + @override + State createState() => ClassAnalyticsV2Controller(); +} + +class ClassAnalyticsV2Controller extends State { + final PangeaController _pangeaController = MatrixState.pangeaController; + bool _initialized = false; + StreamSubscription? stateSub; + Timer? refreshTimer; + + List chats = []; + List students = []; + + @override + void initState() { + super.initState(); + Future.delayed(Duration.zero, () async { + if (classRoom == null || !classRoom!.isSpace) { + context.go('/rooms'); + } + stateSub = _pangeaController.matrixState.client.onRoomState.stream + .where( + (event) => + event.type == PangeaEventTypes.studentAnalyticsSummary && + event.roomId == classId, + ) + .listen(onStateUpdate); + getChatAndStudents(); + }); + } + + Future getChatAndStudents() async { + try { + await classRoom!.requestParticipants(); + + students = classRoom!.students; + + chats = classRoom!.spaceChildren + .where((element) => element.roomId != null) + .map((e) => Matrix.of(context).client.getRoomById(e.roomId!)) + .where((r) => r != null) + .cast() + .toList(); + + setState(() { + _initialized = true; + }); + } catch (err, s) { + debugger(when: kDebugMode); + ErrorHandler.logError(e: err, s: s); + } + } + + void onStateUpdate(Event newState) { + if (!(refreshTimer?.isActive ?? false)) { + refreshTimer = Timer( + const Duration(seconds: 3), + () => getChatAndStudentAnalytics(context, true), + ); + } + } + + @override + void dispose() { + super.dispose(); + refreshTimer?.cancel(); + stateSub?.cancel(); + } + + @override + Widget build(BuildContext context) { + if (!_initialized) return const PCircular(); + return PLoadingStatusV2( + // if we everr want it rebuild the whole thing each time (and run initState again) + // but this is computationally expensive! + // key: UniqueKey(), + shimmerChild: const ListPlaceholder(), + onFinish: () { + getChatAndStudentAnalytics(context); + }, + child: ClassAnalyticsView(this), + ); + } + + Future getChatAndStudentAnalytics( + BuildContext context, [ + forceUpdate = false, + ]) async { + try { + if (classRoom == null) { + debugger(when: kDebugMode); + ErrorHandler.logError(m: 'classroom should not be null'); + } + final List> analyticsFutures = []; + for (final student in students) { + analyticsFutures.add( + _pangeaController.analytics.getAnalytics( + classRoom: classRoom, + studentId: student.id, + forceUpdate: forceUpdate, + ), + ); + } + for (final chat in chats) { + analyticsFutures.add( + _pangeaController.analytics.getAnalytics( + classRoom: classRoom, + chatId: chat.id, + forceUpdate: forceUpdate, + ), + ); + } + analyticsFutures.add( + _pangeaController.analytics.getAnalytics( + classRoom: classRoom, + forceUpdate: forceUpdate, + ), + ); + analyticsFutures.add( + _pangeaController.analytics.getAnalyticsForPrivateChats( + classRoom: classRoom, + forceUpdate: forceUpdate, + ), + ); + await Future.wait(analyticsFutures); + if (mounted) setState(() {}); + } catch (err) { + debugger(when: kDebugMode); + } + } + + String? get classId => GoRouterState.of(context).pathParameters['classid']; + + Room? _classRoom; + Room? get classRoom { + _classRoom ??= classId != null + ? Matrix.of(context).client.getRoomById(classId!) + : null; + return _classRoom; + } + + String className(BuildContext context) { + return classRoom?.name ?? ""; + } +} diff --git a/lib/pangea/pages/analytics/class_analytics/class_analytics_view.dart b/lib/pangea/pages/analytics/class_analytics/class_analytics_view.dart new file mode 100644 index 000000000..06a46a5b2 --- /dev/null +++ b/lib/pangea/pages/analytics/class_analytics/class_analytics_view.dart @@ -0,0 +1,65 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; + +import '../../../../utils/matrix_sdk_extensions/matrix_locals.dart'; +import '../base_analytics_page.dart'; +import 'class_analytics.dart'; + +class ClassAnalyticsView extends StatelessWidget { + final ClassAnalyticsV2Controller controller; + const ClassAnalyticsView(this.controller, {super.key}); + + @override + Widget build(BuildContext context) { + // final String pageTitle = + // "${L10n.of(context)!.classAnalytics}: ${controller.className(context)}"; + final String pageTitle = L10n.of(context)!.classAnalytics; + final TabData tab1 = TabData( + type: AnalyticsEntryType.room, + icon: Icons.chat_bubble_outline, + items: controller.chats + .map( + (room) => TabItem( + avatar: room.avatar, + displayName: + room.getLocalizedDisplayname(MatrixLocals(L10n.of(context)!)), + id: room.id, + ), + ) + .toList(), + ); + final TabData tab2 = TabData( + type: AnalyticsEntryType.student, + icon: Icons.people_outline, + items: controller.students + .map( + (s) => TabItem( + avatar: s.avatarUrl, + displayName: s.displayName ?? "unknown", + id: s.id, + ), + ) + .toList(), + ); + + return controller.classId != null + ? BaseAnalyticsPage( + pageTitle: pageTitle, + tabData1: tab1, + tabData2: tab2, + defaultAnalyticsSelected: AnalyticsSelected( + controller.classId!, + AnalyticsEntryType.space, + controller.className(context), + ), + refreshData: controller.getChatAndStudentAnalytics, + alwaysSelected: AnalyticsSelected( + controller.classId!, + AnalyticsEntryType.space, + controller.className(context), + ), + ) + : const SizedBox(); + } +} diff --git a/lib/pangea/pages/analytics/class_list/class_list.dart b/lib/pangea/pages/analytics/class_list/class_list.dart new file mode 100644 index 000000000..6ce8b994d --- /dev/null +++ b/lib/pangea/pages/analytics/class_list/class_list.dart @@ -0,0 +1,93 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; + +import 'package:matrix/matrix.dart'; + +import 'package:fluffychat/pangea/enum/time_span.dart'; +import 'package:fluffychat/pangea/pages/analytics/class_list/class_list_view.dart'; +import '../../../../widgets/matrix.dart'; +import '../../../constants/pangea_event_types.dart'; +import '../../../controllers/pangea_controller.dart'; +import '../../../models/chart_analytics_model.dart'; +import '../../../utils/sync_status_util_v2.dart'; +import '../../../widgets/common/list_placeholder.dart'; + +class AnalyticsClassList extends StatefulWidget { + const AnalyticsClassList({super.key}); + + @override + State createState() => AnalyticsClassListController(); +} + +class AnalyticsClassListController extends State { + PangeaController pangeaController = MatrixState.pangeaController; + List models = []; + StreamSubscription? stateSub; + Map refreshTimer = {}; + + @override + void initState() { + super.initState(); + Future.delayed(Duration.zero, () async { + stateSub = pangeaController.matrixState.client.onRoomState.stream + .where( + (event) => event.type == PangeaEventTypes.studentAnalyticsSummary, + ) + .listen(onStateUpdate); + }); + } + + void onStateUpdate(Event newState) { + if (!(refreshTimer[newState.room.id]?.isActive ?? false)) { + refreshTimer[newState.room.id] = Timer( + const Duration(seconds: 3), + () => updateClassAnalytics(context, newState.room), + ); + } + } + + @override + void dispose() { + super.dispose(); + for (final timer in refreshTimer.values) { + timer.cancel(); + } + stateSub?.cancel(); + } + + @override + Widget build(BuildContext context) { + return PLoadingStatusV2( + shimmerChild: const ListPlaceholder(), + child: AnalyticsClassListView(this), + onFinish: () { + getAllClassAnalytics(context); + }, + ); + } + + Future getAllClassAnalytics(BuildContext context) async { + await pangeaController.analytics.allClassAnalytics(); + setState(() { + debugPrint("class list post getAllClassAnalytics"); + }); + } + + Future updateClassAnalytics( + BuildContext context, + Room classRoom, + ) async { + await pangeaController.analytics + .getAnalytics(classRoom: classRoom, forceUpdate: true); + setState(() { + debugPrint("class list post updateClassAnalytics"); + }); + } + + void toggleTimeSpan(BuildContext context, TimeSpan timeSpan) { + pangeaController.analytics.setCurrentAnalyticsTimeSpan(timeSpan); + setState(() {}); + getAllClassAnalytics(context); + } +} diff --git a/lib/pangea/pages/analytics/class_list/class_list_view.dart b/lib/pangea/pages/analytics/class_list/class_list_view.dart new file mode 100644 index 000000000..ff9ae7d94 --- /dev/null +++ b/lib/pangea/pages/analytics/class_list/class_list_view.dart @@ -0,0 +1,77 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:go_router/go_router.dart'; +import 'package:matrix/matrix.dart'; + +import 'package:fluffychat/pangea/extensions/client_extension.dart'; +import 'package:fluffychat/pangea/pages/analytics/analytics_list_tile.dart'; +import 'package:fluffychat/pangea/pages/analytics/time_span_menu_button.dart'; +import '../../../../widgets/matrix.dart'; +import '../../../enum/time_span.dart'; +import '../base_analytics_page.dart'; +import 'class_list.dart'; + +class AnalyticsClassListView extends StatelessWidget { + final AnalyticsClassListController controller; + const AnalyticsClassListView(this.controller, {super.key}); + + @override + Widget build(BuildContext context) { + final List classesAndExchanges = + Matrix.of(context).client.classesAndExchangesImTeaching; + return Scaffold( + appBar: AppBar( + centerTitle: true, + title: Text( + L10n.of(context)!.classAnalytics, + style: TextStyle( + color: Theme.of(context).textTheme.bodyLarge!.color, + fontSize: 18, + fontWeight: FontWeight.w700, + ), + overflow: TextOverflow.clip, + textAlign: TextAlign.center, + ), + leading: IconButton( + icon: const Icon(Icons.close_outlined), + onPressed: () => context.pop(), + ), + actions: [ + TimeSpanMenuButton( + value: + controller.pangeaController.analytics.currentAnalyticsTimeSpan, + onChange: (TimeSpan value) => + controller.toggleTimeSpan(context, value), + ), + ], + ), + body: Column( + children: [ + // MessagesBarChart( + // chartAnalytics: controller.chartData(context), + // barChartTitle: "", + // ), + Flexible( + child: ListView.builder( + itemCount: classesAndExchanges.length, + itemBuilder: (context, i) => AnalyticsListTile( + avatar: classesAndExchanges[i].avatar, + model: controller.pangeaController.analytics + .getAnalyticsLocal(classId: classesAndExchanges[i].id), + displayName: classesAndExchanges[i].name, + id: classesAndExchanges[i].id, + type: AnalyticsEntryType.space, + selected: false, + onTap: (selected) => context.go( + '/rooms/analytics/${selected.id}', + ), + allowNavigateOnSelect: true, + ), + ), + ), + ], + ), + ); + } +} diff --git a/lib/pangea/pages/analytics/construct_cloud.dart b/lib/pangea/pages/analytics/construct_cloud.dart new file mode 100644 index 000000000..67bdb02c9 --- /dev/null +++ b/lib/pangea/pages/analytics/construct_cloud.dart @@ -0,0 +1,106 @@ +import 'package:flutter/material.dart'; + +import 'package:fluffychat/pangea/pages/analytics/base_analytics_page.dart'; +import '../../word_cloud/word_cloud_data.dart'; +import '../../word_cloud/word_cloud_shape.dart'; +import '../../word_cloud/word_cloud_tap.dart'; +import '../../word_cloud/word_cloud_tap_view.dart'; +import '../../word_cloud/word_cloud_view.dart'; + +class ConstructCloud extends StatefulWidget { + final AnalyticsSelected? selected; + final AnalyticsSelected defaultSelected; + + const ConstructCloud({ + super.key, + required this.selected, + required this.defaultSelected, + }); + + @override + State createState() => ConstructCloudState(); +} + +class ConstructCloudState extends State { + int count = 0; + String wordstring = ''; + List> wordData = [ + {"word": "loading", 'value': 1}, + {"word": "loading", 'value': 1}, + {"word": "loading", 'value': 1}, + {"word": "loading", 'value': 1}, + ]; + + @override + void initState() { + super.initState(); + } + + @override + Widget build(BuildContext context) { + final WordCloudData wcdata = WordCloudData(data: wordData); + final WordCloudTap wordtaps = WordCloudTap(); + + for (int i = 0; i < wordData.length; i++) { + void tap() { + setState(() { + count += 1; + wordstring = wordData[i]['word']; + }); + } + + wordtaps.addWordtap(wordData[i]['word'], tap); + } + + return Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + 'Clicked Word : $wordstring', + style: const TextStyle(fontSize: 20), + ), + Text('Clicked Count : $count', style: const TextStyle(fontSize: 20)), + SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + WordCloudTapView( + data: wcdata, + wordtap: wordtaps, + mapcolor: const Color.fromARGB(255, 174, 183, 235), + mapwidth: 500, + mapheight: 500, + fontWeight: FontWeight.bold, + shape: WordCloudCircle(radius: 250), + colorlist: const [ + Colors.black, + Colors.redAccent, + Colors.indigoAccent, + ], + ), + const SizedBox( + height: 15, + width: 30, + ), + WordCloudView( + data: wcdata, + mapcolor: const Color.fromARGB(255, 174, 183, 235), + mapwidth: 500, + mapheight: 500, + fontWeight: FontWeight.bold, + colorlist: const [ + Colors.black, + Colors.redAccent, + Colors.indigoAccent, + ], + ), + ], + ), + ), + ], + ), + ); + } +} diff --git a/lib/pangea/pages/analytics/construct_list.dart b/lib/pangea/pages/analytics/construct_list.dart new file mode 100644 index 000000000..2128c827f --- /dev/null +++ b/lib/pangea/pages/analytics/construct_list.dart @@ -0,0 +1,181 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:matrix/matrix.dart'; + +import 'package:fluffychat/pangea/constants/match_rule_ids.dart'; +import 'package:fluffychat/pangea/enum/construct_type_enum.dart'; +import 'package:fluffychat/pangea/pages/analytics/base_analytics_page.dart'; +import 'package:fluffychat/widgets/matrix.dart'; +import '../../constants/pangea_event_types.dart'; +import '../../models/construct_analytics_event.dart'; +import '../../utils/error_handler.dart'; + +class ConstructList extends StatefulWidget { + final AnalyticsSelected? selected; + final AnalyticsSelected defaultSelected; + final ConstructType constructType; + final String title; + + const ConstructList({ + super.key, + required this.selected, + required this.defaultSelected, + required this.constructType, + required this.title, + }); + + @override + State createState() => ConstructListState(); +} + +class ConstructListState extends State { + List constructs = []; + bool initialized = false; + String? langCode; + String? error; + + StreamSubscription? stateSub; + Timer? refreshTimer; + + @override + void initState() { + super.initState(); + + _updateConstructs(); + + stateSub = MatrixState + .pangeaController.matrixState.client.onRoomState.stream + //could optimize here be determing if the vocab event is relevant for + //currently displayed data + .where((event) => event.type == PangeaEventTypes.vocab) + .listen(onStateUpdate); + } + + void onStateUpdate(Event newState) { + if (!(refreshTimer?.isActive ?? false)) { + refreshTimer = Timer( + const Duration(seconds: 3), + () => _updateConstructs(), + ); + } + } + + @override + void dispose() { + super.dispose(); + refreshTimer?.cancel(); + stateSub?.cancel(); + } + + @override + void didUpdateWidget(ConstructList oldWidget) { + super.didUpdateWidget(oldWidget); + + if (widget.selected?.id != oldWidget.selected?.id) { + _updateConstructs(); + } + } + + void _updateConstructs() { + setState(() { + initialized = false; + }); + MatrixState.pangeaController.analytics + .constuctEventsByAnalyticsSelected( + selected: widget.selected, + defaultSelected: widget.defaultSelected, + constructType: widget.constructType, + ) + .then((value) { + setState(() { + constructs = value; + initialized = true; + error = null; + }); + }).onError((error, stackTrace) { + ErrorHandler.logError(e: error, s: stackTrace); + setState(() { + constructs = []; + initialized = true; + error = error?.toString(); + }); + }); + } + + @override + Widget build(BuildContext context) { + return error != null + ? Center( + child: Text(error!), + ) + : Column( + children: [ + Text( + widget.title, + style: Theme.of(context).textTheme.bodyMedium, + ), + ConstructListView( + constructs: constructs.where((element) { + debugPrint("element type is ${element.content.type}"); + return element.content.lemma != + "Try interactive translation" && + element.content.lemma != "itStart" && + element.content.lemma != + MatchRuleIds.interactiveTranslation; + }).toList(), + init: initialized, + ), + ], + ); + } +} + +// list view of construct events +// parameters +// 1) a list of construct events and +// 2) a boolean indicating whether the list has been initialized +// if not initialized, show loading indicator +// for each tile, +// title = construct.content.lemma +// subtitle = total uses, equal to construct.content.uses.length +// list has a fixed height of 400 and is scrollable +class ConstructListView extends StatelessWidget { + final List constructs; + final bool init; + + const ConstructListView({ + super.key, + required this.constructs, + required this.init, + }); + + @override + Widget build(BuildContext context) { + if (!init) { + return const Expanded( + child: Center(child: CircularProgressIndicator()), + ); + } + if (constructs.isEmpty) { + return Expanded( + child: Center(child: Text(L10n.of(context)!.noDataFound)), + ); + } + return Expanded( + child: ListView.builder( + itemCount: constructs.length, + itemBuilder: (context, index) { + return ListTile( + title: Text(constructs[index].content.lemma), + subtitle: Text( + '${L10n.of(context)!.total} ${constructs[index].content.uses.length}', + ), + ); + }, + ), + ); + } +} diff --git a/lib/pangea/pages/analytics/list_summary_analytics.dart b/lib/pangea/pages/analytics/list_summary_analytics.dart new file mode 100644 index 000000000..5b2dde5de --- /dev/null +++ b/lib/pangea/pages/analytics/list_summary_analytics.dart @@ -0,0 +1,102 @@ +import 'dart:math'; + +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; + +import 'package:fluffychat/pangea/models/chart_analytics_model.dart'; +import '../../enum/use_type.dart'; + +class ListSummaryAnalytics extends StatelessWidget { + final ChartAnalyticsModel? chartAnalytics; + + const ListSummaryAnalytics({super.key, this.chartAnalytics}); + + TimeSeriesTotals? get totals => chartAnalytics?.totals; + + String spacer(int baseLength, int number) => + " " * max(baseLength - number.toString().length, 0); + + WidgetSpan spacerIconText( + String toolTip, + String space, + IconData icon, + int value, + Color? color, [ + percentage = true, + ]) => + WidgetSpan( + child: Tooltip( + message: toolTip, + child: RichText( + text: TextSpan( + children: [ + TextSpan( + text: space, + ), + WidgetSpan(child: Icon(icon, size: 14, color: color)), + TextSpan( + text: " $value${percentage ? "%" : ""}", + style: TextStyle(color: color), + ), + ], + ), + ), + ), + ); + + @override + Widget build(BuildContext context) { + if (totals == null) { + return const LinearProgressIndicator(); + } + final l10n = L10n.of(context); + + return RichText( + text: TextSpan( + children: [ + spacerIconText( + L10n.of(context) != null + ? L10n.of(context)!.totalMessages + : "Total messages sent", + "", + Icons.chat_bubble, + totals!.all, + Theme.of(context).textTheme.bodyLarge!.color, + false, + ), + if (totals!.all != 0) ...[ + spacerIconText( + l10n != null ? l10n.taTooltip : "With translation assistance", + spacer(8, totals!.all), + UseType.ta.iconData, + totals!.taPercent, + UseType.ta.color(context), + ), + spacerIconText( + l10n != null ? l10n.gaTooltip : "With grammar assistance", + spacer(4, totals!.taPercent), + UseType.ga.iconData, + totals!.gaPercent, + UseType.ga.color(context), + ), + spacerIconText( + l10n != null ? l10n.waTooltip : "Without assistance", + spacer(4, totals!.gaPercent), + UseType.wa.iconData, + totals!.waPercent, + UseType.wa.color(context), + ), + spacerIconText( + l10n != null ? l10n.unTooltip : "Other", + spacer(4, totals!.waPercent), + UseType.un.iconData, + totals!.unPercent, + UseType.un.color(context), + ), + ], + ], + ), + ); + } +} diff --git a/lib/pangea/pages/analytics/messages_bar_chart.dart b/lib/pangea/pages/analytics/messages_bar_chart.dart new file mode 100644 index 000000000..5f80577db --- /dev/null +++ b/lib/pangea/pages/analytics/messages_bar_chart.dart @@ -0,0 +1,404 @@ +import 'dart:developer'; + +import 'package:fl_chart/fl_chart.dart'; +import 'package:fluffychat/config/themes.dart'; +import 'package:fluffychat/pangea/pages/analytics/bar_chart_placeholder_data.dart'; +import 'package:fluffychat/pangea/utils/error_handler.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; + +import '../../enum/time_span.dart'; +import '../../enum/use_type.dart'; +import '../../models/chart_analytics_model.dart'; +import 'bar_chart_card.dart'; +import 'messages_legend_widget.dart'; + +class MessagesBarChart extends StatefulWidget { + final ChartAnalyticsModel? chartAnalytics; + final String barChartTitle; + + const MessagesBarChart({ + super.key, + required this.chartAnalytics, + required this.barChartTitle, + }); + + @override + State createState() => MessagesBarChartState(); +} + +class MessagesBarChartState extends State { + final double barSpace = 16; + final List> intervalGroupings = []; + + @override + initState() { + super.initState(); + } + + @override + Widget build(BuildContext context) { + final flLine = FlLine( + color: Theme.of(context).dividerColor, + strokeWidth: 1, + ); + + final flTitlesData = FlTitlesData( + show: true, + bottomTitles: AxisTitles( + sideTitles: SideTitles( + showTitles: true, + reservedSize: 28, + getTitlesWidget: bottomTitles, + ), + ), + leftTitles: AxisTitles( + sideTitles: SideTitles( + showTitles: true, + reservedSize: 40, + getTitlesWidget: leftTitles, + ), + ), + topTitles: AxisTitles( + sideTitles: SideTitles(showTitles: false), + ), + rightTitles: AxisTitles( + sideTitles: SideTitles(showTitles: false), + ), + ); + final barChartData = BarChartData( + alignment: BarChartAlignment.spaceEvenly, + barTouchData: BarTouchData( + enabled: false, + ), + // barTouchData: barTouchData, + titlesData: flTitlesData, + gridData: FlGridData( + show: true, + // checkToShowHorizontalLine: (value) => value % 10 == 0, + checkToShowHorizontalLine: (value) => true, + getDrawingHorizontalLine: (value) => flLine, + checkToShowVerticalLine: (value) => false, + getDrawingVerticalLine: (value) => flLine, + ), + borderData: FlBorderData( + show: false, + ), + groupsSpace: barSpace, + barGroups: barChartGroupData, + backgroundColor: Theme.of(context).scaffoldBackgroundColor, + ); + final barChart = BarChart( + barChartData, + swapAnimationDuration: const Duration(milliseconds: 250), + ); + + return BarChartCard( + barChartTitle: widget.barChartTitle, + barChart: barChart, + loadingData: widget.chartAnalytics == null, + legend: const MessagesLegendsListWidget(), + ); + } + + bool showLabelBasedOnTimeSpan( + TimeSpan timeSpan, + TimeSeriesInterval current, + TimeSeriesInterval? last, + int labelIndex, + ) { + switch (timeSpan) { + case TimeSpan.day: + return current.end.hour % 3 == 0; + case TimeSpan.month: + if (current.end.month != last?.end.month) { + return true; + } + double width = MediaQuery.of(context).size.width; + if (FluffyThemes.isColumnMode(context)) { + width = width - FluffyThemes.navRailWidth - FluffyThemes.columnWidth; + } + const int numDays = 28; + const int minSpacePerDay = 20; + final int availableSpaces = width ~/ minSpacePerDay; + final int showAtInterval = (numDays / availableSpaces).floor() + 1; + + final int lastDayOfCurrentMonth = + DateTime(current.end.year, current.end.month + 1, 0).day; + final bool isNextToMonth = labelIndex == 1 || + current.end.day == 2 || + current.end.day == lastDayOfCurrentMonth; + final bool shouldShowNextToMonth = showAtInterval <= 1; + return (current.end.day % showAtInterval == 0) && + (!isNextToMonth || shouldShowNextToMonth); + case TimeSpan.week: + case TimeSpan.sixmonths: + case TimeSpan.year: + default: + return true; + } + } + + String getLabelBasedOnTimeSpan( + TimeSpan timeSpan, + TimeSeriesInterval current, + TimeSeriesInterval? last, + int labelIndex, + ) { + final bool showLabel = showLabelBasedOnTimeSpan( + timeSpan, + current, + last, + labelIndex, + ); + + if (widget.chartAnalytics == null || !showLabel) { + return ""; + } + if (isInSameGroup(last, current, timeSpan)) { + return "-"; + } + + switch (widget.chartAnalytics?.timeSpan ?? TimeSpan.month) { + case TimeSpan.day: + return DateFormat(DateFormat.HOUR).format(current.end); + case TimeSpan.week: + return DateFormat(DateFormat.ABBR_WEEKDAY).format(current.end); + case TimeSpan.month: + return current.end.month != last?.end.month + ? DateFormat(DateFormat.ABBR_MONTH).format(current.end) + : DateFormat(DateFormat.DAY).format(current.end); + case TimeSpan.sixmonths: + case TimeSpan.year: + return DateFormat(DateFormat.ABBR_STANDALONE_MONTH).format(current.end); + default: + return ''; + } + } + + Widget bottomTitles(double value, TitleMeta meta) { + if (widget.chartAnalytics == null) { + return Container(); + } + String text; + final index = value.toInt(); + final TimeSpan timeSpan = widget.chartAnalytics?.timeSpan ?? TimeSpan.month; + final TimeSeriesInterval? last = + index != 0 ? intervalGroupings[index - 1].last : null; + final TimeSeriesInterval current = intervalGroupings[index].last; + + text = getLabelBasedOnTimeSpan(timeSpan, current, last, index); + + return SideTitleWidget( + axisSide: meta.axisSide, + child: Text( + text, + style: titleTextStyle(context), + ), + ); + } + + TextStyle titleTextStyle(context) => TextStyle( + color: Theme.of(context).textTheme.bodyLarge!.color, + fontSize: 10, + ); + + Widget leftTitles(double value, TitleMeta meta) { + Widget textWidget; + if (value != meta.max) { + textWidget = Text(meta.formattedValue, style: titleTextStyle(context)); + } else { + textWidget = const Icon(Icons.chat_bubble, size: 14); + } + return SideTitleWidget( + axisSide: meta.axisSide, + child: textWidget, + ); + } + + bool isInSameGroup( + TimeSeriesInterval? t1, + TimeSeriesInterval t2, + TimeSpan timeSpan, + ) { + final DateTime? date1 = t1?.end; + final DateTime date2 = t2.end; + if (timeSpan == TimeSpan.sixmonths || timeSpan == TimeSpan.year) { + return date1?.month == date2.month; + } else if (timeSpan == TimeSpan.week) { + return date1?.day == date2.day; + } else { + return false; + } + } + + void makeIntervalGroupings() { + intervalGroupings.clear(); + try { + for (final timeSeriesInterval + in widget.chartAnalytics?.timeSeries ?? []) { + //Note: if we decide we'd like to do some sort of grouping in the future, + // this is where that could happen. Currently, we're just putting one + // BarChartRod in each BarChartGroup + final TimeSeriesInterval? last = + intervalGroupings.isNotEmpty ? intervalGroupings.last.last : null; + + if (isInSameGroup( + last, + timeSeriesInterval, + widget.chartAnalytics!.timeSpan, + )) { + intervalGroupings.last.add(timeSeriesInterval); + } else { + intervalGroupings.add([timeSeriesInterval]); + } + } + } catch (err, stack) { + debugger(when: kDebugMode); + ErrorHandler.logError(e: err, s: stack); + } + } + + List get barChartGroupData { + if (widget.chartAnalytics == null) { + return BarChartPlaceHolderData.getRandomData(context); + } + + makeIntervalGroupings(); + + final List chartData = []; + + intervalGroupings.asMap().forEach((index, intervalGroup) { + chartData.add( + BarChartGroupData( + x: index, + barsSpace: barSpace, + // barRods: intervalGroup.map(constructBarChartRodData).toList(), + barRods: constructBarChartRodData(intervalGroup), + ), + ); + }); + return chartData; + } + + // BarChartRodData constructBarChartRodData(TimeSeriesInterval timeSeriesInterval) { + // final double y1 = timeSeriesInterval.spanIT.toDouble(); + // final double y2 = + // (timeSeriesInterval.spanIT + timeSeriesInterval.spanIGC).toDouble(); + // final double y3 = timeSeriesInterval.spanTotal.toDouble(); + // return BarChartRodData( + // toY: y3, + // width: 10.toDouble(), + // rodStackItems: [ + // BarChartRodStackItem(0, y1, UseType.ta.color(context)), + // BarChartRodStackItem(y1, y2, UseType.ga.color(context)), + // BarChartRodStackItem(y2, y3, UseType.wa.color(context)), + // ], + // borderRadius: BorderRadius.zero, + // ); + // } + + List constructBarChartRodData( + List timeSeriesIntervalGroup, + ) { + int y1 = 0; + int y2 = 0; + int y3 = 0; + int y4 = 0; + for (final e in timeSeriesIntervalGroup) { + y1 += e.totals.ta; + y2 += y1 + e.totals.ga; + y3 += y2 + e.totals.wa; + y4 += y3 + e.totals.un; + } + return [ + BarChartRodData( + toY: y4.toDouble(), + width: 10.toDouble(), + rodStackItems: [ + BarChartRodStackItem(0, y1.toDouble(), UseType.ta.color(context)), + BarChartRodStackItem( + y1.toDouble(), + y2.toDouble(), + UseType.ga.color(context), + ), + BarChartRodStackItem( + y2.toDouble(), + y3.toDouble(), + UseType.wa.color(context), + ), + BarChartRodStackItem( + y3.toDouble(), + y4.toDouble(), + UseType.un.color(context), + ), + ], + borderRadius: BorderRadius.zero, + ), + ]; + } + + // BarTouchData get barTouchData => BarTouchData( + // touchTooltipData: BarTouchTooltipData( + // fitInsideVertically: true, + // tooltipBgColor: Colors.blueGrey, + // getTooltipItem: (group, groupIndex, rod, rodIndex) { + // return BarTooltipItem( + // "groupindex $groupIndex rodIndex $rodIndex", + // const TextStyle( + // color: Colors.white, + // fontWeight: FontWeight.bold, + // fontSize: 18, + // ), + // children: [ + // toolTipText(rod), + // ], + // ); + // }, + // ), + // // touchCallback: (FlTouchEvent event, barTouchResponse) { + // // setState(() { + // // if (!event.isInterestedForInteractions || + // // barTouchResponse == null || + // // barTouchResponse.spot == null) { + // // touchedIndex = -1; + // // return; + // // } + // // touchedIndex = barTouchResponse.spot!.touchedBarGroupIndex; + // // }); + // // }, + // ); + + // TextSpan toolTipText(BarChartRodData rodData) { + // double rodPercentage(int index) { + // return (rodData.rodStackItems[index].toY - + // rodData.rodStackItems[index].fromY) / + // rodData.toY * + // 100; + // } + + // return TextSpan( + // children: [ + // const WidgetSpan( + // child: Icon(Icons.chat_bubble, size: 14), + // ), + // TextSpan( + // text: " ${rodData.toY}", + // ), + // TextSpan( + // text: "/nIT ${rodPercentage(0)}%", + // style: TextStyle(color: UseType.ta.color(context)), + // ), + // TextSpan( + // text: " IGC ${rodPercentage(1)}%", + // style: TextStyle(color: UseType.ga.color(context)), + // ), + // TextSpan( + // text: " Direct ${rodPercentage(2)}%", + // style: TextStyle(color: UseType.wa.color(context)), + // ), + // ], + // ); + // } +} diff --git a/lib/pangea/pages/analytics/messages_legend_widget.dart b/lib/pangea/pages/analytics/messages_legend_widget.dart new file mode 100644 index 000000000..ce1337519 --- /dev/null +++ b/lib/pangea/pages/analytics/messages_legend_widget.dart @@ -0,0 +1,36 @@ +import 'package:flutter/material.dart'; + +import 'package:fluffychat/pangea/enum/use_type.dart'; + +class MessagesLegendsListWidget extends StatelessWidget { + const MessagesLegendsListWidget({ + super.key, + }); + + @override + Widget build(BuildContext context) { + return Wrap( + spacing: 16, + children: UseType.values + .map( + // (e) => e.iconView(context, e.color(context), 20), + (e) => Row( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + width: 10, + height: 10, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: e.color(context), + ), + ), + const SizedBox(width: 4), + e.iconView(context, e.color(context), 20), + ], + ), + ) + .toList(), + ); + } +} diff --git a/lib/pangea/pages/analytics/student_analytics/student_analytics.dart b/lib/pangea/pages/analytics/student_analytics/student_analytics.dart new file mode 100644 index 000000000..55252bf8e --- /dev/null +++ b/lib/pangea/pages/analytics/student_analytics/student_analytics.dart @@ -0,0 +1,109 @@ +import 'dart:developer'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + +import 'package:matrix/matrix.dart'; + +import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart'; +import 'package:fluffychat/pangea/models/chart_analytics_model.dart'; +import 'package:fluffychat/pangea/widgets/common/list_placeholder.dart'; +import '../../../../widgets/matrix.dart'; +import '../../../controllers/pangea_controller.dart'; +import '../../../extensions/client_extension.dart'; +import '../../../utils/sync_status_util_v2.dart'; +import '../base_analytics_page.dart'; +import 'student_analytics_view.dart'; + +class StudentAnalyticsPage extends StatefulWidget { + const StudentAnalyticsPage({super.key}); + + @override + State createState() => StudentAnalyticsController(); +} + +class StudentAnalyticsController extends State { + final PangeaController _pangeaController = MatrixState.pangeaController; + + AnalyticsSelected? selected; + + @override + void initState() { + _pangeaController.matrixState.client + .updateMyLearningAnalyticsForAllClassesImIn( + _pangeaController.pStoreService, + ); + super.initState(); + } + + @override + Widget build(BuildContext context) { + return PLoadingStatusV2( + // if we everr want it rebuild the whole thing each time (and run initState again) + // but this is computationally expensive! + // key: UniqueKey(), + shimmerChild: const ListPlaceholder(), + onFinish: () { + getClassAndChatAnalytics(context); + }, + child: StudentAnalyticsView(this), + ); + } + + Future getClassAndChatAnalytics(BuildContext context) async { + final List> analyticsFutures = []; + for (final chat in chats(context)) { + analyticsFutures.add( + _pangeaController.analytics.getAnalytics( + chatId: chat.id, + studentId: userId, + ), + ); + } + for (final space in spaces(context)) { + analyticsFutures.add( + _pangeaController.analytics.getAnalytics( + classRoom: space, + studentId: userId, + ), + ); + } + analyticsFutures.add( + _pangeaController.analytics.getAnalytics(studentId: userId), + ); + await Future.wait(analyticsFutures); + setState(() {}); + } + + List spaces(BuildContext context) { + try { + return _pangeaController + .matrixState.client.classesAndExchangesImStudyingIn; + } catch (err) { + debugger(when: kDebugMode); + return []; + } + } + + List chats(BuildContext context) { + try { + return Matrix.of(context) + .client + .rooms + .where((r) => !r.isSpace && !r.isAnalyticsRoom) + .toList(); + } catch (err) { + debugger(when: kDebugMode); + return []; + } + } + + String? get userId { + final id = _pangeaController.matrixState.client.userID; + debugger(when: kDebugMode && id == null); + return id; + } + + String get username => + _pangeaController.matrixState.client.userID?.localpart ?? ""; +} diff --git a/lib/pangea/pages/analytics/student_analytics/student_analytics_view.dart b/lib/pangea/pages/analytics/student_analytics/student_analytics_view.dart new file mode 100644 index 000000000..3cbe86194 --- /dev/null +++ b/lib/pangea/pages/analytics/student_analytics/student_analytics_view.dart @@ -0,0 +1,70 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:matrix/matrix.dart'; + +import '../../../../utils/matrix_sdk_extensions/matrix_locals.dart'; +import '../base_analytics_page.dart'; +import 'student_analytics.dart'; + +class StudentAnalyticsView extends StatelessWidget { + final StudentAnalyticsController controller; + const StudentAnalyticsView(this.controller, {super.key}); + + @override + Widget build(BuildContext context) { + final List chats = controller.chats(context); + final List spaces = controller.spaces(context); + + final String pageTitle = L10n.of(context)!.myLearning; + final TabData chatTabData = TabData( + type: AnalyticsEntryType.room, + icon: Icons.chat_bubble_outline, + items: chats + .map( + (c) => TabItem( + avatar: c.avatar, + displayName: + c.getLocalizedDisplayname(MatrixLocals(L10n.of(context)!)), + id: c.id, + ), + ) + .toList(), + allowNavigateOnSelect: false, + ); + final TabData classTabData = TabData( + type: AnalyticsEntryType.space, + icon: Icons.workspaces, + items: spaces + .map( + (c) => TabItem( + avatar: c.avatar, + displayName: + c.getLocalizedDisplayname(MatrixLocals(L10n.of(context)!)), + id: c.id, + ), + ) + .toList(), + allowNavigateOnSelect: false, + ); + + return controller.userId != null + ? BaseAnalyticsPage( + pageTitle: pageTitle, + tabData1: chatTabData, + tabData2: classTabData, + defaultAnalyticsSelected: AnalyticsSelected( + controller.userId!, + AnalyticsEntryType.student, + L10n.of(context)!.allChatsAndClasses, + ), + refreshData: controller.getClassAndChatAnalytics, + alwaysSelected: AnalyticsSelected( + controller.userId!, + AnalyticsEntryType.student, + L10n.of(context)!.allChatsAndClasses, + ), + ) + : const SizedBox(); + } +} diff --git a/lib/pangea/pages/analytics/time_span_menu_button.dart b/lib/pangea/pages/analytics/time_span_menu_button.dart new file mode 100644 index 000000000..df885d6cd --- /dev/null +++ b/lib/pangea/pages/analytics/time_span_menu_button.dart @@ -0,0 +1,38 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; + +import '../../enum/time_span.dart'; + +class TimeSpanMenuButton extends StatelessWidget { + final TimeSpan value; + final void Function(TimeSpan) onChange; + const TimeSpanMenuButton({ + super.key, + required this.value, + required this.onChange, + }); + + @override + Widget build(BuildContext context) { + return PopupMenuButton( + icon: const Icon(Icons.calendar_month_outlined), + tooltip: L10n.of(context)!.changeDateRange, + initialValue: value, + onSelected: (TimeSpan? timeSpan) { + if (timeSpan == null) { + debugPrint("when is timeSpan null?"); + return; + } + onChange(timeSpan); + }, + itemBuilder: (BuildContext context) => + TimeSpan.values.map>((TimeSpan timeSpan) { + return PopupMenuItem( + value: timeSpan, + child: Text(timeSpan.string(context)), + ); + }).toList(), + ); + } +} diff --git a/lib/pangea/pages/analytics/vocab_bar_chart.dart b/lib/pangea/pages/analytics/vocab_bar_chart.dart new file mode 100644 index 000000000..34dc16a69 --- /dev/null +++ b/lib/pangea/pages/analytics/vocab_bar_chart.dart @@ -0,0 +1,174 @@ +import 'package:flutter/material.dart'; + +import 'package:fl_chart/fl_chart.dart'; + +import 'package:fluffychat/pangea/controllers/pangea_controller.dart'; +import 'package:fluffychat/pangea/models/headwords.dart'; +import 'package:fluffychat/pangea/pages/analytics/base_analytics_page.dart'; +import 'package:fluffychat/widgets/matrix.dart'; +import 'bar_chart_card.dart'; +import 'messages_legend_widget.dart'; + +class VocabBarChart extends StatefulWidget { + final AnalyticsSelected? selected; + final AnalyticsSelected defaultSelected; + + const VocabBarChart({ + super.key, + required this.selected, + required this.defaultSelected, + }); + + @override + State createState() => VocabBarChartState(); +} + +class VocabBarChartState extends State { + final double barSpace = 16; + + final PangeaController _pangeaController = MatrixState.pangeaController; + + @override + initState() { + super.initState(); + } + + @override + Widget build(BuildContext context) { + return FutureBuilder( + future: _pangeaController.analytics.vocabHeadsByAnalyticsSelected( + selected: widget.selected, + defaultSelected: widget.defaultSelected, + ), + builder: ((context, snapshot) => BarChartCard( + barChartTitle: (widget.selected != null + ? widget.selected! + : widget.defaultSelected) + .displayName, + barChart: snapshot.hasData + ? buildBarChart(context, snapshot.data!) + : null, + loadingData: snapshot.connectionState != ConnectionState.done, + legend: const MessagesLegendsListWidget(), + )), + ); + } + + TextStyle titleTextStyle(BuildContext context) => TextStyle( + color: Theme.of(context).textTheme.bodyLarge!.color, + fontSize: 10, + ); + + BarChart buildBarChart(BuildContext context, VocabHeadwords vocabHeadwords) { + final flLine = FlLine( + color: Theme.of(context).dividerColor, + strokeWidth: 1, + ); + + return BarChart( + BarChartData( + alignment: BarChartAlignment.spaceEvenly, + barTouchData: BarTouchData( + enabled: false, + ), + // barTouchData: barTouchData, + titlesData: FlTitlesData( + show: true, + bottomTitles: AxisTitles( + sideTitles: SideTitles( + showTitles: true, + reservedSize: 28, + getTitlesWidget: (double value, TitleMeta meta) => + SideTitleWidget( + axisSide: meta.axisSide, + child: Text( + vocabHeadwords.lists[value.toInt()].name, + style: titleTextStyle(context), + ), + ), + ), + ), + leftTitles: AxisTitles( + sideTitles: SideTitles( + showTitles: true, + reservedSize: 40, + getTitlesWidget: (double value, TitleMeta meta) { + Widget textWidget; + if (value != meta.max) { + textWidget = + Text(meta.formattedValue, style: titleTextStyle(context)); + } else { + textWidget = const Icon(Icons.abc_outlined, size: 14); + } + return SideTitleWidget( + axisSide: meta.axisSide, + child: textWidget, + ); + }, + ), + ), + topTitles: AxisTitles( + sideTitles: SideTitles(showTitles: false), + ), + rightTitles: AxisTitles( + sideTitles: SideTitles(showTitles: false), + ), + ), + gridData: FlGridData( + show: true, + // checkToShowHorizontalLine: (value) => value % 10 == 0, + checkToShowHorizontalLine: (value) => true, + getDrawingHorizontalLine: (value) => flLine, + checkToShowVerticalLine: (value) => false, + getDrawingVerticalLine: (value) => flLine, + ), + borderData: FlBorderData( + show: false, + ), + groupsSpace: barSpace, + barGroups: barChartGroupData(vocabHeadwords), + backgroundColor: Colors.transparent, + ), + swapAnimationDuration: const Duration(milliseconds: 250), + ); + } + + List barChartGroupData(VocabHeadwords vocabHeadwords) { + // sort vocab into lists + // calculate levels based on vocab data + + final List chartData = []; + + vocabHeadwords.lists.asMap().forEach((index, intervalGroup) { + chartData.add( + BarChartGroupData( + x: index, + barsSpace: barSpace, + // barRods: intervalGroup.map(constructBarChartRodData).toList(), + barRods: constructBarChartRodData(intervalGroup), + ), + ); + }); + return chartData; + } + + List constructBarChartRodData(VocabList vocabList) { + final ListTotals listTotals = vocabList.calculuateTotals(); + final y1 = listTotals.low; + final y2 = y1 + listTotals.medium; + final y3 = y2 + listTotals.high; + + return [ + BarChartRodData( + toY: y3.toDouble(), + width: 10.toDouble(), + rodStackItems: [ + BarChartRodStackItem(0, y1.toDouble(), Colors.red), + BarChartRodStackItem(y1.toDouble(), y2.toDouble(), Colors.grey), + BarChartRodStackItem(y2.toDouble(), y3.toDouble(), Colors.green), + ], + borderRadius: BorderRadius.zero, + ), + ]; + } +} diff --git a/lib/pangea/pages/analytics/vocab_legend_widget.dart b/lib/pangea/pages/analytics/vocab_legend_widget.dart new file mode 100644 index 000000000..da6413c3e --- /dev/null +++ b/lib/pangea/pages/analytics/vocab_legend_widget.dart @@ -0,0 +1,36 @@ +import 'package:flutter/material.dart'; + +import 'package:fluffychat/pangea/enum/use_type.dart'; + +class VocabLegendsListWidget extends StatelessWidget { + const VocabLegendsListWidget({ + super.key, + }); + + @override + Widget build(BuildContext context) { + return Wrap( + spacing: 16, + children: UseType.values + .where((e) => e != UseType.un) + .map( + (e) => Row( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + width: 10, + height: 10, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: e.color(context), + ), + ), + const SizedBox(width: 4), + e.iconView(context, e.color(context), 20), + ], + ), + ) + .toList(), + ); + } +} diff --git a/lib/pangea/pages/class_analytics/measure_able.dart b/lib/pangea/pages/class_analytics/measure_able.dart new file mode 100644 index 000000000..444997995 --- /dev/null +++ b/lib/pangea/pages/class_analytics/measure_able.dart @@ -0,0 +1,53 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/scheduler.dart'; + +class MeasurableWidget extends StatefulWidget { + final Widget child; + + Function? triggerMeasure; + final Function(Size? size, Offset? position) onChange; + + MeasurableWidget({super.key, required this.onChange, required this.child}); + + @override + _WidgetSizeState createState() => _WidgetSizeState(); +} + +class _WidgetSizeState extends State { + var widgetKey = GlobalKey(); + Offset? oldPosition; + @override + void initState() { + // TODO: implement initState + super.initState(); + } + + void postFrameCallback(_) { + final context = widgetKey.currentContext; + if (context == null) return; + + final newSize = context.size; + + final RenderBox? box = + widgetKey.currentContext?.findRenderObject() as RenderBox?; + final Offset? position = box?.localToGlobal(Offset.zero); + + if (oldPosition != null) { + if (oldPosition!.dx == position!.dx && oldPosition!.dy == position.dy) { + return; + } + } + oldPosition = position; + + widget.onChange(newSize, position); + } + + @override + Widget build(BuildContext context) { + SchedulerBinding.instance.addPostFrameCallback(postFrameCallback); + return Container( + key: widgetKey, + child: widget.child, + ); + } +} diff --git a/lib/pangea/pages/class_invitation_selection/class_invitation_selection.dart b/lib/pangea/pages/class_invitation_selection/class_invitation_selection.dart new file mode 100644 index 000000000..fad4e6b53 --- /dev/null +++ b/lib/pangea/pages/class_invitation_selection/class_invitation_selection.dart @@ -0,0 +1,165 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; + +import 'package:adaptive_dialog/adaptive_dialog.dart'; +import 'package:collection/collection.dart'; +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; +import 'package:go_router/go_router.dart'; +import 'package:matrix/matrix.dart'; + +import 'package:fluffychat/widgets/matrix.dart'; + +class ClassInvitationSelection extends StatefulWidget { + const ClassInvitationSelection({super.key}); + + @override + ClassInvitationSelectionController createState() => + ClassInvitationSelectionController(); +} + +class ClassInvitationSelectionController + extends State { + TextEditingController controller = TextEditingController(); + late String currentSearchTerm; + bool loading = true; + List allClassParticipants = []; + List allChatParticipants = []; + List classParticipantsFilteredByChat = []; + + ///Class participants filtered by chat participants and any search query + List foundProfiles = []; + + Timer? coolDown; + + String? get roomId => GoRouterState.of(context).pathParameters['roomid']; + + StreamSubscription? _spaceSubscription; + + void inviteAction(BuildContext context, String id) async { + final room = Matrix.of(context).client.getRoomById(roomId!)!; + if (OkCancelResult.ok != + await showOkCancelAlertDialog( + context: context, + title: L10n.of(context)!.inviteContactToGroup(id, room.name), + okLabel: L10n.of(context)!.yes, + cancelLabel: L10n.of(context)!.cancel, + )) { + return; + } + final success = await showFutureLoadingDialog( + context: context, + future: () => room.invite(id), + ); + if (success.error == null) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text(L10n.of(context)!.contactHasBeenInvitedToTheGroup), + ), + ); + } + } + + void setDisplayListWithCoolDown(String text) { + coolDown?.cancel(); + coolDown = Timer( + const Duration(milliseconds: 0), + () => _setfoundProfiles(context, text), + ); + } + + void _setfoundProfiles(BuildContext context, String text) { + coolDown?.cancel(); + // debugger(when: kDebugMode); + allClassParticipants = getClassParticipants(context); + allChatParticipants = getChatParticipants(context); + classParticipantsFilteredByChat = getClassParticipantsFilteredByChat(); + + currentSearchTerm = text; + + foundProfiles = currentSearchTerm.isNotEmpty + ? classParticipantsFilteredByChat + .where( + (user) => + user.displayName?.contains(text) ?? + false || user.id.contains(text), + ) + .toList() + : classParticipantsFilteredByChat; + + setState(() => loading = false); + } + + Room? _getParentClass(BuildContext context) => Matrix.of(context) + .client + .rooms + .where( + (r) => r.isSpace, + ) + .firstWhereOrNull( + (space) => space.spaceChildren.any( + (ithroom) => ithroom.roomId == roomId, + ), + ); + + List getClassParticipants(BuildContext context) { + final Room? parent = _getParentClass(context); + if (parent == null) return []; + + final List classParticipants = + parent.getParticipants([Membership.join]); + return classParticipants; + } + + List getChatParticipants(BuildContext context) => Matrix.of(context) + .client + .getRoomById(roomId!)! + .getParticipants([Membership.join, Membership.invite]).toList(); + + List getClassParticipantsFilteredByChat() => allClassParticipants + .where( + (profile) => + allChatParticipants.indexWhere((u) => u.id == profile.id) == -1, + ) + .toList(); + + @override + void initState() { + Future.delayed(Duration.zero, () async { + final Room? classParent = _getParentClass(context); + await classParent + ?.requestParticipants([Membership.join, Membership.invite]); + _setfoundProfiles(context, ""); + _spaceSubscription = Matrix.of(context) + .client + .onSync + .stream + .where( + (event) => + event.rooms?.join?.keys + .any((ithRoomId) => ithRoomId == classParent?.id) ?? + false, + ) + .listen( + (SyncUpdate syncUpdate) async { + debugPrint("updating lists"); + await classParent + ?.requestParticipants([Membership.join, Membership.invite]); + setState(() {}); + }, + ); + }); + super.initState(); + } + + @override + void dispose() { + _spaceSubscription?.cancel(); + super.dispose(); + } + + @override + // Widget build(BuildContext context) => InvitationSelectionView(this); + Widget build(BuildContext context) => const SizedBox(); +} diff --git a/lib/pangea/pages/class_settings/class_name_header.dart b/lib/pangea/pages/class_settings/class_name_header.dart new file mode 100644 index 000000000..39adaa126 --- /dev/null +++ b/lib/pangea/pages/class_settings/class_name_header.dart @@ -0,0 +1,51 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/src/widgets/visibility.dart' as visible; + +import 'package:matrix/matrix.dart'; + +import 'package:fluffychat/pages/chat_details/chat_details.dart'; +import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart'; + +class ClassNameHeader extends StatelessWidget { + final Room room; + final ChatDetailsController controller; + const ClassNameHeader({ + super.key, + required this.room, + required this.controller, + }); + + @override + Widget build(BuildContext context) { + return TextButton.icon( + onPressed: + room.canSendDefaultStates ? controller.setDisplaynameAction : null, + onHover: room.canSendDefaultStates ? controller.hoverEditNameIcon : null, + style: TextButton.styleFrom( + padding: const EdgeInsets.symmetric(horizontal: 25), + ), + label: visible.Visibility( + visible: controller.showEditNameIcon, + child: Icon( + Icons.edit, + color: Theme.of(context).colorScheme.onBackground, + ), + ), + icon: room.nameAndRoomTypeIcon( + TextStyle( + fontSize: 20, + color: Theme.of(context).textTheme.bodyLarge!.color, + ), + ), + // icon: Text( + // room.getLocalizedDisplayname( + // MatrixLocals(L10n.of(context)!), + // ), + // style: TextStyle( + // fontSize: 20, + // color: Theme.of(context).textTheme.bodyText1!.color, + // ), + // ), + ); + } +} diff --git a/lib/pangea/pages/class_settings/class_settings_page.dart b/lib/pangea/pages/class_settings/class_settings_page.dart new file mode 100644 index 000000000..d0c2d385d --- /dev/null +++ b/lib/pangea/pages/class_settings/class_settings_page.dart @@ -0,0 +1,96 @@ +import 'dart:async'; +import 'dart:developer'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:go_router/go_router.dart'; +import 'package:matrix/matrix.dart'; + +import 'package:fluffychat/pangea/controllers/pangea_controller.dart'; +import 'package:fluffychat/widgets/layouts/empty_page.dart'; +import '../../../widgets/matrix.dart'; +import '../../utils/error_handler.dart'; +import '../../utils/set_class_name.dart'; +import '../../widgets/space/class_settings.dart'; +import 'class_settings_view.dart'; +import 'p_class_widgets/room_rules_editor.dart'; + +class ClassSettingsPage extends StatefulWidget { + const ClassSettingsPage({super.key}); + + @override + State createState() => ClassSettingsController(); +} + +class ClassSettingsController extends State { + PangeaController pangeaController = MatrixState.pangeaController; + + final GlobalKey rulesEditorKey = GlobalKey(); + final GlobalKey classSettingsKey = + GlobalKey(); + + Room? room; + + String? get roomId => GoRouterState.of(context).pathParameters['roomid']; + + Future handleSave(BuildContext context) async { + if (classSettingsKey.currentState!.sameLanguages) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text(L10n.of(context)!.noIdenticalLanguages), + ), + ); + return; + } + if (rulesEditorKey.currentState != null) { + await rulesEditorKey.currentState?.setRoomRules(roomId!); + } else { + debugger(when: kDebugMode); + ErrorHandler.logError(m: "Null rules editor state"); + } + if (classSettingsKey.currentState != null) { + await classSettingsKey.currentState?.setClassSettings( + roomId!, + ); + } else { + debugger(when: kDebugMode); + ErrorHandler.logError(m: "Null class settings state"); + } + } + + void goback(BuildContext context) { + context.push("/spaces/$roomId"); + } + + String get className => + Matrix.of(context).client.getRoomById(roomId!)?.name ?? ''; + + @override + void initState() { + // TODO: implement initState + super.initState(); + + Future.delayed(Duration.zero, () { + room = Matrix.of(context).client.getRoomById(roomId!); + if (room == null) { + debugger(when: kDebugMode); + context.pop(); + } + setState(() {}); + }); + } + //PTODO - show loading widget + + void setDisplaynameAction() => setClassDisplayname(context, roomId); + + bool showEditNameIcon = false; + void hoverEditNameIcon(bool hovering) => + setState(() => showEditNameIcon = !showEditNameIcon); + + @override + Widget build(BuildContext context) => room != null + ? ClassSettingsPageView(controller: this) + : const EmptyPage(); +} diff --git a/lib/pangea/pages/class_settings/class_settings_view.dart b/lib/pangea/pages/class_settings/class_settings_view.dart new file mode 100644 index 000000000..f6fa434e9 --- /dev/null +++ b/lib/pangea/pages/class_settings/class_settings_view.dart @@ -0,0 +1,85 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; +import 'package:go_router/go_router.dart'; + +import 'package:fluffychat/pangea/pages/class_settings/class_settings_page.dart'; +import 'package:fluffychat/pangea/pages/class_settings/p_class_widgets/room_rules_editor.dart'; +import 'package:fluffychat/pangea/widgets/space/class_settings.dart'; +import '../../../widgets/layouts/max_width_body.dart'; + +class ClassSettingsPageView extends StatelessWidget { + final ClassSettingsController controller; + const ClassSettingsPageView({super.key, required this.controller}); + + @override + Widget build(BuildContext context) { + debugPrint("in class settings page with roomId ${controller.roomId}"); + // PTODO-Lala - make the page scrollable anywhere, not just in the area of the elements + // so like, the user should be able scroll using the mouse wheel from anywhere within this view + // currently, your cursor needs be horizontally within the tiles in order to scroll + return Scaffold( + appBar: AppBar( + leading: GoRouterState.of(context).path?.startsWith('/spaces/') ?? false + ? null + : IconButton( + icon: const Icon(Icons.close_outlined), + onPressed: () => controller.goback(context), + ), + centerTitle: true, + title: Text(L10n.of(context)!.classSettings), + ), + body: ListView( + children: [ + MaxWidthBody( + child: ListTile( + title: Center( + child: TextButton.icon( + onPressed: controller.setDisplaynameAction, + onHover: controller.hoverEditNameIcon, + style: TextButton.styleFrom( + padding: const EdgeInsets.symmetric(horizontal: 25), + ), + label: Visibility( + visible: controller.showEditNameIcon, + child: Icon( + Icons.edit, + color: Theme.of(context).colorScheme.onBackground, + ), + ), + icon: Text( + controller.className, + style: TextStyle( + color: Theme.of(context).colorScheme.secondary, + fontWeight: FontWeight.bold, + ), + ), + ), + ), + ), + ), + MaxWidthBody( + child: Column( + children: [ + ClassSettings( + roomId: controller.roomId, + startOpen: true, + ), + RoomRulesEditor(roomId: controller.roomId), + ], + ), + ), + ], + ), + floatingActionButton: FloatingActionButton.extended( + onPressed: () => showFutureLoadingDialog( + context: context, + future: () => controller.handleSave(context), + ), + label: Text(L10n.of(context)!.saveChanges), + icon: const Icon(Icons.save_outlined), + ), + ); + } +} diff --git a/lib/pangea/pages/class_settings/p_class_widgets/class_analytics_button.dart b/lib/pangea/pages/class_settings/p_class_widgets/class_analytics_button.dart new file mode 100644 index 000000000..1ac293494 --- /dev/null +++ b/lib/pangea/pages/class_settings/p_class_widgets/class_analytics_button.dart @@ -0,0 +1,35 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:go_router/go_router.dart'; + +class ClassAnalyticsButton extends StatelessWidget { + const ClassAnalyticsButton({super.key}); + + @override + Widget build(BuildContext context) { + final roomId = GoRouterState.of(context).pathParameters['roomid']; + final iconColor = Theme.of(context).textTheme.bodyLarge!.color; + + return Column( + children: [ + ListTile( + title: Text( + L10n.of(context)!.classAnalytics, + style: TextStyle( + color: Theme.of(context).colorScheme.secondary, + fontWeight: FontWeight.bold, + ), + ), + subtitle: Text(L10n.of(context)!.classAnalyticsDesc), + leading: CircleAvatar( + backgroundColor: Theme.of(context).scaffoldBackgroundColor, + foregroundColor: iconColor, + child: const Icon(Icons.analytics_outlined), + ), + onTap: () => context.go('/rooms/analytics/$roomId'), + ), + ], + ); + } +} diff --git a/lib/pangea/pages/class_settings/p_class_widgets/class_description_button.dart b/lib/pangea/pages/class_settings/p_class_widgets/class_description_button.dart new file mode 100644 index 000000000..0d6779e82 --- /dev/null +++ b/lib/pangea/pages/class_settings/p_class_widgets/class_description_button.dart @@ -0,0 +1,53 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:matrix/matrix.dart'; + +import 'package:fluffychat/pages/chat_details/chat_details.dart'; + +class ClassDescriptionButton extends StatelessWidget { + final Room room; + final ChatDetailsController controller; + const ClassDescriptionButton({ + super.key, + required this.room, + required this.controller, + }); + + @override + Widget build(BuildContext context) { + final iconColor = Theme.of(context).textTheme.bodyLarge!.color; + return Column( + children: [ + ListTile( + onTap: room.canSendEvent(EventTypes.RoomTopic) + ? controller.setTopicAction + : null, + leading: room.canSendEvent(EventTypes.RoomTopic) + ? CircleAvatar( + backgroundColor: Theme.of(context).scaffoldBackgroundColor, + foregroundColor: iconColor, + child: const Icon(Icons.topic_outlined), + ) + : null, + subtitle: Text( + room.topic.isEmpty + ? (room.isSpace + ? L10n.of(context)!.classDescriptionDesc + : L10n.of(context)!.chatTopicDesc) + : room.topic, + ), + title: Text( + room.isSpace + ? L10n.of(context)!.classDescription + : L10n.of(context)!.chatTopic, + style: TextStyle( + color: Theme.of(context).colorScheme.secondary, + fontWeight: FontWeight.bold, + ), + ), + ), + ], + ); + } +} diff --git a/lib/pangea/pages/class_settings/p_class_widgets/class_details_toggle_add_students_tile.dart b/lib/pangea/pages/class_settings/p_class_widgets/class_details_toggle_add_students_tile.dart new file mode 100644 index 000000000..051824659 --- /dev/null +++ b/lib/pangea/pages/class_settings/p_class_widgets/class_details_toggle_add_students_tile.dart @@ -0,0 +1,40 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; + +import '../../../../pages/chat_details/chat_details.dart'; + +class SpaceDetailsToggleAddStudentsTile extends StatelessWidget { + const SpaceDetailsToggleAddStudentsTile({ + super.key, + required this.controller, + }); + + final ChatDetailsController controller; + + @override + Widget build(BuildContext context) { + return ListTile( + title: Text( + L10n.of(context)!.addStudents, + style: TextStyle( + color: Theme.of(context).colorScheme.secondary, + fontWeight: FontWeight.bold, + ), + ), + leading: CircleAvatar( + backgroundColor: Theme.of(context).scaffoldBackgroundColor, + foregroundColor: Theme.of(context).textTheme.bodyLarge!.color, + child: const Icon( + Icons.add, + ), + ), + trailing: Icon( + controller.displayAddStudentOptions + ? Icons.keyboard_arrow_down_outlined + : Icons.keyboard_arrow_right_outlined, + ), + onTap: controller.toggleAddStudentOptions, + ); + } +} diff --git a/lib/pangea/pages/class_settings/p_class_widgets/class_invitation_buttons.dart b/lib/pangea/pages/class_settings/p_class_widgets/class_invitation_buttons.dart new file mode 100644 index 000000000..8c1cb0a6c --- /dev/null +++ b/lib/pangea/pages/class_settings/p_class_widgets/class_invitation_buttons.dart @@ -0,0 +1,146 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:go_router/go_router.dart'; +import 'package:matrix/matrix.dart'; +import 'package:universal_html/html.dart' as html; + +import 'package:fluffychat/pangea/config/environment.dart'; +import 'package:fluffychat/pangea/constants/url_query_parameter_keys.dart'; +import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart'; +import 'package:fluffychat/widgets/matrix.dart'; +import '../../../../utils/fluffy_share.dart'; +import '../../../../widgets/avatar.dart'; + +class ClassInvitationButtons extends StatelessWidget { + final String roomId; + const ClassInvitationButtons({super.key, required this.roomId}); + + @override + Widget build(BuildContext context) { + final Room? room = Matrix.of(context).client.getRoomById(roomId); + if (room == null) return Text(L10n.of(context)!.oopsSomethingWentWrong); + + final copyClassLinkListTile = ListTile( + title: Text( + L10n.of(context)!.copyClassLink, + style: TextStyle( + color: Theme.of(context).colorScheme.secondary, + fontWeight: FontWeight.bold, + ), + ), + subtitle: Text(L10n.of(context)!.copyClassLinkDesc), + leading: CircleAvatar( + backgroundColor: Theme.of(context).scaffoldBackgroundColor, + foregroundColor: Theme.of(context).textTheme.bodyLarge!.color, + child: const Icon( + Icons.copy_outlined, + ), + ), + onTap: () { + final String initialUrl = + kIsWeb ? html.window.origin! : Environment.frontendURL; + FluffyShare.share( + "$initialUrl/#/join_with_link?${UrlQueryParameterKeys.classCode}=${room.classCode}", + context, + ); + }, + ); + + final copyCodeListTile = ListTile( + title: Text( + "${L10n.of(context)!.copyClassCode}: ${room.classCode}", + style: TextStyle( + color: Theme.of(context).colorScheme.secondary, + fontWeight: FontWeight.bold, + ), + ), + subtitle: Text(L10n.of(context)!.copyClassCodeDesc), + leading: CircleAvatar( + backgroundColor: Theme.of(context).scaffoldBackgroundColor, + foregroundColor: Theme.of(context).textTheme.bodyLarge!.color, + child: const Icon( + Icons.copy, + ), + ), + onTap: () async { + //PTODO-Lala: Standarize toast + //PTODO - explore using Fluffyshare for this + await Clipboard.setData(ClipboardData(text: room.classCode)); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text(L10n.of(context)!.copiedToClipboard)), + ); + }, + ); + + // final inviateWithEmailListTile = ListTile( + // enabled: false, + // //PTODO - add to copy + // title: const Text("Invite with email"), + // subtitle: const Text("Coming soon"), + // leading: CircleAvatar( + // backgroundColor: Theme.of(context).primaryColor, + // foregroundColor: Colors.white, + // radius: Avatar.defaultSize / 2, + // child: const Icon(Icons.email_outlined), + // ), + // //PTODO: Add invite with email functionality + // // onTap: () => VRouter.of(context).to('invite'), + // ); + + // final addFromGoogleClassooomListTile = ListTile( + // enabled: false, + // //PTODO - add to copy + // title: Text( + // L10n.of(context)!.addFromGoogleClassroom, + // style: TextStyle( + // color: Theme.of(context).colorScheme.secondary, + // fontWeight: FontWeight.bold, + // ), + // ), + // subtitle: Text(L10n.of(context)!.addFromGoogleClassroomDesc), + // leading: CircleAvatar( + // backgroundColor: Theme.of(context).primaryColor, + // foregroundColor: Colors.white, + // radius: Avatar.defaultSize / 2, + // child: SvgPicture.asset( + // "assets/pangea/google.svg", + // height: 20, + // width: 20, + // ), + // ), + // //PTODO: Add via google classroom functionality + // // onTap: () => VRouter.of(context).to('invite'), + // ); + + final inviteStudentByUserNameTile = ListTile( + title: Text( + L10n.of(context)!.inviteStudentByUserName, + style: TextStyle( + color: Theme.of(context).colorScheme.secondary, + fontWeight: FontWeight.bold, + ), + ), + subtitle: Text(L10n.of(context)!.inviteStudentByUserNameDesc), + leading: CircleAvatar( + backgroundColor: Theme.of(context).primaryColor, + foregroundColor: Colors.white, + radius: Avatar.defaultSize / 2, + child: const Icon(Icons.add_outlined), + ), + onTap: () => context.go('/rooms/$roomId/invite'), + ); + + return Column( + children: [ + // inviteStudentByUserNameTile, + copyClassLinkListTile, + copyCodeListTile, + // inviateWithEmailListTile, + // addFromGoogleClassooomListTile, + ], + ); + } +} diff --git a/lib/pangea/pages/class_settings/p_class_widgets/class_name_button.dart b/lib/pangea/pages/class_settings/p_class_widgets/class_name_button.dart new file mode 100644 index 000000000..7d4229e90 --- /dev/null +++ b/lib/pangea/pages/class_settings/p_class_widgets/class_name_button.dart @@ -0,0 +1,48 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:matrix/matrix.dart'; + +import 'package:fluffychat/pages/chat_details/chat_details.dart'; +import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart'; + +class ClassNameButton extends StatelessWidget { + final Room room; + final ChatDetailsController controller; + const ClassNameButton({ + super.key, + required this.room, + required this.controller, + }); + + @override + Widget build(BuildContext context) { + final iconColor = Theme.of(context).textTheme.bodyLarge!.color; + return Column( + children: [ + ListTile( + onTap: controller.setDisplaynameAction, + title: Text( + room.isSpace + ? L10n.of(context)!.changeTheNameOfTheClass + : L10n.of(context)!.changeTheNameOfTheChat, + style: TextStyle( + color: Theme.of(context).colorScheme.secondary, + fontWeight: FontWeight.bold, + ), + ), + leading: CircleAvatar( + backgroundColor: Theme.of(context).scaffoldBackgroundColor, + foregroundColor: iconColor, + child: const Icon(Icons.people_outline_outlined), + ), + subtitle: Text( + room.getLocalizedDisplayname( + MatrixLocals(L10n.of(context)!), + ), + ), + ), + ], + ); + } +} diff --git a/lib/pangea/pages/class_settings/p_class_widgets/class_settings_button.dart b/lib/pangea/pages/class_settings/p_class_widgets/class_settings_button.dart new file mode 100644 index 000000000..3915d0ca0 --- /dev/null +++ b/lib/pangea/pages/class_settings/p_class_widgets/class_settings_button.dart @@ -0,0 +1,41 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:go_router/go_router.dart'; + +class ClassSettingsButton extends StatelessWidget { + const ClassSettingsButton({super.key}); + + // final PangeaController _pangeaController = MatrixState.pangeaController; + + @override + Widget build(BuildContext context) { + // final roomId = GoRouterState.of(context).pathParameters['roomid']; + + final iconColor = Theme.of(context).textTheme.bodyLarge!.color; + return Column( + children: [ + ListTile( + // enabled: roomId != null && + // _pangeaController.classController + // .getClassModelBySpaceIdLocal(roomId) != + // null, + title: Text( + L10n.of(context)!.classSettings, + style: TextStyle( + color: Theme.of(context).colorScheme.secondary, + fontWeight: FontWeight.bold, + ), + ), + subtitle: Text(L10n.of(context)!.classSettingsDesc), + leading: CircleAvatar( + backgroundColor: Theme.of(context).scaffoldBackgroundColor, + foregroundColor: iconColor, + child: const Icon(Icons.settings_outlined), + ), + onTap: () => context.go('/class_settings'), + ), + ], + ); + } +} diff --git a/lib/pangea/pages/class_settings/p_class_widgets/class_show_edit_dialog.dart b/lib/pangea/pages/class_settings/p_class_widgets/class_show_edit_dialog.dart new file mode 100644 index 000000000..d18d09c39 --- /dev/null +++ b/lib/pangea/pages/class_settings/p_class_widgets/class_show_edit_dialog.dart @@ -0,0 +1,37 @@ +import 'package:flutter/material.dart'; + +import 'package:adaptive_dialog/adaptive_dialog.dart'; +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; + +void showEditFieldDialog(BuildContext context, String title) async { + // final room = Matrix.of(context).client.getRoomById(roomId!)!; + final input = await showTextInputDialog( + useRootNavigator: false, + context: context, + title: title, + okLabel: L10n.of(context)!.ok, + cancelLabel: L10n.of(context)!.cancel, + textFields: [ + DialogTextField( + hintText: title, + // initialText: room.topic, + minLines: 1, + maxLines: 4, + ), + ], + ); + if (input == null) return; + final success = await showFutureLoadingDialog( + context: context, + // TODO change this later + future: () async => null, + ); + if (success.error == null) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text(L10n.of(context)!.groupDescriptionHasBeenChanged), + ), + ); + } +} diff --git a/lib/pangea/pages/class_settings/p_class_widgets/class_textfields_group.dart b/lib/pangea/pages/class_settings/p_class_widgets/class_textfields_group.dart new file mode 100644 index 000000000..a6a33d9c7 --- /dev/null +++ b/lib/pangea/pages/class_settings/p_class_widgets/class_textfields_group.dart @@ -0,0 +1,38 @@ +// import 'package:fluffychat/pangea/controllers/pangea_controller.dart'; +// import 'package:flutter/cupertino.dart'; + +// import '../../../../pages/new_space/new_space.dart'; +// import '../../../widgets/common_widgets/p_input_field.dart'; + +// import 'package:flutter_gen/gen_l10n/l10n.dart'; + +// class ClassTextFieldGroup extends StatelessWidget { +// PangeaController controller; +// ClassTextFieldGroup({Key? key, required this.controller}) : super(key: key); + +// @override +// Widget build(BuildContext context) { +// return Column( +// children: [ +// PInputTextField( +// controller: controller.classController.cityController, +// hintText: L10n.of(context)!.enterCityName, +// labelText: L10n.of(context)!.optionalCity, +// onSubmit: (String value) {}, +// ), +// PInputTextField( +// controller: controller.classController.cityController, +// hintText: L10n.of(context)!.enterCountryName, +// labelText: L10n.of(context)!.optionalCountry, +// onSubmit: (String value) {}, +// ), +// PInputTextField( +// controller: controller.classController.cityController, +// hintText: L10n.of(context)!.enterSchoolName, +// labelText: L10n.of(context)!.optionalSchool, +// onSubmit: (String value) {}, +// ), +// ], +// ); +// } +// } diff --git a/lib/pangea/pages/class_settings/p_class_widgets/delete_class_tile.dart b/lib/pangea/pages/class_settings/p_class_widgets/delete_class_tile.dart new file mode 100644 index 000000000..7e3fc3af6 --- /dev/null +++ b/lib/pangea/pages/class_settings/p_class_widgets/delete_class_tile.dart @@ -0,0 +1,149 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; +import 'package:go_router/go_router.dart'; +import 'package:matrix/matrix.dart'; + +import 'package:fluffychat/pangea/utils/delete_room.dart'; +import 'package:fluffychat/widgets/matrix.dart'; + +class DeleteSpaceTile extends StatelessWidget { + final Room room; + + const DeleteSpaceTile({ + super.key, + required this.room, + }); + + @override + Widget build(BuildContext context) { + bool classNameMatch = true; + final textController = TextEditingController(); + Future deleteSpace() async { + final Client client = Matrix.of(context).client; + final GetSpaceHierarchyResponse spaceHierarchy = + await client.getSpaceHierarchy(room.id); + + if (spaceHierarchy.rooms.isNotEmpty) { + final List spaceChats = spaceHierarchy.rooms + .where((c) => c.roomId != room.id) + .map((e) => Matrix.of(context).client.getRoomById(e.roomId)) + .where((c) => c != null && !c.isSpace && !c.isDirectChat) + .cast() + .toList(); + + await Future.wait( + spaceChats.map((c) => deleteRoom(c.id, client)), + ); + } + deleteRoom(room.id, client); + context.go('/rooms'); + return; + } + + Future deleteChat() { + context.go('/rooms'); + return deleteRoom(room.id, Matrix.of(context).client); + } + + Future deleteChatAction() async { + showDialog( + context: context, + useRootNavigator: false, + builder: (context) { + return StatefulBuilder( + builder: (context, setState) { + return AlertDialog( + title: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + room.isSpace + ? L10n.of(context)!.areYouSureDeleteClass + : L10n.of(context)!.areYouSureDeleteGroup, + style: const TextStyle( + fontSize: 20, + ), + textAlign: TextAlign.center, + ), + const SizedBox(height: 5), + Text( + L10n.of(context)!.cannotBeReversed, + style: const TextStyle( + fontSize: 16, + ), + textAlign: TextAlign.center, + ), + const SizedBox(height: 10), + if (room.isSpace) + Text( + L10n.of(context)!.enterDeletedClassName, + style: const TextStyle( + fontSize: 14, + ), + textAlign: TextAlign.center, + ), + ], + ), + content: room.isSpace + ? TextField( + autofocus: true, + controller: textController, + decoration: InputDecoration( + hintText: room.name, + errorText: !classNameMatch + ? L10n.of(context)!.incorrectClassName + : null, + ), + ) + : null, + actions: [ + TextButton( + child: Text(L10n.of(context)!.ok), + onPressed: () async { + if (room.isSpace) { + setState(() { + classNameMatch = textController.text == room.name; + }); + if (classNameMatch) { + Navigator.of(context).pop(); + await showFutureLoadingDialog( + context: context, + future: () => deleteSpace(), + ); + } + } else { + await showFutureLoadingDialog( + context: context, + future: () => deleteChat(), + ); + } + }, + ), + TextButton( + child: Text(L10n.of(context)!.cancel), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + ], + ); + }, + ); + }, + ); + } + + return ListTile( + trailing: const Icon(Icons.delete_outlined), + title: Text( + room.isSpace + ? L10n.of(context)!.deleteSpace + : L10n.of(context)!.deleteGroup, + style: const TextStyle(color: Colors.red), + ), + onTap: () => deleteChatAction(), + ); + } +} diff --git a/lib/pangea/pages/class_settings/p_class_widgets/room_rules_editor.dart b/lib/pangea/pages/class_settings/p_class_widgets/room_rules_editor.dart new file mode 100644 index 000000000..c9e157e12 --- /dev/null +++ b/lib/pangea/pages/class_settings/p_class_widgets/room_rules_editor.dart @@ -0,0 +1,251 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; +import 'package:matrix/matrix.dart'; + +import 'package:fluffychat/pangea/models/class_model.dart'; +import '../../../../config/app_config.dart'; +import '../../../../widgets/matrix.dart'; +import '../../../constants/pangea_event_types.dart'; +import '../../../extensions/pangea_room_extension.dart'; + +class RoomRulesEditor extends StatefulWidget { + final String? roomId; + final bool startOpen; + final bool showAdd; + + const RoomRulesEditor({ + super.key, + this.roomId, + this.startOpen = true, + this.showAdd = false, + }); + + @override + RoomRulesState createState() => RoomRulesState(); +} + +class RoomRulesState extends State { + Room? room; + late PangeaRoomRules rules; + late bool isOpen; + + RoomRulesState({ + Key? key, + }); + + @override + void initState() { + isOpen = widget.startOpen; + + room = widget.roomId != null + ? Matrix.of(context).client.getRoomById(widget.roomId!) + : null; + + rules = room?.pangeaRoomRules ?? PangeaRoomRules(); + + super.initState(); + } + + Future setRoomRules(String roomId) { + return Matrix.of(context).client.setRoomStateWithKey( + roomId, + PangeaEventTypes.rules, + '', + (rules).toJson(), + ); + } + + Future updatePermission(void Function() makeLocalRuleChange) async { + makeLocalRuleChange(); + if (room != null) { + await showFutureLoadingDialog( + context: context, + future: () => setRoomRules(room!.id), + ); + } + setState(() {}); + } + + // //function to handleShowAdd + // void handleShowAdd() { + // setState(() => isOpen = !isOpen); + // debugger(when: rules != null && kDebugMode); + + // rules = PangeaRoomRules(); + // } + + @override + Widget build(BuildContext context) { + return Column( + children: [ + // if (widget.showAdd) + // ListTile( + // title: Text( + // L10n.of(context)!.studentPermissions, + // style: TextStyle( + // color: Theme.of(context).colorScheme.secondary, + // fontWeight: FontWeight.bold, + // ), + // ), + // subtitle: Text(L10n.of(context)!.addRoomRulesDesc), + // leading: CircleAvatar( + // backgroundColor: Theme.of(context).primaryColor, + // foregroundColor: Colors.white, + // radius: Avatar.defaultSize / 2, + // child: Icon(rules == null ? Icons.add : Icons.remove), + // ), + // trailing: Icon( + // isOpen + // ? Icons.keyboard_arrow_down_outlined + // : Icons.keyboard_arrow_right_outlined, + // ), + // onTap: handleShowAdd, + // ), + + ListTile( + enableFeedback: !widget.startOpen, + title: Text( + L10n.of(context)!.studentPermissions, + style: TextStyle( + color: Theme.of(context).colorScheme.secondary, + fontWeight: FontWeight.bold, + ), + ), + subtitle: Text(L10n.of(context)!.studentPermissionsDesc), + leading: CircleAvatar( + backgroundColor: Theme.of(context).scaffoldBackgroundColor, + foregroundColor: Theme.of(context).textTheme.bodyLarge!.color, + child: const Icon( + Icons.settings_outlined, + ), + ), + trailing: !widget.startOpen + ? Icon( + isOpen + ? Icons.keyboard_arrow_down_outlined + : Icons.keyboard_arrow_right_outlined, + ) + : null, + onTap: () => + !widget.startOpen ? setState(() => isOpen = !isOpen) : null, + ), + if (isOpen) + AnimatedContainer( + duration: const Duration(milliseconds: 300), + height: isOpen ? null : 0, + child: Padding( + padding: const EdgeInsets.fromLTRB(16.0, 0, 16.0, 8.0), + child: Column( + children: [ + for (final setting in ToolSetting.values) + Column( + children: [ + ListTile( + title: Text( + "${setting.toolName( + context, + )}: ${rules.languageToolPermissionsText( + context, + setting, + )}", + ), + subtitle: Text(setting.toolDescription(context)), + ), + Padding( + padding: + const EdgeInsets.symmetric(horizontal: 120.0), + child: Slider( + value: rules.getToolSettings(setting).toDouble(), + onChanged: (value) { + updatePermission(() { + rules.setLanguageToolSetting( + setting, + value.toInt(), + ); + }); + }, + divisions: 2, + max: 2, + min: 0, + label: rules.languageToolPermissionsText( + context, + setting, + ), + ), + ), + ], + ), + SwitchListTile.adaptive( + activeColor: AppConfig.activeToggleColor, + title: Text(L10n.of(context)!.oneToOneChatsWithinClass), + subtitle: + Text(L10n.of(context)!.oneToOneChatsWithinClassDesc), + value: rules.oneToOneChatClass, + onChanged: (value) => updatePermission( + () => rules.oneToOneChatClass = value, + ), + ), + SwitchListTile.adaptive( + activeColor: AppConfig.activeToggleColor, + title: Text(L10n.of(context)!.createGroupChats), + subtitle: Text(L10n.of(context)!.createGroupChatsDesc), + value: rules.isCreateRooms, + onChanged: (value) => updatePermission( + () => rules.isCreateRooms = value, + ), + ), + SwitchListTile.adaptive( + activeColor: AppConfig.activeToggleColor, + title: Text(L10n.of(context)!.shareVideo), + subtitle: Text(L10n.of(context)!.shareVideoDesc), + value: rules.isShareVideo, + onChanged: (value) => updatePermission( + () => rules.isShareVideo = value, + ), + ), + SwitchListTile.adaptive( + activeColor: AppConfig.activeToggleColor, + title: Text(L10n.of(context)!.sharePhotos), + subtitle: Text(L10n.of(context)!.sharePhotosDesc), + value: rules.isSharePhoto, + onChanged: (value) => updatePermission( + () => rules.isSharePhoto = value, + ), + ), + SwitchListTile.adaptive( + activeColor: AppConfig.activeToggleColor, + title: Text(L10n.of(context)!.shareFiles), + subtitle: Text(L10n.of(context)!.shareFilesDesc), + value: rules.isShareFiles, + onChanged: (value) => updatePermission( + () => rules.isShareFiles = value, + ), + ), + SwitchListTile.adaptive( + activeColor: AppConfig.activeToggleColor, + title: Text(L10n.of(context)!.sendVoiceNotes), + subtitle: Text(L10n.of(context)!.sendVoiceNotesDesc), + value: rules.isVoiceNotes, + onChanged: (value) => updatePermission( + () => rules.isVoiceNotes = value, + ), + ), + SwitchListTile.adaptive( + activeColor: AppConfig.activeToggleColor, + title: Text(L10n.of(context)!.shareLocation), + subtitle: Text(L10n.of(context)!.shareLocationDesc), + value: rules.isShareLocation, + onChanged: (value) => updatePermission( + () => rules.isShareLocation = value, + ), + ), + ], + ), + ), + ), + ], + ); + } +} diff --git a/lib/pangea/pages/connect/p_sso_button.dart b/lib/pangea/pages/connect/p_sso_button.dart new file mode 100644 index 000000000..835d0454e --- /dev/null +++ b/lib/pangea/pages/connect/p_sso_button.dart @@ -0,0 +1,86 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:matrix/matrix.dart'; + +import 'package:fluffychat/config/app_config.dart'; +import 'package:fluffychat/pages/homeserver_picker/homeserver_picker.dart'; +import 'package:fluffychat/widgets/matrix.dart'; + +class ButtonInfo { + String iconPath; + String text; + + ButtonInfo(this.iconPath, this.text); +} + +class PangeaSsoButton extends StatelessWidget { + final IdentityProvider identityProvider; + final void Function()? onPressed; + const PangeaSsoButton({ + super.key, + required this.identityProvider, + this.onPressed, + }); + + ButtonInfo getButtonInfo(BuildContext context) { + switch (identityProvider.id) { + case "oidc-google": + return ButtonInfo( + "assets/pangea/google.svg", + "${L10n.of(context)!.loginOrSignup} Google", + ); + case "oidc-apple": + return ButtonInfo( + "assets/pangea/apple.svg", + "${L10n.of(context)!.loginOrSignup} Apple", + ); + default: + return ButtonInfo( + "assets/pangea/pangea.svg", + "${L10n.of(context)!.loginOrSignup} Pangea Chat", + ); + } + } + + @override + Widget build(BuildContext context) { + final ButtonInfo buttonInfo = getButtonInfo(context); + return ElevatedButton( + onPressed: onPressed, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + identityProvider.icon == null + ? SvgPicture.asset( + buttonInfo.iconPath, + height: 20, + width: 20, + color: Theme.of(context).brightness == Brightness.light + ? AppConfig.primaryColor + : AppConfig.primaryColorLight, + ) + : Image.network( + Uri.parse(identityProvider.icon!) + .getDownloadLink(Matrix.of(context).getLoginClient()) + .toString(), + width: 32, + height: 32, + ), + // #Pangea + Padding( + padding: const EdgeInsets.fromLTRB(10, 0, 10, 0), + child: Text( + identityProvider.name != null + ? buttonInfo.text + : (identityProvider.brand != null + ? L10n.of(context)!.loginOrSignup + : L10n.of(context)!.loginOrSignup), + ), + ), + ], + ), + ); + } +} diff --git a/lib/pangea/pages/exchange/add_exchange_to_class.dart b/lib/pangea/pages/exchange/add_exchange_to_class.dart new file mode 100644 index 000000000..eb5e7d59a --- /dev/null +++ b/lib/pangea/pages/exchange/add_exchange_to_class.dart @@ -0,0 +1,57 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:go_router/go_router.dart'; + +import 'package:fluffychat/pangea/widgets/class/add_class_and_invite.dart'; +import 'package:fluffychat/pangea/widgets/class/add_space_toggles.dart'; +import 'package:fluffychat/widgets/matrix.dart'; + +class AddExchangeToClass extends StatefulWidget { + const AddExchangeToClass({super.key}); + + @override + AddExchangeToClassState createState() => AddExchangeToClassState(); +} + +class AddExchangeToClassState extends State { + final GlobalKey addToSpaceKey = GlobalKey(); + + @override + Widget build(BuildContext context) { + final String spaceId = + GoRouterState.of(context).pathParameters['exchangeid']!; + return Scaffold( + appBar: AppBar( + centerTitle: true, + title: Text(L10n.of(context)!.addToClassTitle), + ), + body: FutureBuilder( + future: + Matrix.of(context).client.waitForRoomInSync(spaceId, join: true), + builder: (context, snapshot) { + if (snapshot.hasData) { + return ListView( + children: [ + const SizedBox(height: 40), + AddToSpaceToggles( + roomId: + GoRouterState.of(context).pathParameters['exchangeid'], + key: addToSpaceKey, + startOpen: true, + mode: AddToClassMode.exchange, + ), + ], + ); + } else { + return const Center(child: CircularProgressIndicator()); + } + }, + ), + floatingActionButton: FloatingActionButton( + onPressed: () => context.go("/rooms"), + child: const Icon(Icons.arrow_forward_outlined), + ), + ); + } +} diff --git a/lib/pangea/pages/find_partner/find_partner.dart b/lib/pangea/pages/find_partner/find_partner.dart new file mode 100644 index 000000000..18fc71307 --- /dev/null +++ b/lib/pangea/pages/find_partner/find_partner.dart @@ -0,0 +1,108 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; + +import 'package:fluffychat/pangea/models/language_model.dart'; +import 'package:fluffychat/pangea/models/user_model.dart'; +import '../../../widgets/matrix.dart'; +import '../../controllers/pangea_controller.dart'; +import '../../models/user_profile_search_model.dart'; +import '../../repo/user_repo.dart'; +import 'find_partner_view.dart'; + +class FindPartner extends StatefulWidget { + const FindPartner({super.key}); + + @override + State createState() => FindPartnerController(); +} + +class FindPartnerController extends State { + PangeaController pangeaController = MatrixState.pangeaController; + + bool loading = false; + String currentSearchTerm = ""; + late LanguageModel targetLanguageSearch; + late LanguageModel sourceLanguageSearch; + String? countrySearch; + String? flagEmoji; + + //PTODO - implement pagination + String? previousPage; + + Timer? coolDown; + + final List _userProfilesCache = []; + + @override + void initState() { + targetLanguageSearch = pangeaController.languageController.userL1 ?? + pangeaController.pLanguageStore.targetOptions[1]; + sourceLanguageSearch = pangeaController.languageController.userL2 ?? + pangeaController.pLanguageStore.targetOptions[0]; + + searchUserProfiles(); + super.initState(); + } + + @override + Widget build(BuildContext context) { + return FindPartnerView(this); + } + + // List get userProfiles => currentSearchTerm.isNotEmpty + // ? _userProfilesCache + // .where((p) => + // (p.fullName != null && p.fullName!.contains(currentSearchTerm)) || + // (p.pangeaUserId != null && + // p.pangeaUserId!.contains(currentSearchTerm)) || + // (p.sourceLanguage != null && + // p.sourceLanguage!.contains(currentSearchTerm)) || + // // (p.speaks != null && + // // p.speaks!.any((e) => e.contains(currentSearchTerm))) || + // (p.country != null && p.country!.contains(currentSearchTerm)) || + // // (p.interests != null && + // // p.interests!.any((e) => e.contains(currentSearchTerm)))) + // .toList() + // : _userProfilesCache; + + List get userProfiles => _userProfilesCache.where((p) { + return (p.targetLanguage != null && + targetLanguageSearch.langCode == p.targetLanguage) && + (p.sourceLanguage != null && + sourceLanguageSearch.langCode == p.sourceLanguage) && + (countrySearch == null || + (p.country != null && countrySearch == p.country)); + }).toList(); + + void searchUserProfilesWithCoolDown(String text) { + coolDown?.cancel(); + coolDown = Timer( + const Duration(milliseconds: 0), + () => searchUserProfiles(), + ); + } + + void searchUserProfiles() async { + coolDown?.cancel(); + if (loading) return; + setState(() => loading = true); + + final UserProfileSearchResponse response = + await PUserRepo.searchUserProfiles( + accessToken: await pangeaController.userController.accessToken, + targetLanguage: targetLanguageSearch.langCode, + sourceLanguage: sourceLanguageSearch.langCode, + country: countrySearch, + limit: 30, + ); + for (final p in response.results) { + if (!_userProfilesCache + .any((element) => p.pangeaUserId == element.pangeaUserId)) { + _userProfilesCache.add(p); + } + } + + setState(() => loading = false); + } +} diff --git a/lib/pangea/pages/find_partner/find_partner_view.dart b/lib/pangea/pages/find_partner/find_partner_view.dart new file mode 100644 index 000000000..bbb163a69 --- /dev/null +++ b/lib/pangea/pages/find_partner/find_partner_view.dart @@ -0,0 +1,299 @@ +import 'package:flutter/material.dart'; + +import 'package:country_picker/country_picker.dart'; +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:go_router/go_router.dart'; +import 'package:matrix/matrix.dart' as matrix; + +import 'package:fluffychat/config/themes.dart'; +import 'package:fluffychat/pangea/models/user_model.dart'; +import 'package:fluffychat/pangea/widgets/common/list_placeholder.dart'; +import 'package:fluffychat/pangea/widgets/common/pangea_logo_svg.dart'; +import 'package:fluffychat/pangea/widgets/user_settings/p_language_dropdown.dart'; +import 'package:fluffychat/widgets/avatar.dart'; +import 'package:fluffychat/widgets/matrix.dart'; +import '../../../widgets/profile_bottom_sheet.dart'; +import 'find_partner.dart'; + +class FindPartnerView extends StatelessWidget { + final FindPartnerController controller; + const FindPartnerView(this.controller, {super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + leading: IconButton( + icon: const Icon(Icons.close_outlined), + onPressed: () => context.pop(), + ), + centerTitle: true, + title: const PageTitleText(), + ), + body: Center( + child: Container( + constraints: const BoxConstraints( + maxWidth: FluffyThemes.columnWidth * 2, + minWidth: FluffyThemes.columnWidth * 2, + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + LanguageSelectionRow( + controller: controller, + isSource: true, + ), + LanguageSelectionRow( + controller: controller, + isSource: false, + ), + Padding( + padding: const EdgeInsets.all(18), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + L10n.of(context)!.iWantALanguagePartnerFrom, + style: const TextStyle(fontSize: 16), + ), + Row( + children: [ + Text( + controller.countrySearch ?? + L10n.of(context)!.worldWide, + ), + Padding( + padding: const EdgeInsets.fromLTRB(15, 0, 15, 0), + child: controller.flagEmoji != null + ? RichText( + text: TextSpan( + text: controller.flagEmoji, + style: const TextStyle(fontSize: 30), + ), + ) + : const PangeaLogoSvg(width: 30), + ), + IconButton( + icon: const Icon(Icons.expand_more), + onPressed: () => showCountryPicker( + showWorldWide: true, + context: context, + showPhoneCode: false, + onSelect: (Country country) { + if (country.name != "World Wide") { + controller.countrySearch = + country.displayNameNoCountryCode; + controller.flagEmoji = country.flagEmoji; + } else { + controller.countrySearch = null; + controller.flagEmoji = null; + } + controller.searchUserProfiles(); + }, + ), + ), + ], + ), + ], + ), + ), + controller.loading + ? const ExpandedContainer(body: ListPlaceholder()) + : controller.userProfiles.isNotEmpty + ? ExpandedContainer( + body: ListView.builder( + itemCount: controller.userProfiles.length, + itemBuilder: (context, i) => UserProfileEntry( + pangeaProfile: controller.userProfiles[i], + controller: controller, + ), + ), + ) + : ExpandedContainer( + body: Center( + child: Text(L10n.of(context)!.noResults), + ), + ), + ], + ), + ), + ), + ); + } +} + +class ExpandedContainer extends StatelessWidget { + const ExpandedContainer({ + super.key, + required this.body, + }); + + final Widget body; + + @override + Widget build(BuildContext context) { + return Expanded( + child: Container( + margin: const EdgeInsets.fromLTRB(0, 20, 0, 20), + child: body, + ), + ); + } +} + +class ProfileSearchTextField extends StatelessWidget { + const ProfileSearchTextField({ + super.key, + required this.controller, + }); + + final FindPartnerController controller; + + @override + Widget build(BuildContext context) { + return TextField( + autofocus: true, + decoration: InputDecoration( + hintText: L10n.of(context)!.searchBy, + suffixIconConstraints: const BoxConstraints( + maxWidth: 48, + maxHeight: 48, + minWidth: 48, + ), + suffixIcon: controller.loading + ? const CircularProgressIndicator.adaptive() + : const Icon(Icons.search_outlined), + contentPadding: const EdgeInsets.symmetric(horizontal: 16), + ), + onChanged: controller.searchUserProfilesWithCoolDown, + ); + } +} + +class PageTitleText extends StatelessWidget { + const PageTitleText({ + super.key, + }); + + @override + Widget build(BuildContext context) { + return FittedBox( + child: Text( + L10n.of(context)!.iWantAConversationPartner, + style: TextStyle( + color: Theme.of(context).textTheme.bodyLarge!.color, + fontSize: 18, + fontWeight: FontWeight.w700, + ), + overflow: TextOverflow.clip, + textAlign: TextAlign.center, + ), + ); + } +} + +class LanguageSelectionRow extends StatelessWidget { + const LanguageSelectionRow({ + super.key, + required this.controller, + required this.isSource, + }); + + final FindPartnerController controller; + final bool isSource; + + @override + Widget build(BuildContext context) { + return Row( + children: [ + Flexible( + child: ListTile( + title: isSource + ? Text( + L10n.of(context)!.iWantALanguagePartnerWhoSpeaks, + style: const TextStyle(fontSize: 16), + ) + : Text( + L10n.of(context)!.iWantALanguagePartnerWhoIsLearning, + style: const TextStyle(fontSize: 16), + ), + ), + ), + Flexible( + child: PLanguageDropdown( + languages: isSource + ? controller.pangeaController.pLanguageStore.baseOptions + : controller.pangeaController.pLanguageStore.targetOptions, + onChange: (language) { + isSource + ? controller.sourceLanguageSearch = language + : controller.targetLanguageSearch = language; + controller.searchUserProfiles(); + }, + initialLanguage: isSource + ? controller.sourceLanguageSearch + : controller.targetLanguageSearch, + ), + ), + ], + ); + } +} + +class UserProfileEntry extends StatelessWidget { + final Profile pangeaProfile; + final FindPartnerController controller; + + const UserProfileEntry({ + super.key, + required this.pangeaProfile, + required this.controller, + }); + + @override + Widget build(BuildContext context) { + return Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + FutureBuilder( + future: Matrix.of(context) + .client + .getProfileFromUserId(pangeaProfile.pangeaUserId), + builder: ((context, snapshot) { + final matrixProfile = snapshot.data; + return ListTile( + leading: Avatar( + name: matrixProfile == null || matrixProfile.avatarUrl == null + ? pangeaProfile.pangeaUserId + : null, + mxContent: matrixProfile?.avatarUrl, + ), + title: Row( + children: [ + Text( + //PTODO - get matrix u and show displayName + matrixProfile?.displayName ?? pangeaProfile.pangeaUserId, + ), + const SizedBox(width: 20), + RichText( + text: TextSpan( + text: pangeaProfile.flagEmoji, + style: const TextStyle(fontSize: 15), + ), + ), + ], + ), + onTap: () => showModalBottomSheet( + context: context, + builder: (c) => ProfileBottomSheet( + userId: pangeaProfile.pangeaUserId, + outerContext: context, + ), + ), + ); + }), + ), + ], + ); + } +} diff --git a/lib/pangea/pages/new_class/new_class.dart b/lib/pangea/pages/new_class/new_class.dart new file mode 100644 index 000000000..55b7d083d --- /dev/null +++ b/lib/pangea/pages/new_class/new_class.dart @@ -0,0 +1,122 @@ +import 'dart:developer'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; +import 'package:go_router/go_router.dart'; +import 'package:matrix/matrix.dart' as sdk; +import 'package:matrix/matrix.dart'; + +import 'package:fluffychat/pangea/pages/new_class/new_class_view.dart'; +import 'package:fluffychat/pangea/utils/class_code.dart'; +import 'package:fluffychat/pangea/utils/error_handler.dart'; +import 'package:fluffychat/widgets/matrix.dart'; +import '../../controllers/pangea_controller.dart'; +import '../../widgets/space/class_settings.dart'; +import '../class_settings/p_class_widgets/room_rules_editor.dart'; + +class NewClass extends StatefulWidget { + const NewClass({super.key}); + + @override + NewClassController createState() => NewClassController(); +} + +class NewClassController extends State { + TextEditingController controller = TextEditingController(); + + final PangeaController pangeaController = MatrixState.pangeaController; + final GlobalKey rulesEditorKey = GlobalKey(); + final GlobalKey classSettingsKey = + GlobalKey(); + + void submitAction([_]) async { + //TODO: validate that object is complete + final matrix = Matrix.of(context); + if (controller.text.isEmpty) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text(L10n.of(context)!.classNameRequired), + ), + ); + return; + } + if (classSettingsKey.currentState == null) { + debugger(when: kDebugMode); + } + if (classSettingsKey.currentState!.sameLanguages) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text(L10n.of(context)!.noIdenticalLanguages), + ), + ); + return; + } + + final roomID = await showFutureLoadingDialog( + context: context, + future: () async { + final String roomID = await matrix.client.createRoom( + //PTODO - investigate effects of changing visibility from public + preset: sdk.CreateRoomPreset.publicChat, + creationContent: { + 'type': RoomCreationTypes.mSpace, + }, + visibility: sdk.Visibility.public, + // roomAliasName: controller.text.isNotEmpty + // ? "${matrix.client.userID!.localpart}-${controller.text.trim().toLowerCase().replaceAll(' ', '_')}" + // : null, + roomAliasName: ClassCodeUtil.generateClassCode(), + name: controller.text.isNotEmpty ? controller.text : null, + ); + + if (rulesEditorKey.currentState != null) { + await rulesEditorKey.currentState!.setRoomRules(roomID); + } else { + debugger(when: kDebugMode); + ErrorHandler.logError(m: "Null rules editor state"); + } + if (classSettingsKey.currentState != null) { + await classSettingsKey.currentState!.setClassSettings( + roomID, + ); + } else { + debugger(when: kDebugMode); + ErrorHandler.logError(m: "Null class settings state"); + } + return roomID; + }, + onError: (e) { + debugger(when: kDebugMode); + return e; + }, + ); + + if (roomID.error == null && roomID.result is String) { + pangeaController.classController.setActiveSpaceIdInChatListController( + roomID.result!, + ); + context.push('/spaces/${roomID.result!}'); + } else { + debugger(when: kDebugMode); + ErrorHandler.logError(e: roomID.error, s: StackTrace.current); + } + } + + @override + void initState() { + // TODO: implement initState + super.initState(); + } + + @override + void dispose() { + controller.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) => NewSpaceView(this); +} diff --git a/lib/pangea/pages/new_class/new_class_view.dart b/lib/pangea/pages/new_class/new_class_view.dart new file mode 100644 index 000000000..13796e2d8 --- /dev/null +++ b/lib/pangea/pages/new_class/new_class_view.dart @@ -0,0 +1,88 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; + +import 'package:fluffychat/pangea/constants/class_default_values.dart'; +import 'package:fluffychat/pangea/pages/new_class/new_class.dart'; +import 'package:fluffychat/widgets/layouts/max_width_body.dart'; +import '../../widgets/space/class_settings.dart'; +import '../class_settings/p_class_widgets/room_rules_editor.dart'; + +class NewSpaceView extends StatelessWidget { + // #Pangea + // final NewSpaceController controller; + final NewClassController controller; + // Pangea# + + const NewSpaceView(this.controller, {super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + // #Pangea + centerTitle: true, + // Pangea# + title: Text(L10n.of(context)!.createNewClass), + ), + body: MaxWidthBody( + // #Pangea + child: ListView( + // child: Column( + // mainAxisSize: MainAxisSize.min, + // #Pangea + children: [ + Padding( + padding: const EdgeInsets.all(12.0), + child: TextField( + // #Pangea + maxLength: ClassDefaultValues.maxClassName, + maxLengthEnforcement: MaxLengthEnforcement.enforced, + // #Pangea + controller: controller.controller, + autofocus: true, + autocorrect: false, + textInputAction: TextInputAction.go, + onSubmitted: controller.submitAction, + decoration: InputDecoration( + labelText: L10n.of(context)!.spaceName, + prefixIcon: const Icon(Icons.people_outlined), + hintText: L10n.of(context)!.enterASpacepName, + ), + ), + ), + // #Pangea + ClassSettings( + key: controller.classSettingsKey, + roomId: null, + startOpen: true, + ), + RoomRulesEditor( + key: controller.rulesEditorKey, + roomId: null, + ), + const SizedBox(height: 45), + // SwitchListTile.adaptive( + // title: Text(L10n.of(context)!.spaceIsPublic), + // value: controller.publicGroup, + // onChanged: controller.setPublicGroup, + // ), + // ListTile( + // trailing: const Padding( + // padding: EdgeInsets.symmetric(horizontal: 16.0), + // child: Icon(Icons.info_outlined), + // ), + // subtitle: Text(L10n.of(context)!.newSpaceDescription), + // ), + // #Pangea + ], + ), + ), + floatingActionButton: FloatingActionButton( + onPressed: controller.submitAction, + child: const Icon(Icons.arrow_forward_outlined), + ), + ); + } +} diff --git a/lib/pangea/pages/p_user_age/p_user_age.dart b/lib/pangea/pages/p_user_age/p_user_age.dart new file mode 100644 index 000000000..415379309 --- /dev/null +++ b/lib/pangea/pages/p_user_age/p_user_age.dart @@ -0,0 +1,133 @@ +import 'dart:developer'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:intl/intl.dart'; + +import 'package:fluffychat/pangea/constants/age_limits.dart'; +import 'package:fluffychat/pangea/controllers/pangea_controller.dart'; +import 'package:fluffychat/pangea/pages/p_user_age/p_user_age_view.dart'; +import 'package:fluffychat/pangea/utils/p_extension.dart'; +import 'package:fluffychat/widgets/fluffy_chat_app.dart'; +import 'package:fluffychat/widgets/matrix.dart'; +import '../../utils/bot_name.dart'; +import '../../utils/error_handler.dart'; + +class PUserAge extends StatefulWidget { + const PUserAge({super.key}); + + @override + PUserAgeController createState() => PUserAgeController(); +} + +class PUserAgeController extends State { + bool loading = false; + final GlobalKey formKey = GlobalKey(); + TextEditingController dobController = TextEditingController(); + // #Pangea + + String? error; + bool unknownErrorState = false; + // DateTime? dateOfBirth; + + final PangeaController pangeaController = MatrixState.pangeaController; + + @override + void initState() { + super.initState(); + Future.delayed( + Duration.zero, + () => Matrix.of(context) + .client + .startDirectChat( + BotName.byEnvironment, + enableEncryption: false, + ) + .onError( + (error, stackTrace) => + ErrorHandler.logError(e: error, s: stackTrace), + ), + ); + } + + String? dobFieldValidator(String? value) { + try { + if (value?.isEmpty ?? true) { + return L10n.of(context)!.yourBirthdayPleaseShort; + } + final DateTime dob = _textToDate!; + if (!dob.isAtLeastYearsOld(AgeLimits.toUseTheApp)) { + return L10n.of(context)!.mustBe13; + } + return null; + } catch (err, stack) { + ErrorHandler.logError(e: err, s: stack); + return L10n.of(context)!.invalidDob; + } + } + + DateTime? get _textToDate { + try { + final DateTime initial = DateFormat.yMd().parse(dobController.text); + return initial; + } catch (err) { + return null; + } + } + + DateTime get initialDate => + _textToDate ?? DateTime.now().subtract(const Duration(days: 13 * 365)); + + //Note: used linear progress bar (also used in fluffychat signup button) for consistency + createUserInPangea() async { + try { + setState(() { + error = null; + }); + if (!formKey.currentState!.validate()) return; + setState(() { + loading = true; + }); + + final String date = DateFormat('MM-dd-yyyy').format(_textToDate!); + + if (pangeaController.userController.userModel?.access == null) { + await pangeaController.userController.createPangeaUser(dob: date); + } else { + await pangeaController.userController.updateUserProfile( + dateOfBirth: date, + ); + } + // Matrix.of(context).widget.router!.currentState!.to( + // '/rooms', + // queryParameters: + // Matrix.of(context).widget.router!.currentState!.queryParameters, + // ); + FluffyChatApp.router.go('/rooms'); + } catch (err, s) { + setState(() { + unknownErrorState = true; + }); + debugger(when: kDebugMode); + ErrorHandler.logError(e: err, s: s); + } finally { + loading = false; + } + } + + @override + Widget build(BuildContext context) { + return !unknownErrorState + ? PUserAgeView(this) + : Center( + child: Padding( + padding: const EdgeInsets.all(50), + child: Text( + "${L10n.of(context)!.oopsSomethingWentWrong} \n ${L10n.of(context)!.errorPleaseRefresh}", + ), + ), + ); + } +} diff --git a/lib/pangea/pages/p_user_age/p_user_age_view.dart b/lib/pangea/pages/p_user_age/p_user_age_view.dart new file mode 100644 index 000000000..dd0b16a95 --- /dev/null +++ b/lib/pangea/pages/p_user_age/p_user_age_view.dart @@ -0,0 +1,109 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:intl/intl.dart'; + +import 'package:fluffychat/pangea/pages/p_user_age/p_user_age.dart'; +import '../../../widgets/layouts/login_scaffold.dart'; + +class PUserAgeView extends StatelessWidget { + final PUserAgeController controller; + const PUserAgeView(this.controller, {super.key}); + + @override + Widget build(BuildContext context) { + controller.dobController.text = ""; + return LoginScaffold( + appBar: AppBar( + automaticallyImplyLeading: !controller.loading, + ), + body: Form( + key: controller.formKey, + child: ListView( + children: [ + // #Pangea + Container( + margin: const EdgeInsets.only(top: 10), + padding: const EdgeInsets.all(12), + child: Text( + L10n.of(context)!.yourBirthdayPlease, + textAlign: TextAlign.justify, + style: const TextStyle(color: Colors.white), + ), + ), + const SizedBox( + height: 10, + ), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 12), + child: TextFormField( + readOnly: controller.loading, + autocorrect: false, + controller: controller.dobController, + keyboardType: TextInputType.datetime, + autofillHints: + controller.loading ? null : [AutofillHints.birthday], + validator: controller.dobFieldValidator, + onTap: () async { + final DateTime? pickedDate = await showDatePicker( + initialDatePickerMode: DatePickerMode.year, + context: context, + initialDate: controller.initialDate, + firstDate: DateTime(1940), + lastDate: DateTime.now(), + ); + + if (pickedDate != null) { + controller.dobController.text = + DateFormat.yMd().format(pickedDate); + controller.error = null; + } else { + controller.error = L10n.of(context)!.invalidDob; + } + }, + // onChanged: (String newValue) { + // try { + // controller.dateOfBirth = + // DateTime.parse(controller.dobController.text); + // controller.error = null; + // } catch (err) { + // controller.error = L10n.of(context)!.invalidDob; + // } + // }, + decoration: InputDecoration( + prefixIcon: const Icon(Icons.calendar_today), + hintText: L10n.of(context)!.enterYourDob, + fillColor: Theme.of(context) + .colorScheme + .background + .withOpacity(0.75), + errorText: controller.error, + errorStyle: TextStyle( + color: controller.dobController.text.isEmpty + ? Colors.orangeAccent + : Colors.orange, + ), + ), + ), + ), + const SizedBox( + height: 10, + ), + Hero( + tag: 'loginButton', + child: Padding( + padding: const EdgeInsets.all(12), + child: ElevatedButton( + onPressed: controller.createUserInPangea, + child: controller.loading + ? const LinearProgressIndicator() + : Text(L10n.of(context)!.getStarted), + ), + ), + ), + ], + ), + ), + ); + } +} diff --git a/lib/pangea/pages/settings_learning/settings_learning.dart b/lib/pangea/pages/settings_learning/settings_learning.dart new file mode 100644 index 000000000..f699fc7b5 --- /dev/null +++ b/lib/pangea/pages/settings_learning/settings_learning.dart @@ -0,0 +1,45 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; + +import 'package:fluffychat/pangea/controllers/pangea_controller.dart'; +import 'package:fluffychat/pangea/pages/settings_learning/settings_learning_view.dart'; +import 'package:fluffychat/widgets/matrix.dart'; + +class SettingsLearning extends StatefulWidget { + const SettingsLearning({super.key}); + + @override + SettingsLearningController createState() => SettingsLearningController(); +} + +class SettingsLearningController extends State { + late StreamSubscription _userSubscription; + PangeaController pangeaController = MatrixState.pangeaController; + + setPublicProfile(bool b) async { + await pangeaController.userController.updateUserProfile(publicProfile: b); + setState(() {}); + } + + @override + void initState() { + super.initState(); + + _userSubscription = + pangeaController.userController.stateStream.listen((event) { + setState(() {}); + }); + } + + @override + void dispose() { + super.dispose(); + _userSubscription.cancel(); + } + + @override + Widget build(BuildContext context) { + return SettingsLearningView(this); + } +} diff --git a/lib/pangea/pages/settings_learning/settings_learning_view.dart b/lib/pangea/pages/settings_learning/settings_learning_view.dart new file mode 100644 index 000000000..657ee0770 --- /dev/null +++ b/lib/pangea/pages/settings_learning/settings_learning_view.dart @@ -0,0 +1,69 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; + +import 'package:fluffychat/pangea/models/class_model.dart'; +import 'package:fluffychat/pangea/pages/settings_learning/settings_learning.dart'; +import 'package:fluffychat/pangea/utils/error_handler.dart'; +import 'package:fluffychat/pangea/widgets/user_settings/country_picker_tile.dart'; +import 'package:fluffychat/pangea/widgets/user_settings/language_tile.dart'; +import 'package:fluffychat/pangea/widgets/user_settings/p_settings_switch_list_tile.dart'; +import 'package:fluffychat/widgets/layouts/max_width_body.dart'; +import '../../../config/app_config.dart'; + +class SettingsLearningView extends StatelessWidget { + final SettingsLearningController controller; + const SettingsLearningView(this.controller, {super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + centerTitle: true, + title: Text( + L10n.of(context)!.learningSettings, + ), + ), + body: ListTileTheme( + iconColor: Theme.of(context).textTheme.bodyLarge!.color, + child: MaxWidthBody( + withScrolling: true, + child: Column( + children: [ + LanguageTile(), + CountryPickerTile(), + const SizedBox(height: 8), + const Divider(height: 1), + const SizedBox(height: 8), + if (controller.pangeaController.permissionsController.isUser18()) + SwitchListTile.adaptive( + activeColor: AppConfig.activeToggleColor, + title: Text(L10n.of(context)!.publicProfileTitle), + subtitle: Text(L10n.of(context)!.publicProfileDesc), + value: controller.pangeaController.userController.isPublic, + onChanged: (bool isPublicProfile) => showFutureLoadingDialog( + context: context, + future: () => controller.setPublicProfile(isPublicProfile), + onError: (err) => + ErrorHandler.logError(e: err, s: StackTrace.current), + ), + ), + ListTile( + subtitle: Text(L10n.of(context)!.toggleToolSettingsDescription), + ), + for (final setting in ToolSetting.values) + PSettingsSwitchListTile.adaptive( + defaultValue: controller.pangeaController.localSettings + .userLanguageToolSetting(setting), + title: setting.toolName(context), + subtitle: setting.toolDescription(context), + pStoreKey: setting.toString(), + ), + ], + ), + ), + ), + ); + } +} diff --git a/lib/pangea/pages/settings_subscription/change_subscription.dart b/lib/pangea/pages/settings_subscription/change_subscription.dart new file mode 100644 index 000000000..8a57a317f --- /dev/null +++ b/lib/pangea/pages/settings_subscription/change_subscription.dart @@ -0,0 +1,103 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + +import 'package:adaptive_dialog/adaptive_dialog.dart'; +import 'package:flutter_gen/gen_l10n/l10n.dart'; + +import 'package:fluffychat/pangea/controllers/pangea_controller.dart'; +import 'package:fluffychat/pangea/pages/settings_subscription/settings_subscription.dart'; +import 'package:fluffychat/pangea/widgets/subscription/subscription_buttons.dart'; +import 'package:fluffychat/widgets/matrix.dart'; + +class ChangeSubscription extends StatelessWidget { + final SubscriptionManagementController controller; + ChangeSubscription({ + required this.controller, + super.key, + }); + + final PangeaController pangeaController = MatrixState.pangeaController; + + @override + Widget build(BuildContext context) { + void submitChange({bool isPromo = false}) { + try { + pangeaController.subscriptionController.submitSubscriptionChange( + controller.selectedSubscription, + context, + isPromo: isPromo, + ); + } catch (err) { + showOkAlertDialog( + context: context, + title: L10n.of(context)!.oopsSomethingWentWrong, + message: L10n.of(context)!.errorPleaseRefresh, + okLabel: L10n.of(context)!.close, + ); + } + } + + return pangeaController.subscriptionController.subscription != null && + pangeaController.subscriptionController.subscription! + .availableSubscriptions.isNotEmpty + ? Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + L10n.of(context)!.selectYourPlan, + style: const TextStyle(fontSize: 16), + ), + const SizedBox(height: 16.0), + const Divider(height: 1), + SubscriptionButtons(controller: controller), + const SizedBox(height: 32), + if (controller.selectedSubscription != null) + IntrinsicWidth( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + OutlinedButton( + onPressed: () => submitChange(), + child: Text(L10n.of(context)!.pay), + ), + const SizedBox(height: 10), + if (kIsWeb) + OutlinedButton( + onPressed: () => submitChange(isPromo: true), + child: Text(L10n.of(context)!.redeemPromoCode), + ), + ], + ), + ), + // if (controller.selectedSubscription != null && Platform.isIOS) + // TextButton( + // onPressed: () { + // try { + // pangeaController.subscriptionController + // .redeemPromoCode(context); + // } catch (err) { + // showOkAlertDialog( + // context: context, + // title: L10n.of(context)!.oopsSomethingWentWrong, + // message: L10n.of(context)!.errorPleaseRefresh, + // okLabel: L10n.of(context)!.close, + // ); + // } + // }, + // child: Text(L10n.of(context)!.redeemPromoCode), + // ) + ], + ) + : Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text(L10n.of(context)!.oopsSomethingWentWrong), + Text(L10n.of(context)!.errorPleaseRefresh), + ], + ), + ); + } +} diff --git a/lib/pangea/pages/settings_subscription/settings_subscription.dart b/lib/pangea/pages/settings_subscription/settings_subscription.dart new file mode 100644 index 000000000..349e3eade --- /dev/null +++ b/lib/pangea/pages/settings_subscription/settings_subscription.dart @@ -0,0 +1,127 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; + +import 'package:url_launcher/url_launcher_string.dart'; + +import 'package:fluffychat/config/app_config.dart'; +import 'package:fluffychat/pangea/config/environment.dart'; +import 'package:fluffychat/pangea/controllers/pangea_controller.dart'; +import 'package:fluffychat/pangea/controllers/subscription_controller.dart'; +import 'package:fluffychat/pangea/pages/settings_subscription/settings_subscription_view.dart'; +import 'package:fluffychat/pangea/utils/subscription_app_id.dart'; +import 'package:fluffychat/widgets/matrix.dart'; + +class SubscriptionManagement extends StatefulWidget { + const SubscriptionManagement({super.key}); + + @override + SubscriptionManagementController createState() => + SubscriptionManagementController(); +} + +class SubscriptionManagementController extends State { + final PangeaController pangeaController = MatrixState.pangeaController; + SubscriptionDetails? selectedSubscription; + late StreamSubscription _settingsSubscription; + + @override + void initState() { + _settingsSubscription = + pangeaController.subscriptionController.stateStream.listen((event) { + debugPrint("stateStream event in subscription settings"); + setState(() {}); + }); + pangeaController.subscriptionController.updateCustomerInfo(); + super.initState(); + } + + @override + void dispose() { + super.dispose(); + _settingsSubscription.cancel(); + } + + bool get currentSubscriptionAvailable => + pangeaController.subscriptionController.currentSubscriptionAvailable; + + String? get purchasePlatformDisplayName => pangeaController + .subscriptionController.subscription?.purchasePlatformDisplayName; + + bool get currentSubscriptionIsPromotional => + pangeaController.subscriptionController.subscription + ?.currentSubscriptionIsPromotional ?? + false; + + bool get showManagementOptions { + if (!currentSubscriptionAvailable) { + return false; + } + if (pangeaController.subscriptionController.subscription!.purchasedOnWeb) { + return true; + } + return pangeaController.subscriptionController.subscription! + .currentPlatformMatchesPurchasePlatform; + } + + Future launchMangementUrl(ManagementOption option) async { + String managementUrl = Environment.stripeManagementUrl; + final String? email = await pangeaController.userController.userEmail; + if (email != null) { + managementUrl += "?prefilled_email=${Uri.encodeComponent(email)}"; + } + final String? purchaseAppId = pangeaController + .subscriptionController.subscription?.currentSubscription?.appId!; + if (purchaseAppId == null) return; + + final SubscriptionAppIds? appIds = + pangeaController.subscriptionController.subscription!.appIds; + + if (purchaseAppId == appIds?.stripeId) { + launchUrlString(managementUrl); + return; + } + if (purchaseAppId == appIds?.appleId) { + launchUrlString( + AppConfig.appleMangementUrl, + mode: LaunchMode.externalApplication, + ); + return; + } + switch (option) { + case ManagementOption.history: + launchUrlString( + AppConfig.googlePlayHistoryUrl, + mode: LaunchMode.externalApplication, + ); + break; + case ManagementOption.paymentMethod: + launchUrlString( + AppConfig.googlePlayPaymentMethodUrl, + mode: LaunchMode.externalApplication, + ); + break; + default: + launchUrlString( + AppConfig.googlePlayMangementUrl, + mode: LaunchMode.externalApplication, + ); + break; + } + } + + void selectSubscription(SubscriptionDetails? subscription) { + setState(() => selectedSubscription = subscription); + } + + @override + Widget build(BuildContext context) { + return SettingsSubscriptionView(this); + } +} + +enum ManagementOption { + cancel, + paymentMethod, + history, +} diff --git a/lib/pangea/pages/settings_subscription/settings_subscription_view.dart b/lib/pangea/pages/settings_subscription/settings_subscription_view.dart new file mode 100644 index 000000000..708bd8d66 --- /dev/null +++ b/lib/pangea/pages/settings_subscription/settings_subscription_view.dart @@ -0,0 +1,150 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:intl/intl.dart'; + +import 'package:fluffychat/pangea/controllers/pangea_controller.dart'; +import 'package:fluffychat/pangea/controllers/subscription_controller.dart'; +import 'package:fluffychat/pangea/pages/settings_subscription/change_subscription.dart'; +import 'package:fluffychat/pangea/pages/settings_subscription/settings_subscription.dart'; +import 'package:fluffychat/widgets/layouts/max_width_body.dart'; +import 'package:fluffychat/widgets/matrix.dart'; + +class SettingsSubscriptionView extends StatelessWidget { + final SubscriptionManagementController controller; + final PangeaController pangeaController = MatrixState.pangeaController; + SettingsSubscriptionView(this.controller, {super.key}); + + @override + Widget build(BuildContext context) { + final String currentSubscriptionTitle = pangeaController + .subscriptionController.subscription?.currentSubscription + ?.displayName(context) ?? + ""; + final String currentSubscriptionPrice = pangeaController + .subscriptionController.subscription?.currentSubscription + ?.displayPrice(context) ?? + ""; + + return Scaffold( + appBar: AppBar( + centerTitle: true, + title: Text( + L10n.of(context)!.subscriptionManagement, + ), + ), + body: ListTileTheme( + iconColor: Theme.of(context).textTheme.bodyLarge!.color, + child: MaxWidthBody( + child: !(pangeaController.subscriptionController.isSubscribed) + ? ChangeSubscription(controller: controller) + : Column( + children: [ + if (pangeaController.subscriptionController.subscription! + .currentSubscription != + null) + ListTile( + title: Text(L10n.of(context)!.currentSubscription), + subtitle: Text(currentSubscriptionTitle), + trailing: Text(currentSubscriptionPrice), + ), + Column( + children: [ + ListTile( + title: Text(L10n.of(context)!.cancelSubscription), + enabled: controller.showManagementOptions, + onTap: () => controller.launchMangementUrl( + ManagementOption.cancel, + ), + trailing: const Icon(Icons.cancel_outlined), + ), + const Divider(height: 1), + ListTile( + title: Text(L10n.of(context)!.paymentMethod), + trailing: const Icon(Icons.credit_card), + onTap: () => controller.launchMangementUrl( + ManagementOption.paymentMethod, + ), + enabled: controller.showManagementOptions, + ), + ListTile( + title: Text(L10n.of(context)!.paymentHistory), + trailing: + const Icon(Icons.keyboard_arrow_right_outlined), + onTap: () => controller.launchMangementUrl( + ManagementOption.history, + ), + enabled: controller.showManagementOptions, + ), + ], + ), + const SizedBox(height: 50), + if (!(controller.showManagementOptions)) + ManagementNotAvailableWarning( + controller: controller, + subscriptionController: + pangeaController.subscriptionController, + ), + ], + ), + ), + ), + ); + } +} + +class ManagementNotAvailableWarning extends StatelessWidget { + final SubscriptionManagementController controller; + final SubscriptionController subscriptionController; + + const ManagementNotAvailableWarning({ + required this.controller, + required this.subscriptionController, + super.key, + }); + + @override + Widget build(BuildContext context) { + final bool currentSubscriptionAvailable = + controller.currentSubscriptionAvailable; + final bool currentSubscriptionIsPromotional = + controller.currentSubscriptionIsPromotional; + final String? purchasePlatformDisplayName = + controller.purchasePlatformDisplayName; + final bool isLifetimeSubscription = + subscriptionController.subscription?.isLifetimeSubscription ?? false; + final DateTime? expirationDate = + subscriptionController.subscription?.expirationDate; + + String warningText = L10n.of(context)!.subscriptionManagementUnavailable; + final DateFormat formatter = DateFormat('yyyy-MM-dd'); + + if (currentSubscriptionAvailable) { + warningText = L10n.of(context)!.subsciptionPlatformTooltip; + } else if (currentSubscriptionIsPromotional) { + if (isLifetimeSubscription) { + warningText = L10n.of(context)!.promotionalSubscriptionDesc; + } else { + warningText = L10n.of(context)!.promoSubscriptionExpirationDesc( + formatter.format(expirationDate!), + ); + } + } + + return Center( + child: Column( + children: [ + Text( + warningText, + textAlign: TextAlign.center, + ), + if (purchasePlatformDisplayName != null) + Text( + "${L10n.of(context)!.originalSubscriptionPlatform} $purchasePlatformDisplayName", + textAlign: TextAlign.center, + ), + ], + ), + ); + } +} diff --git a/lib/pangea/pages/sign_up/signup.dart b/lib/pangea/pages/sign_up/signup.dart new file mode 100644 index 000000000..33c4b1788 --- /dev/null +++ b/lib/pangea/pages/sign_up/signup.dart @@ -0,0 +1,156 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; + +import 'package:fluffychat/pangea/pages/sign_up/signup_view.dart'; +import 'package:fluffychat/pangea/utils/error_handler.dart'; +import 'package:fluffychat/pangea/utils/firebase_analytics.dart'; +import 'package:fluffychat/utils/localized_exception_extension.dart'; +import 'package:fluffychat/utils/platform_infos.dart'; +import 'package:fluffychat/widgets/matrix.dart'; + +class SignupPage extends StatefulWidget { + const SignupPage({super.key}); + + @override + SignupPageController createState() => SignupPageController(); +} + +class SignupPageController extends State { + final TextEditingController passwordController = TextEditingController(); + final TextEditingController password2Controller = TextEditingController(); + final TextEditingController emailController = TextEditingController(); + String? error; + bool loading = false; + bool showPassword = false; + bool noEmailWarningConfirmed = false; + bool displaySecondPasswordField = false; + + static const int minPassLength = 8; + + void toggleShowPassword() => setState(() => showPassword = !showPassword); + + // String? get domain => VRouter.of(context).queryParameters['domain']; + + final GlobalKey formKey = GlobalKey(); + + void onPasswordType(String text) { + if (text.length >= minPassLength && !displaySecondPasswordField) { + setState(() { + displaySecondPasswordField = true; + }); + } + } + + String? password1TextFieldValidator(String? value) { + if (value!.isEmpty) { + return L10n.of(context)!.chooseAStrongPassword; + } + if (value.length < minPassLength) { + return L10n.of(context)! + .pleaseChooseAtLeastChars(minPassLength.toString()); + } + return null; + } + + String? password2TextFieldValidator(String? value) { + if (value!.isEmpty) { + return L10n.of(context)!.repeatPassword; + } + if (value != passwordController.text) { + return L10n.of(context)!.passwordsDoNotMatch; + } + return null; + } + + String? emailTextFieldValidator(String? value) { + if (value!.isEmpty && !noEmailWarningConfirmed) { + noEmailWarningConfirmed = true; + return L10n.of(context)!.noEmailWarning; + } + if (value.isNotEmpty && !value.contains('@')) { + return L10n.of(context)!.pleaseEnterValidEmail; + } + return null; + } + + // #Pangea + bool isTnCChecked = false; + String? signupError; + void onTncChange(bool? value) { + isTnCChecked = value ?? false; + signupError = null; + setState(() {}); + } + // #Pangea + + void signup([_]) async { + setState(() { + error = null; + }); + if (!formKey.currentState!.validate()) return; + // #Pangea + if (!isTnCChecked) { + setState(() { + signupError = 'Please agree to the Terms and Conditions'; + }); + return; + } + // #Pangea + setState(() { + loading = true; + }); + + try { + final client = Matrix.of(context).getLoginClient(); + final email = emailController.text; + if (email.isNotEmpty) { + Matrix.of(context).currentClientSecret = + DateTime.now().millisecondsSinceEpoch.toString(); + Matrix.of(context).currentThreepidCreds = + await client.requestTokenToRegisterEmail( + Matrix.of(context).currentClientSecret, + email, + 0, + ); + } + + final displayname = Matrix.of(context).loginUsername!; + final localPart = displayname.toLowerCase().replaceAll(' ', '_'); + + final registerRes = await client.uiaRequestBackground( + (auth) => client.register( + username: localPart, + password: passwordController.text, + initialDeviceDisplayName: PlatformInfos.clientName, + auth: auth, + ), + ); + + //@brord is this right?? + //#Pangea + GoogleAnalytics.login("pangea", registerRes.userId); + //Pangea# + + // Set displayname + if (displayname != localPart) { + await client.setDisplayName( + client.userID!, + displayname, + ); + } + } catch (e) { + //#Pangea + ErrorHandler.logError(e: e); + //Pangea# + error = (e).toLocalizedString(context); + } finally { + if (mounted) { + setState(() => loading = false); + } + } + } + + @override + Widget build(BuildContext context) => SignupPageView(this); +} diff --git a/lib/pangea/pages/sign_up/signup_view.dart b/lib/pangea/pages/sign_up/signup_view.dart new file mode 100644 index 000000000..ce1e18c0d --- /dev/null +++ b/lib/pangea/pages/sign_up/signup_view.dart @@ -0,0 +1,166 @@ +// Flutter imports: + +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; + +import 'package:fluffychat/pangea/widgets/signup/tos_checkbox.dart'; +import 'package:fluffychat/widgets/layouts/login_scaffold.dart'; +import 'signup.dart'; + +class SignupPageView extends StatelessWidget { + final SignupPageController controller; + const SignupPageView(this.controller, {super.key}); + + @override + Widget build(BuildContext context) { + return LoginScaffold( + appBar: AppBar( + leading: controller.loading ? null : const BackButton(), + automaticallyImplyLeading: !controller.loading, + title: Text( + L10n.of(context)!.signUp, + // #Pangea + style: const TextStyle(color: Colors.white), + // #Pangea + ), + ), + body: Form( + key: controller.formKey, + child: ListView( + children: [ + Padding( + padding: const EdgeInsets.all(12.0), + child: TextFormField( + readOnly: controller.loading, + autocorrect: false, + onChanged: controller.onPasswordType, + autofillHints: + controller.loading ? null : [AutofillHints.newPassword], + controller: controller.passwordController, + obscureText: !controller.showPassword, + validator: controller.password1TextFieldValidator, + decoration: InputDecoration( + prefixIcon: const Icon(Icons.vpn_key_outlined), + suffixIcon: IconButton( + tooltip: L10n.of(context)!.showPassword, + icon: Icon( + controller.showPassword + ? Icons.visibility_off_outlined + : Icons.visibility_outlined, + color: Colors.black, + ), + onPressed: controller.toggleShowPassword, + ), + // #Pangea + // errorStyle: const TextStyle(color: Colors.orange), + errorStyle: TextStyle( + color: Theme.of(context).textTheme.bodyMedium?.color, + fontSize: 14, + ), + // Pangea# + hintText: L10n.of(context)!.chooseAStrongPassword, + // #Pangea + fillColor: Theme.of(context) + .colorScheme + .background + .withOpacity(0.75), + // #Pangea + ), + ), + ), + if (controller.displaySecondPasswordField) + Padding( + padding: const EdgeInsets.all(12.0), + child: TextFormField( + readOnly: controller.loading, + autocorrect: false, + autofillHints: + controller.loading ? null : [AutofillHints.newPassword], + controller: controller.password2Controller, + obscureText: !controller.showPassword, + validator: controller.password2TextFieldValidator, + decoration: InputDecoration( + prefixIcon: const Icon(Icons.repeat_outlined), + hintText: L10n.of(context)!.repeatPassword, + // #Pangea + // errorStyle: const TextStyle(color: Colors.orange), + errorStyle: TextStyle( + color: Theme.of(context).textTheme.bodyMedium?.color, + fontSize: 14, + ), + fillColor: Theme.of(context) + .colorScheme + .background + .withOpacity(0.75), + // #Pangea + ), + ), + ), + Padding( + padding: const EdgeInsets.all(12.0), + child: TextFormField( + readOnly: controller.loading, + autocorrect: false, + controller: controller.emailController, + keyboardType: TextInputType.emailAddress, + autofillHints: + controller.loading ? null : [AutofillHints.username], + validator: controller.emailTextFieldValidator, + decoration: InputDecoration( + prefixIcon: const Icon(Icons.mail_outlined), + hintText: L10n.of(context)!.enterAnEmailAddress, + errorText: controller.error, + errorMaxLines: 4, + // #Pangea + fillColor: Theme.of(context) + .colorScheme + .background + .withOpacity(0.75), + // errorStyle: TextStyle( + // color: controller.emailController.text.isEmpty + // ? Colors.orangeAccent + // : Colors.orange, + // ), + errorStyle: TextStyle( + color: Theme.of(context).textTheme.bodyMedium?.color, + fontSize: 14, + ), + // Pangea# + ), + ), + ), + // #Pangea + TosCheckbox(controller), + // #Pangea + Hero( + tag: 'loginButton', + child: Padding( + padding: const EdgeInsets.all(12), + // #Pangea + child: ElevatedButton( + onPressed: controller.loading ? () {} : controller.signup, + child: controller.loading + ? const LinearProgressIndicator() + : Text(L10n.of(context)!.signUp), + ), + // child: ElevatedButton.icon( + // icon: const Icon(Icons.person_add_outlined), + // style: ElevatedButton.styleFrom( + // foregroundColor: Theme.of(context).colorScheme.onPrimary, + // backgroundColor: Theme.of(context).colorScheme.primary, + // ), + // onPressed: controller.loading ? () {} : controller.signup, + // label: controller.loading + // ? const LinearProgressIndicator() + // : Text(L10n.of(context)!.signUp), + // ), + // #Pangea + ), + ), + ], + ), + ), + ); + } +} diff --git a/lib/pangea/repo/class_analytics_repo.dart b/lib/pangea/repo/class_analytics_repo.dart new file mode 100644 index 000000000..fae8fe3b5 --- /dev/null +++ b/lib/pangea/repo/class_analytics_repo.dart @@ -0,0 +1,76 @@ +// import 'dart:convert'; +// import 'dart:developer'; + +// import 'package:fluffychat/pangea/network/requests.dart'; +// import 'package:fluffychat/pangea/utils/analytics_util.dart'; +// import 'package:flutter/foundation.dart'; +// import 'package:http/http.dart'; + +// import '../../config/environment.dart'; +// import '../models/analytics_model_oldest.dart'; +// import '../network/urls.dart'; + +class PClassAnalyticsRepo { + /// deprecated in favor of new analytics + static Future repoGetAnalyticsByIds( + String accessToken, + String timeSpan, { + List? classIds, + List? userIds, + List? chatIds, + }) async { + // if (!AnalyticsUtil.isValidSpan(timeSpan)) throw "Invalid span"; + + // final Requests req = Requests( + // accessToken: accessToken, choreoApiKey: Environment.choreoApiKey); + + // final body = {}; + // body["timespan"] = timeSpan; + // if (classIds != null) body["class_ids"] = classIds; + // if (chatIds != null) body["chat_ids"] = chatIds; + // if (userIds != null) body["user_ids"] = userIds; + + // final Response res = + // await req.post(url: PApiUrls.classAnalytics, body: body); + // final json = jsonDecode(res.body); + + // final Iterable? classJson = json["class_analytics"]; + // final Iterable? chatJson = json["chat_analytics"]; + // final Iterable? userJson = json["user_analytics"]; + + // final classInfo = classJson != null + // ? (classJson) + // .map((e) { + // e["timespan"] = timeSpan; + // return chartAnalytics(e); + // }) + // .toList() + // .cast() + // : []; + // final chatInfo = chatJson != null + // ? (chatJson) + // .map((e) { + // e["timespan"] = timeSpan; + // return chartAnalytics(e); + // }) + // .toList() + // .cast() + // : []; + // final userInfo = userJson != null + // ? (userJson) + // .map((e) { + // e["timespan"] = timeSpan; + // return chartAnalytics(e); + // }) + // .toList() + // .cast() + // : []; + + // final List allAnalytics = [ + // ...classInfo, + // ...chatInfo, + // ...userInfo + // ]; + // return allAnalytics; + } +} diff --git a/lib/pangea/repo/class_repo.dart b/lib/pangea/repo/class_repo.dart new file mode 100644 index 000000000..f6a92c924 --- /dev/null +++ b/lib/pangea/repo/class_repo.dart @@ -0,0 +1,70 @@ +import 'dart:convert'; + +import 'package:flutter/material.dart'; + +import 'package:http/http.dart'; + +import 'package:fluffychat/pangea/models/class_email_invite_model.dart'; +import 'package:fluffychat/pangea/models/class_model.dart'; +import '../network/requests.dart'; +import '../network/urls.dart'; + +class PClassRepo { + static classesBySpaceIds(String accessToken, List spaceIds) async { + final Requests req = + Requests(baseUrl: PApiUrls.baseAPI, accessToken: accessToken); + final Response res = await req + .post(url: PApiUrls.classListBySpaceIds, body: {"class_ids": spaceIds}); + final json = jsonDecode(res.body); + final List pangeaClasses = json["results"] + .map((e) { + final ClassSettingsModel model = ClassSettingsModel.fromJson(e); + return model; + }) + .toList() + .cast(); + return pangeaClasses; + } + + //Question for Jordan - what happens if code is incorrect? statuscode 400? + // what about if user is already in the class? + //Question for Lala: In this widget, controller, repo framework, where are + // errors handled? How are they passed? + static Future getClassByCode( + String classCode, + String accessToken, + ) async { + final Requests req = + Requests(baseUrl: PApiUrls.baseAPI, accessToken: accessToken); + final Response res = + await req.get(url: PApiUrls.getClassByClassCode + classCode); + + if (res.statusCode == 400) { + return null; + } + final json = jsonDecode(res.body); + + final classSettings = ClassSettingsModel.fromJson(json); + + return classSettings; + } + + static searchClass(String text) async {} + + static sendEmailToJoinClass( + List data, + String roomId, + String teacherName, + ) async {} + + static inviteAction(BuildContext context, String id, String roomId) async {} + + static reportUser({ + String? classRoomNamedata, + String? classTeacherNamedata, + String? reportedUserdata, + String? classTeacherEmaildata, + String? offensivedata, + String? reasondata, + }) async {} +} diff --git a/lib/pangea/repo/contextualized_translation_repo.dart b/lib/pangea/repo/contextualized_translation_repo.dart new file mode 100644 index 000000000..c2ffe1853 --- /dev/null +++ b/lib/pangea/repo/contextualized_translation_repo.dart @@ -0,0 +1,108 @@ +import 'dart:convert'; + +import 'package:http/http.dart'; +import 'package:sentry_flutter/sentry_flutter.dart'; + +import 'package:fluffychat/pangea/constants/model_keys.dart'; +import 'package:fluffychat/pangea/utils/error_handler.dart'; +import '../config/environment.dart'; +import '../models/pangea_token_model.dart'; +import '../network/requests.dart'; +import '../network/urls.dart'; + +class ContextualizationTranslationRepo { + //Question for Jordan - is this for an individual token or could it be a span? + static Future translate({ + required String accessToken, + required ContextualTranslationRequestModel request, + }) async { + final Requests req = Requests( + choreoApiKey: Environment.choreoApiKey, + accessToken: accessToken, + ); + + final Response res = await req.post( + url: PApiUrls.contextualizedTranslation, + body: request.toJson(), + ); + + final ContextTranslationResponseModel response = + ContextTranslationResponseModel.fromJson( + jsonDecode( + utf8.decode(res.bodyBytes).toString(), + ), + ); + + if (response.translations.isEmpty) { + ErrorHandler.logError( + e: Exception( + "empty translations in contextual translation response return", + ), + ); + } + + return response; + } +} + +class ContextualTranslationRequestModel { + String fullText; + String srcLangCode; + String tgtLangCode; + String userL1; + String userL2; + PangeaTokenText span; + + ContextualTranslationRequestModel({ + required this.fullText, + required this.srcLangCode, + required this.tgtLangCode, + required this.span, + required this.userL1, + required this.userL2, + }); + + static const String _spanKey = "span"; + + Map toJson() => { + ModelKey.fullText: fullText, + ModelKey.srcLang: srcLangCode, + ModelKey.tgtLang: tgtLangCode, + _spanKey: span.toJson(), + ModelKey.userL1: userL1, + ModelKey.userL2: userL2, + }; +} + +class ContextTranslationResponseModel { + List translations; + + ContextTranslationResponseModel({required this.translations}); + + static const _translationsKey = "translation"; + + factory ContextTranslationResponseModel.fromJson( + Map json, + ) { + final List trans = json[_translationsKey] is List + ? (json[_translationsKey] as List).map((e) => e.toString()).toList() + : json[_translationsKey] != null + ? [ + json[_translationsKey], + ] + : []; + + if (trans.isEmpty) { + Sentry.addBreadcrumb( + Breadcrumb( + message: "ContextTranslationResponseModel with empty translations", + data: {"response": json}, + ), + ); + } + + return ContextTranslationResponseModel( + translations: trans, + ); + } +} diff --git a/lib/pangea/repo/exchange_repo.dart b/lib/pangea/repo/exchange_repo.dart new file mode 100644 index 000000000..a4b78112c --- /dev/null +++ b/lib/pangea/repo/exchange_repo.dart @@ -0,0 +1,34 @@ +import 'package:flutter/material.dart'; + +class PExchangeRepo { + static fetchExchangeClassInfo(String exchangePangeaId) async {} + + static saveExchangeRecord( + String requestFromClass, + String requestToClass, + String requestTeacher, + String requestToClassAuthor, + String exchangePangeaId, + ) async {} + + static exchangeRejectRequest(String roomId, String teacherName) async {} + + static validateExchange({ + required String requestFromClass, + required String requestToClass, + required BuildContext context, + }) async {} + + static createExchangeRequest({ + required String roomId, + required String teacherID, + required String toClass, + required BuildContext context, + }) async {} + + static isExchange( + BuildContext context, + String accessToken, + String exchangeId, + ) async {} +} diff --git a/lib/pangea/repo/full_text_translation_repo.dart b/lib/pangea/repo/full_text_translation_repo.dart new file mode 100644 index 000000000..a781b4b0d --- /dev/null +++ b/lib/pangea/repo/full_text_translation_repo.dart @@ -0,0 +1,90 @@ +//Question for Jordan - is this for an individual token or could it be a span? + +import 'dart:convert'; + +import 'package:http/http.dart'; + +import '../config/environment.dart'; +import '../constants/model_keys.dart'; +import '../network/requests.dart'; +import '../network/urls.dart'; + +class FullTextTranslationRepo { + static Future translate({ + required String accessToken, + required FullTextTranslationRequestModel request, + }) async { + final Requests req = Requests( + choreoApiKey: Environment.choreoApiKey, + accessToken: accessToken, + ); + + final Response res = await req.post( + url: PApiUrls.simpleTranslation, + body: request.toJson(), + ); + + return FullTextTranslationResponseModel.fromJson( + jsonDecode(utf8.decode(res.bodyBytes)), + ); + } +} + +class FullTextTranslationRequestModel { + String text; + String? srcLang; + String tgtLang; + String userL1; + String userL2; + bool? deepL; + + FullTextTranslationRequestModel({ + required this.text, + this.srcLang, + required this.tgtLang, + required this.userL2, + required this.userL1, + this.deepL = false, + }); + + //PTODO throw error for null + + Map toJson() => { + "text": text, + ModelKey.srcLang: srcLang, + ModelKey.tgtLang: tgtLang, + ModelKey.userL2: userL2, + ModelKey.userL1: userL1, + ModelKey.deepL: deepL, + }; +} + +class FullTextTranslationResponseModel { + List translations; + + /// detected source + /// PTODO - + String source; + String? deepL; + + FullTextTranslationResponseModel({ + required this.translations, + required this.source, + required this.deepL, + }); + + factory FullTextTranslationResponseModel.fromJson(Map json) { + return FullTextTranslationResponseModel( + translations: (json["translations"] as Iterable) + .map( + (e) => e, + ) + .toList() + .cast(), + source: json[ModelKey.srcLang], + deepL: json['deepl_res'], + ); + } + + String get bestTranslation => deepL ?? translations.first; +} diff --git a/lib/pangea/repo/igc_repo.dart b/lib/pangea/repo/igc_repo.dart new file mode 100644 index 000000000..068a009e8 --- /dev/null +++ b/lib/pangea/repo/igc_repo.dart @@ -0,0 +1,113 @@ +import 'dart:convert'; + +import 'package:http/http.dart'; + +import 'package:fluffychat/pangea/config/environment.dart'; +import 'package:fluffychat/pangea/models/language_detection_model.dart'; +import 'package:fluffychat/pangea/models/lemma.dart'; +import 'package:fluffychat/pangea/models/pangea_match_model.dart'; +import 'package:fluffychat/pangea/models/pangea_token_model.dart'; +import 'package:fluffychat/pangea/repo/span_data_repo.dart'; +import '../constants/model_keys.dart'; +import '../models/igc_text_data_model.dart'; +import '../network/requests.dart'; +import '../network/urls.dart'; + +class IgcRepo { + static Future getIGC( + String? accessToken, { + required IGCRequestBody igcRequest, + }) async { + final Requests req = Requests( + accessToken: accessToken, + choreoApiKey: Environment.choreoApiKey, + ); + final Response res = await req.post( + url: PApiUrls.igcLite, + body: igcRequest.toJson(), + ); + + final Map json = + jsonDecode(utf8.decode(res.bodyBytes).toString()); + + final IGCTextData response = IGCTextData.fromJson(json); + + return response; + } + + static Future getMockData() async { + await Future.delayed(const Duration(seconds: 2)); + + final IGCTextData igcTextData = IGCTextData( + detections: [LanguageDetection(langCode: "en")], + tokens: [ + PangeaToken( + text: PangeaTokenText(content: "This", offset: 0, length: 4), + hasInfo: true, + lemmas: [Lemma(form: "This", text: "this", saveVocab: true)], + ), + PangeaToken( + text: PangeaTokenText(content: "be", offset: 5, length: 2), + hasInfo: true, + lemmas: [Lemma(form: "be", text: "be", saveVocab: true)], + ), + PangeaToken( + text: PangeaTokenText(content: "a", offset: 8, length: 1), + hasInfo: false, + lemmas: [], + ), + PangeaToken( + text: PangeaTokenText(content: "sample", offset: 10, length: 6), + hasInfo: false, + lemmas: [], + ), + PangeaToken( + text: PangeaTokenText(content: "text", offset: 17, length: 4), + hasInfo: false, + lemmas: [], + ), + ], + matches: [ + PangeaMatch( + match: spanDataRepomockSpan, + status: PangeaMatchStatus.open, + ), + ], + originalInput: "This be a sample text", + fullTextCorrection: "This is a sample text", + userL1: "es", + userL2: "en", + enableIT: true, + enableIGC: true, + ); + + return igcTextData; + } +} + +class IGCRequestBody { + String fullText; + String userL1; + String userL2; + bool tokensOnly; + bool enableIT; + bool enableIGC; + + IGCRequestBody({ + required this.fullText, + required this.userL1, + required this.userL2, + required this.enableIGC, + required this.enableIT, + this.tokensOnly = false, + }); + + Map toJson() => { + ModelKey.fullText: fullText, + ModelKey.userL1: userL1, + ModelKey.userL2: userL2, + "enable_it": enableIT, + "enable_igc": enableIGC, + "tokens_only": tokensOnly, + }; +} diff --git a/lib/pangea/repo/interactive_translation_repo.dart b/lib/pangea/repo/interactive_translation_repo.dart new file mode 100644 index 000000000..b46db4b75 --- /dev/null +++ b/lib/pangea/repo/interactive_translation_repo.dart @@ -0,0 +1,43 @@ +import 'dart:convert'; + +import 'package:http/http.dart'; + +import 'package:fluffychat/pangea/config/environment.dart'; +import '../models/custom_input_translation_model.dart'; +import '../models/it_response_model.dart'; +import '../models/system_choice_translation_model.dart'; +import '../network/requests.dart'; +import '../network/urls.dart'; + +class ITRepo { + static Future customInputTranslate( + CustomInputRequestModel initalText, + ) async { + final Requests req = Requests( + baseUrl: PApiUrls.choreoBaseApi, + choreoApiKey: Environment.choreoApiKey, + ); + final Response res = + await req.post(url: PApiUrls.firstStep, body: initalText.toJson()); + + final json = jsonDecode(utf8.decode(res.bodyBytes).toString()); + + return ITResponseModel.fromJson(json); + } + + static Future systemChoiceTranslate( + SystemChoiceRequestModel subseqText, + ) async { + final Requests req = Requests( + baseUrl: PApiUrls.choreoBaseApi, + choreoApiKey: Environment.choreoApiKey, + ); + + final Response res = + await req.post(url: PApiUrls.subseqStep, body: subseqText.toJson()); + + final decodedBody = jsonDecode(utf8.decode(res.bodyBytes).toString()); + + return ITResponseModel.fromJson(decodedBody); + } +} diff --git a/lib/pangea/repo/language_repo.dart b/lib/pangea/repo/language_repo.dart new file mode 100644 index 000000000..b74b8a030 --- /dev/null +++ b/lib/pangea/repo/language_repo.dart @@ -0,0 +1,32 @@ +import 'dart:convert'; +import 'dart:developer'; + +import 'package:flutter/foundation.dart'; + +import 'package:http/http.dart'; + +import 'package:fluffychat/pangea/models/language_model.dart'; +import 'package:fluffychat/pangea/network/urls.dart'; +import 'package:fluffychat/pangea/utils/error_handler.dart'; +import '../config/environment.dart'; +import '../network/requests.dart'; + +class LanguageRepo { + static Future> fetchLanguages() async { + final Requests req = Requests(baseUrl: Environment.baseAPI); + final Response res = await req.get(url: PApiUrls.getLanguages); + + final decodedBody = + jsonDecode(utf8.decode(res.bodyBytes).toString()) as List; + final List langFlag = decodedBody.map((e) { + try { + return LanguageModel.fromJson(e); + } catch (err, stack) { + debugger(when: kDebugMode); + ErrorHandler.logError(e: err, s: stack, data: e); + return LanguageModel.unknown; + } + }).toList(); + return langFlag; + } +} diff --git a/lib/pangea/repo/message_service.repo.dart b/lib/pangea/repo/message_service.repo.dart new file mode 100644 index 000000000..612ee0c61 --- /dev/null +++ b/lib/pangea/repo/message_service.repo.dart @@ -0,0 +1,55 @@ +import '../config/environment.dart'; +import '../network/requests.dart'; +import '../network/urls.dart'; + +class MessageServiceRepo { + static Future sendPayloads( + MessageServiceModel serviceModel, + String messageId, + ) async { + final Requests req = Requests( + baseUrl: PApiUrls.choreoBaseApi, + choreoApiKey: Environment.choreoApiKey, + ); + + final json = serviceModel.toJson(); + json["msg_id"] = messageId; + + await req.post(url: PApiUrls.messageService, body: json); + } +} + +class MessageServiceModel { + List payloadIds; + String? messageId; + String message; + String userId; + String roomId; + String? classId; + String? l1Lang; + String l2Lang; + + MessageServiceModel({ + required this.payloadIds, + required this.messageId, + required this.message, + required this.userId, + required this.roomId, + required this.classId, + required this.l1Lang, + required this.l2Lang, + }); + + toJson() { + return { + 'payload_ids': payloadIds, + 'msg_id': messageId, + 'message': message, + 'user_id': userId, + 'room_id': roomId, + 'class_id': classId, + 'l1_lang': l1Lang, + 'l2_lang': l2Lang, + }; + } +} diff --git a/lib/pangea/repo/similarity_repo.dart b/lib/pangea/repo/similarity_repo.dart new file mode 100644 index 000000000..9b3786af8 --- /dev/null +++ b/lib/pangea/repo/similarity_repo.dart @@ -0,0 +1,106 @@ +import 'dart:convert'; + +import 'package:http/http.dart'; + +import 'package:fluffychat/pangea/config/environment.dart'; +import '../network/requests.dart'; +import '../network/urls.dart'; + +class SimilarityRepo { + static Future get({ + required String accessToken, + required SimilarityRequestModel request, + }) async { + final Requests req = Requests( + choreoApiKey: Environment.choreoApiKey, + accessToken: accessToken, + ); + + final Response res = await req.post( + url: PApiUrls.similarity, + body: request.toJson(), + ); + + final SimilartyResponseModel response = SimilartyResponseModel.fromJson( + jsonDecode( + utf8.decode(res.bodyBytes).toString(), + ), + ); + + return response; + } +} + +class SimilarityRequestModel { + String benchmark; + List toCompare; + + SimilarityRequestModel({required this.benchmark, required this.toCompare}); + + Map toJson() => { + "original": benchmark, + "to_compare": toCompare, + }; +} + +class SimilartyResponseModel { + String benchmark; + List scores; + + SimilartyResponseModel({required this.benchmark, required this.scores}); + + factory SimilartyResponseModel.fromJson( + Map json, + ) => + SimilartyResponseModel( + benchmark: json["original"], + scores: List.from( + json["scores"].map( + (x) => SimilarityScore.fromJson(x), + ), + ), + ); + + SimilarityScore get highestScore { + SimilarityScore highest = scores.first; + for (final SimilarityScore score in scores) { + if (score.score > highest.score) { + highest = score; + } + } + return highest; + } + + bool userTranslationIsDifferentButBetter(String userTranslation) { + return highestScore.text == userTranslation; + } + + bool userTranslationIsSameAsBotTranslation(String userTranslation) { + return highestScore.text == userTranslation && + scores.where((e) => e.text == userTranslation).length == 2; + } + + num userScore(String userTranslation) { + return scores.firstWhere((e) => e.text == userTranslation).score; + } +} + +class SimilarityScore { + String text; + double score; + int index; + + SimilarityScore({ + required this.text, + required this.score, + required this.index, + }); + + factory SimilarityScore.fromJson(Map json) { + return SimilarityScore( + text: json["text"], + score: json["score"], + index: json["index"], + ); + } +} diff --git a/lib/pangea/repo/span_data_repo.dart b/lib/pangea/repo/span_data_repo.dart new file mode 100644 index 000000000..878ae5f44 --- /dev/null +++ b/lib/pangea/repo/span_data_repo.dart @@ -0,0 +1,113 @@ +import 'dart:convert'; + +import 'package:http/http.dart'; + +import 'package:fluffychat/pangea/config/environment.dart'; +import 'package:fluffychat/pangea/enum/span_choice_type.dart'; +import 'package:fluffychat/pangea/enum/span_data_type.dart'; +import 'package:fluffychat/pangea/models/span_data.dart'; +import '../constants/model_keys.dart'; +import '../network/requests.dart'; +import '../network/urls.dart'; + +class SpanDataRepo { + static Future getSpanDetails( + String? accessToken, { + required SpanDetailsRepoReqAndRes request, + }) async { + final Requests req = Requests( + accessToken: accessToken, + choreoApiKey: Environment.choreoApiKey, + ); + final Response res = await req.post( + url: PApiUrls.spanDetails, + body: request.toJson(), + ); + + final Map json = + jsonDecode(utf8.decode(res.bodyBytes).toString()); + + return SpanDetailsRepoReqAndRes.fromJson(json); + } +} + +Future getMock(SpanDetailsRepoReqAndRes req) async { + await Future.delayed(const Duration(seconds: 2)); + if (req.span.choices != null && + req.span.choices!.any((element) => element.selected)) { + return req..span = mockReponseWithHintOne.span; + } else { + return req..span = mockReponseWithChoices.span; + } +} + +class SpanDetailsRepoReqAndRes { + String userL1; + String userL2; + bool enableIT; + bool enableIGC; + SpanData span; + + SpanDetailsRepoReqAndRes({ + required this.userL1, + required this.userL2, + required this.enableIGC, + required this.enableIT, + required this.span, + }); + + Map toJson() => { + ModelKey.userL1: userL1, + ModelKey.userL2: userL2, + "enable_it": enableIT, + "enable_igc": enableIGC, + 'span': span.toJson(), + }; + + factory SpanDetailsRepoReqAndRes.fromJson(Map json) => + SpanDetailsRepoReqAndRes( + userL1: json['user_l1'] as String, + userL2: json['user_l2'] as String, + enableIT: json['enable_it'] as bool, + enableIGC: json['enable_igc'] as bool, + span: SpanData.fromJson(json['span']), + ); +} + +final spanDataRepomockSpan = SpanData( + offset: 5, + length: 2, + fullText: "This be a sample text", + type: SpanDataType(typeName: SpanDataTypeEnum.correction), + context: null, + choices: [SpanChoice(value: "is", type: SpanChoiceType.bestCorrection)], + message: null, + rule: null, + shortMessage: null, +); + +//json mock request +final mockRequest = SpanDetailsRepoReqAndRes( + userL1: "es", + userL2: "en", + enableIGC: true, + enableIT: true, + span: spanDataRepomockSpan, +); + +SpanDetailsRepoReqAndRes get mockReponseWithChoices { + final SpanDetailsRepoReqAndRes res = mockRequest; + res.span.choices = [ + SpanChoice(value: "is", type: SpanChoiceType.bestCorrection), + SpanChoice(value: "are", type: SpanChoiceType.distractor), + SpanChoice(value: "was", type: SpanChoiceType.distractor), + ]; + return res; +} + +SpanDetailsRepoReqAndRes get mockReponseWithHintOne { + final SpanDetailsRepoReqAndRes res = mockReponseWithChoices; + res.span.choices![1].selected = true; + res.span.message = "Conjugation error"; + return res; +} diff --git a/lib/pangea/repo/subscription_repo.dart b/lib/pangea/repo/subscription_repo.dart new file mode 100644 index 000000000..16ea60c4d --- /dev/null +++ b/lib/pangea/repo/subscription_repo.dart @@ -0,0 +1,223 @@ +import 'dart:convert'; + +import 'package:flutter/material.dart'; + +import 'package:collection/collection.dart'; +import 'package:http/http.dart' as http; + +import 'package:fluffychat/pangea/config/environment.dart'; +import 'package:fluffychat/pangea/controllers/subscription_controller.dart'; +import 'package:fluffychat/pangea/utils/error_handler.dart'; +import 'package:fluffychat/pangea/utils/subscription_app_id.dart'; +import '../network/urls.dart'; + +class SubscriptionRepo { + static final Map requestHeaders = { + 'Content-type': 'application/json', + 'Accept': 'application/json', + 'Authorization': 'Bearer ${Environment.rcKey}', + }; + + static Future getAppIds() async { + try { + final http.Response res = await http.get( + Uri.parse(PApiUrls.rcApps), + headers: SubscriptionRepo.requestHeaders, + ); + final json = jsonDecode(res.body); + return SubscriptionAppIds.fromJson(json); + } catch (err) { + ErrorHandler.logError( + m: "Failed to fetch app information for revenuecat API", + s: StackTrace.current, + ); + return null; + } + } + + static Future?> getAllProducts() async { + try { + final http.Response res = await http.get( + Uri.parse(PApiUrls.rcProducts), + headers: SubscriptionRepo.requestHeaders, + ); + final Map json = jsonDecode(res.body); + final RCProductsResponseModel resp = + RCProductsResponseModel.fromJson(json); + return resp.allProducts; + } catch (err) { + ErrorHandler.logError( + m: "Failed to fetch entitlement information for revenuecat API", + s: StackTrace.current, + ); + return null; + } + } + + static Future getCurrentSubscriptionInfo( + String? userId, + List? allProducts, + ) async { + final Map stripeHeaders = { + 'Content-type': 'application/json', + 'Accept': 'application/json', + 'Authorization': 'Bearer ${Environment.rcStripeKey}', + }; + final String url = "${PApiUrls.rcSubscribers}/$userId"; + final http.Response res = await http.get( + Uri.parse(url), + headers: stripeHeaders, + ); + final Map json = jsonDecode(res.body); + final RCSubscriptionResponseModel resp = + RCSubscriptionResponseModel.fromJson( + json, + allProducts, + ); + return resp; + } +} + +class RCProductsResponseModel { + List allProducts; + + RCProductsResponseModel({ + required this.allProducts, + }); + + factory RCProductsResponseModel.fromJson( + Map json, + ) { + final List offerings = json["items"] as List; + final offering = offerings.firstWhereOrNull( + Environment.isStaging + ? (offering) => !(offering['is_current'] as bool) + : (offering) => offering['is_current'] as bool, + ); + final Map metadata = offering['metadata']; + + final List allProducts = []; + for (final packageDetails in offering['packages']['items']) { + final String packageId = packageDetails['id']; + final List products = + RCProductsResponseModel.productsFromPackageDetails( + packageDetails, + packageId, + metadata, + ); + allProducts.addAll(products); + } + + return RCProductsResponseModel(allProducts: allProducts); + } + + static List productsFromPackageDetails( + Map packageDetails, + String packageId, + Map metadata, + ) { + return packageDetails['products']['items'] + .map( + (productDetails) => SubscriptionDetails( + price: double.parse(metadata['$packageId.price']), + duration: metadata['$packageId.duration'], + id: productDetails['product']['store_identifier'], + appId: productDetails['product']['app_id'], + ), + ) + .toList() + .cast(); + } +} + +class RCSubscriptionResponseModel { + String? currentSubscriptionId; + SubscriptionDetails? currentSubscription; + DateTime? expirationDate; + List? allEntitlements; + + RCSubscriptionResponseModel({ + this.currentSubscriptionId, + this.currentSubscription, + this.allEntitlements, + this.expirationDate, + }); + + factory RCSubscriptionResponseModel.fromJson( + Map json, + List? allProducts, + ) { + final List activeEntitlements = + RCSubscriptionResponseModel.getActiveEntitlements(json); + + final List allEntitlements = + RCSubscriptionResponseModel.getAllEntitlements(json); + + if (activeEntitlements.length > 1) { + debugPrint( + "User has more than one active entitlement. This shouldn't happen", + ); + } + if (activeEntitlements.isEmpty) { + debugPrint("User has no active entitlements"); + return RCSubscriptionResponseModel(); + } + + final String currentSubscriptionId = activeEntitlements[0]; + + final Map currentSubscriptionMetadata = + json['subscriber']['subscriptions'][currentSubscriptionId]; + + final DateTime expirationDate = DateTime.parse( + currentSubscriptionMetadata['expires_date'], + ); + + final String currentSubscriptionPeriodType = + currentSubscriptionMetadata['period_type'] ?? ""; + + final SubscriptionDetails? currentSubscription = + allProducts?.firstWhereOrNull( + (SubscriptionDetails sub) => + sub.id.contains(currentSubscriptionId) || + currentSubscriptionId.contains(sub.id), + ); + + if (currentSubscriptionPeriodType == "trial") { + currentSubscription?.makeTrial(); + } + + return RCSubscriptionResponseModel( + currentSubscription: currentSubscription, + currentSubscriptionId: currentSubscriptionId, + expirationDate: expirationDate, + allEntitlements: activeEntitlements, + ); + } + + static List getActiveEntitlements(Map json) { + return json['subscriber']['entitlements'] + .entries + .where( + (MapEntry entitlement) => DateTime.parse( + entitlement.value['expires_date'], + ).isAfter(DateTime.now()), + ) + .map( + (MapEntry entitlement) => + entitlement.value['product_identifier'], + ) + .cast() + .toList(); + } + + static List getAllEntitlements(Map json) { + return json['subscriber']['entitlements'] + .entries + .map( + (MapEntry entitlement) => + entitlement.value['product_identifier'], + ) + .cast() + .toList(); + } +} diff --git a/lib/pangea/repo/tokens_repo.dart b/lib/pangea/repo/tokens_repo.dart new file mode 100644 index 000000000..8d47e1a2c --- /dev/null +++ b/lib/pangea/repo/tokens_repo.dart @@ -0,0 +1,81 @@ +import 'dart:convert'; + +import 'package:http/http.dart'; + +import 'package:fluffychat/pangea/constants/model_keys.dart'; +import 'package:fluffychat/pangea/utils/error_handler.dart'; +import '../config/environment.dart'; +import '../models/pangea_token_model.dart'; +import '../network/requests.dart'; +import '../network/urls.dart'; + +class TokensRepo { + static Future tokenize( + String accessToken, + TokensRequestModel request, + ) async { + final Requests req = Requests( + choreoApiKey: Environment.choreoApiKey, + accessToken: accessToken, + ); + + final Response res = await req.post( + url: PApiUrls.tokenize, + body: request.toJson(), + ); + + final TokensResponseModel response = TokensResponseModel.fromJson( + jsonDecode( + utf8.decode(res.bodyBytes).toString(), + ), + ); + + if (response.tokens.isEmpty) { + ErrorHandler.logError( + e: Exception( + "empty tokens in tokenize response return", + ), + ); + } + + return response; + } +} + +class TokensRequestModel { + String fullText; + String userL1; + String userL2; + + TokensRequestModel({ + required this.fullText, + required this.userL1, + required this.userL2, + }); + + Map toJson() => { + ModelKey.fullText: fullText, + ModelKey.userL1: userL1, + ModelKey.userL2: userL2, + }; +} + +class TokensResponseModel { + List tokens; + String lang; + + TokensResponseModel({required this.tokens, required this.lang}); + + factory TokensResponseModel.fromJson( + Map json, + ) => + TokensResponseModel( + tokens: (json[ModelKey.tokens] as Iterable) + .map( + (e) => PangeaToken.fromJson(e as Map), + ) + .toList() + .cast(), + lang: json[ModelKey.lang], + ); +} diff --git a/lib/pangea/repo/topic_data_repo.dart b/lib/pangea/repo/topic_data_repo.dart new file mode 100644 index 000000000..9a5def03f --- /dev/null +++ b/lib/pangea/repo/topic_data_repo.dart @@ -0,0 +1,72 @@ +import 'dart:convert'; + +import 'package:flutter/services.dart'; + +import 'package:http/http.dart'; + +import '../config/environment.dart'; +import '../models/chat_topic_model.dart'; +import '../network/requests.dart'; +import '../network/urls.dart'; + +/// accepts ChatTopic and calls an API for a list of Lemma +class TopicDataRepo { + static Future generate( + String? accessToken, { + required TopicDataRequest request, + }) async { + final Requests req = Requests( + accessToken: accessToken, + choreoApiKey: Environment.choreoApiKey, + ); + final Response res = await req.post( + url: PApiUrls.topicInfo, + body: request.toJson(), + ); + + return TopicDataResponse.fromJson(jsonDecode(res.body)).topicInfo; + } + + /// gets list of ChatTopic from assets/chat_data.json + static Future> getTopics(String langCode) async { + final String data = await rootBundle.loadString("assets/chat_data.json"); + final jsonResult = json.decode(data); + final List topics = []; + for (final topic in jsonResult['chats']) { + topics.add(ChatTopic.fromJson(topic)); + } + return topics; + } +} + +class TopicDataResponse { + final ChatTopic topicInfo; + + TopicDataResponse({required this.topicInfo}); + + factory TopicDataResponse.fromJson(Map json) { + return TopicDataResponse( + topicInfo: ChatTopic.fromJson(json['topic_info']), + ); + } +} + +class TopicDataRequest { + final ChatTopic topicInfo; + final int numWords; + final int numPrompts; + + TopicDataRequest({ + required this.topicInfo, + required this.numWords, + required this.numPrompts, + }); + + Map toJson() { + return { + 'topic_info': topicInfo.toJson(), + 'num_words': numWords, + 'num_prompts': numPrompts, + }; + } +} diff --git a/lib/pangea/repo/user_repo.dart b/lib/pangea/repo/user_repo.dart new file mode 100644 index 000000000..452120962 --- /dev/null +++ b/lib/pangea/repo/user_repo.dart @@ -0,0 +1,124 @@ +import 'dart:convert'; +import 'dart:developer'; + +import 'package:http/http.dart'; + +import 'package:fluffychat/pangea/constants/model_keys.dart'; +import '../../widgets/matrix.dart'; +import '../models/user_model.dart'; +import '../models/user_profile_search_model.dart'; +import '../network/requests.dart'; +import '../network/urls.dart'; + +class PUserRepo { + static Future repoCreatePangeaUser({ + required String userID, + required String dateOfBirth, + required fullName, + required String matrixAccessToken, + }) async { + final Requests req = Requests( + baseUrl: PApiUrls.baseAPI, + matrixAccessToken: matrixAccessToken, + ); + + final Map body = { + ModelKey.userFullName: fullName, + ModelKey.userPangeaUserId: userID, + ModelKey.userDateOfBirth: dateOfBirth, + }; + final Response res = await req.post( + url: PApiUrls.createUser, + body: body, + ); + return PUserModel.fromJson(jsonDecode(res.body)); + } + + static Future fetchPangeaUserInfo({ + required String userID, + required String matrixAccessToken, + }) async { + Response res; + try { + final Requests req = Requests( + baseUrl: PApiUrls.baseAPI, + matrixAccessToken: matrixAccessToken, + ); + res = await req.get( + url: PApiUrls.userDetails, + objectId: userID, + ); + + return PUserModel.fromJson(jsonDecode(res.body)); + } catch (err) { + //status code should be 400 - PTODO - check ffor this. + log("Most likely a first signup and needs to make an account"); + return null; + } + } + + //notes for jordan - only replace non-null fields, return whole profile + //Jordan - should return pangeaUserId as well + static Future updateUserProfile( + Profile userProfile, + String accessToken, + ) async { + final Requests req = Requests( + baseUrl: PApiUrls.baseAPI, + accessToken: accessToken, + ); + final Response res = await req.put( + url: PApiUrls.updateUserProfile, + body: userProfile.toJson(), + ); + + //temp fix + final content = jsonDecode(res.body); + //PTODO - try taking this out and see where bug occurs + if (content[ModelKey.userPangeaUserId] == null) { + content[ModelKey.userPangeaUserId] = + MatrixState.pangeaController.matrixState.client.userID; + } + + return Profile.fromJson(content); + } + + static Future searchUserProfiles({ + // List? interests, + String? targetLanguage, + String? sourceLanguage, + String? country, + // String? speaks, + String? pageNumber, + required String accessToken, + required int limit, + }) async { + final Requests req = Requests( + baseUrl: PApiUrls.baseAPI, + accessToken: accessToken, + ); + final Map body = {}; + // if (interests != null) body[ModelKey.userInterests] = interests.toString(); + if (targetLanguage != null) { + body[ModelKey.userTargetLanguage] = targetLanguage; + } + if (sourceLanguage != null) { + body[ModelKey.userSourceLanguage] = sourceLanguage; + } + if (country != null) body[ModelKey.userCountry] = country; + // if (speaks != null) body[ModelKey.userSpeaks] = speaks; + if (pageNumber != null) { + body["page_number"] = pageNumber; + } + body["limit"] = limit; + + final Response res = await req.post( + url: PApiUrls.searchUserProfiles, + body: body, + ); + + //PTODO - implement paginiation - make another call with next url + + return UserProfileSearchResponse.fromJson(jsonDecode(res.body)); + } +} diff --git a/lib/pangea/repo/word_repo.dart b/lib/pangea/repo/word_repo.dart new file mode 100644 index 000000000..399c620dd --- /dev/null +++ b/lib/pangea/repo/word_repo.dart @@ -0,0 +1,45 @@ +import 'dart:convert'; + +import 'package:http/http.dart'; + +import 'package:fluffychat/pangea/config/environment.dart'; +import '../constants/model_keys.dart'; +import '../models/word_data_model.dart'; +import '../network/requests.dart'; +import '../network/urls.dart'; + +class WordRepo { + static Future getWordNetData({ + required String accessToken, + required String fullText, + required String word, + required String userL1, + required String userL2, + }) async { + final Requests req = Requests( + choreoApiKey: Environment.choreoApiKey, + accessToken: accessToken, + ); + final Response res = await req.post( + url: PApiUrls.wordNet, + body: { + ModelKey.word: word, + ModelKey.fullText: fullText, + ModelKey.userL1: userL1, + ModelKey.userL2: userL2, + }, + ); + + final json = jsonDecode(utf8.decode(res.bodyBytes)); + + final WordData wordData = WordData.fromJson( + json, + fullText: fullText, + word: word, + userL1: userL1, + userL2: userL2, + ); + + return wordData; + } +} diff --git a/lib/pangea/utils/add_to_space.dart b/lib/pangea/utils/add_to_space.dart new file mode 100644 index 000000000..92458856c --- /dev/null +++ b/lib/pangea/utils/add_to_space.dart @@ -0,0 +1,42 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:matrix/matrix.dart'; + +import 'package:fluffychat/pangea/controllers/pangea_controller.dart'; +import 'package:fluffychat/widgets/matrix.dart'; + +bool canAddToSpace(Room space, PangeaController pangeaController) { + final bool pangeaPermission = + pangeaController.permissionsController.canUserGroupChat(roomID: space.id); + final Map powerLevelsMap = + space.getState(EventTypes.RoomPowerLevels)?.content ?? {}; + final pl = powerLevelsMap + .tryGetMap('events') + ?.tryGet(EventTypes.spaceChild) ?? + powerLevelsMap.tryGet('events_default') ?? + 50; + return space.ownPowerLevel >= pl && pangeaPermission; +} + +bool chatIsInSpace(Room chat, Room space) { + return chat.spaceParents.map((e) => e.roomId).toList().contains(space.id); +} + +Future pangeaAddToSpace( + Room space, + List selectedRoomIds, + BuildContext context, + PangeaController pangeaController, +) async { + if (!canAddToSpace(space, pangeaController)) { + throw L10n.of(context)!.noAddToSpacePermissions; + } + for (final roomId in selectedRoomIds) { + final Room? room = Matrix.of(context).client.getRoomById(roomId); + if (room != null && chatIsInSpace(room, space)) { + throw L10n.of(context)!.alreadyInSpace; + } + await space.setSpaceChild(roomId); + } +} diff --git a/lib/pangea/utils/any_state_holder.dart b/lib/pangea/utils/any_state_holder.dart new file mode 100644 index 000000000..46efff974 --- /dev/null +++ b/lib/pangea/utils/any_state_holder.dart @@ -0,0 +1,70 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; + +import 'package:sentry_flutter/sentry_flutter.dart'; + +import '../models/widget_measurement.dart'; + +class PangeaAnyState { + final Map?> _streams = {}; + final Map> _pastValues = {}; + final Map _layerLinkAndKeys = {}; + OverlayEntry? overlay; + + dispose() { + closeOverlay(); + _layerLinkAndKeys.clear(); + } + + LayerLinkAndKey layerLinkAndKey( + String transformTargetId, [ + throwErrorIfNotThere = false, + ]) { + if (_layerLinkAndKeys[transformTargetId] == null) { + if (throwErrorIfNotThere) { + Sentry.addBreadcrumb(Breadcrumb.fromJson(_layerLinkAndKeys)); + throw Exception("layerLinkAndKey with null for $transformTargetId"); + } else { + _layerLinkAndKeys[transformTargetId] = + LayerLinkAndKey(transformTargetId); + } + } + + return _layerLinkAndKeys[transformTargetId]!; + } + + void disposeByWidgetKey(String transformTargetId) { + _layerLinkAndKeys.remove(transformTargetId); + } + + void closeOverlay() { + if (overlay != null) { + overlay!.remove(); + overlay = null; + } + } + + LayerLinkAndKey messageLinkAndKey(String eventId) => layerLinkAndKey(eventId); + + // String chatViewTargetKey(String? roomId) => "chatViewKey$roomId"; + // LayerLinkAndKey chatViewLinkAndKey(String? roomId) => + // layerLinkAndKey(chatViewTargetKey(roomId)); +} + +class LayerLinkAndKey { + late LabeledGlobalKey key; + late LayerLink link; + String transformTargetId; + + LayerLinkAndKey(this.transformTargetId) { + key = LabeledGlobalKey(transformTargetId); + link = LayerLink(); + } + + Map toJson() => { + "key": key.toString(), + "link": link.toString(), + "transformTargetId": transformTargetId, + }; +} diff --git a/lib/pangea/utils/archive_space.dart b/lib/pangea/utils/archive_space.dart new file mode 100644 index 000000000..72f10fae4 --- /dev/null +++ b/lib/pangea/utils/archive_space.dart @@ -0,0 +1,20 @@ +import 'package:matrix/matrix.dart'; + +import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart'; +import 'package:fluffychat/pangea/utils/error_handler.dart'; + +Future archiveSpace(Room? space, Client client) async { + if (space == null) { + ErrorHandler.logError( + e: 'Tried to archive a space that is null. This should not happen.', + s: StackTrace.current, + ); + return; + } + + final List children = await space.getChildRooms(); + for (final Room child in children) { + await child.leave(); + } + await space.leave(); +} diff --git a/lib/pangea/utils/bot_name.dart b/lib/pangea/utils/bot_name.dart new file mode 100644 index 000000000..dc7c0da8f --- /dev/null +++ b/lib/pangea/utils/bot_name.dart @@ -0,0 +1,7 @@ +import 'package:fluffychat/pangea/config/environment.dart'; + +class BotName { + static String get byEnvironment => + Environment.isStaging ? "@bot:staging.pangea.chat" : "@bot:pangea.chat"; + static String get localBot => "@matrix-bot-test:staging.pangea.chat"; +} diff --git a/lib/pangea/utils/bot_style.dart b/lib/pangea/utils/bot_style.dart new file mode 100644 index 000000000..8c971b307 --- /dev/null +++ b/lib/pangea/utils/bot_style.dart @@ -0,0 +1,36 @@ +import 'package:flutter/material.dart'; + +import 'package:fluffychat/config/app_config.dart'; +import 'package:fluffychat/pangea/utils/error_handler.dart'; + +class BotStyle { + static TextStyle text( + BuildContext context, { + TextStyle? existingStyle, + bool setColor = true, + bool big = false, + bool italics = false, + bool bold = true, + }) { + try { + final TextStyle botStyle = TextStyle( + fontFamily: 'Inconsolata', + fontWeight: bold ? FontWeight.w700 : null, + fontSize: AppConfig.messageFontSize * + AppConfig.fontSizeFactor * + (big == true ? 1.2 : 1), + fontStyle: italics ? FontStyle.italic : null, + color: setColor + ? Theme.of(context).brightness == Brightness.dark + ? AppConfig.primaryColorLight + : AppConfig.primaryColor + : null, + ); + + return existingStyle?.merge(botStyle) ?? botStyle; + } catch (err, stack) { + ErrorHandler.logError(m: "error getting styles", s: stack); + return existingStyle ?? const TextStyle(); + } + } +} diff --git a/lib/pangea/utils/chat_list_handle_space_tap.dart b/lib/pangea/utils/chat_list_handle_space_tap.dart new file mode 100644 index 000000000..4ddb76129 --- /dev/null +++ b/lib/pangea/utils/chat_list_handle_space_tap.dart @@ -0,0 +1,142 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; +import 'package:go_router/go_router.dart'; +import 'package:matrix/matrix.dart'; + +import 'package:fluffychat/pages/chat_list/chat_list.dart'; +import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart'; +import 'package:fluffychat/widgets/matrix.dart'; +import 'error_handler.dart'; + +// ignore: curly_braces_in_flow_control_structures +void chatListHandleSpaceTap( + BuildContext context, + ChatListController controller, + Room space, +) { + void setActiveSpaceAndCloseChat() { + controller.setActiveSpace(space.id); + if (controller.activeChat != null && + !space.isFirstOrSecondChild(controller.activeChat!)) { + context.go("/rooms"); + } + } + + void autoJoin(Room space) { + showFutureLoadingDialog( + context: context, + future: () async { + await space.join(); + await space.postLoad(); + setActiveSpaceAndCloseChat(); + }, + onError: (exception) { + ErrorHandler.logError(e: exception); + return exception.toString(); + }, + ); + } + + //show alert dialog prompting user to accept invite or reject + //if accepted, setActiveSpaceAndCloseChat() + //if rejected, leave space + // use standard alert diolog, not cupertino + void showAlertDialog(BuildContext context) { + // set up the AlertDialog + final AlertDialog alert = AlertDialog( + title: Text(L10n.of(context)!.youreInvited), + content: Text( + space.isSpace + ? L10n.of(context)! + .invitedToClassOrExchange(space.name, space.creatorId ?? "???") + : L10n.of(context)! + .invitedToChat(space.name, space.creatorId ?? "???"), + ), + actions: [ + TextButton( + onPressed: () => showFutureLoadingDialog( + context: context, + future: () async { + await space.leave(); + //show snackbar message that you've left + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text(L10n.of(context)!.declinedInvitation), + duration: const Duration(seconds: 3), + ), + ); + Navigator.of(context).pop(); + }, + onError: (exception) { + ErrorHandler.logError(e: exception); + Navigator.of(context).pop(); + return exception.toString(); + }, + ), + child: Text(L10n.of(context)!.decline), + ), + TextButton( + onPressed: () => showFutureLoadingDialog( + context: context, + future: () async { + await space.join(); + setActiveSpaceAndCloseChat(); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text(L10n.of(context)!.acceptedInvitation), + duration: const Duration(seconds: 3), + ), + ); + context.go( + '/rooms/join_exchange/${controller.activeSpaceId}', + ); + }, + onError: (exception) { + ErrorHandler.logError(e: exception); + Navigator.of(context).pop(); + return exception.toString(); + }, + ), + child: Text(L10n.of(context)!.accept), + ), + ], + ); + + // show the dialog + showDialog( + context: context, + builder: (BuildContext context) { + return alert; + }, + ); + } + + switch (space.membership) { + case Membership.join: + setActiveSpaceAndCloseChat(); + break; + case Membership.invite: + //if space is a child of a space you're in, automatically join + //else confirm you want to join + //can we tell whether space or chat? + final rooms = Matrix.of(context).client.rooms.where( + (element) => + element.isSpace && element.membership == Membership.join, + ); + if (rooms.any((s) => s.spaceChildren.any((c) => c.roomId == space.id))) { + autoJoin(space); + } else { + showAlertDialog(context); + } + break; + default: + setActiveSpaceAndCloseChat(); + ErrorHandler.logError( + m: 'should not show space with membership ${space.membership}', + data: space.toJson(), + ); + break; + } +} diff --git a/lib/pangea/utils/class_chat_power_levels.dart b/lib/pangea/utils/class_chat_power_levels.dart new file mode 100644 index 000000000..db19bb6ee --- /dev/null +++ b/lib/pangea/utils/class_chat_power_levels.dart @@ -0,0 +1,39 @@ +import 'package:flutter/material.dart'; + +import 'package:matrix/matrix.dart'; + +import 'package:fluffychat/pangea/constants/pangea_event_types.dart'; +import '../../widgets/matrix.dart'; +import '../constants/class_default_values.dart'; +import '../extensions/pangea_room_extension.dart'; + +class ClassChatPowerLevels { + static Future> powerLevelOverrideForClassChat( + BuildContext context, + List spaceParents, + ) async { + final Client client = Matrix.of(context).client; + final Map powerLevelOverride = {}; + powerLevelOverride['events'] = { + EventTypes.spaceChild: 0, + PangeaEventTypes.studentAnalyticsSummary: 0, + }; + powerLevelOverride['users'] = {}; + + final List spaceAdmin = []; + for (final classRoom in spaceParents) { + final List classTeachers = await classRoom.teachers; + spaceAdmin.addAll(classTeachers); + } + + for (final admin in spaceAdmin) { + powerLevelOverride['users'][admin.id] = + ClassDefaultValues.powerLevelOfAdmin; + } + + powerLevelOverride['users'][client.userID] = + ClassDefaultValues.powerLevelOfAdmin; + + return powerLevelOverride; + } +} diff --git a/lib/pangea/utils/class_code.dart b/lib/pangea/utils/class_code.dart new file mode 100644 index 000000000..6bd9c9764 --- /dev/null +++ b/lib/pangea/utils/class_code.dart @@ -0,0 +1,108 @@ +import 'dart:math'; + +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; +import 'package:go_router/go_router.dart'; + +import 'package:fluffychat/pangea/utils/error_handler.dart'; +import '../controllers/pangea_controller.dart'; + +class ClassCodeUtil { + static const codeLength = 6; + + static bool isValidCode(String? classcode) { + return classcode == null || classcode.length > 4; + } + + static String generateClassCode() { + final r = Random(); + const chars = 'AaBbCcDdEeFfGgHhiJjKkLMmNnoPpQqRrSsTtUuVvWwXxYyZz1234567890'; + return List.generate(codeLength, (index) => chars[r.nextInt(chars.length)]) + .join(); + } + + static void joinWithClassCodeDialog( + BuildContext outerContext, + PangeaController pangeaController, + String? classCode, + ) { + final TextEditingController textFieldController = TextEditingController( + text: classCode, + ); + + showDialog( + context: outerContext, + useRootNavigator: false, + builder: (BuildContext context) => Scaffold( + backgroundColor: Colors.transparent, + body: AlertDialog( + title: Text(L10n.of(context)!.joinWithClassCode), + content: TextField( + controller: textFieldController, + decoration: InputDecoration( + hintText: L10n.of(context)!.joinWithClassCodeHint, + ), + ), + actions: [ + TextButton( + child: Text(L10n.of(context)!.cancel), + onPressed: () => Navigator.of(context).pop(), + ), + TextButton( + child: Text(L10n.of(context)!.ok), + onPressed: () => showFutureLoadingDialog( + context: context, + future: () async { + try { + await pangeaController.classController.joinClasswithCode( + outerContext, + textFieldController.text, + ); + } catch (err) { + messageSnack( + outerContext, + ErrorCopy(outerContext, err).body, + ); + } finally { + context.go("/rooms"); + Navigator.of(context).pop(); + } + }, + ), + ), + ], + ), + ), + ); + } + + static messageDialog( + BuildContext context, + String title, + void Function()? action, + ) => + showDialog( + context: context, + useRootNavigator: false, + builder: (context) => AlertDialog( + content: Text(title), + actions: [ + TextButton( + onPressed: action, + child: Text(L10n.of(context)!.ok), + ), + ], + ), + ); + + static void messageSnack(BuildContext context, String message) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + duration: const Duration(seconds: 10), + content: Text(message), + ), + ); + } +} diff --git a/lib/pangea/utils/custom_exception.dart b/lib/pangea/utils/custom_exception.dart new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/lib/pangea/utils/custom_exception.dart @@ -0,0 +1 @@ + diff --git a/lib/pangea/utils/delete_room.dart b/lib/pangea/utils/delete_room.dart new file mode 100644 index 000000000..f8e168779 --- /dev/null +++ b/lib/pangea/utils/delete_room.dart @@ -0,0 +1,89 @@ +import 'package:matrix/matrix.dart'; + +import 'package:fluffychat/pangea/constants/class_default_values.dart'; +import 'error_handler.dart'; + +Future deleteRoom(String? roomID, Client client) async { + if (roomID == null) { + ErrorHandler.logError( + m: "in deleteRoomAction with null pangeaClassRoomID", + s: StackTrace.current, + ); + return; + } + + final Room? room = client.getRoomById(roomID); + if (room == null) { + ErrorHandler.logError( + m: "failed to fetch room with roomID $roomID", + s: StackTrace.current, + ); + return; + } + + try { + await room.join(); + } catch (err) { + ErrorHandler.logError( + m: "failed to join room with roomID $roomID", + s: StackTrace.current, + ); + return; + } + + List members; + try { + members = await room.requestParticipants(); + } catch (err) { + ErrorHandler.logError( + m: "failed to fetch members for room with roomID $roomID", + s: StackTrace.current, + ); + return; + } + + final List otherAdmins = []; + for (final User member in members) { + final String memberID = member.id; + final int memberPowerLevel = room.getPowerLevelByUserId(memberID); + if (memberID == client.userID) continue; + if (memberPowerLevel >= ClassDefaultValues.powerLevelOfAdmin) { + otherAdmins.add(member); + continue; + } + try { + await room.kick(memberID); + } catch (err) { + ErrorHandler.logError( + m: "Failed to kick user $memberID from room with id $roomID. Error: $err", + s: StackTrace.current, + ); + continue; + } + } + + if (otherAdmins.isNotEmpty && room.canSendEvent(EventTypes.RoomJoinRules)) { + try { + await client.setRoomStateWithKey( + roomID, + EventTypes.RoomJoinRules, + "", + {"join_rules": "invite"}, + ); + } catch (err) { + ErrorHandler.logError( + m: "Failed to update student create room permissions. error: $err, roomId: $roomID", + s: StackTrace.current, + ); + } + } + + try { + await room.leave(); + } catch (err) { + ErrorHandler.logError( + m: "Failed to leave room with id $roomID. Error: $err", + s: StackTrace.current, + ); + } +} diff --git a/lib/pangea/utils/download_chat.dart b/lib/pangea/utils/download_chat.dart new file mode 100644 index 000000000..c1c28935d --- /dev/null +++ b/lib/pangea/utils/download_chat.dart @@ -0,0 +1,379 @@ +import 'dart:async'; +import 'dart:io'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + +import 'package:csv/csv.dart'; +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:intl/intl.dart'; +import 'package:matrix/matrix.dart'; +import 'package:matrix/src/models/timeline_chunk.dart'; +import 'package:open_file/open_file.dart'; +import 'package:path_provider/path_provider.dart'; +import 'package:permission_handler/permission_handler.dart'; +import 'package:syncfusion_flutter_xlsio/xlsio.dart'; +import 'package:universal_html/html.dart' as webFile; + +import 'package:fluffychat/pangea/models/class_model.dart'; +import 'package:fluffychat/pangea/models/pangea_message_event.dart'; +import 'package:fluffychat/pangea/utils/error_handler.dart'; +import '../models/choreo_record.dart'; + +enum DownloadType { txt, csv, xlsx } + +Future downloadChat( + Room room, + ClassSettingsModel classSettings, + DownloadType type, + Client client, + BuildContext context, +) async { + List allPangeaMessages; + + try { + final List allEvents = await getAllEvents(room, client); + final TimelineChunk chunk = TimelineChunk(events: allEvents); + final Timeline timeline = Timeline( + room: room, + chunk: chunk, + ); + + allPangeaMessages = getPangeaMessageEvents( + allEvents, + timeline, + room, + classSettings.targetLanguage, + ); + } catch (err) { + ErrorHandler.logError( + e: Exception( + "Failed to fetch messages for chat ${room.id} in while downloading chat", + ), + s: StackTrace.current, + ); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text( + "${L10n.of(context)!.oopsSomethingWentWrong} ${L10n.of(context)!.errorPleaseRefresh}", + ), + ), + ); + return; + } + + if (allPangeaMessages.isEmpty) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text( + L10n.of(context)!.emptyChatDownloadWarning, + ), + ), + ); + return; + } + + final String filename = getFilename(room, type); + + switch (type) { + case DownloadType.txt: + final String content = + getTxtContent(allPangeaMessages, context, filename, room); + downloadFile(content, filename, DownloadType.txt); + break; + case DownloadType.csv: + final String content = + getCSVContent(allPangeaMessages, context, filename); + downloadFile(content, filename, DownloadType.csv); + return; + case DownloadType.xlsx: + final List content = + getExcelContent(allPangeaMessages, context, filename); + downloadFile(content, filename, DownloadType.xlsx); + return; + } +} + +Future> getAllEvents(Room room, Client client) async { + final GetRoomEventsResponse initalResp = + await client.getRoomEvents(room.id, Direction.b); + if (initalResp.end == null) return []; + String? nextStartToken = initalResp.end; + List allMatrixEvents = initalResp.chunk; + while (nextStartToken != null) { + final GetRoomEventsResponse resp = await client.getRoomEvents( + room.id, + Direction.b, + from: nextStartToken, + ); + final chunkMessages = resp.chunk; + allMatrixEvents.addAll(chunkMessages); + resp.end != nextStartToken + ? nextStartToken = resp.end + : nextStartToken = null; + } + allMatrixEvents = allMatrixEvents.reversed.toList(); + final List allEvents = allMatrixEvents + .map((MatrixEvent message) => Event.fromMatrixEvent(message, room)) + .toList(); + return allEvents; +} + +List getPangeaMessageEvents( + List events, + Timeline timeline, + Room room, + String? targetLang, +) { + final List allPangeaMessages = events + .where( + (Event event) => + event.type == EventTypes.Message && + event.content['msgtype'] == MessageTypes.Text, + ) + .map( + (Event message) => PangeaMessageEvent( + event: message, + timeline: timeline, + ownMessage: false, + selected: false, + ), + ) + .cast() + .toList(); + return allPangeaMessages; +} + +String getOriginalText(PangeaMessageEvent message) { + try { + final List? steps = + message.originalSent?.choreo?.choreoSteps; + if (steps != null && steps.isNotEmpty) return steps.first.text; + if (message.originalWritten != null) return message.originalWritten!.text; + if (message.originalSent != null) return message.originalSent!.text; + return message.body; + } catch (err) { + return message.body; + } +} + +String getSentText(PangeaMessageEvent message) => + message.originalSent?.text ?? message.body; + +bool usageIsAvailable(PangeaMessageEvent message) { + try { + return message.originalSent?.choreo != null; + } catch (err) { + return false; + } +} + +String getFilename(Room room, DownloadType type) { + final String roomName = room + .getLocalizedDisplayname() + .trim() + .replaceAll(RegExp(r'[^A-Za-z0-9\s]'), "") + .replaceAll(RegExp(r'\s+'), "-"); + final String timestamp = + DateFormat('yyyy-MM-dd-hh:mm:ss').format(DateTime.now()); + final String extension = type == DownloadType.txt + ? 'txt' + : type == DownloadType.csv + ? 'csv' + : 'xlsx'; + return "$roomName-$timestamp.$extension"; +} + +String mimetype(DownloadType fileType) { + switch (fileType) { + case DownloadType.txt: + return 'text/plain'; + case DownloadType.csv: + return 'text/csv'; + case DownloadType.xlsx: + return 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'; + } +} + +Future downloadFile( + contents, + String filename, + DownloadType fileType, +) async { + if (kIsWeb) { + final blob = webFile.Blob([contents], mimetype(fileType), 'native'); + webFile.AnchorElement( + href: webFile.Url.createObjectUrlFromBlob(blob).toString(), + ) + ..setAttribute("download", filename) + ..click(); + return; + } + if (await Permission.storage.request().isGranted) { + Directory? directory; + try { + if (Platform.isIOS) { + directory = await getApplicationDocumentsDirectory(); + } else { + directory = Directory('/storage/emulated/0/Download'); + if (!await directory.exists()) { + directory = await getExternalStorageDirectory(); + } + } + } catch (err) { + debugPrint("Failed to get download folder path"); + ErrorHandler.logError( + e: Exception("Failed to get download folder path"), + s: StackTrace.current, + ); + } + if (directory != null) { + final File f = File("${directory.path}/$filename"); + File resp; + if (fileType == DownloadType.txt || fileType == DownloadType.csv) { + resp = await f.writeAsString(contents); + } else { + resp = await f.writeAsBytes(contents); + } + OpenFile.open(resp.path); + } + } +} + +String getTxtContent( + List messages, + BuildContext context, + String filename, + Room room, +) { + String formattedInfo = ""; + for (final PangeaMessageEvent message in messages) { + final String timestamp = + DateFormat('yyyy-MM-dd hh:mm:ss').format(message.originServerTs); + final String sender = message.senderId; + final String originalMsg = getOriginalText(message); + final String sentMsg = getSentText(message); + final bool usageAvailable = usageIsAvailable(message); + + if (!usageAvailable) { + formattedInfo += + "${L10n.of(context)!.sender}: $sender\n${L10n.of(context)!.time}: $timestamp\n${L10n.of(context)!.originalMessage}: $originalMsg\n${L10n.of(context)!.sentMessage}: $sentMsg\n${L10n.of(context)!.useType}: ${L10n.of(context)!.notAvailable}\n\n"; + continue; + } + + final bool includedIT = message.originalSent!.choreo!.includedIT; + final bool includedIGC = message.originalSent!.choreo!.includedIGC; + + formattedInfo += + "${L10n.of(context)!.sender}: $sender\n${L10n.of(context)!.time}: $timestamp\n${L10n.of(context)!.originalMessage}: $originalMsg\n${L10n.of(context)!.sentMessage}: $sentMsg\n${L10n.of(context)!.useType}: "; + if (includedIT && includedIGC) { + formattedInfo += L10n.of(context)!.taAndGaTooltip; + } else if (includedIT) { + formattedInfo += L10n.of(context)!.taTooltip; + } else if (includedIGC) { + formattedInfo += L10n.of(context)!.gaTooltip; + } else { + formattedInfo += L10n.of(context)!.waTooltip; + } + formattedInfo += "\n\n"; + } + formattedInfo = "${room.getLocalizedDisplayname()}\n\n$formattedInfo"; + return formattedInfo; +} + +String getCSVContent( + List messages, + BuildContext context, + String fileName, +) { + final List> csvData = [ + [ + L10n.of(context)!.sender, + L10n.of(context)!.time, + L10n.of(context)!.originalMessage, + L10n.of(context)!.sentMessage, + L10n.of(context)!.taTooltip, + L10n.of(context)!.gaTooltip, + ] + ]; + for (final PangeaMessageEvent message in messages) { + final String timestamp = + DateFormat('yyyy-MM-dd hh:mm:ss').format(message.originServerTs); + final String sender = message.senderId; + final String originalMsg = getOriginalText(message); + final String sentMsg = getSentText(message); + final bool usageAvailable = usageIsAvailable(message); + + if (!usageAvailable) { + csvData.add([ + sender, + timestamp, + originalMsg, + sentMsg, + L10n.of(context)!.notAvailable, + L10n.of(context)!.notAvailable, + ]); + continue; + } + + final bool includedIT = message.originalSent!.choreo!.includedIT; + final bool includedIGC = message.originalSent!.choreo!.includedIGC; + + csvData.add([ + sender, + timestamp, + originalMsg, + sentMsg, + includedIT.toString(), + includedIGC.toString(), + ]); + } + final String fileString = const ListToCsvConverter().convert(csvData); + return fileString; +} + +List getExcelContent( + List messages, + BuildContext context, + String filename, +) { + final Workbook workbook = Workbook(); + final Worksheet sheet = workbook.worksheets[0]; + + sheet.getRangeByIndex(1, 1).setValue(L10n.of(context)!.sender); + sheet.getRangeByIndex(1, 2).setValue(L10n.of(context)!.time); + sheet.getRangeByIndex(1, 3).setValue(L10n.of(context)!.originalMessage); + sheet.getRangeByIndex(1, 4).setValue(L10n.of(context)!.sentMessage); + sheet.getRangeByIndex(1, 5).setValue(L10n.of(context)!.taTooltip); + sheet.getRangeByIndex(1, 6).setValue(L10n.of(context)!.gaTooltip); + + for (int i = 0; i < messages.length; i++) { + final PangeaMessageEvent message = messages[i]; + final String sender = message.senderId; + final String originalMsg = getOriginalText(message); + final String sentMsg = getSentText(message); + final bool usageAvailable = usageIsAvailable(message); + + bool includedIT = false; + bool includedIGC = false; + + if (usageAvailable) { + includedIT = message.originalSent!.choreo!.includedIT; + includedIGC = message.originalSent!.choreo!.includedIGC; + } + + sheet.getRangeByIndex(i + 2, 1).setValue(sender); + sheet.getRangeByIndex(i + 2, 2).setDateTime(message.originServerTs); + sheet.getRangeByIndex(i + 2, 3).setValue(originalMsg); + sheet.getRangeByIndex(i + 2, 4).setValue(sentMsg); + sheet.getRangeByIndex(i + 2, 5).setValue(L10n.of(context)!.notAvailable); + sheet.getRangeByIndex(i + 2, 6).setValue(L10n.of(context)!.notAvailable); + if (usageAvailable) { + sheet.getRangeByIndex(i + 2, 5).setValue(includedIT); + sheet.getRangeByIndex(i + 2, 6).setValue(includedIGC); + } + } + + final List bytes = workbook.saveAsStream(); + return bytes; +} diff --git a/lib/pangea/utils/error_handler.dart b/lib/pangea/utils/error_handler.dart new file mode 100644 index 000000000..7784b1614 --- /dev/null +++ b/lib/pangea/utils/error_handler.dart @@ -0,0 +1,169 @@ +import 'dart:async'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:http/http.dart' as http; +import 'package:sentry_flutter/sentry_flutter.dart'; + +import 'package:fluffychat/pangea/config/environment.dart'; + +class ErrorHandler { + ErrorHandler(); + + static Future initialize() async { + FutureOr Function(Scope)? withScope( + Scope scope, + FlutterErrorDetails details, + ) { + // if (details.exception is http.Response) { + // final res = details.exception as http.Response; + // scope.addBreadcrumb( + // Breadcrumb.http( + // url: res.request?.url ?? Uri(path: "not available"), + // method: "where does method go?", + // statusCode: res.statusCode, + // ), + // ); + // } else { + // debugPrint("not an http exception ${details.exception.toString()}"); + // } + return null; + } + + await SentryFlutter.init( + (options) { + options.dsn = Environment.sentryDsn; + options.tracesSampleRate = 0.1; + options.debug = kDebugMode; + options.environment = Environment.isStaging ? "staging" : "productionC"; + // options.beforeSend = (event, {hint}) { + // debugger(when: kDebugMode); + // return null; + // }; + }, + ); + + // Error handling + FlutterError.onError = (FlutterErrorDetails details) async { + if (!kDebugMode) { + Sentry.captureException( + details.exception, + stackTrace: details.stack ?? StackTrace.current, + withScope: (scope) => withScope(scope, details), + ); + } + }; + + PlatformDispatcher.instance.onError = (exception, stack) { + logError(e: exception, s: stack); + return true; + }; + } + + static logError({ + Object? e, + StackTrace? s, + String? m, + Map? data, + }) async { + if ((e ?? m) != null) debugPrint("error: ${e?.toString() ?? m}"); + if (data != null) { + Sentry.addBreadcrumb(Breadcrumb.fromJson(data)); + } + FlutterError.reportError( + FlutterErrorDetails( + exception: e ?? Exception(m ?? "no message supplied"), + stack: s, + library: 'Pangea', + context: ErrorSummary(e?.toString() ?? "error not defined"), + stackFilter: (input) => input.where( + (e) => !(e.contains("org-dartlang-sdk") || + e.contains("future_impl") || + e.contains("microtask") || + e.contains("async_patch")), + ), + ), + ); + } +} + +class ErrorCopy { + BuildContext context; + Object? error; + + late String title; + late String body; + int? errorCode; + + ErrorCopy(this.context, this.error) { + setCopy(); + } + + void _setDefaults() { + title = "Unexpected error."; + body = "Please reload and try again."; + errorCode = 400; + } + + void setCopy() { + try { + if (error is http.Response) { + errorCode = (error as http.Response).statusCode; + } else { + ErrorHandler.logError(e: error, s: StackTrace.current); + errorCode = null; + } + if (L10n.of(context) == null) { + _setDefaults(); + Sentry.addBreadcrumb(Breadcrumb.fromJson({"error": error?.toString()})); + ErrorHandler.logError( + m: "null L10n in ErrorCopy.setCopy", + s: StackTrace.current, + ); + return; + } + final L10n l10n = L10n.of(context)!; + + switch (errorCode) { + case 502: + case 504: + case 500: + title = l10n.error502504Title; + body = l10n.error502504Desc; + break; + case 404: + title = l10n.error404Title; + body = l10n.error404Desc; + break; + case 405: + title = l10n.error405Title; + body = l10n.error405Desc; + break; + case 601: + title = l10n.errorDisableIT; + body = l10n.errorDisableITUserDesc; + break; + case 602: + title = l10n.errorDisableIGC; + body = l10n.errorDisableIGCUserDesc; + break; + case 603: + title = l10n.errorDisableIT; + body = l10n.errorDisableITClassDesc; + break; + case 604: + title = l10n.errorDisableIGC; + body = l10n.errorDisableIGCClassDesc; + break; + default: + title = l10n.oopsSomethingWentWrong; + body = l10n.errorPleaseRefresh; + } + } catch (e, s) { + ErrorHandler.logError(e: s, s: s); + _setDefaults(); + } + } +} diff --git a/lib/pangea/utils/find_conversation_partner_dialog.dart b/lib/pangea/utils/find_conversation_partner_dialog.dart new file mode 100644 index 000000000..035f091d8 --- /dev/null +++ b/lib/pangea/utils/find_conversation_partner_dialog.dart @@ -0,0 +1,41 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:go_router/go_router.dart'; + +import '../controllers/pangea_controller.dart'; + +void findConversationPartnerDialog( + BuildContext context, + PangeaController pangeaController, +) { + debugPrint(pangeaController.userController.isPublic.toString()); + if (pangeaController.userController.isPublic) { + context.go('/rooms/partner'); + } else { + showDialog( + context: context, + useRootNavigator: false, + builder: (context) => AlertDialog( + title: Text(L10n.of(context)!.setToPublicSettingsTitle), + content: ConstrainedBox( + constraints: const BoxConstraints(maxWidth: 250), + child: Text(L10n.of(context)!.setToPublicSettingsDesc), + ), + actions: [ + TextButton( + onPressed: Navigator.of(context).pop, + child: Text(L10n.of(context)!.cancel), + ), + TextButton( + onPressed: () { + context.go('/rooms/settings/learning'); + Navigator.of(context).pop(); + }, + child: Text(L10n.of(context)!.accountSettings), + ), + ], + ), + ); + } +} diff --git a/lib/pangea/utils/firebase_analytics.dart b/lib/pangea/utils/firebase_analytics.dart new file mode 100644 index 000000000..001161e2b --- /dev/null +++ b/lib/pangea/utils/firebase_analytics.dart @@ -0,0 +1,182 @@ +import 'package:flutter/widgets.dart'; + +import 'package:firebase_analytics/firebase_analytics.dart'; +import 'package:firebase_core/firebase_core.dart'; + +import 'package:fluffychat/pangea/controllers/subscription_controller.dart'; +import '../../config/firebase_options.dart'; +import '../enum/use_type.dart'; + +// PageRoute import + +// Add import: +// import 'package:fluffychat/pangea/utils/firebase_analytics.dart'; +// Call method: GoogleAnalytics.logout() + +class GoogleAnalytics { + static FirebaseAnalytics? analytics; + + GoogleAnalytics(); + + static Future initialize() async { + FirebaseApp app; + try { + app = await Firebase.initializeApp( + options: DefaultFirebaseOptions.currentPlatform, + ); + } on Exception { + app = Firebase.app(); + } + + analytics = FirebaseAnalytics.instanceFor(app: app); + } + + static analyticsUserUpdate(String? userID) { + print("user update $userID"); + analytics?.setUserId(id: userID); + } + + static updateUserSubscriptionStatus(bool subscribed) { + analytics?.setUserProperty( + name: 'subscribed', + value: "$subscribed", + ); + } + + static logEvent(String name, {parameters}) { + debugPrint("event: $name - parameters: $parameters"); + analytics?.logEvent(name: name, parameters: parameters); + } + + static login(String type, String? userID) { + logEvent('login', parameters: {'method': type}); + analyticsUserUpdate(userID); + } + + static signUp(String type) { + logEvent('sign_up', parameters: {'method': type}); + } + + static logout() { + logEvent('logout'); + analyticsUserUpdate(null); + } + + static createClass(String className, String classCode) { + logEvent( + 'create_class', + parameters: {'name': className, 'group_id': classCode}, + ); + } + + static createExchange(String exchangeName, String classCode) { + logEvent( + 'create_exchange', + parameters: {'name': exchangeName, 'group_id': classCode}, + ); + } + + static createChat(String newChatRoomId) { + logEvent('create_chat', parameters: {"chat_id": newChatRoomId}); + } + + static addParent(String chatRoomId, String classCode) { + logEvent( + 'add_room_to_class', + parameters: {"chat_id": chatRoomId, 'group_id': classCode}, + ); + } + + static removeChatFromClass(String chatRoomId, String classCode) { + logEvent( + 'remove_room_from_class', + parameters: {"chat_id": chatRoomId, 'group_id': classCode}, + ); + } + + static addChatToExchange(String chatRoomId, String classCode) { + logEvent( + 'add_chat_to_exchange', + parameters: {"chat_id": chatRoomId, 'group_id': classCode}, + ); + } + + static inviteClassToExchange(String classId, String exchangeId) { + logEvent( + 'invite_class_to_exchange', + parameters: {'group_id': classId, 'exchange_id': exchangeId}, + ); + } + + static kickClassFromExchange(String classId, String exchangeId) { + logEvent( + 'kick_class_from_exchange', + parameters: {'group_id': classId, 'exchange_id': exchangeId}, + ); + } + + static joinClass(String classCode) { + logEvent('join_group', parameters: {'group_id': classCode}); + } + + static sendMessage(String chatRoomId, String classCode, UseType useType) { + logEvent( + 'sent_message', + parameters: { + "chat_id": chatRoomId, + 'group_id': classCode, + "message_type": useType.toString(), + }, + ); + } + + static contextualRequest() { + logEvent('context_request'); + } + + static messageTranslate() { + logEvent('message_translate'); + } + + static beginPurchaseSubscription( + SubscriptionDetails details, + BuildContext context, + ) { + logEvent( + 'begin_checkout', + parameters: { + "currency": "USD", + 'value': details.price, + 'transaction_id': details.id, + 'items': [ + { + 'item_id': details.package!.identifier, + 'item_name': details.displayName(context), + 'price': details.price, + 'item_category': "subscription", + 'quantity': 1, + } + ], + }, + ); + } + + static FirebaseAnalyticsObserver getAnalyticsObserver() => + FirebaseAnalyticsObserver( + analytics: analytics!, + routeFilter: (route) { + // By default firebase only tracks page routes + if (route is! PageRoute || + // No user logged in, so we dont track + route.settings.name == "login" || + route.settings.name == "/home" || + route.settings.name == "connect" || + route.settings.name == "signup") { + return false; + } + final String? name = route.settings.name; + debugPrint("navigating to route: $name"); + return true; + }, + ); +} diff --git a/lib/pangea/utils/get_chat_list_item_subtitle.dart b/lib/pangea/utils/get_chat_list_item_subtitle.dart new file mode 100644 index 000000000..a1ce04349 --- /dev/null +++ b/lib/pangea/utils/get_chat_list_item_subtitle.dart @@ -0,0 +1,78 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:matrix/matrix.dart'; + +import 'package:fluffychat/pangea/constants/language_keys.dart'; +import 'package:fluffychat/pangea/controllers/pangea_controller.dart'; +import 'package:fluffychat/pangea/models/class_model.dart'; +import 'package:fluffychat/pangea/models/pangea_message_event.dart'; +import '../../utils/matrix_sdk_extensions/matrix_locals.dart'; + +class GetChatListItemSubtitle { + Future getSubtitle( + BuildContext context, + Event? event, + PangeaController pangeaController, + ) async { + if (event == null) return L10n.of(context)!.emptyChat; + // try { + if (event.type != EventTypes.Message || + !pangeaController.permissionsController + .isToolEnabled(ToolSetting.immersionMode, event.room)) { + return event.calcLocalizedBody( + MatrixLocals(L10n.of(context)!), + hideReply: true, + hideEdit: true, + plaintextBody: true, + removeMarkdown: true, + withSenderNamePrefix: !event.room.isDirectChat || + event.room.directChatMatrixID != event.room.lastEvent?.senderId, + ); + } + + final Timeline timeline = + await event.room.getTimeline(eventContextId: event.eventId); + final PangeaMessageEvent pangeaMessageEvent = PangeaMessageEvent( + event: event, + timeline: timeline, + ownMessage: false, + selected: false, + ); + final l2Code = + pangeaController.languageController.activeL2Code(roomID: event.roomId); + + if (l2Code == null || l2Code == LanguageKeys.unknownLanguage) { + return event.body; + } + + final String? text = + (await pangeaMessageEvent.representationByLanguageGlobal( + context: context, + langCode: l2Code, + )) + ?.text; + + final i18n = MatrixLocals(L10n.of(context)!); + + if (text == null) return L10n.of(context)!.emptyChat; + + if (!event.room.isDirectChat || + event.room.directChatMatrixID != event.room.lastEvent?.senderId) { + final senderNameOrYou = event.senderId == event.room.client.userID + ? i18n.you + : event.room + .unsafeGetUserFromMemoryOrFallback(event.senderId) + .calcDisplayname(i18n: i18n); + + return "$senderNameOrYou: $text"; + } + + return text; + // } catch (e, s) { + // debugger(when: kDebugMode); + // ErrorHandler.logError(e: e, s: s); + // return event.body; + // } + } +} diff --git a/lib/pangea/utils/instructions.dart b/lib/pangea/utils/instructions.dart new file mode 100644 index 000000000..40253a00d --- /dev/null +++ b/lib/pangea/utils/instructions.dart @@ -0,0 +1,165 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; + +import '../../config/app_config.dart'; +import '../../widgets/matrix.dart'; +import '../controllers/pangea_controller.dart'; +import '../widgets/common/bot_face_svg.dart'; +import '../widgets/igc/card_header.dart'; +import 'bot_style.dart'; +import 'error_handler.dart'; +import 'overlay.dart'; + +class InstructionsController { + late PangeaController _pangeaController; + + final Map _instructionsClosed = {}; + final Map _instructionsShown = {}; + + InstructionsController(PangeaController pangeaController) { + _pangeaController = pangeaController; + } + + bool wereInstructionsTurnedOff(InstructionsEnum key) => + _pangeaController.pStoreService.read(key.toString()) ?? + _instructionsClosed[key] ?? + false; + + void updateEnableInstructions(InstructionsEnum key, bool value) => + _pangeaController.pStoreService.save(key.toString(), value); + + Future show( + BuildContext context, + InstructionsEnum key, + String transformTargetKey, [ + bool showToggle = true, + ]) async { + if (wereInstructionsTurnedOff(key)) { + return; + } + if (L10n.of(context) == null) { + ErrorHandler.logError( + m: "null context in ITBotButton.showCard", + s: StackTrace.current, + ); + return; + } + if (_instructionsShown[key] ?? false) { + return; + } + + final bool userLangsSet = + await _pangeaController.userController.areUserLanguagesSet; + if (!userLangsSet && key == InstructionsEnum.blurMeansTranslate) { + return; + } + + _instructionsShown[key] = true; + + final botStyle = BotStyle.text(context); + Future.delayed( + const Duration(seconds: 1), + () => OverlayUtil.showPositionedCard( + context: context, + backDropToDismiss: false, + cardToShow: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + CardHeader( + text: key.title(context), + botExpression: BotExpression.surprised, + onClose: () => {_instructionsClosed[key] = true}, + ), + const SizedBox(height: 10.0), + Expanded( + child: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.all(6.0), + child: Text( + key.body(context), + style: botStyle, + ), + ), + ), + ), + if (showToggle) InstructionsToggle(instructionsKey: key), + ], + ), + cardSize: const Size(300.0, 300.0), + transformTargetId: transformTargetKey, + ), + ); + } +} + +enum InstructionsEnum { + itInstructions, + clickMessage, + understandingMessages, + blurMeansTranslate, +} + +extension Copy on InstructionsEnum { + String title(BuildContext context) { + switch (this) { + case InstructionsEnum.itInstructions: + return L10n.of(context)!.itInstructionsTitle; + case InstructionsEnum.clickMessage: + return L10n.of(context)!.clickMessageTitle; + case InstructionsEnum.understandingMessages: + return L10n.of(context)!.understandingMessagesTitle; + case InstructionsEnum.blurMeansTranslate: + return L10n.of(context)!.blurMeansTranslateTitle; + } + } + + String body(BuildContext context) { + switch (this) { + case InstructionsEnum.itInstructions: + return L10n.of(context)!.itInstructionsBody; + case InstructionsEnum.clickMessage: + return L10n.of(context)!.clickMessageBody; + case InstructionsEnum.understandingMessages: + return L10n.of(context)!.understandingMessagesBody; + case InstructionsEnum.blurMeansTranslate: + return L10n.of(context)!.blurMeansTranslateBody; + } + } +} + +class InstructionsToggle extends StatefulWidget { + const InstructionsToggle({ + super.key, + required this.instructionsKey, + }); + + final InstructionsEnum instructionsKey; + + @override + InstructionsToggleState createState() => InstructionsToggleState(); +} + +class InstructionsToggleState extends State { + PangeaController pangeaController = MatrixState.pangeaController; + + @override + void initState() { + super.initState(); + } + + @override + Widget build(BuildContext context) { + return SwitchListTile.adaptive( + activeColor: AppConfig.activeToggleColor, + title: Text(L10n.of(context)!.doNotShowAgain), + value: pangeaController.instructions + .wereInstructionsTurnedOff(widget.instructionsKey), + onChanged: ((value) { + pangeaController.instructions + .updateEnableInstructions(widget.instructionsKey, value); + setState(() {}); + }), + ); + } +} diff --git a/lib/pangea/utils/join_all_space_chats.dart b/lib/pangea/utils/join_all_space_chats.dart new file mode 100644 index 000000000..cd4ee87db --- /dev/null +++ b/lib/pangea/utils/join_all_space_chats.dart @@ -0,0 +1,49 @@ +import 'package:flutter/material.dart'; + +import 'package:matrix/matrix.dart'; + +import 'package:fluffychat/pangea/utils/error_handler.dart'; + +// Used in lock space. Handles case when child rooms return null from client.getRoomById +// Because the user hasn't joined them +Future> joinAllSpaceChats(Room space, Client client) async { + final List childrenIds = + space.spaceChildren.map((x) => x.roomId!).toList(); + + final List children = []; + for (final String childId in childrenIds) { + final Room? child = client.getRoomById(childId); + if (child != null) { + children.add(child); + } + // child may be null if the user is not in the room + else { + final Room? child = await tryGetRoomById(childId, client); + if (child != null) { + children.add(child); + } + } + } + return children; +} + +Future tryGetRoomById(String roomId, Client client) async { + try { + await client.joinRoomById(roomId); + } catch (err) { + // caused when chat has been archived + debugPrint("Failed to join $roomId"); + return null; + } + await client.waitForRoomInSync(roomId); + final Room? room = client.getRoomById(roomId); + if (room != null) { + return room; + } else { + ErrorHandler.logError( + e: "Failed to fetch child room with id $roomId after joining", + s: StackTrace.current, + ); + } + return null; +} diff --git a/lib/pangea/utils/language_level_copy.dart b/lib/pangea/utils/language_level_copy.dart new file mode 100644 index 000000000..804f45573 --- /dev/null +++ b/lib/pangea/utils/language_level_copy.dart @@ -0,0 +1,27 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; + +class LanguageLevelTextPicker { + static String languageLevelText(BuildContext context, int languageLevel) { + final L10n copy = L10n.of(context)!; + switch (languageLevel) { + case 0: + return copy.languageLevelPreA1; + case 1: + return copy.languageLevelA1; + case 2: + return copy.languageLevelA2; + case 3: + return copy.languageLevelB1; + case 4: + return copy.languageLevelB2; + case 5: + return copy.languageLevelC1; + case 6: + return copy.languageLevelC2; + default: + return "undefined level"; + } + } +} diff --git a/lib/pangea/utils/lock_room.dart b/lib/pangea/utils/lock_room.dart new file mode 100644 index 000000000..884ec3bad --- /dev/null +++ b/lib/pangea/utils/lock_room.dart @@ -0,0 +1,64 @@ +import 'package:matrix/matrix.dart'; + +import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart'; +import 'package:fluffychat/pangea/utils/join_all_space_chats.dart'; + +Future unlockChat(Room room, Client client) async { + final Map powerLevelsContent = Map.from( + room.getState(EventTypes.RoomPowerLevels)!.content, + ); + + powerLevelsContent['events_default'] = 0; + powerLevelsContent['events'][EventTypes.spaceChild] = 0; + + await room.client.setRoomStateWithKey( + room.id, + EventTypes.RoomPowerLevels, + '', + powerLevelsContent, + ); +} + +Future lockChat(Room room, Client client) async { + final Map powerLevelsContent = Map.from( + room.getState(EventTypes.RoomPowerLevels)!.content, + ); + powerLevelsContent['events_default'] = 100; + powerLevelsContent['events'][EventTypes.spaceChild] = 100; + + await room.client.setRoomStateWithKey( + room.id, + EventTypes.RoomPowerLevels, + '', + powerLevelsContent, + ); +} + +Future lockSpace(Room space, Client client) async { + final List children = await joinAllSpaceChats(space, client); + for (final Room child in children) { + await lockChat(child, client); + } + await lockChat(space, client); +} + +Future unlockSpace(Room space, Client client) async { + final List children = space.spaceChildren + .map((child) => client.getRoomById(child.roomId!)) + .toList(); + for (final Room? child in children) { + if (child != null) { + await unlockChat(child, client); + } + } + await unlockChat(space, client); +} + +Future toggleLockRoom(Room? room, Client client) async { + if (room == null || !room.isRoomAdmin) return; + if (!room.isSpace) { + room.locked ? await unlockChat(room, client) : await lockChat(room, client); + return; + } + room.locked ? await unlockSpace(room, client) : await lockSpace(room, client); +} diff --git a/lib/pangea/utils/logout.dart b/lib/pangea/utils/logout.dart new file mode 100644 index 000000000..aa4441e13 --- /dev/null +++ b/lib/pangea/utils/logout.dart @@ -0,0 +1,27 @@ +import 'package:flutter/material.dart'; + +import 'package:adaptive_dialog/adaptive_dialog.dart'; +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; + +import 'package:fluffychat/widgets/matrix.dart'; + +void pLogoutAction(BuildContext context, {bool? isDestructiveAction}) async { + if (await showOkCancelAlertDialog( + useRootNavigator: false, + context: context, + title: L10n.of(context)!.areYouSureYouWantToLogout, + message: L10n.of(context)!.noBackupWarning, + isDestructiveAction: isDestructiveAction ?? false, + okLabel: L10n.of(context)!.logout, + cancelLabel: L10n.of(context)!.cancel, + ) == + OkCancelResult.cancel) { + return; + } + final matrix = Matrix.of(context); + await showFutureLoadingDialog( + context: context, + future: () => matrix.client.logout(), + ); +} diff --git a/lib/pangea/utils/martix.utils.dart b/lib/pangea/utils/martix.utils.dart new file mode 100644 index 000000000..99e535a1b --- /dev/null +++ b/lib/pangea/utils/martix.utils.dart @@ -0,0 +1,7 @@ +import 'package:matrix/matrix.dart'; + +class MatrixUtils { + static String generateUniqueTransactionId(Client client) { + return client.generateUniqueTransactionId(); + } +} diff --git a/lib/pangea/utils/match_copy.dart b/lib/pangea/utils/match_copy.dart new file mode 100644 index 000000000..28080f9b5 --- /dev/null +++ b/lib/pangea/utils/match_copy.dart @@ -0,0 +1,228 @@ +import 'dart:developer'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:sentry_flutter/sentry_flutter.dart'; + +import 'package:fluffychat/pangea/enum/span_data_type.dart'; +import 'package:fluffychat/pangea/utils/error_handler.dart'; +import '../constants/match_rule_ids.dart'; +import '../models/pangea_match_model.dart'; + +class MatchCopy { + PangeaMatch match; + late String title; + String? description; + + MatchCopy(BuildContext context, this.match) { + if (match.match.rule?.id != null) { + _byMatchRuleId(context); + return; + } + if (match.match.shortMessage != null) { + title = match.match.shortMessage!; + } + if (match.match.message != null) { + description = match.match.message!; + } + if (match.match.shortMessage == null) { + _bySpanDataType(context); + } + } + + _setDefaults() { + try { + title = match.match.shortMessage ?? "unknown"; + description = match.match.message ?? "unknown"; + } catch (err) { + title = "Error"; + description = "Could not find the check info"; + } + } + + void _bySpanDataType(BuildContext context) { + try { + final L10n l10n = L10n.of(context)!; + switch (match.match.type.typeName) { + case SpanDataTypeEnum.correction: + title = l10n.someErrorTitle; + description = l10n.someErrorBody; + break; + case SpanDataTypeEnum.definition: + title = match.matchContent; + description = null; + break; + case SpanDataTypeEnum.itStart: + title = l10n.needsItShortMessage; + // description = l10n.needsItMessage; + break; + case SpanDataTypeEnum.practice: + title = match.match.shortMessage ?? "Activity"; + description = match.match.message; + break; + } + } catch (err, stack) { + debugger(when: kDebugMode); + Sentry.addBreadcrumb( + Breadcrumb( + message: "match", + data: { + "match": match.toJson(), + }, + ), + ); + ErrorHandler.logError(e: err, s: stack); + _setDefaults(); + } + } + + void _byMatchRuleId(BuildContext context) { + try { + if (match.match.rule?.id == null) { + throw Exception("match.match.rule.id is null"); + } + final L10n l10n = L10n.of(context)!; + + final List splits = match.match.rule!.id.split(":"); + if (splits.length >= 2) { + splits.removeAt(0); + } + final String afterColon = splits.join(); + + print("grammar rule ${match.match.rule!.id}"); + + switch (afterColon) { + case MatchRuleIds.interactiveTranslation: + title = l10n.needsItShortMessage; + description = l10n.needsItMessage; + break; + case MatchRuleIds.tokenNeedsTranslation: + title = l10n.tokenTranslationTitle; + description = l10n.spanTranslationDesc; + break; + case MatchRuleIds.tokenSpanNeedsTranslation: + title = l10n.spanTranslationTitle; + description = l10n.spanTranslationDesc; + break; + case MatchRuleIds.l1SpanAndGrammar: + title = l10n.l1SpanAndGrammarTitle; + description = l10n.l1SpanAndGrammarDesc; + break; + // case "PART": + // title = l10n.partTitle; + // description = l10n.partDesc; + // break; + // case "PUNCT": + // title = l10n.punctTitle; + // description = l10n.punctDesc; + // break; + // case "ORTH": + // title = l10n.orthTitle; + // description = l10n.orthDesc; + // break; + // case "SPELL": + // title = l10n.spellTitle; + // description = l10n.spellDesc; + // break; + // case "WO": + // title = l10n.woTitle; + // description = l10n.woDesc; + // break; + // case "MORPH": + // title = l10n.morphTitle; + // description = l10n.morphDesc; + // break; + // case "ADV": + // title = l10n.advTitle; + // description = l10n.advDesc; + // break; + // case "CONTR": + // title = l10n.contrTitle; + // description = l10n.contrDesc; + // break; + // case "CONJ": + // title = l10n.conjTitle; + // description = l10n.conjDesc; + // break; + // case "DET": + // title = l10n.detTitle; + // description = l10n.detDesc; + // break; + // case "DETART": + // title = l10n.detArtTitle; + // description = l10n.detArtDesc; + // break; + // case "PREP": + // title = l10n.prepTitle; + // description = l10n.prepDesc; + // break; + // case "PRON": + // title = l10n.pronTitle; + // description = l10n.pronDesc; + // break; + // case "VERB": + // title = l10n.verbTitle; + // description = l10n.verbDesc; + // break; + // case "VERBFORM": + // title = l10n.verbFormTitle; + // description = l10n.verbFormDesc; + // break; + // case "VERBTENSE": + // title = l10n.verbTenseTitle; + // description = l10n.verbTenseDesc; + // break; + // case "VERBSVA": + // title = l10n.verbSvaTitle; + // description = l10n.verbSvaDesc; + // break; + // case "VERBINFL": + // title = l10n.verbInflTitle; + // description = l10n.verbInflDesc; + // break; + // case "ADJ": + // title = l10n.adjTitle; + // description = l10n.adjDesc; + // break; + // case "ADJFORM": + // title = l10n.adjFormTitle; + // description = l10n.adjFormDesc; + // break; + // case "NOUN": + // title = l10n.nounTitle; + // description = l10n.nounDesc; + // break; + // case "NOUNPOSS": + // title = l10n.nounPossTitle; + // description = l10n.nounPossDesc; + // break; + // case "NOUNINFL": + // title = l10n.nounInflTitle; + // description = l10n.nounInflDesc; + // break; + // case "NOUNNUM": + // title = l10n.nounNumTitle; + // description = l10n.nounNumDesc; + // break; + case "OTHER": + default: + _setDefaults(); + break; + } + } catch (err, stack) { + debugger(when: kDebugMode); + Sentry.addBreadcrumb( + Breadcrumb( + message: "match", + data: { + "match": match.toJson(), + }, + ), + ); + ErrorHandler.logError(e: err, s: stack); + _setDefaults(); + } + } +} diff --git a/lib/pangea/utils/overlay.dart b/lib/pangea/utils/overlay.dart new file mode 100644 index 000000000..33dea2018 --- /dev/null +++ b/lib/pangea/utils/overlay.dart @@ -0,0 +1,210 @@ +import 'dart:developer'; +import 'dart:math'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + +import 'package:fluffychat/config/app_config.dart'; +import 'package:fluffychat/pangea/utils/any_state_holder.dart'; +import 'package:fluffychat/pangea/widgets/common_widgets/overlay_container.dart'; +import '../../config/themes.dart'; +import '../../widgets/matrix.dart'; +import 'error_handler.dart'; + +class OverlayUtil { + static showPositionedCard({ + required BuildContext context, + required Widget cardToShow, + required Size cardSize, + required String transformTargetId, + backDropToDismiss = true, + Color? borderColor, + }) { + try { + MatrixState.pAnyState.closeOverlay(); + + final LayerLinkAndKey layerLinkAndKey = + MatrixState.pAnyState.layerLinkAndKey(transformTargetId); + + final Offset cardOffset = _calculateCardOffset( + cardSize: cardSize, + transformTargetKey: layerLinkAndKey.key, + ); + + MatrixState.pAnyState.overlay = OverlayEntry( + builder: (context) => Stack( + children: [ + if (backDropToDismiss) const TransparentBackdrop(), + Positioned( + width: cardSize.width, + height: cardSize.height, + child: CompositedTransformFollower( + link: layerLinkAndKey.link, + showWhenUnlinked: false, + offset: cardOffset, + child: Material( + borderOnForeground: false, + color: Colors.transparent, + clipBehavior: Clip.antiAlias, + child: OverlayContainer( + cardToShow: cardToShow, + borderColor: borderColor, + ), + ), + ), + ), + ], + ), + ); + + Overlay.of(layerLinkAndKey.key.currentContext!) + .insert(MatrixState.pAnyState.overlay!); + } catch (err, stack) { + debugger(when: kDebugMode); + ErrorHandler.logError(e: err, s: stack); + } + } + + /// calculates the card offset relative to the target + /// identified by [transformTargetKey] + static Offset _calculateCardOffset({ + required Size cardSize, + required LabeledGlobalKey transformTargetKey, + final double minPadding = 10.0, + }) { + // debugger(when: kDebugMode); + //Note: assumes overlay in chatview + final OverlayConstraints constraints = + ChatViewConstraints(transformTargetKey.currentContext!); + + final RenderObject? targetRenderBox = + transformTargetKey.currentContext!.findRenderObject(); + if (targetRenderBox == null) return Offset.zero; + final Offset transformTargetOffset = + (targetRenderBox as RenderBox).localToGlobal(Offset.zero); + final Size transformTargetSize = targetRenderBox.size; + + // ideally horizontally centered on target + double dx = transformTargetSize.width / 2 - cardSize.width / 2; + // make sure it's not off the left edge of the screen + // if transformTargetOffset.dx + dc < constraints.x0 + minPadding + + if (transformTargetOffset.dx + dx < minPadding + constraints.x0) { + debugPrint("setting dx"); + dx = minPadding + constraints.x0 - transformTargetOffset.dx; + } + // make sure it's not off the right edge of the screen + if (transformTargetOffset.dx + dx + cardSize.width + minPadding > + constraints.x1) { + dx = constraints.x1 - + transformTargetOffset.dx - + cardSize.width - + minPadding; + } + + // if there's more room above target, + // put the card there + // else, + // put it below + // debugPrint( + // "transformTargetOffset.dx ${transformTargetOffset.dx} transformTargetOffset.dy ${transformTargetOffset.dy}"); + // debugPrint( + // "transformTargetSize.width ${transformTargetSize.width} transformTargetSize.height ${transformTargetSize.height}"); + double dy = transformTargetOffset.dy > + constraints.y1 - + transformTargetOffset.dy - + transformTargetSize.height + ? -cardSize.height - minPadding + : transformTargetSize.height + minPadding; + // make sure it's not off the top edge of the screen + if (dy < minPadding + constraints.y0 - transformTargetOffset.dy) { + dy = minPadding + constraints.y0 - transformTargetOffset.dy; + } + // make sure it's not off the bottom edge of the screen + if (transformTargetOffset.dy + dy + cardSize.height + minPadding > + constraints.y1) { + dy = constraints.y1 - + transformTargetOffset.dy - + cardSize.height - + minPadding; + } + // debugPrint("dx $dx dy $dy"); + + return Offset(dx, dy); + } +} + +class TransparentBackdrop extends StatelessWidget { + const TransparentBackdrop({ + super.key, + }); + + @override + Widget build(BuildContext context) { + return Material( + borderOnForeground: false, + color: Colors.transparent, + clipBehavior: Clip.antiAlias, + child: InkWell( + hoverColor: Colors.transparent, + splashColor: Colors.transparent, + focusColor: Colors.transparent, + highlightColor: Colors.transparent, + onTap: () { + MatrixState.pAnyState.closeOverlay(); + }, + child: Container( + height: double.infinity, + width: double.infinity, + color: Colors.transparent, + ), + ), + ); + } +} + +/// global coordinates that the overlay should stay inside +abstract class OverlayConstraints { + late double x0; + late double y0; + late double x1; + late double y1; +} + +class ChatViewConstraints implements OverlayConstraints { + @override + late double x0; + @override + late double y0; + @override + late double x1; + @override + late double y1; + + ChatViewConstraints(BuildContext context) { + final MediaQueryData mediaQueryData = + MediaQuery.of(Scaffold.of(context).context); + final bool isColumnMode = FluffyThemes.isColumnMode(context); + + x0 = isColumnMode + ? AppConfig.columnWidth + 70.0 + : max(mediaQueryData.viewPadding.left, mediaQueryData.viewInsets.left); + y0 = max(mediaQueryData.viewPadding.top, mediaQueryData.viewInsets.top); + x1 = mediaQueryData.size.width - + max(mediaQueryData.viewPadding.right, mediaQueryData.viewInsets.right); + y1 = mediaQueryData.size.height - + max( + mediaQueryData.viewPadding.bottom, + mediaQueryData.viewInsets.bottom, + ); + + // https://medium.com/flutter-community/a-flutter-guide-to-visual-overlap-padding-viewpadding-and-viewinsets-a63e214be6e8 + // debugPrint( + // "viewInsets ${mediaQueryData.viewInsets.left} ${mediaQueryData.viewInsets.top} ${mediaQueryData.viewInsets.right} ${mediaQueryData.viewInsets.bottom}"); + // debugPrint( + // "padding ${mediaQueryData.padding.left} ${mediaQueryData.padding.top} ${mediaQueryData.padding.right} ${mediaQueryData.padding.bottom}"); + // debugPrint( + // "viewPadding ${mediaQueryData.viewPadding.left} ${mediaQueryData.viewPadding.top} ${mediaQueryData.viewPadding.right} ${mediaQueryData.viewPadding.bottom}"); + // debugPrint("chatViewConstraints x0: $x0 y0: $y0 x1: $x1 y1: $y1"); + } +} diff --git a/lib/pangea/utils/p_extension.dart b/lib/pangea/utils/p_extension.dart new file mode 100644 index 000000000..a80a302a5 --- /dev/null +++ b/lib/pangea/utils/p_extension.dart @@ -0,0 +1,12 @@ +extension IsAtLeastYearsOld on DateTime { + bool isAtLeastYearsOld(int years) { + final now = DateTime.now(); + final boundaryDate = DateTime(now.year - years, now.month, now.day); + + // Discard the time from [this]. + final thisDate = DateTime(year, month, day); + + // Did [thisDate] occur on or before [boundaryDate]? + return thisDate.compareTo(boundaryDate) <= 0; + } +} diff --git a/lib/pangea/utils/p_store.dart b/lib/pangea/utils/p_store.dart new file mode 100644 index 000000000..bdc0efc6c --- /dev/null +++ b/lib/pangea/utils/p_store.dart @@ -0,0 +1,44 @@ +import 'package:get_storage/get_storage.dart'; + +import 'package:fluffychat/pangea/controllers/pangea_controller.dart'; + +class PLocalStore { + final GetStorage _box = GetStorage(); + final PangeaController pangeaController; + + PLocalStore({required this.pangeaController}); + + /// save data in local + Future save( + String key, + dynamic data, { + bool addClientIdToKey = true, + }) async { + await _box.write(_key(key, addClientIdToKey: addClientIdToKey), data); + } + + /// fetch data from local + dynamic read(String key, {bool addClientIdToKey = true}) { + return pangeaController.matrixState.client.userID != null + ? _box.read(_key(key, addClientIdToKey: addClientIdToKey)) + : null; + } + + /// delete data from local + Future delete(String key, {bool addClientIdToKey = true}) async { + return pangeaController.matrixState.client.userID != null + ? _box.remove(_key(key, addClientIdToKey: addClientIdToKey)) + : null; + } + + _key(String key, {bool addClientIdToKey = true}) { + return addClientIdToKey + ? pangeaController.matrixState.client.userID! + key + : key; + } + + /// clear all local storage + clearStorage() { + _box.erase(); + } +} diff --git a/lib/pangea/utils/p_toast.dart b/lib/pangea/utils/p_toast.dart new file mode 100644 index 000000000..7ccbd2c14 --- /dev/null +++ b/lib/pangea/utils/p_toast.dart @@ -0,0 +1,31 @@ +// import 'package:flutter/material.dart'; + +class PToastController { + //TODO: Figure out best toast to show + //Ideal is reuse FluffyChat UI for consistency + ///show toast message + static toastMsg({bool success = false, String msg = ""}) { + // success + // ? Fluttertoast.showToast( + // msg: msg, + // fontSize: 16.0, + // backgroundColor: Color(0xFF228C22), + // webBgColor: "#228C22", + // textColor: Colors.white, + // timeInSecForIosWeb: 2) + // : Fluttertoast.showToast( + // msg: msg, + // fontSize: 16.0, + // timeInSecForIosWeb: 2, + // webBgColor: "#ff0000", + // backgroundColor: Colors.red, + // textColor: Colors.white, + // ); + } + + // @override + // void dispose() { + // // TODO: implement dispose + // super.dispose(); + //} +} diff --git a/lib/pangea/utils/password_forgotten.dart b/lib/pangea/utils/password_forgotten.dart new file mode 100644 index 000000000..186d76ce8 --- /dev/null +++ b/lib/pangea/utils/password_forgotten.dart @@ -0,0 +1,153 @@ +import 'package:flutter/material.dart'; + +import 'package:adaptive_dialog/adaptive_dialog.dart'; +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; +import 'package:matrix/matrix.dart'; + +import 'package:fluffychat/pages/login/login.dart'; +import '../../widgets/matrix.dart'; + +extension PangeaPasswordForgotten on LoginController { + void pangeaPasswordForgotten() async { + final TextEditingController emailController = TextEditingController(); + final TextEditingController newPasswordController = TextEditingController(); + showDialog( + context: context, + useRootNavigator: false, + builder: (BuildContext context) => Scaffold( + backgroundColor: Colors.transparent, + body: AlertDialog( + title: Text(L10n.of(context)!.passwordForgotten), + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text(L10n.of(context)!.enterAnEmailAddress), + const SizedBox(height: 12), + TextField( + controller: emailController, + decoration: InputDecoration( + hintText: L10n.of(context)!.enterAnEmailAddress, + ), + ), + ], + ), + actions: [ + TextButton( + child: Text(L10n.of(context)!.cancel), + onPressed: () { + Navigator.of(context).pop(); + return; + }, + ), + TextButton( + child: Text(L10n.of(context)!.ok), + onPressed: () async { + if (emailController.text == "") return; + final clientSecret = + DateTime.now().millisecondsSinceEpoch.toString(); + final response = await showFutureLoadingDialog( + context: context, + future: () => Matrix.of(context) + .getLoginClient() + .requestTokenToResetPasswordEmail( + clientSecret, + emailController.text, + LoginController.sendAttempt++, + ), + ); + if (response.error != null) { + return; + } + Navigator.of(context).pop(); + final TextEditingController textFieldController = + TextEditingController(); + showDialog( + context: context, + useRootNavigator: false, + builder: (BuildContext context) => Scaffold( + backgroundColor: Colors.transparent, + body: AlertDialog( + title: Text(L10n.of(context)!.passwordForgotten), + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text(L10n.of(context)!.chooseAStrongPassword), + const SizedBox(height: 12), + TextField( + obscureText: true, + controller: newPasswordController, + decoration: const InputDecoration( + hintText: "******", + ), + ), + ], + ), + actions: [ + TextButton( + child: Text(L10n.of(context)!.cancel), + onPressed: () { + Navigator.of(context).pop(); + return; + }, + ), + TextButton( + child: Text(L10n.of(context)!.ok), + onPressed: () async { + if (newPasswordController.text == "") return; + final ok = await showOkAlertDialog( + useRootNavigator: false, + context: context, + title: L10n.of(context)!.weSentYouAnEmail, + message: L10n.of(context)!.pleaseClickOnLink, + okLabel: L10n.of(context)!.iHaveClickedOnLink, + fullyCapitalizedForMaterial: false, + ); + if (ok != OkCancelResult.ok) return; + final data = { + 'new_password': newPasswordController.text, + 'logout_devices': false, + "auth": AuthenticationThreePidCreds( + type: AuthenticationTypes.emailIdentity, + threepidCreds: ThreepidCreds( + sid: response.result!.sid, + clientSecret: clientSecret, + ), + ).toJson(), + }; + final success = await showFutureLoadingDialog( + context: context, + future: () => + Matrix.of(context).getLoginClient().request( + RequestType.POST, + '/client/r0/account/password', + data: data, + ), + ); + if (success.error == null) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text( + L10n.of(context)!.passwordHasBeenChanged, + ), + ), + ); + usernameController.text = emailController.text; + passwordController.text = + newPasswordController.text; + login(); + } + }, + ), + ], + ), + ), + ); + }, + ), + ], + ), + ), + ); + } +} diff --git a/lib/pangea/utils/platform_name.dart b/lib/pangea/utils/platform_name.dart new file mode 100644 index 000000000..f5b6c1dd4 --- /dev/null +++ b/lib/pangea/utils/platform_name.dart @@ -0,0 +1,41 @@ +import 'dart:io' show Platform; + +import 'package:flutter/foundation.dart' show kIsWeb, kDebugMode; + +class MyPlatformName { + static String get platformName { + if (kIsWeb) { + return 'web'; + } + if (Platform.isAndroid) { + return 'android'; + } + + if (Platform.isIOS) { + return 'ios'; + } + + if (Platform.isFuchsia) { + return 'fuchsia'; + } + + if (Platform.isLinux) { + return 'linux'; + } + if (Platform.isMacOS) { + return 'macos'; + } + if (Platform.isWindows) { + return 'windows'; + } + return 'unknownplatform'; + } + + static String get getPlatformWithModeName { + String mode = 'Release'; + if (kDebugMode) { + mode = 'Debug'; + } + return MyPlatformName.platformName + mode; + } +} diff --git a/lib/pangea/utils/report_message.dart b/lib/pangea/utils/report_message.dart new file mode 100644 index 000000000..a7b3f1c28 --- /dev/null +++ b/lib/pangea/utils/report_message.dart @@ -0,0 +1,181 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:matrix/matrix.dart'; + +import 'package:fluffychat/pangea/constants/pangea_message_types.dart'; +import 'package:fluffychat/pangea/extensions/client_extension.dart'; +import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart'; +import 'package:fluffychat/widgets/matrix.dart'; + +Future reportMessage( + BuildContext context, + String roomId, + String reason, + String reportedUserId, + String reportedMessage, +) async { + final Room? reportedInRoom = Matrix.of(context).client.getRoomById(roomId); + if (reportedInRoom == null) { + throw ("Null room with id $roomId in reportMessage"); + } + + final List teachers = + await getReportTeachers(context, reportedInRoom); + if (teachers.isEmpty) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text( + L10n.of(context)!.noTeachersFound, + ), + ), + ); + return; + } + + final List? selectedTeachers = await showDialog( + context: context, + useRootNavigator: false, + builder: (BuildContext context) => TeacherSelectDialog(teachers: teachers), + ); + + if (selectedTeachers == null || selectedTeachers.isEmpty) { + return; + } + + final List reportDMs = []; + for (final SpaceTeacher teacher in selectedTeachers) { + final Room reportDM = await Matrix.of(context).client.getReportsDM( + teacher.teacher, + teacher.space, + ); + reportDMs.add(reportDM); + } + + final String reportingUserId = Matrix.of(context).client.userID ?? ""; + final String roomName = reportedInRoom.getLocalizedDisplayname(); + final String messageTitle = L10n.of(context)!.reportMessageTitle( + reportingUserId, + reportedUserId, + roomName, + ); + final String messageBody = L10n.of(context)!.reportMessageBody( + reportedMessage, + reason, + ); + final String message = "$messageTitle\n\n$messageBody"; + for (final Room reportDM in reportDMs) { + final event = { + 'msgtype': PangeaMessageTypes.report, + 'body': message, + }; + await reportDM.sendEvent(event); + } +} + +Future> getReportTeachers( + BuildContext context, + Room room, +) async { + // create a list of teachers and their assosiated spaces + // prioritize the spaces that are parents of the report room + final List teachers = []; + + final List reportRoomParentSpaces = room.spaceParents + .where((parentSpace) => parentSpace.roomId != null) + .map( + (parentSpace) => + Matrix.of(context).client.getRoomById(parentSpace.roomId!), + ) + .where((parentSpace) => parentSpace != null) + .cast() + .toList(); + + for (final Room space in reportRoomParentSpaces) { + final List spaceTeachers = await space.teachers; + for (final User spaceTeacher in spaceTeachers) { + if (!teachers.any((teacher) => teacher.teacher.id == spaceTeacher.id) && + spaceTeacher.id != Matrix.of(context).client.userID) { + teachers.add(SpaceTeacher(spaceTeacher, space)); + } + } + } + + final List otherSpaces = Matrix.of(context) + .client + .classesAndExchangesImIn + .where((space) => !reportRoomParentSpaces.contains(space)) + .toList(); + + for (final space in otherSpaces) { + for (final spaceTeacher in await space.teachers) { + if (!teachers.any((teacher) => teacher.teacher.id == spaceTeacher.id) && + spaceTeacher.id != Matrix.of(context).client.userID) { + teachers.add(SpaceTeacher(spaceTeacher, space)); + } + } + } + + return teachers; +} + +class TeacherSelectDialog extends StatefulWidget { + final List teachers; + const TeacherSelectDialog({super.key, required this.teachers}); + + @override + State createState() => _TeacherSelectDialogState(); +} + +class _TeacherSelectDialogState extends State { + final List _selectedItems = []; + + void _itemChange(SpaceTeacher itemValue, bool isSelected) { + setState(() { + isSelected + ? _selectedItems.add(itemValue) + : _selectedItems.remove(itemValue); + }); + } + + @override + Widget build(BuildContext context) { + return AlertDialog( + title: Text( + L10n.of(context)!.reportToTeacher, + style: const TextStyle(fontSize: 16), + ), + content: SingleChildScrollView( + child: ListBody( + children: widget.teachers + .map( + (teacher) => CheckboxListTile( + value: _selectedItems.contains(teacher), + title: Text(teacher.teacher.id), + controlAffinity: ListTileControlAffinity.leading, + onChanged: (isChecked) => _itemChange(teacher, isChecked!), + ), + ) + .toList(), + ), + ), + actions: [ + TextButton( + onPressed: () => Navigator.of(context).pop(), + child: Text(L10n.of(context)!.cancel), + ), + TextButton( + onPressed: () => Navigator.of(context).pop(_selectedItems), + child: Text(L10n.of(context)!.submit), + ), + ], + ); + } +} + +class SpaceTeacher { + final User teacher; + final Room space; + + SpaceTeacher(this.teacher, this.space); +} diff --git a/lib/pangea/utils/set_class_name.dart b/lib/pangea/utils/set_class_name.dart new file mode 100644 index 000000000..13a9c6c45 --- /dev/null +++ b/lib/pangea/utils/set_class_name.dart @@ -0,0 +1,59 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; + +import 'package:fluffychat/widgets/matrix.dart'; +import '../../utils/matrix_sdk_extensions/matrix_locals.dart'; + +void setClassDisplayname(BuildContext context, String? roomId) async { + final room = Matrix.of(context).client.getRoomById(roomId!)!; + final TextEditingController textFieldController = TextEditingController( + text: room.getLocalizedDisplayname( + MatrixLocals( + L10n.of(context)!, + ), + ), + ); + + showDialog( + context: context, + useRootNavigator: false, + builder: (BuildContext context) => AlertDialog( + title: Text( + room.isSpace + ? L10n.of(context)!.changeTheNameOfTheClass + : L10n.of(context)!.changeTheNameOfTheChat, + ), + content: TextField( + controller: textFieldController, + ), + actions: [ + TextButton( + child: Text(L10n.of(context)!.cancel), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + TextButton( + child: Text(L10n.of(context)!.ok), + onPressed: () async { + if (textFieldController.text == "") return; + final success = await showFutureLoadingDialog( + context: context, + future: () => room.setName(textFieldController.text), + ); + if (success.error == null) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text(L10n.of(context)!.displaynameHasBeenChanged), + ), + ); + Navigator.of(context).pop(); + } + }, + ), + ], + ), + ); +} diff --git a/lib/pangea/utils/set_class_topic.dart b/lib/pangea/utils/set_class_topic.dart new file mode 100644 index 000000000..67610c0ca --- /dev/null +++ b/lib/pangea/utils/set_class_topic.dart @@ -0,0 +1,51 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; +import 'package:matrix/matrix.dart'; + +void setClassTopic(Room room, BuildContext context) { + final TextEditingController textFieldController = + TextEditingController(text: room.topic); + showDialog( + context: context, + useRootNavigator: false, + builder: (BuildContext context) => AlertDialog( + title: Text( + room.isSpace + ? L10n.of(context)!.classDescription + : L10n.of(context)!.chatTopic, + ), + content: TextField( + controller: textFieldController, + ), + actions: [ + TextButton( + child: Text(L10n.of(context)!.cancel), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + TextButton( + child: Text(L10n.of(context)!.ok), + onPressed: () async { + if (textFieldController.text == "") return; + final success = await showFutureLoadingDialog( + context: context, + future: () => room.setDescription(textFieldController.text), + ); + if (success.error == null) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: + Text(L10n.of(context)!.groupDescriptionHasBeenChanged), + ), + ); + Navigator.of(context).pop(); + } + }, + ), + ], + ), + ); +} diff --git a/lib/pangea/utils/shared_prefs.dart b/lib/pangea/utils/shared_prefs.dart new file mode 100644 index 000000000..3d22a9971 --- /dev/null +++ b/lib/pangea/utils/shared_prefs.dart @@ -0,0 +1,37 @@ +import 'dart:convert'; + +import 'package:shared_preferences/shared_preferences.dart'; + +class MyShared { + static saveString(String key, String value) async { + final SharedPreferences prefs = await SharedPreferences.getInstance(); + prefs.setString(key, value); + } + + static Future? readString(String key) async { + final SharedPreferences prefs = await SharedPreferences.getInstance(); + final String? source = prefs.getString(key); + return source; + } + + static saveJson(String key, Map value) async { + final SharedPreferences prefs = await SharedPreferences.getInstance(); + prefs.setString(key, json.encode(value)); + } + + static Future? readJson(String key) async { + try { + final SharedPreferences prefs = await SharedPreferences.getInstance(); + final String? source = prefs.getString(key); + + if (source == null) { + return null; + } + final decodedJson = json.decoder.convert(source); + //var decodedJson = json.decode(source); + return decodedJson; + } catch (err) { + return null; + } + } +} diff --git a/lib/pangea/utils/space_navigator.dart b/lib/pangea/utils/space_navigator.dart new file mode 100644 index 000000000..af72a0b25 --- /dev/null +++ b/lib/pangea/utils/space_navigator.dart @@ -0,0 +1,23 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; + +/// this is a workaround to allow navigation of spaces out from any widget. +/// Reason is that we have no reliable way to listen on *query* changes of +/// VRouter. +/// +/// Time wasted: 3h +abstract class SpaceNavigator { + const SpaceNavigator._(); + + // TODO(TheOneWithTheBraid): adjust routing table in order to represent spaces + // ... in any present path + static final routeObserver = RouteObserver(); + + static final StreamController _controller = + StreamController.broadcast(); + + static Stream get stream => _controller.stream; + + static void navigateToSpace(String? spaceId) => _controller.add(spaceId); +} diff --git a/lib/pangea/utils/subscription_app_id.dart b/lib/pangea/utils/subscription_app_id.dart new file mode 100644 index 000000000..20a69d4a2 --- /dev/null +++ b/lib/pangea/utils/subscription_app_id.dart @@ -0,0 +1,67 @@ +import 'dart:io'; + +import 'package:flutter/foundation.dart'; + +class SubscriptionAppIds { + String? stripeId; + String? androidId; + String? appleId; + + SubscriptionAppIds(); + + String? get currentAppId => kIsWeb + ? stripeId + : Platform.isAndroid + ? androidId + : appleId; + + String? appDisplayName(String appId) { + if (appId == stripeId) return "web"; + if (appId == androidId) return "Google Play Store"; + if (appId == appleId) return "Apple App Store"; + return null; + } + + factory SubscriptionAppIds.fromJson(json) { + final SubscriptionAppIds appIds = SubscriptionAppIds(); + for (final appInfo in (json['items'] as List)) { + final String platform = appInfo['type']; + final String appId = appInfo['id']; + switch (platform) { + case 'stripe': + appIds.stripeId = appId; + continue; + case 'app_store': + appIds.appleId = appId; + continue; + case 'play_store': + appIds.androidId = appId; + continue; + } + } + return appIds; + } +} + +enum RCPlatform { + stripe, + android, + apple, +} + +class SubscriptionPlatform { + RCPlatform currentPlatform = kIsWeb + ? RCPlatform.stripe + : Platform.isAndroid + ? RCPlatform.android + : RCPlatform.apple; + + @override + String toString() { + return currentPlatform == RCPlatform.stripe + ? 'stripe' + : currentPlatform == RCPlatform.android + ? 'play_store' + : 'app_store'; + } +} diff --git a/lib/pangea/utils/sync_status_util.dart b/lib/pangea/utils/sync_status_util.dart new file mode 100644 index 000000000..a03a96cc2 --- /dev/null +++ b/lib/pangea/utils/sync_status_util.dart @@ -0,0 +1,127 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:matrix/matrix.dart'; + +import 'package:fluffychat/utils/localized_exception_extension.dart'; +import '../../widgets/matrix.dart'; + +class PLoadingStatus extends StatefulWidget { + final void Function()? onFinish; + + final Widget child; + final Widget? shimmerChild; + const PLoadingStatus({ + super.key, + required this.child, + this.onFinish, + this.shimmerChild, + }); + + @override + PLoadingStatusState createState() => PLoadingStatusState(); +} + +class PLoadingStatusState extends State { + late final StreamSubscription _onSyncSub; + bool isFinished = false; + @override + void initState() { + _onSyncSub = Matrix.of(context).client.onSyncStatus.stream.listen( + (status) => setState(() { + if (status.status == SyncStatus.finished) { + //PTODO - test this + if (!isFinished) { + isFinished = true; + widget.onFinish?.call(); + } + } + }), + ); + super.initState(); + } + + @override + void dispose() { + _onSyncSub.cancel(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + final Client client = Matrix.of(context).client; + final SyncStatusUpdate status = client.onSyncStatus.value ?? + const SyncStatusUpdate(SyncStatus.waitingForResponse); + final bool hide = client.onSync.value != null && + status.status != SyncStatus.error && + client.prevBatch != null; + + final shimmerComponent = widget.shimmerChild == null + ? PangeaDefaultShimmer(hide: hide, status: status) + : widget.shimmerChild!; + + return hide ? widget.child : shimmerComponent; + } +} + +class PangeaDefaultShimmer extends StatelessWidget { + const PangeaDefaultShimmer({ + super.key, + required this.hide, + required this.status, + }); + + final bool hide; + final SyncStatusUpdate status; + + @override + Widget build(BuildContext context) { + return AnimatedContainer( + duration: const Duration(milliseconds: 200), + curve: Curves.bounceInOut, + height: hide ? 0 : 36, + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration(color: Theme.of(context).colorScheme.surface), + padding: const EdgeInsets.symmetric(horizontal: 12), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SizedBox( + width: 24, + height: 24, + child: CircularProgressIndicator.adaptive( + strokeWidth: 2, + value: hide ? 1.0 : status.progress, + ), + ), + const SizedBox(width: 12), + Text( + status.toLocalizedString(context), + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: TextStyle(color: Theme.of(context).colorScheme.onSurface), + ), + ], + ), + ); + } +} + +extension on SyncStatusUpdate { + String toLocalizedString(BuildContext context) { + switch (status) { + case SyncStatus.waitingForResponse: + return L10n.of(context)!.loadingPleaseWait; + case SyncStatus.error: + return ((error?.exception ?? Object()) as Object) + .toLocalizedString(context); + case SyncStatus.processing: + case SyncStatus.cleaningUp: + case SyncStatus.finished: + default: + return L10n.of(context)!.synchronizingPleaseWait; + } + } +} diff --git a/lib/pangea/utils/sync_status_util_v2.dart b/lib/pangea/utils/sync_status_util_v2.dart new file mode 100644 index 000000000..640dc7054 --- /dev/null +++ b/lib/pangea/utils/sync_status_util_v2.dart @@ -0,0 +1,127 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:matrix/matrix.dart'; + +import 'package:fluffychat/utils/localized_exception_extension.dart'; +import '../../widgets/matrix.dart'; +import 'error_handler.dart'; + +class PLoadingStatusV2 extends StatefulWidget { + final void Function()? onFinish; + + final Widget child; + final Widget? shimmerChild; + const PLoadingStatusV2({ + super.key, + required this.child, + this.onFinish, + this.shimmerChild, + }); + + @override + PLoadingStatusStateV2 createState() => PLoadingStatusStateV2(); +} + +class PLoadingStatusStateV2 extends State { + bool isFinished = false; + @override + void initState() { + _waitForSync(); + super.initState(); + } + + _waitForSync() async { + try { + final Client client = Matrix.of(context).client; + if (client.rooms.isEmpty) await client.roomsLoading; + + // await client.accountDataLoading; + // client.prevBatch == null ? await client.onSync.stream.first : null; + + if (!isFinished) { + isFinished = true; + widget.onFinish?.call(); + } + } catch (err, s) { + ErrorHandler.logError(e: err, s: s); + isFinished = true; + } + } + + @override + Widget build(BuildContext context) { + final Client client = Matrix.of(context).client; + final SyncStatusUpdate status = client.onSyncStatus.value ?? + const SyncStatusUpdate(SyncStatus.waitingForResponse); + final bool hide = client.onSync.value != null && + status.status != SyncStatus.error && + client.prevBatch != null; + + final shimmerComponent = widget.shimmerChild == null + ? PangeaDefaultShimmer(hide: hide, status: status) + : widget.shimmerChild!; + + return isFinished ? widget.child : shimmerComponent; + } +} + +class PangeaDefaultShimmer extends StatelessWidget { + const PangeaDefaultShimmer({ + super.key, + required this.hide, + required this.status, + }); + + final bool hide; + final SyncStatusUpdate status; + + @override + Widget build(BuildContext context) { + return AnimatedContainer( + duration: const Duration(milliseconds: 200), + curve: Curves.bounceInOut, + height: hide ? 0 : 36, + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration(color: Theme.of(context).colorScheme.surface), + padding: const EdgeInsets.symmetric(horizontal: 12), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SizedBox( + width: 24, + height: 24, + child: CircularProgressIndicator.adaptive( + strokeWidth: 2, + value: hide ? 1.0 : status.progress, + ), + ), + const SizedBox(width: 12), + Text( + status.toLocalizedString(context), + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: TextStyle(color: Theme.of(context).colorScheme.onSurface), + ), + ], + ), + ); + } +} + +extension on SyncStatusUpdate { + String toLocalizedString(BuildContext context) { + switch (status) { + case SyncStatus.waitingForResponse: + return L10n.of(context)!.loadingPleaseWait; + case SyncStatus.error: + return ((error?.exception ?? Object()) as Object) + .toLocalizedString(context); + case SyncStatus.processing: + case SyncStatus.cleaningUp: + case SyncStatus.finished: + default: + return L10n.of(context)!.synchronizingPleaseWait; + } + } +} diff --git a/lib/pangea/widgets/chat/locked_chat_message.dart b/lib/pangea/widgets/chat/locked_chat_message.dart new file mode 100644 index 000000000..7c890c7c5 --- /dev/null +++ b/lib/pangea/widgets/chat/locked_chat_message.dart @@ -0,0 +1,36 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; + +import 'package:fluffychat/config/app_config.dart'; + +class LockedChatMessage extends StatelessWidget { + const LockedChatMessage({super.key}); + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.symmetric( + horizontal: 8.0, + vertical: 4.0, + ), + child: Center( + child: Container( + padding: const EdgeInsets.all(8), + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.onInverseSurface, + borderRadius: BorderRadius.circular(AppConfig.borderRadius / 2), + ), + child: Text( + L10n.of(context)!.lockedChatWarning, + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 14 * AppConfig.fontSizeFactor, + color: Theme.of(context).colorScheme.onSecondaryContainer, + ), + ), + ), + ), + ); + } +} diff --git a/lib/pangea/widgets/chat_list/chat_list_body_text.dart b/lib/pangea/widgets/chat_list/chat_list_body_text.dart new file mode 100644 index 000000000..c8984f8d7 --- /dev/null +++ b/lib/pangea/widgets/chat_list/chat_list_body_text.dart @@ -0,0 +1,53 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; + +import 'package:fluffychat/pangea/controllers/pangea_controller.dart'; +import '../../../pages/chat_list/chat_list.dart'; +import '../../../widgets/matrix.dart'; +import '../../extensions/pangea_room_extension.dart'; + +class ChatListBodyStartText extends StatelessWidget { + const ChatListBodyStartText({ + super.key, + required this.controller, + }); + + final ChatListController controller; + + chatListBodyStartText(BuildContext context) { + // note: only shows if user is in no chats in that space + + final PangeaController pangeaController = MatrixState.pangeaController; + + if (controller.activeSpaceId != null) { + if (Matrix.of(context) + .client + .getRoomById(controller.activeSpaceId!) + ?.isSpaceAdmin ?? + false) { + return L10n.of(context)!.welcomeToYourNewClass; + } + + return L10n.of(context)!.welcomeToClass; + } + + if (pangeaController.permissionsController.isUser18()) { + return L10n.of(context)!.welcomeToPangea18Plus; + } + + return L10n.of(context)!.welcomeToPangeaMinor; + } + + @override + Widget build(BuildContext context) { + return Text( + chatListBodyStartText(context), + textAlign: TextAlign.start, + style: const TextStyle( + color: Colors.grey, + fontSize: 16, + ), + ); + } +} diff --git a/lib/pangea/widgets/chat_list/find_a_partner_tile.dart b/lib/pangea/widgets/chat_list/find_a_partner_tile.dart new file mode 100644 index 000000000..78fe7c7b4 --- /dev/null +++ b/lib/pangea/widgets/chat_list/find_a_partner_tile.dart @@ -0,0 +1,56 @@ +// import 'package:flutter/material.dart'; +// import 'package:flutter_gen/gen_l10n/l10n.dart'; +// import 'package:vrouter/vrouter.dart'; + +// import '../../../pages/chat_list/chat_list.dart'; + +// class FindALanguagePartnerTile extends StatelessWidget { +// const FindALanguagePartnerTile({ +// Key? key, +// required this.controller, +// }) : super(key: key); + +// final ChatListController controller; + +// @override +// Widget build(BuildContext context) { +// return ListTile( +// leading: Icon( +// Icons.add_circle_outline, +// color: Theme.of(context).colorScheme.onBackground, +// ), +// title: Text(L10n.of(context)!.findALanguagePartner), +// onTap: () { +// if (controller +// .pangeaController.permissionsController.isPublic) { +// Scaffold.of(context).closeDrawer(); +// VRouter.of(context).to('/partner'); +// } else { +// showDialog( +// context: context, +// useRootNavigator: false, +// builder: (context) => AlertDialog( +// title: Text(L10n.of(context)!.setToPublicSettingsTitle), +// content: ConstrainedBox( +// constraints: const BoxConstraints(maxWidth: 250), +// child: Text(L10n.of(context)!.setToPublicSettingsDesc), +// ), +// actions: [ +// TextButton( +// onPressed: Navigator.of(context).pop, +// child: Text(L10n.of(context)!.cancel), +// ), +// TextButton( +// onPressed: () { +// VRouter.of(context).to('/settings/account'); +// }, +// child: Text(L10n.of(context)!.accountSettings), +// ), +// ], +// ), +// ); +// } +// }, +// ); +// } +// } diff --git a/lib/pangea/widgets/class/add_class_and_invite.dart b/lib/pangea/widgets/class/add_class_and_invite.dart new file mode 100644 index 000000000..e33118c73 --- /dev/null +++ b/lib/pangea/widgets/class/add_class_and_invite.dart @@ -0,0 +1,297 @@ +import 'dart:developer'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; +import 'package:go_router/go_router.dart'; +import 'package:matrix/matrix.dart'; + +import 'package:fluffychat/config/app_config.dart'; +import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart'; +import '../../../widgets/matrix.dart'; +import '../../utils/error_handler.dart'; +import '../../utils/firebase_analytics.dart'; + +enum AddToClassMode { exchange, chat } + +class AddToClassAndInviteToggles extends StatefulWidget { + final String? roomId; + final bool startOpen; + final Function? setParentState; + final AddToClassMode mode; + + const AddToClassAndInviteToggles({ + super.key, + this.roomId, + this.startOpen = false, + this.setParentState, + required this.mode, + }); + + @override + AddToClassAndInviteState createState() => AddToClassAndInviteState(); +} + +class AddToClassAndInviteState extends State { + late Room? room; + late List parents; + late List possibleParents; + late bool isOpen; + + AddToClassAndInviteState({Key? key}); + + @override + void initState() { + room = widget.roomId != null + ? Matrix.of(context).client.getRoomById(widget.roomId!) + : null; + + if (room != null && room!.isPangeaClass) { + debugger(when: kDebugMode); + ErrorHandler.logError( + m: "should not be able to add class to space, not yet at least", + ); + context.go('/rooms'); + } + + possibleParents = Matrix.of(context) + .client + .rooms + .where( + widget.mode == AddToClassMode.exchange + ? (Room r) => r.isPangeaClass && widget.roomId != r.id + : (Room r) => + (r.isPangeaClass || r.isExchange) && widget.roomId != r.id, + ) + .toList(); + + parents = widget.roomId != null + ? possibleParents + .where( + (r) => + r.spaceChildren.any((room) => room.roomId == widget.roomId), + ) + .toList() + : []; + + isOpen = widget.startOpen; + + super.initState(); + } + + Future addParents(String roomToAddId) async { + final List> addFutures = []; + for (final Room newParent in parents) { + addFutures.add(_addSingleParent(roomToAddId, newParent)); + } + await addFutures.wait; + } + + Future _addSingleParent(String roomToAddId, Room newParent) async { + GoogleAnalytics.addParent(roomToAddId, newParent.classCode); + final List> existingMembers = await Future.wait([ + room!.requestParticipants(), + newParent.requestParticipants(), + ]); + final List roomMembers = existingMembers[0]; + final List spaceMembers = existingMembers[1]; + + final List> inviteFutures = [ + newParent.setSpaceChild(roomToAddId, suggested: true), + ]; + for (final spaceMember + in spaceMembers.where((element) => element.id != room!.client.userID)) { + if (!roomMembers.any( + (m) => m.id == spaceMember.id && m.membership == Membership.join, + )) { + inviteFutures.add(_inviteSpaceMember(spaceMember)); + } else { + debugPrint('User ${spaceMember.id} is already in the room'); + } + } + await Future.wait(inviteFutures); + return; + } + + //function for kicking single student and haandling error + Future _kickSpaceMember(User spaceMember) async { + try { + await room!.kick(spaceMember.id); + debugPrint('Kicked ${spaceMember.id}'); + } catch (e) { + debugger(when: kDebugMode); + ErrorHandler.logError(e: e); + } + } + + //function for adding single student and haandling error + Future _inviteSpaceMember(User spaceMember) async { + try { + await room!.invite(spaceMember.id); + debugPrint('added ${spaceMember.id}'); + } catch (e) { + debugger(when: kDebugMode); + ErrorHandler.logError(e: e); + } + } + + //remove single class + Future _removeSingleSpaceFromParents( + String roomToRemoveId, + Room spaceToRemove, + ) async { + GoogleAnalytics.removeChatFromClass( + roomToRemoveId, + spaceToRemove.classCode, + ); + + if (room == null) { + ErrorHandler.logError(m: 'Room is null in kickSpaceMembers'); + debugger(when: kDebugMode); + return; + } + final List> roomsMembers = await Future.wait([ + room!.requestParticipants(), + spaceToRemove.requestParticipants(), + ]); + + final List toKick = roomsMembers[1] + .where( + (element) => + element.id != room!.client.userID && + roomsMembers[0].any((m) => m.id == element.id), + ) + .toList(); + + final List> kickFutures = [ + spaceToRemove.removeSpaceChild(roomToRemoveId), + ]; + for (final spaceMember in toKick) { + kickFutures.add(_kickSpaceMember(spaceMember)); + } + await Future.wait(kickFutures); + + // if (widget.setParentState != null) { + // widget.setParentState!(); + // } + await room!.requestParticipants(); + + GoogleAnalytics.kickClassFromExchange(room!.id, spaceToRemove.id); + return; + } + + // ignore: curly_braces_in_flow_control_structures + Future _handleAdd(bool add, Room possibleParent) async { + //in this case, the room has already been made so we handle adding as it happens + if (room != null) { + await showFutureLoadingDialog( + context: context, + future: () async { + await (add + ? _addSingleParent(room!.id, possibleParent) + : _removeSingleSpaceFromParents(room!.id, possibleParent)); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text( + add + ? L10n.of(context)!.youAddedToSpace( + room!.name, + possibleParent.name, + ) + : L10n.of(context)!.youRemovedFromSpace( + room!.name, + possibleParent.name, + ), + ), + ), + ); + }, + ); + } + setState( + () => add + ? parents.add(possibleParent) + : parents.removeWhere((r) => r.id == possibleParent.id), + ); + } + + @override + Widget build(BuildContext context) { + return Column( + children: [ + if (!widget.startOpen) + ListTile( + enableFeedback: !widget.startOpen, + title: Text( + widget.mode == AddToClassMode.exchange + ? L10n.of(context)!.addToClass + : L10n.of(context)!.addToClassOrExchange, + style: TextStyle( + color: Theme.of(context).colorScheme.secondary, + fontWeight: FontWeight.bold, + ), + ), + leading: CircleAvatar( + backgroundColor: Theme.of(context).scaffoldBackgroundColor, + foregroundColor: Theme.of(context).textTheme.bodyLarge!.color, + child: const Icon( + Icons.workspaces_outline, + ), + ), + trailing: !widget.startOpen + ? Icon( + isOpen + ? Icons.keyboard_arrow_down_outlined + : Icons.keyboard_arrow_right_outlined, + ) + : null, + onTap: () => setState(() => isOpen = !isOpen), + ), + if (isOpen) + Padding( + padding: const EdgeInsets.fromLTRB(16.0, 0, 16.0, 0), + child: Column( + children: [ + if (possibleParents.isEmpty) + ListTile( + title: Text(L10n.of(context)!.noEligibleSpaces), + ), + ListView.builder( + shrinkWrap: true, + itemCount: possibleParents.length, + itemBuilder: (BuildContext context, int i) { + final bool canIAddSpaceChildren = + possibleParents[i].canIAddSpaceChild(room) && + (room?.canIAddSpaceParents ?? true); + return Column( + children: [ + Opacity( + opacity: canIAddSpaceChildren ? 1 : 0.5, + child: SwitchListTile.adaptive( + title: possibleParents[i].nameAndRoomTypeIcon(), + activeColor: AppConfig.activeToggleColor, + value: parents + .any((r) => r.id == possibleParents[i].id), + onChanged: (bool add) => canIAddSpaceChildren + ? _handleAdd(add, possibleParents[i]) + : ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: + Text(L10n.of(context)!.noPermission), + ), + ), + ), + ), + ], + ); + }, + ), + ], + ), + ), + ], + ); + } +} diff --git a/lib/pangea/widgets/class/add_space_toggles.dart b/lib/pangea/widgets/class/add_space_toggles.dart new file mode 100644 index 000000000..ca9cba14e --- /dev/null +++ b/lib/pangea/widgets/class/add_space_toggles.dart @@ -0,0 +1,304 @@ +import 'package:collection/collection.dart'; +import 'package:fluffychat/config/app_config.dart'; +import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart'; +import 'package:fluffychat/pangea/utils/error_handler.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; +import 'package:matrix/matrix.dart'; + +import '../../../widgets/matrix.dart'; +import '../../utils/firebase_analytics.dart'; +import 'add_class_and_invite.dart'; + +//PTODO - auto invite students when you add a space and delete the add_class_and_invite.dart file +class AddToSpaceToggles extends StatefulWidget { + final String? roomId; + final bool startOpen; + final String? activeSpaceId; + final AddToClassMode mode; + + const AddToSpaceToggles({ + super.key, + this.roomId, + this.startOpen = false, + this.activeSpaceId, + required this.mode, + }); + + @override + AddToSpaceState createState() => AddToSpaceState(); +} + +class AddToSpaceState extends State { + late Room? room; + late List parents; + late List possibleParents; + late bool isOpen; + + AddToSpaceState({Key? key}); + + @override + void initState() { + //if roomId is null, it means this widget is being used in the creation flow + room = widget.roomId != null + ? Matrix.of(context).client.getRoomById(widget.roomId!) + : null; + + possibleParents = Matrix.of(context) + .client + .rooms + .where( + widget.mode == AddToClassMode.exchange + ? (Room r) => r.isPangeaClass && widget.roomId != r.id + : (Room r) => + (r.isPangeaClass || r.isExchange) && widget.roomId != r.id, + ) + .toList(); + + parents = widget.roomId != null + ? possibleParents + .where( + (r) => + r.spaceChildren.any((room) => room.roomId == widget.roomId), + ) + .map((r) => SuggestionStatus(false, r)) + .cast() + .toList() + : []; + + if (widget.activeSpaceId != null) { + final activeSpace = + Matrix.of(context).client.getRoomById(widget.activeSpaceId!); + if (activeSpace != null) { + parents.add(SuggestionStatus(false, activeSpace)); + } else { + ErrorHandler.logError( + e: Exception('activeSpaceId ${widget.activeSpaceId} not found'), + ); + } + } + + //sort possibleParents + //if possibleParent in parents, put first + //use sort but use any instead of contains because contains uses == and we want to compare by id + possibleParents.sort((a, b) { + if (parents.any((suggestionStatus) => suggestionStatus.room.id == a.id)) { + return -1; + } else if (parents + .any((suggestionStatus) => suggestionStatus.room.id == b.id)) { + return 1; + } else { + return a.name.compareTo(b.name); + } + }); + + isOpen = widget.startOpen; + initSuggestedParents(); + super.initState(); + } + + Future initSuggestedParents() async { + if (room != null) { + for (var i = 0; i < parents.length; i++) { + final parent = parents[i]; + final bool suggested = + await room?.suggestedInSpace(parent.room) ?? false; + parents[i].suggested = suggested; + } + setState(() {}); + } + } + + Future _addSingleSpace(String roomToAddId, Room newParent) { + GoogleAnalytics.addParent(roomToAddId, newParent.classCode); + return newParent.setSpaceChild( + roomToAddId, + suggested: isSuggestedInSpace(newParent), + ); + } + + Future addSpaces(String roomToAddId) async { + final List> addFutures = []; + for (final SuggestionStatus newParent in parents) { + addFutures.add(_addSingleSpace(roomToAddId, newParent.room)); + } + await addFutures.wait; + } + + Future handleAdd(bool add, Room possibleParent) async { + //in this case, the room has already been made so we handle adding as it happens + if (room != null) { + await showFutureLoadingDialog( + context: context, + future: () => add + ? _addSingleSpace(room!.id, possibleParent) + : possibleParent.removeSpaceChild(room!.id), + ); + } + + setState( + () => add + ? parents.add(SuggestionStatus(false, possibleParent)) + : parents.removeWhere( + (suggestionStatus) => + suggestionStatus.room.id == possibleParent.id, + ), + ); + } + + Future setSuggested(bool suggest, Room possibleParent) async { + if (room != null) { + await showFutureLoadingDialog( + context: context, + future: () => room!.setSuggestedInSpace(suggest, possibleParent), + ); + } + + for (final SuggestionStatus suggestionStatus in parents) { + if (suggestionStatus.room.id == possibleParent.id) { + suggestionStatus.suggested = suggest; + } + } + + setState(() {}); + } + + bool isSuggestedInSpace(Room parent) => + parents.firstWhereOrNull((r) => r.room.id == parent.id)?.suggested ?? + false; + + Widget getAddToSpaceToggleItem(int index) { + final Room possibleParent = possibleParents[index]; + final String possibleParentName = possibleParent.getLocalizedDisplayname(); + final bool canAdd = possibleParent.canIAddSpaceChild(room); + + return Opacity( + opacity: canAdd ? 1 : 0.5, + child: Column( + children: [ + SwitchListTile.adaptive( + title: possibleParent.nameAndRoomTypeIcon(), + activeColor: AppConfig.activeToggleColor, + value: parents.any((r) => r.room.id == possibleParent.id), + onChanged: (bool add) => canAdd + ? handleAdd(add, possibleParent) + : ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text(L10n.of(context)!.noPermission), + ), + ), + ), + AnimatedSize( + duration: const Duration(milliseconds: 300), + curve: Curves.easeInOut, + child: parents.any((r) => r.room.id == possibleParent.id) + ? SwitchListTile.adaptive( + title: Row( + children: [ + const SizedBox(width: 32), + Text( + L10n.of(context)!.suggestTo(possibleParentName), + style: TextStyle( + color: Theme.of(context).colorScheme.secondary, + ), + ), + ], + ), + subtitle: Row( + children: [ + const SizedBox(width: 32), + Expanded( + child: Text( + widget.mode == AddToClassMode.chat + ? L10n.of(context)! + .suggestChatDesc(possibleParentName) + : L10n.of(context)!.suggestExchangeDesc( + possibleParentName, + ), + overflow: TextOverflow.ellipsis, + ), + ), + ], + ), + activeColor: AppConfig.activeToggleColor, + value: isSuggestedInSpace(possibleParent), + onChanged: (bool suggest) => + setSuggested(suggest, possibleParent), + ) + : Container(), + ), + Divider( + height: 0.5, + color: Theme.of(context).colorScheme.secondary.withAlpha(25), + ), + ], + ), + ); + } + + @override + Widget build(BuildContext context) { + final String title = widget.mode == AddToClassMode.exchange + ? L10n.of(context)!.addToClass + : L10n.of(context)!.addToClassOrExchange; + final String subtitle = widget.mode == AddToClassMode.exchange + ? L10n.of(context)!.addToClassDesc + : L10n.of(context)!.addToClassOrExchangeDesc; + + return Column( + children: [ + ListTile( + title: Text( + title, + style: TextStyle( + color: Theme.of(context).colorScheme.secondary, + fontWeight: FontWeight.bold, + ), + ), + subtitle: Text(subtitle), + leading: CircleAvatar( + backgroundColor: Theme.of(context).scaffoldBackgroundColor, + foregroundColor: Theme.of(context).textTheme.bodyLarge!.color, + child: const Icon(Icons.workspaces_outlined), + ), + trailing: Icon( + isOpen + ? Icons.keyboard_arrow_down_outlined + : Icons.keyboard_arrow_right_outlined, + ), + onTap: () { + setState(() => isOpen = !isOpen); + }, + ), + if (isOpen) ...[ + const Divider(height: 1), + possibleParents.isNotEmpty + ? Column( + children: possibleParents + .mapIndexed((index, _) => getAddToSpaceToggleItem(index)) + .toList(), + ) + : Center( + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Text( + L10n.of(context)!.inNoSpaces, + style: TextStyle( + color: Theme.of(context).colorScheme.secondary, + ), + ), + ), + ), + ], + ], + ); + } +} + +class SuggestionStatus { + bool suggested; + final Room room; + + SuggestionStatus(this.suggested, this.room); +} diff --git a/lib/pangea/widgets/class/invite_students_from_class.dart b/lib/pangea/widgets/class/invite_students_from_class.dart new file mode 100644 index 000000000..70bafeb7d --- /dev/null +++ b/lib/pangea/widgets/class/invite_students_from_class.dart @@ -0,0 +1,342 @@ +// import 'dart:developer'; + +// import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart'; +// import 'package:flutter/foundation.dart'; +// import 'package:flutter/material.dart'; +// import 'package:flutter_gen/gen_l10n/l10n.dart'; +// import 'package:future_loading_dialog/future_loading_dialog.dart'; +// import 'package:matrix/matrix.dart'; + +// import '../../../utils/matrix_sdk_extensions/matrix_locals.dart'; +// import '../../../widgets/avatar.dart'; +// import '../../../widgets/matrix.dart'; +// import '../../utils/error_handler.dart'; +// import '../../utils/firebase_analytics.dart'; + +// class InviteStudentsFromClass extends StatefulWidget { +// final String? roomId; +// final bool startOpen; +// final Function setParentState; + +// const InviteStudentsFromClass({ +// Key? key, +// this.roomId, +// this.startOpen = false, +// required this.setParentState, +// }) : super(key: key); + +// @override +// InviteStudentsFromClassState createState() => InviteStudentsFromClassState(); +// } + +// class InviteStudentsFromClassState extends State { +// late Room? room; +// late List otherSpaces; +// late bool isOpen; +// final List invitedSpaces = []; +// final List kickedSpaces = []; + +// InviteStudentsFromClassState({Key? key, cont}); + +// @override +// void initState() { +// room = widget.roomId != null +// ? Matrix.of(context).client.getRoomById(widget.roomId!) +// : null; + +// otherSpaces = Matrix.of(context) +// .client +// .rooms +// .where((r) => r.isPangeaClass && r.id != widget.roomId) +// .toList(); + +// isOpen = widget.startOpen; + +// super.initState(); +// } + +// Future inviteSpaceMembers(BuildContext context, Room spaceToInvite) => +// showFutureLoadingDialog( +// context: context, +// future: () async { +// if (room == null) { +// ErrorHandler.logError(m: 'Room is null in inviteSpaceMembers'); +// debugger(when: kDebugMode); +// return; +// } +// final List> existingMembers = await Future.wait([ +// room!.requestParticipants(), +// spaceToInvite.requestParticipants(), +// ]); +// final List roomMembers = existingMembers[0]; +// final List spaceMembers = existingMembers[1]; +// final List> inviteFutures = []; +// for (final spaceMember in spaceMembers +// .where((element) => element.id != room!.client.userID)) { +// if (!roomMembers.any((m) => +// m.id == spaceMember.id && m.membership == Membership.join)) { +// inviteFutures.add(inviteSpaceMember(spaceMember)); +// //add to invitedSpaces +// invitedSpaces.add(spaceToInvite.id); +// //if in kickedSpaces, remove +// kickedSpaces.remove(spaceToInvite.id); +// } else { +// debugPrint('User ${spaceMember.id} is already in the room'); +// } +// } +// await Future.wait(inviteFutures); +// debugPrint('Invited ${spaceMembers.length} members'); +// GoogleAnalytics.inviteClassToExchange(room!.id, spaceToInvite.id); +// // setState(() { +// // widget.setParentState(); +// // }); +// }, +// onError: handleError, +// ); + +// //function for kicking single student and haandling error +// Future kickSpaceMember(User spaceMember) async { +// try { +// await room!.kick(spaceMember.id); +// debugPrint('Kicked ${spaceMember.id}'); +// } catch (e) { +// debugger(when: kDebugMode); +// ErrorHandler.logError(e: e); +// } +// } + +// //function for adding single student and haandling error +// Future inviteSpaceMember(User spaceMember) async { +// try { +// await room!.invite(spaceMember.id); +// debugPrint('added ${spaceMember.id}'); +// } catch (e) { +// debugger(when: kDebugMode); +// ErrorHandler.logError(e: e); +// } +// } + +// Future kickSpaceMembers(BuildContext context, Room spaceToKick) => +// showFutureLoadingDialog( +// context: context, +// future: () async { +// if (room == null) { +// ErrorHandler.logError(m: 'Room is null in kickSpaceMembers'); +// debugger(when: kDebugMode); +// return; +// } +// final List> existingMembers = await Future.wait([ +// room!.requestParticipants(), +// spaceToKick.requestParticipants(), +// ]); +// final List roomMembers = existingMembers[0]; +// final List spaceMembers = existingMembers[1]; +// final List toKick = spaceMembers +// .where((element) => +// element.id != room!.client.userID && +// roomMembers.any((m) => m.id == element.id)) +// .toList(); +// //add to kickedSpaces +// kickedSpaces.add(spaceToKick.id); +// //if in invitedSpaces, remove from invitedSpaces +// invitedSpaces.remove(spaceToKick.id); +// final List> kickFutures = []; + +// for (final spaceMember in toKick) { +// kickFutures.add(kickSpaceMember(spaceMember)); +// } +// await Future.wait(kickFutures); +// GoogleAnalytics.kickClassFromExchange(room!.id, spaceToKick.id); +// setState(() { +// widget.setParentState(); +// }); +// return; +// }, +// onError: handleError, +// ); + +// String handleError(dynamic exception) { +// ErrorHandler.logError( +// e: exception, m: 'Error inviting or kicking students'); +// ScaffoldMessenger.of(context).showSnackBar( +// SnackBar( +// content: Text(exception.toString()), +// ), +// ); +// return exception.toString(); +// } + +// @override +// Widget build(BuildContext context) { +// if (room == null) return Container(); +// return Column( +// children: [ +// ListTile( +// title: Text( +// L10n.of(context)!.inviteStudentsFromOtherClasses, +// style: TextStyle( +// color: Theme.of(context).colorScheme.secondary, +// fontWeight: FontWeight.bold, +// ), +// ), +// leading: CircleAvatar( +// backgroundColor: Theme.of(context).primaryColor, +// foregroundColor: Colors.white, +// radius: Avatar.defaultSize / 2, +// child: const Icon(Icons.workspaces_outlined), +// ), +// trailing: Icon( +// isOpen +// ? Icons.keyboard_arrow_down_outlined +// : Icons.keyboard_arrow_right_outlined, +// ), +// onTap: () => setState(() => isOpen = !isOpen), +// ), +// if (isOpen) +// Padding( +// padding: const EdgeInsets.fromLTRB(16.0, 0, 16.0, 0), +// child: Column( +// children: [ +// if (otherSpaces.isEmpty) +// ListTile(title: Text(L10n.of(context)!.noEligibleSpaces)), +// ListView.builder( +// shrinkWrap: true, +// itemCount: otherSpaces.length, +// itemBuilder: (BuildContext context, int i) { +// final bool canIAddSpaceChildren = +// otherSpaces[i].canIAddSpaceChild(room); +// return Column( +// children: [ +// Opacity( +// opacity: canIAddSpaceChildren ? 1 : 0.5, +// child: InviteKickClass( +// room: otherSpaces[i], +// inviteCallback: (Room room) => +// inviteSpaceMembers(context, otherSpaces[i]), +// kickCallback: (Room room) => +// kickSpaceMembers(context, otherSpaces[i]), +// controller: this, +// ), +// ), +// ], +// ); +// }, +// ), +// ], +// ), +// ), +// // END: ed8c6549bwf9 +// ], +// ); +// } +// } + +// //listTile with two buttons - one to invite all students in the class and the other to kick them all out +// // parameters +// // 1. Room +// // 2. invite callback +// // 3. kick callback +// // when the user clicks either button, a dialog pops up asking for confirmation +// // after the dialog is confirmed, the callback is executed +// class InviteKickClass extends StatelessWidget { +// final Room room; +// final Function inviteCallback; +// final Function kickCallback; +// final InviteStudentsFromClassState controller; + +// const InviteKickClass({ +// Key? key, +// required this.room, +// required this.inviteCallback, +// required this.kickCallback, +// required this.controller, +// }) : super(key: key); + +// @override +// Widget build(BuildContext context) { +// return ListTile( +// title: Text( +// room.getLocalizedDisplayname( +// MatrixLocals(L10n.of(context)!), +// ), +// ), +// leading: const SizedBox( +// height: Avatar.defaultSize, +// width: Avatar.defaultSize, +// ), +// trailing: Row( +// mainAxisSize: MainAxisSize.min, +// children: [ +// IconButton( +// icon: const Icon(Icons.add), +// isSelected: controller.invitedSpaces.contains(room.id), +// onPressed: () async { +// final bool? result = await showDialog( +// context: context, +// builder: (BuildContext context) => AlertDialog( +// title: Text( +// L10n.of(context)!.inviteAllStudents, +// style: TextStyle( +// color: Theme.of(context).colorScheme.secondary, +// fontWeight: FontWeight.bold, +// ), +// ), +// content: Text( +// L10n.of(context)!.inviteAllStudentsConfirmation, +// ), +// actions: [ +// TextButton( +// onPressed: () => Navigator.of(context).pop(false), +// child: Text(L10n.of(context)!.cancel), +// ), +// TextButton( +// onPressed: () => Navigator.of(context).pop(true), +// child: Text(L10n.of(context)!.ok), +// ), +// ], +// ), +// ); +// if (result != null && result) { +// inviteCallback(room); +// } +// }, +// ), +// IconButton( +// icon: const Icon(Icons.remove), +// isSelected: controller.kickedSpaces.contains(room.id), +// onPressed: () async { +// final bool? result = await showDialog( +// context: context, +// builder: (BuildContext context) => AlertDialog( +// title: Text( +// L10n.of(context)!.kickAllStudents, +// style: TextStyle( +// color: Theme.of(context).colorScheme.secondary, +// fontWeight: FontWeight.bold, +// ), +// ), +// content: Text( +// L10n.of(context)!.kickAllStudentsConfirmation, +// ), +// actions: [ +// TextButton( +// onPressed: () => Navigator.of(context).pop(false), +// child: Text(L10n.of(context)!.cancel), +// ), +// TextButton( +// onPressed: () => Navigator.of(context).pop(true), +// child: Text(L10n.of(context)!.ok), +// ), +// ], +// ), +// ); +// if (result != null && result) { +// kickCallback(room); +// } +// }, +// ), +// ], +// ), +// ); +// } +// } diff --git a/lib/pangea/widgets/class/join_with_link.dart b/lib/pangea/widgets/class/join_with_link.dart new file mode 100644 index 000000000..8011d718b --- /dev/null +++ b/lib/pangea/widgets/class/join_with_link.dart @@ -0,0 +1,76 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:go_router/go_router.dart'; + +import 'package:fluffychat/pangea/constants/url_query_parameter_keys.dart'; +import 'package:fluffychat/pangea/controllers/pangea_controller.dart'; +import 'package:fluffychat/pangea/utils/class_code.dart'; +import 'package:fluffychat/widgets/layouts/empty_page.dart'; +import '../../../widgets/matrix.dart'; +import '../../constants/local.key.dart'; +import '../../utils/error_handler.dart'; + +//if on home with classcode in url and not logged in, then save it soemhow and after llogin, join class automatically +//if on home with classcode in url and logged in, then join class automatically +class JoinClassWithLink extends StatefulWidget { + const JoinClassWithLink({super.key}); + + @override + State createState() => _JoinClassWithLinkState(); +} + +//PTODO - show class info in field so they know they're joining the right class +class _JoinClassWithLinkState extends State { + String? classCode; + final PangeaController _pangeaController = MatrixState.pangeaController; + + @override + void initState() { + super.initState(); + + Future.delayed(Duration.zero, () { + classCode = GoRouterState.of(context) + .uri + .queryParameters[UrlQueryParameterKeys.classCode]; + + if (classCode == null) { + return ClassCodeUtil.messageDialog( + context, + L10n.of(context)!.unableToFindClassCode, + () => context.go("/rooms"), + ); + } + + if (!Matrix.of(context).client.isLogged()) { + return ClassCodeUtil.messageDialog( + context, L10n.of(context)!.pleaseLoginFirst, () async { + await _pangeaController.pStoreService.save( + PLocalKey.cachedClassCodeToJoin, + classCode, + addClientIdToKey: false, + ); + context.go("/home"); + }); + } + + _pangeaController.classController + .joinClasswithCode( + context, + classCode!, + ) + .onError( + (error, stackTrace) => ClassCodeUtil.messageSnack( + context, + ErrorCopy(context, error).body, + ), + ) + .whenComplete( + () => context.go("/rooms"), + ); + }); + } + + @override + Widget build(BuildContext context) => const EmptyPage(); +} diff --git a/lib/pangea/widgets/common/aligned_dialog.dart b/lib/pangea/widgets/common/aligned_dialog.dart new file mode 100644 index 000000000..c7bc5da59 --- /dev/null +++ b/lib/pangea/widgets/common/aligned_dialog.dart @@ -0,0 +1,206 @@ +import 'package:flutter/material.dart'; + +Future showAlignedDialog({ + required BuildContext context, + required WidgetBuilder builder, + bool barrierDismissible = true, + Color? barrierColor = Colors.black54, + String? barrierLabel, + bool useRootNavigator = true, + RouteSettings? routeSettings, + Alignment followerAnchor = Alignment.center, + Alignment targetAnchor = Alignment.center, + Size? refChildSize, + Offset offset = Offset.zero, + bool avoidOverflow = false, + bool isGlobal = false, + RouteTransitionsBuilder? transitionsBuilder, + Duration? duration, +}) { + assert(debugCheckHasMaterialLocalizations(context)); + + final CapturedThemes themes = InheritedTheme.capture( + from: context, + to: Navigator.of( + context, + rootNavigator: useRootNavigator, + ).context, + ); + + final RenderBox targetBox = context.findRenderObject()! as RenderBox; + final RenderBox overlay = + Navigator.of(context).overlay!.context.findRenderObject()! as RenderBox; + Offset position = targetBox + .localToGlobal(targetAnchor.alongSize(targetBox.size), ancestor: overlay); + + if (isGlobal) { + position = overlay.localToGlobal(followerAnchor.alongSize(overlay.size)); + } + + return Navigator.of(context, rootNavigator: useRootNavigator).push( + AlignedDialogRoute( + followerAlignment: followerAnchor, + position: position, + context: context, + builder: builder, + barrierColor: barrierColor, + barrierDismissible: barrierDismissible, + barrierLabel: barrierLabel, + useSafeArea: isGlobal == true, + settings: routeSettings, + themes: themes, + transitionsBuilder: transitionsBuilder, + duration: duration, + avoidOverflow: avoidOverflow, + offset: offset, + ), + ); +} + +class AlignedDialogRoute extends RawDialogRoute { + /// A dialog route with Material entrance and exit animations, + /// modal barrier color, and modal barrier behavior (dialog is dismissible + /// with a tap on the barrier). + AlignedDialogRoute({ + required BuildContext context, + required WidgetBuilder builder, + required Alignment followerAlignment, + required Offset position, + CapturedThemes? themes, + super.barrierColor = Colors.transparent, + super.barrierDismissible, + String? barrierLabel, + bool useSafeArea = false, + super.settings, + RouteTransitionsBuilder? transitionsBuilder, + Duration? duration, + bool avoidOverflow = false, + Offset offset = Offset.zero, + }) : super( + pageBuilder: ( + BuildContext buildContext, + Animation animation, + Animation secondaryAnimation, + ) { + final Widget pageChild = Builder(builder: builder); + Widget dialog = Builder( + builder: (BuildContext context) { + final MediaQueryData mediaQuery = MediaQuery.of(context); + return CustomSingleChildLayout( + delegate: _FollowerDialogRouteLayout( + followerAlignment, + position, + Directionality.of(context), + mediaQuery.padding.top, + mediaQuery.padding.bottom, + offset, + avoidOverflow, + ), + child: pageChild, + ); + }, + ); + dialog = themes?.wrap(dialog) ?? dialog; + if (useSafeArea) { + dialog = SafeArea(child: dialog); + } + return dialog; + }, + barrierLabel: barrierLabel ?? + MaterialLocalizations.of(context).modalBarrierDismissLabel, + transitionDuration: duration ?? const Duration(milliseconds: 200), + transitionBuilder: + transitionsBuilder ?? _buildMaterialDialogTransitions, + ); +} + +// Positioning of the menu on the screen. +class _FollowerDialogRouteLayout extends SingleChildLayoutDelegate { + _FollowerDialogRouteLayout( + this.followerAnchor, + this.position, + this.textDirection, + this.topPadding, + this.bottomPadding, + this.offset, + this.avoidOverflow, + ); + + final Alignment followerAnchor; + + final Offset position; + + final TextDirection textDirection; + + final double topPadding; + + final double bottomPadding; + + final Offset offset; + final bool avoidOverflow; + + @override + BoxConstraints getConstraintsForChild(BoxConstraints constraints) { + // The menu can be at most the size of the overlay minus 8.0 pixels in each + // direction. + return BoxConstraints.loose(constraints.biggest) + .deflate(EdgeInsets.only(top: topPadding, bottom: bottomPadding)); + } + + @override + Offset getPositionForChild(Size size, Size childSize) { + Offset rst = followerAnchor.alongSize(childSize); + rst = position - rst; + rst += offset; + if (avoidOverflow) { + if (rst.dx < 0) rst = Offset(0, rst.dy); + if (rst.dy < 0) rst = Offset(rst.dx, 0); + if (rst.dx + childSize.width > size.width) { + rst = Offset(size.width - childSize.width, rst.dy); + } + if (rst.dy + childSize.height > size.height) { + rst = Offset(rst.dx, size.height - childSize.height); + } + } + return rst; + } + + @override + bool shouldRelayout(_FollowerDialogRouteLayout oldDelegate) { + return followerAnchor != oldDelegate.followerAnchor || + position != oldDelegate.position || + offset != oldDelegate.offset || + avoidOverflow != oldDelegate.avoidOverflow || + textDirection != oldDelegate.textDirection || + topPadding != oldDelegate.topPadding || + bottomPadding != oldDelegate.bottomPadding; + } +} + +Widget _buildMaterialDialogTransitions( + BuildContext context, + Animation animation, + Animation secondaryAnimation, + Widget child, +) { + return FadeTransition( + opacity: CurvedAnimation( + parent: animation, + curve: Curves.easeOut, + ), + child: child, + ); +} + +Offset _buildOffSet( + BuildContext context, { + required Size refChildSize, + required Offset offset, +}) { + final Size screenSize = MediaQuery.of(context).size; + final Size maxAvilableArea = Size( + screenSize.width - refChildSize.width, + screenSize.height - refChildSize.height, + ); + return const Offset(0, 0); +} diff --git a/lib/pangea/widgets/common/bot_face_svg.dart b/lib/pangea/widgets/common/bot_face_svg.dart new file mode 100644 index 000000000..718f10c90 --- /dev/null +++ b/lib/pangea/widgets/common/bot_face_svg.dart @@ -0,0 +1,36 @@ +import 'package:flutter/material.dart'; + +enum BotExpression { surprised, right, addled, left, down, shocked } + +class BotFace extends StatelessWidget { + const BotFace({ + super.key, + required this.width, + required this.expression, + this.forceColor, + }); + + final double width; + final Color? forceColor; + final BotExpression expression; + + @override + Widget build(BuildContext context) { + return Image.asset( + 'assets/pangea/bot_faces/${expression.toString().split('.').last}.png', + // 'assets/pangea/bot_faces/surprised.png', + width: width, + height: width, + // color: forceColor ?? + // (Theme.of(context).brightness == Brightness.light + // ? Theme.of(context).colorScheme.primary + // : Theme.of(context).colorScheme.primary), + ); + } +} + +// extension ParseToString on BotExpressions { +// String toShortString() { +// return toString().split('.').last; +// } +// } diff --git a/lib/pangea/widgets/common/list_placeholder.dart b/lib/pangea/widgets/common/list_placeholder.dart new file mode 100644 index 000000000..4b37c08d6 --- /dev/null +++ b/lib/pangea/widgets/common/list_placeholder.dart @@ -0,0 +1,72 @@ +import 'package:flutter/material.dart'; + +class ListPlaceholder extends StatelessWidget { + static const dummyChatCount = 5; + + const ListPlaceholder({super.key}); + + @override + Widget build(BuildContext context) { + final titleColor = + Theme.of(context).textTheme.bodyLarge!.color!.withAlpha(100); + final subtitleColor = + Theme.of(context).textTheme.bodyLarge!.color!.withAlpha(50); + + return ListView.builder( + itemCount: dummyChatCount, + itemBuilder: (context, i) => Opacity( + opacity: (dummyChatCount - i) / dummyChatCount, + child: Material( + child: ListTile( + leading: CircleAvatar( + backgroundColor: titleColor, + child: CircularProgressIndicator( + strokeWidth: 1, + color: Theme.of(context).textTheme.bodyLarge!.color, + ), + ), + title: Row( + children: [ + Expanded( + child: Container( + height: 14, + decoration: BoxDecoration( + color: titleColor, + borderRadius: BorderRadius.circular(3), + ), + ), + ), + const SizedBox(width: 36), + Container( + height: 14, + width: 14, + decoration: BoxDecoration( + color: subtitleColor, + borderRadius: BorderRadius.circular(14), + ), + ), + const SizedBox(width: 12), + Container( + height: 14, + width: 14, + decoration: BoxDecoration( + color: subtitleColor, + borderRadius: BorderRadius.circular(14), + ), + ), + ], + ), + subtitle: Container( + decoration: BoxDecoration( + color: subtitleColor, + borderRadius: BorderRadius.circular(3), + ), + height: 12, + margin: const EdgeInsets.only(right: 22), + ), + ), + ), + ), + ); + } +} diff --git a/lib/pangea/widgets/common/p_circular_loader.dart b/lib/pangea/widgets/common/p_circular_loader.dart new file mode 100644 index 000000000..a5b6d0e1c --- /dev/null +++ b/lib/pangea/widgets/common/p_circular_loader.dart @@ -0,0 +1,21 @@ +import 'package:flutter/material.dart'; + +class PCircular extends StatelessWidget { + final double? size; + const PCircular({super.key, this.size}); + + @override + Widget build(BuildContext context) { + return Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + SizedBox( + height: size ?? 25, + width: size ?? 25, + child: const CircularProgressIndicator(), + ), + ], + ); + } +} diff --git a/lib/pangea/widgets/common/pangea_logo_svg.dart b/lib/pangea/widgets/common/pangea_logo_svg.dart new file mode 100644 index 000000000..485f08b65 --- /dev/null +++ b/lib/pangea/widgets/common/pangea_logo_svg.dart @@ -0,0 +1,23 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_svg/svg.dart'; + +class PangeaLogoSvg extends StatelessWidget { + const PangeaLogoSvg({super.key, required this.width, this.forceColor}); + + final double width; + final Color? forceColor; + + @override + Widget build(BuildContext context) { + return SvgPicture.asset( + 'assets/pangea/pangea_logo.svg', + width: width, + height: width, + color: forceColor ?? + (Theme.of(context).brightness == Brightness.light + ? Theme.of(context).colorScheme.primary + : Theme.of(context).colorScheme.primary), + ); + } +} diff --git a/lib/pangea/widgets/common/star_rating.dart b/lib/pangea/widgets/common/star_rating.dart new file mode 100644 index 000000000..b415ec030 --- /dev/null +++ b/lib/pangea/widgets/common/star_rating.dart @@ -0,0 +1,56 @@ +import 'package:flutter/material.dart'; + +typedef RatingChangeCallback = void Function(double rating); + +class StarRating extends StatelessWidget { + final int starCount; + final double rating; + final RatingChangeCallback? onRatingChanged; + final Color color; + + const StarRating({ + super.key, + this.starCount = 5, + this.rating = 0, + this.onRatingChanged, + required this.color, + }); + + Widget buildStar(BuildContext context, int index) { + Icon icon; + if (index >= rating) { + icon = const Icon( + Icons.star_border, + size: 20, + color: Color(0xffFFC403), + ); + } else if (index > rating - 1 && index < rating) { + icon = Icon( + Icons.star_half, + color: color, + //?? Theme.of(context).primaryColor, + size: 20, + ); + } else { + icon = Icon( + Icons.star, + color: color, + //?? Theme.of(context).primaryColor, + size: 20, + ); + } + return InkResponse( + onTap: + onRatingChanged == null ? null : () => onRatingChanged!(index + 1.0), + child: icon, + ); + } + + @override + Widget build(BuildContext context) { + return Row( + mainAxisSize: MainAxisSize.min, + children: List.generate(starCount, (index) => buildStar(context, index)), + ); + } +} diff --git a/lib/pangea/widgets/common/switch_list_tile.dart b/lib/pangea/widgets/common/switch_list_tile.dart new file mode 100644 index 000000000..594a61e9d --- /dev/null +++ b/lib/pangea/widgets/common/switch_list_tile.dart @@ -0,0 +1,28 @@ +// import 'package:flutter/material.dart'; + +// import '../../../config/app_config.dart'; + +// class PSwitchListTile extends StatelessWidget { +// final String title; +// final String subtitle; +// final bool value; +// final Function(bool value) onChanged; +// const PSwitchListTile( +// {Key? key, +// required this.title, +// required this.subtitle, +// required this.value, +// required this.onChanged}) +// : super(key: key); + +// @override +// Widget build(BuildContext context) { +// return SwitchListTile.adaptive( +// activeColor: AppConfig.activeToggleColor, +// title: Text(title), +// subtitle: Text(subtitle), +// value: value, +// onChanged: onChanged, +// ); +// } +// } diff --git a/lib/pangea/widgets/common_widgets/edit_list_tile.dart b/lib/pangea/widgets/common_widgets/edit_list_tile.dart new file mode 100644 index 000000000..38d1db883 --- /dev/null +++ b/lib/pangea/widgets/common_widgets/edit_list_tile.dart @@ -0,0 +1,48 @@ +import 'package:flutter/material.dart'; + +import '../../../widgets/avatar.dart'; + +class EditClassListTile extends StatefulWidget { + String title = ''; + Function() onTap; + String subtitle = ""; + EditClassListTile({ + super.key, + required this.title, + required this.onTap, + required this.subtitle, + }); + + @override + State createState() => _EditClassListTileState(); +} + +class _EditClassListTileState extends State { + @override + Widget build(BuildContext context) { + final iconColor = Theme.of(context).textTheme.bodyLarge!.color; + return ListTile( + leading: CircleAvatar( + backgroundColor: Theme.of(context).scaffoldBackgroundColor, + foregroundColor: iconColor, + radius: Avatar.defaultSize / 2, + child: const Icon(Icons.edit_outlined), + ), + title: Text( + '${widget.title}:', + style: TextStyle( + color: Theme.of(context).colorScheme.secondary, + fontWeight: FontWeight.bold, + ), + ), + subtitle: Text( + widget.subtitle, + style: TextStyle( + fontSize: 14, + color: Theme.of(context).textTheme.bodyMedium!.color, + ), + ), + onTap: widget.onTap, + ); + } +} diff --git a/lib/pangea/widgets/common_widgets/overlay_container.dart b/lib/pangea/widgets/common_widgets/overlay_container.dart new file mode 100644 index 000000000..4fc64fb3d --- /dev/null +++ b/lib/pangea/widgets/common_widgets/overlay_container.dart @@ -0,0 +1,41 @@ +import 'package:flutter/material.dart'; + +class OverlayContainer extends StatelessWidget { + final Widget cardToShow; + final Size cardSize; + final Color? borderColor; + + const OverlayContainer({ + super.key, + required this.cardToShow, + this.cardSize = const Size(300.0, 300.0), + this.borderColor, + }); + + @override + Widget build(BuildContext context) { + return Container( + padding: const EdgeInsets.fromLTRB(10, 10, 10, 10), + decoration: BoxDecoration( + color: Theme.of(context).cardColor, + // color: Colors.purple, + border: Border.all( + width: 2, + color: borderColor ?? Theme.of(context).colorScheme.primary, + ), + borderRadius: const BorderRadius.all( + Radius.circular(25), + ), + ), + constraints: BoxConstraints( + maxWidth: cardSize.width, + maxHeight: cardSize.height, + minWidth: cardSize.width, + minHeight: cardSize.height, + ), + //PTODO - position card above input/message + // margin: const EdgeInsets.all(10), + child: cardToShow, + ); + } +} diff --git a/lib/pangea/widgets/common_widgets/p_input_field.dart b/lib/pangea/widgets/common_widgets/p_input_field.dart new file mode 100644 index 000000000..10898615b --- /dev/null +++ b/lib/pangea/widgets/common_widgets/p_input_field.dart @@ -0,0 +1,34 @@ +import 'package:flutter/material.dart'; + +class PInputTextField extends StatelessWidget { + TextEditingController controller; + Function(String) onSubmit; + String labelText; + String hintText; + PInputTextField({ + super.key, + required this.controller, + required this.onSubmit, + required this.labelText, + required this.hintText, + }); + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.all(12.0), + child: TextField( + controller: controller, + autofocus: true, + autocorrect: false, + textInputAction: TextInputAction.go, + onSubmitted: onSubmit, + decoration: InputDecoration( + labelText: labelText, + prefixIcon: const Icon(Icons.people_outlined), + hintText: hintText, + ), + ), + ); + } +} diff --git a/lib/pangea/widgets/flag.dart b/lib/pangea/widgets/flag.dart new file mode 100644 index 000000000..08327530d --- /dev/null +++ b/lib/pangea/widgets/flag.dart @@ -0,0 +1,54 @@ +import 'package:flutter/material.dart'; + +import 'package:fluffychat/widgets/avatar.dart'; +import '../models/language_model.dart'; + +class LanguageFlag extends StatelessWidget { + final LanguageModel? language; + final double size; + const LanguageFlag({ + super.key, + required this.language, + this.size = 30, + }); + + @override + Widget build(BuildContext context) { + return Avatar( + name: language?.langCode, + size: size, + ); + + // return Center( + // child: Container( + // decoration: BoxDecoration( + // borderRadius: BorderRadius.circular(size / 2), + // boxShadow: [ + // BoxShadow( + // color: Colors.grey.withOpacity(0.2), + // spreadRadius: 1, + // blurRadius: 15, + // offset: const Offset(0, 4), // changes position of shadow + // ), + // ], + // ), + // child: ClipRRect( + // borderRadius: BorderRadius.circular(50), + // child: SizedBox( + // height: size, + // width: size, + // child: language?.languageFlag != null + // ? language!.languageFlag.contains("media/flags") + // ? Image.network(language!.languageFlag) + // : Image.asset( + // language!.languageFlag, + // width: size, + // height: size, + // ) + // : const SizedBox.expand(), + // ), + // ), + // ), + // ); + } +} diff --git a/lib/pangea/widgets/igc/card_error_widget.dart b/lib/pangea/widgets/igc/card_error_widget.dart new file mode 100644 index 000000000..8c546c7f6 --- /dev/null +++ b/lib/pangea/widgets/igc/card_error_widget.dart @@ -0,0 +1,48 @@ +import 'package:flutter/material.dart'; + +import 'package:fluffychat/pangea/choreographer/controllers/choreographer.dart'; +import 'package:fluffychat/pangea/utils/bot_style.dart'; +import 'package:fluffychat/pangea/utils/error_handler.dart'; +import 'package:fluffychat/pangea/widgets/common/bot_face_svg.dart'; +import 'package:fluffychat/pangea/widgets/igc/card_header.dart'; + +class CardErrorWidget extends StatelessWidget { + final Object? error; + final Choreographer? choreographer; + final int? offset; + const CardErrorWidget({ + super.key, + this.error, + this.choreographer, + this.offset, + }); + + @override + Widget build(BuildContext context) { + final ErrorCopy errorCopy = ErrorCopy(context, error); + + return SingleChildScrollView( + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + CardHeader( + text: errorCopy.title, + botExpression: BotExpression.addled, + onClose: () => choreographer != null + ? choreographer!.onMatchError( + cursorOffset: offset, + ) + : null, + ), + const SizedBox(height: 10.0), + Center( + child: Text( + errorCopy.body, + style: BotStyle.text(context), + ), + ), + ], + ), + ); + } +} diff --git a/lib/pangea/widgets/igc/card_header.dart b/lib/pangea/widgets/igc/card_header.dart new file mode 100644 index 000000000..5ee6b98f2 --- /dev/null +++ b/lib/pangea/widgets/igc/card_header.dart @@ -0,0 +1,60 @@ +import 'package:flutter/material.dart'; + +import 'package:fluffychat/config/app_config.dart'; +import '../../../widgets/matrix.dart'; +import '../../utils/bot_style.dart'; +import '../common/bot_face_svg.dart'; + +class CardHeader extends StatelessWidget { + const CardHeader({ + super.key, + required this.text, + required this.botExpression, + this.onClose, + }); + + final BotExpression botExpression; + final String text; + final void Function()? onClose; + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.only(bottom: 5.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Padding( + padding: const EdgeInsets.only(top: 3.0), + child: BotFace( + width: 50.0, + expression: botExpression, + ), + ), + const SizedBox(width: 5.0), + Expanded( + child: Text( + text, + style: BotStyle.text(context), + textAlign: TextAlign.left, + ), + ), + CircleAvatar( + backgroundColor: AppConfig.primaryColor.withOpacity(0.1), + child: IconButton( + icon: const Icon(Icons.close_outlined), + onPressed: () { + if (onClose != null) onClose!(); + MatrixState.pAnyState.closeOverlay(); + }, + color: Theme.of(context).brightness == Brightness.dark + ? AppConfig.primaryColorLight + : AppConfig.primaryColor, + ), + ), + ], + ), + ); + } +} diff --git a/lib/pangea/widgets/igc/pangea_rich_text.dart b/lib/pangea/widgets/igc/pangea_rich_text.dart new file mode 100644 index 000000000..746c65cc2 --- /dev/null +++ b/lib/pangea/widgets/igc/pangea_rich_text.dart @@ -0,0 +1,261 @@ +import 'dart:developer'; +import 'dart:ui'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + +import 'package:sentry_flutter/sentry_flutter.dart'; + +import 'package:fluffychat/config/app_config.dart'; +import 'package:fluffychat/pangea/choreographer/controllers/choreographer.dart'; +import 'package:fluffychat/pangea/constants/language_keys.dart'; +import 'package:fluffychat/pangea/controllers/pangea_controller.dart'; +import 'package:fluffychat/pangea/models/language_model.dart'; +import 'package:fluffychat/pangea/models/pangea_message_event.dart'; +import 'package:fluffychat/pangea/utils/error_handler.dart'; +import 'package:fluffychat/widgets/matrix.dart'; +import '../../models/igc_text_data_model.dart'; +import '../../models/language_detection_model.dart'; +import '../../models/pangea_match_model.dart'; +import '../../models/pangea_representation_event.dart'; +import '../../utils/bot_style.dart'; +import '../../utils/instructions.dart'; + +class PangeaRichText extends StatefulWidget { + final PangeaMessageEvent pangeaMessageEvent; + final TextStyle? existingStyle; + final bool selected; + final LanguageModel? selectedDisplayLang; + final bool immersionMode; + final bool definitions; + final Choreographer? choreographer; + + const PangeaRichText({ + super.key, + required this.pangeaMessageEvent, + required this.selected, + required this.selectedDisplayLang, + required this.immersionMode, + required this.definitions, + this.choreographer, + this.existingStyle, + }); + + @override + PangeaRichTextState createState() => PangeaRichTextState(); +} + +class PangeaRichTextState extends State { + final PangeaController pangeaController = MatrixState.pangeaController; + bool _fetchingRepresentation = false; + bool _fetchingTokens = false; + double get blur => _fetchingRepresentation && widget.immersionMode ? 5 : 0; + List textSpan = []; + + @override + void initState() { + super.initState(); + setState(() => textSpan = getTextSpan(context)); + } + + @override + void didUpdateWidget(PangeaRichText oldWidget) { + super.didUpdateWidget(oldWidget); + setState(() => textSpan = getTextSpan(context)); + } + + @override + Widget build(BuildContext context) { + //TODO - take out of build function of every message + // if (areLanguagesSet) { + + if (!widget.selected && + widget.selectedDisplayLang != null && + widget.selectedDisplayLang!.langCode != LanguageKeys.unknownLanguage) { + pangeaController.instructions.show( + context, + InstructionsEnum.clickMessage, + widget.pangeaMessageEvent.eventId, + ); + } else if (blur > 0) { + pangeaController.instructions.show( + context, + InstructionsEnum.blurMeansTranslate, + widget.pangeaMessageEvent.eventId, + ); + } + + final Widget richText = RichText( + text: TextSpan( + children: [ + ...textSpan, + if (widget.selected && (_fetchingRepresentation || _fetchingTokens)) + // if (widget.selected) + const WidgetSpan( + child: Padding( + padding: EdgeInsets.only(left: 5.0), + child: SizedBox( + height: 14, + width: 14, + child: CircularProgressIndicator( + strokeWidth: 2.0, + color: AppConfig.secondaryColor, + ), + ), + ), + ), + ], + ), + ); + + return blur > 0 + ? ImageFiltered( + imageFilter: ImageFilter.blur(sigmaX: blur, sigmaY: blur), + child: richText, + ) + : richText; + } + + List getTextSpan(BuildContext context) { + final String? displayLangCode = + widget.selected ? widget.selectedDisplayLang?.langCode : userL2LangCode; + + if (displayLangCode == null || !widget.immersionMode) { + return simpleText(widget.pangeaMessageEvent.body); + } + + if (widget.pangeaMessageEvent.eventId.contains("webdebug")) { + debugger(when: kDebugMode); + return simpleText(widget.pangeaMessageEvent.body); + } + + final RepresentationEvent? repEvent = + widget.pangeaMessageEvent.representationByLanguage( + displayLangCode, + ); + + if (repEvent == null) { + _fetchingRepresentation = true; + + setState(() => {}); + widget.pangeaMessageEvent + .representationByLanguageGlobal( + context: context, + langCode: displayLangCode, + ) + .onError((error, stackTrace) => ErrorHandler.logError()) + .whenComplete(() => setState(() => _fetchingRepresentation = false)); + return simpleText(widget.pangeaMessageEvent.body); + } + + if (repEvent.event?.eventId.contains("web") ?? false) { + Sentry.addBreadcrumb( + Breadcrumb.fromJson({"repEvent.event": repEvent.event?.toJson()}), + ); + Sentry.addBreadcrumb( + Breadcrumb( + message: + "representationByLanguageGlobal returned RepEvent with event ID containing 'web' - ${repEvent.event?.eventId}", + ), + ); + // debugger(when: kDebugMode); + return textWithBotStyle(repEvent, context); + } + + if (!widget.selected || + displayLangCode != userL2LangCode || + !widget.definitions) { + return textWithBotStyle(repEvent, context); + } + + if (repEvent.tokens == null) { + setState(() => _fetchingTokens = true); + repEvent + .tokensGlobal(context) + .onError((error, stackTrace) => ErrorHandler.logError()) + .whenComplete(() => setState(() => _fetchingTokens = false)); + + return textWithBotStyle(repEvent, context); + } + + return IGCTextData( + originalInput: repEvent.text, + fullTextCorrection: repEvent.text, + matches: [], + detections: [LanguageDetection(langCode: displayLangCode)], + tokens: repEvent.tokens!, + enableIT: true, + enableIGC: true, + userL2: userL2LangCode ?? LanguageKeys.unknownLanguage, + userL1: userL1LangCode ?? LanguageKeys.unknownLanguage, + ).constructTokenSpan( + context: context, + defaultStyle: textStyle(repEvent, context), + handleClick: true, + spanCardModel: null, + showTokens: widget.definitions, + transformTargetId: widget.pangeaMessageEvent.eventId, + room: widget.pangeaMessageEvent.room, + ); + } + + List simpleText(String text) => [ + TextSpan( + text: text, + style: widget.existingStyle, + ), + ]; + + List textWithBotStyle( + RepresentationEvent repEvent, + BuildContext context, + ) => + [ + TextSpan( + text: repEvent.text, + style: textStyle(repEvent, context), + ), + ]; + + TextStyle? textStyle(RepresentationEvent repEvent, BuildContext context) => + // !repEvent.botAuthored + true + ? widget.existingStyle + : BotStyle.text( + context, + existingStyle: widget.existingStyle, + setColor: false, + ); + + bool get areLanguagesSet => + userL2LangCode != null && userL2LangCode != LanguageKeys.unknownLanguage; + + String? get userL2LangCode => + pangeaController.languageController.activeL2Code( + roomID: widget.pangeaMessageEvent.room.id, + ); + + String? get userL1LangCode => + pangeaController.languageController.activeL1Code( + roomID: widget.pangeaMessageEvent.room.id, + ); + + Future onIgnore() async { + debugPrint("PTODO implement onIgnore"); + } + + Future onITStart() async { + debugPrint("PTODO implement onITStart"); + } + + Future onReplacementSelect( + PangeaMatch pangeaMatch, + String replacement, + ) async { + debugPrint("PTODO implement onReplacementSelect"); + } + + Future onSentenceRewrite(String sentenceRewrite) async { + debugPrint("PTODO implement onSentenceRewrite"); + } +} diff --git a/lib/pangea/widgets/igc/pangea_text_controller.dart b/lib/pangea/widgets/igc/pangea_text_controller.dart new file mode 100644 index 000000000..5e64b4bef --- /dev/null +++ b/lib/pangea/widgets/igc/pangea_text_controller.dart @@ -0,0 +1,153 @@ +import 'dart:developer'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + +import 'package:fluffychat/pangea/widgets/igc/span_card.dart'; +import 'package:fluffychat/pangea/widgets/igc/word_data_card.dart'; +import '../../choreographer/controllers/choreographer.dart'; +import '../../enum/edit_type.dart'; +import '../../models/pangea_token_model.dart'; +import '../../models/span_card_model.dart'; +import '../../models/widget_measurement.dart'; +import '../../utils/overlay.dart'; + +class PangeaTextController extends TextEditingController { + Choreographer choreographer; + + EditType editType = EditType.keyboard; + WidgetMeasurements? measurements; + PangeaTextController({ + String? text, + required this.choreographer, + }) { + text ??= ''; + this.text = text; + } + bool forceKeepOpen = false; + + setSystemText(String text, EditType type) { + editType = type; + this.text = text; + } + + void onBarSizeChange(Size? size, Offset? position, String? uid) { + measurements = WidgetMeasurements(position: position, size: size, uid: uid); + } + + void onInputTap(BuildContext context, {required FocusNode fNode}) { + fNode.requestFocus(); + forceKeepOpen = true; + if (!context.mounted) { + debugger(when: kDebugMode); + return; + } + if (choreographer.igc.igcTextData == null) return; + + // debugPrint( + // "onInputTap matches are ${choreographer.igc.igcTextData?.matches.map((e) => e.match.rule.id).toList().toString()}"); + + final int tokenIndex = choreographer.igc.igcTextData!.tokenIndexByOffset( + selection.baseOffset, + ); + + if (tokenIndex == -1) return; + + final PangeaToken token = choreographer.igc.igcTextData!.tokens[tokenIndex]; + final int matchIndex = + choreographer.igc.igcTextData!.getTopMatchIndexForOffset( + selection.baseOffset, + ); + final Widget cardToShow = matchIndex != -1 + ? SpanCard( + scm: SpanCardModel( + // igcTextData: choreographer.igc.igcTextData!, + matchIndex: matchIndex, + onReplacementSelect: choreographer.onReplacementSelect, + // may not need this + onSentenceRewrite: ((sentenceRewrite) async { + debugPrint("onSentenceRewrite $tokenIndex $sentenceRewrite"); + }), + onIgnore: () => choreographer.onIgnoreMatch( + cursorOffset: selection.baseOffset, + ), + onITStart: () { + choreographer.onITStart( + choreographer.igc.igcTextData!.matches[matchIndex], + ); + }, + choreographer: choreographer, + ), + roomId: choreographer.roomId, + ) + : WordDataCard( + fullText: text, + fullTextLang: + choreographer.igc.igcTextData!.detections.first.langCode, + word: token.text.content, + //Note: this assumes that the token must be in the target language + //since it didn't have a match + wordLang: choreographer.itController.targetLangCode, + hasInfo: token.hasInfo, + room: choreographer.chatController.room, + ); + + OverlayUtil.showPositionedCard( + context: context, + cardSize: matchIndex != -1 && + choreographer.igc.igcTextData!.matches[matchIndex].isITStart + ? const Size(350, 220) + : const Size(350, 400), + cardToShow: cardToShow, + transformTargetId: choreographer.inputTransformTargetKey, + ); + } + + @override + TextSpan buildTextSpan({ + required BuildContext context, + TextStyle? style, + required bool withComposing, + }) { + // If the composing range is out of range for the current text, ignore it to + // preserve the tree integrity, otherwise in release mode a RangeError will + // be thrown and this EditableText will be built with a broken subtree. + // debugPrint("composing? $withComposing"); + // if (!value.isComposingRangeValid || !withComposing) { + // debugPrint("just returning straight text"); + // // debugger(when: kDebugMode); + // return TextSpan(style: style, text: text); + // } + // if (value.isComposingRangeValid) { + // debugPrint("composing before ${value.composing.textBefore(value.text)}"); + // debugPrint("composing inside ${value.composing.textInside(value.text)}"); + // debugPrint("composing after ${value.composing.textAfter(value.text)}"); + // } + + if (choreographer.igc.igcTextData == null || text.isEmpty) { + return TextSpan(text: text, style: style); + } else { + final parts = text.split(choreographer.igc.igcTextData!.originalInput); + + if (parts.length == 1 || parts.length > 2) { + return TextSpan(text: text, style: style); + } + + return TextSpan( + style: style, + children: [ + ...choreographer.igc.igcTextData!.constructTokenSpan( + context: context, + defaultStyle: style, + showTokens: choreographer.definitionsEnabled, + spanCardModel: null, + handleClick: false, + transformTargetId: choreographer.inputTransformTargetKey, + room: choreographer.chatController.room, + ), + TextSpan(text: parts[1], style: style), + ], + ); + } + } +} diff --git a/lib/pangea/widgets/igc/span_card.dart b/lib/pangea/widgets/igc/span_card.dart new file mode 100644 index 000000000..a060ed2e1 --- /dev/null +++ b/lib/pangea/widgets/igc/span_card.dart @@ -0,0 +1,430 @@ +import 'dart:developer'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; + +import 'package:fluffychat/config/app_config.dart'; +import 'package:fluffychat/pangea/enum/span_data_type.dart'; +import 'package:fluffychat/pangea/models/span_data.dart'; +import 'package:fluffychat/pangea/utils/bot_style.dart'; +import 'package:fluffychat/pangea/utils/error_handler.dart'; +import 'package:fluffychat/pangea/utils/match_copy.dart'; +import 'package:fluffychat/pangea/widgets/igc/card_error_widget.dart'; +import '../../../widgets/matrix.dart'; +import '../../choreographer/widgets/choice_array.dart'; +import '../../controllers/pangea_controller.dart'; +import '../../enum/span_choice_type.dart'; +import '../../models/span_card_model.dart'; +import '../common/bot_face_svg.dart'; +import 'card_header.dart'; + +const wordMatchResultsCount = 5; + +//switch for definition vs correction vs practice + +//always show a title +//if description then show description +//choices then show choices +// + +class SpanCard extends StatefulWidget { + final PangeaController pangeaController = MatrixState.pangeaController; + final SpanCardModel scm; + final String? roomId; + + SpanCard({ + super.key, + required this.scm, + this.roomId, + }); + + @override + State createState() => SpanCardState(); +} + +class SpanCardState extends State { + Object? error; + bool fetchingData = false; + int? selectedChoiceIndex; + + //on initState, get SpanDetails + @override + void initState() { + // debugger(when: kDebugMode); + super.initState(); + getSpanDetails(); + } + + //get selected choice + SpanChoice? get selectedChoice => selectedChoiceIndex != null && + widget.scm.pangeaMatch?.match.choices != null + ? widget.scm.pangeaMatch!.match.choices![selectedChoiceIndex!] + : null; + + Future getSpanDetails() async { + try { + if (widget.scm.pangeaMatch?.isITStart ?? false) return; + setState(() { + fetchingData = true; + }); + + await widget.scm.choreographer.igc.getSpanDetails(widget.scm.matchIndex); + + setState(() => fetchingData = false); + } catch (e) { + // debugger(when: kDebugMode); + ErrorHandler.logError(e: e, s: StackTrace.current); + setState(() { + error = e; + fetchingData = false; + }); + } + } + + @override + Widget build(BuildContext context) { + return WordMatchContent(controller: this); + } +} + +class WordMatchContent extends StatelessWidget { + final PangeaController pangeaController = MatrixState.pangeaController; + final SpanCardState controller; + + WordMatchContent({ + required this.controller, + super.key, + }); + + Future onChoiceSelect(int index) async { + controller.selectedChoiceIndex = index; + controller + .widget + .scm + .choreographer + .igc + .igcTextData! + .matches[controller.widget.scm.matchIndex] + .match + .choices![index] + .selected = true; + + controller.setState(() => ()); + // if (controller.widget.scm.pangeaMatch.match.choices![index].type == + // SpanChoiceType.distractor) { + // await controller.getSpanDetails(); + // } + // controller.setState(() {}); + } + + void onReplaceSelected() { + controller.widget.scm + .onReplacementSelect( + matchIndex: controller.widget.scm.matchIndex, + choiceIndex: controller.selectedChoiceIndex!, + ) + .then((value) { + controller.setState(() {}); + }); + } + + @override + Widget build(BuildContext context) { + if (controller.widget.scm.pangeaMatch == null) { + return const SizedBox(); + } + if (controller.error != null) { + return CardErrorWidget( + error: controller.error!, + choreographer: controller.widget.scm.choreographer, + offset: controller.widget.scm.pangeaMatch?.match.offset, + ); + } + final MatchCopy matchCopy = MatchCopy( + context, + controller.widget.scm.pangeaMatch!, + ); + + final ScrollController scrollController = ScrollController(); + + try { + return Column( + children: [ + CardHeader( + text: controller.error?.toString() ?? matchCopy.title, + botExpression: controller.error == null + ? BotExpression.right + : BotExpression.addled, + ), + Expanded( + child: Scrollbar( + controller: scrollController, + thumbVisibility: true, + child: SingleChildScrollView( + controller: scrollController, + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + // const SizedBox(height: 10.0), + // if (matchCopy.description != null) + // Padding( + // padding: const EdgeInsets.only(), + // child: Text( + // matchCopy.description!, + // style: BotStyle.text(context), + // ), + // ), + const SizedBox(height: 8), + if (!controller.widget.scm.pangeaMatch!.isITStart) + ChoicesArray( + originalSpan: + controller.widget.scm.pangeaMatch!.matchContent, + isLoading: controller.fetchingData, + choices: + controller.widget.scm.pangeaMatch!.match.choices + ?.map( + (e) => Choice( + text: e.value, + color: e.selected ? e.type.color : null, + ), + ) + .toList(), + onPressed: onChoiceSelect, + uniqueKeyForLayerLink: (int index) => "wordMatch$index", + selectedChoiceIndex: controller.selectedChoiceIndex, + ), + const SizedBox(height: 12), + PromptAndFeedback(controller: controller), + ], + ), + ), + ), + ), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + const SizedBox(width: 10), + Expanded( + child: Opacity( + opacity: 0.8, + child: TextButton( + style: ButtonStyle( + backgroundColor: MaterialStateProperty.all( + AppConfig.primaryColor.withOpacity(0.1), + ), + ), + onPressed: () { + MatrixState.pAnyState.closeOverlay(); + Future.delayed( + Duration.zero, + () => controller.widget.scm.onIgnore(), + ); + }, + child: Center( + child: Text(L10n.of(context)!.ignoreInThisText), + ), + ), + ), + ), + const SizedBox(width: 10), + if (!controller.widget.scm.pangeaMatch!.isITStart) + Expanded( + child: Opacity( + opacity: controller.selectedChoiceIndex != null ? 1.0 : 0.5, + child: TextButton( + onPressed: controller.selectedChoiceIndex != null + ? onReplaceSelected + : null, + style: ButtonStyle( + backgroundColor: MaterialStateProperty.all( + (controller.selectedChoice != null + ? controller.selectedChoice!.color + : AppConfig.primaryColor) + .withOpacity(0.2), + ), + ), + child: Text(L10n.of(context)!.replace), + ), + ), + ), + const SizedBox(width: 10), + if (controller.widget.scm.pangeaMatch!.isITStart) + Expanded( + child: TextButton( + onPressed: () { + MatrixState.pAnyState.closeOverlay(); + Future.delayed( + Duration.zero, + () => controller.widget.scm.onITStart(), + ); + }, + style: ButtonStyle( + backgroundColor: MaterialStateProperty.all( + (AppConfig.primaryColor).withOpacity(0.1), + ), + ), + child: Text(L10n.of(context)!.helpMeTranslate), + ), + ), + ], + ), + ], + ); + } on Exception catch (e) { + debugger(when: kDebugMode); + ErrorHandler.logError(e: e, s: StackTrace.current); + print(e); + rethrow; + } + } +} + +class PromptAndFeedback extends StatelessWidget { + const PromptAndFeedback({ + super.key, + required this.controller, + }); + + final SpanCardState controller; + + @override + Widget build(BuildContext context) { + return Container( + constraints: controller.widget.scm.pangeaMatch!.isITStart + ? null + : const BoxConstraints(minHeight: 100), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + if (controller.selectedChoice == null && controller.fetchingData) + const Center( + child: SizedBox( + width: 24.0, + height: 24.0, + child: CircularProgressIndicator(), + ), + ), + if (controller.selectedChoice != null) ...[ + Text( + controller.selectedChoice!.feedbackToDisplay(context), + style: BotStyle.text(context), + ), + const SizedBox(height: 8), + if (controller.selectedChoice?.feedback == null) + TextButton( + onPressed: () { + if (!controller.fetchingData) { + controller.getSpanDetails(); + } + }, + style: ButtonStyle( + backgroundColor: MaterialStateProperty.all( + AppConfig.primaryColor.withOpacity(0.1), + ), + ), + child: SizedBox( + width: 150, // set the width of the button contents here + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + if (!controller.fetchingData) + const Icon(Icons.lightbulb_outline), + if (controller.fetchingData) + const Center( + child: SizedBox( + width: 24.0, + height: 24.0, + child: CircularProgressIndicator(), + ), + ), + const SizedBox(width: 8), + Text(L10n.of(context)!.why), + ], + ), + ), + ), + ], + if (!controller.fetchingData && + controller.selectedChoiceIndex == null) + Text( + controller.widget.scm.pangeaMatch!.match.type.typeName + .defaultPrompt(context), + style: BotStyle.text(context), + ), + ], + ), + ); + } +} + +class LoadingText extends StatefulWidget { + const LoadingText({ + super.key, + }); + + @override + _LoadingTextState createState() => _LoadingTextState(); +} + +class _LoadingTextState extends State + with SingleTickerProviderStateMixin { + late final AnimationController _controller = AnimationController( + duration: const Duration(seconds: 1), + vsync: this, + )..repeat(); + + @override + Widget build(BuildContext context) { + return Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + L10n.of(context)!.makingActivity, + style: BotStyle.text(context), + ), + AnimatedBuilder( + animation: _controller, + builder: (BuildContext context, Widget? child) { + return Text( + _controller.isAnimating ? '.' * _controller.value.toInt() : '', + style: BotStyle.text(context), + ); + }, + ), + ], + ); + } + + @override + void dispose() { + _controller.dispose(); + super.dispose(); + } +} + +class StartITButton extends StatelessWidget { + const StartITButton({ + super.key, + required this.onITStart, + }); + + final void Function() onITStart; + + @override + Widget build(BuildContext context) { + return Material( + type: MaterialType.transparency, + child: ListTile( + leading: const Icon(Icons.translate_outlined), + title: Text(L10n.of(context)!.helpMeTranslate), + onTap: () { + MatrixState.pAnyState.closeOverlay(); + Future.delayed(Duration.zero, () => onITStart()); + }, + ), + ); + } +} diff --git a/lib/pangea/widgets/igc/span_data.dart b/lib/pangea/widgets/igc/span_data.dart new file mode 100644 index 000000000..a92f32f74 --- /dev/null +++ b/lib/pangea/widgets/igc/span_data.dart @@ -0,0 +1,184 @@ +//Possible actions/effects from cards +// Nothing +// useType of viewed definitions +// SpanChoice of text in message from options +// Call to server for additional/followup info + +import 'package:collection/collection.dart'; + +import '../../enum/span_data_type.dart'; + +class SpanData { + String? message; + String? shortMessage; + List? choices; + List? replacements; + int offset; + int length; + String fullText; + Context? context; + SpanDataTypeEnum type; + Rule? rule; + + SpanData({ + this.message, + this.shortMessage, + this.choices, + this.replacements, + required this.offset, + required this.length, + required this.fullText, + this.context, + required this.type, + this.rule, + }); + + factory SpanData.fromJson(Map json) { + return SpanData( + message: json['message'], + shortMessage: json['shortMessage'], + choices: json['choices'] != null + ? List.from( + json['choices'].map((x) => SpanChoice.fromJson(x)), + ) + : null, + replacements: json['replacements'] != null + ? List.from( + json['replacements'].map((x) => Replacement.fromJson(x)), + ) + : null, + offset: json['offset'], + length: json['length'], + fullText: json['full_text'], + context: + json['context'] != null ? Context.fromJson(json['context']) : null, + type: SpanDataTypeEnum.values.firstWhereOrNull( + (e) => e.toString() == 'SpanDataTypeEnum.${json['type']}', + ) ?? + SpanDataTypeEnum.correction, + rule: json['rule'] != null ? Rule.fromJson(json['rule']) : null, + ); + } + + Map toJson() { + final Map data = {}; + data['message'] = message; + data['shortMessage'] = shortMessage; + if (choices != null) { + data['choices'] = choices!.map((x) => x.toJson()).toList(); + } + if (replacements != null) { + data['replacements'] = replacements!.map((x) => x.toJson()).toList(); + } + data['offset'] = offset; + data['length'] = length; + data['full_text'] = fullText; + if (context != null) { + data['context'] = context!.toJson(); + } + data['type'] = type.toString().split('.').last; + if (rule != null) { + data['rule'] = rule!.toJson(); + } + return data; + } +} + +class Context { + String sentence; + int offset; + int length; + + Context({required this.sentence, required this.offset, required this.length}); + + factory Context.fromJson(Map json) { + return Context( + sentence: json['sentence'], + offset: json['offset'], + length: json['length'], + ); + } + + Map toJson() { + final Map data = {}; + data['sentence'] = sentence; + data['offset'] = offset; + data['length'] = length; + return data; + } +} + +class SpanChoice { + String value; + bool selected; + + SpanChoice({required this.value, required this.selected}); + + factory SpanChoice.fromJson(Map json) { + return SpanChoice( + value: json['value'], + selected: json['selected'], + ); + } + + Map toJson() { + final Map data = {}; + data['value'] = value; + data['selected'] = selected; + return data; + } +} + +class Replacement { + String value; + + Replacement({required this.value}); + + factory Replacement.fromJson(Map json) { + return Replacement( + value: json['value'], + ); + } + + Map toJson() { + final Map data = {}; + data['value'] = value; + return data; + } +} + +class Rule { + String id; + + Rule({required this.id}); + + factory Rule.fromJson(Map json) { + return Rule( + id: json['id'], + ); + } + + Map toJson() { + final Map data = {}; + data['id'] = id; + return data; + } +} + +class SpanDataType { + String type; + + SpanDataType({required this.type}); + + factory SpanDataType.fromJson(Map json) { + return SpanDataType( + type: json['type'], + ); + } + + Map toJson() { + final Map data = {}; + data['type'] = type; + return data; + } +} diff --git a/lib/pangea/widgets/igc/word_data_card.dart b/lib/pangea/widgets/igc/word_data_card.dart new file mode 100644 index 000000000..8c1940aae --- /dev/null +++ b/lib/pangea/widgets/igc/word_data_card.dart @@ -0,0 +1,371 @@ +import 'dart:developer'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:http/http.dart'; +import 'package:matrix/matrix.dart'; + +import 'package:fluffychat/pangea/constants/language_keys.dart'; +import 'package:fluffychat/pangea/controllers/contextual_definition_controller.dart'; +import 'package:fluffychat/pangea/controllers/pangea_controller.dart'; +import 'package:fluffychat/pangea/models/language_model.dart'; +import 'package:fluffychat/pangea/utils/bot_style.dart'; +import 'package:fluffychat/pangea/utils/error_handler.dart'; +import 'package:fluffychat/pangea/utils/firebase_analytics.dart'; +import 'package:fluffychat/pangea/widgets/common/bot_face_svg.dart'; +import 'package:fluffychat/pangea/widgets/common/p_circular_loader.dart'; +import 'package:fluffychat/pangea/widgets/igc/card_header.dart'; +import 'package:fluffychat/widgets/matrix.dart'; +import '../../models/word_data_model.dart'; +import '../flag.dart'; +import 'card_error_widget.dart'; + +class WordDataCard extends StatefulWidget { + final bool hasInfo; + final String word; + final String fullText; + final String? choiceFeedback; + final String wordLang; + final String fullTextLang; + final Room room; + + const WordDataCard({ + super.key, + required this.word, + required this.wordLang, + required this.hasInfo, + required this.fullText, + required this.fullTextLang, + required this.room, + this.choiceFeedback, + }); + + @override + State createState() => WordDataCardController(); +} + +class WordDataCardController extends State { + final PangeaController controller = MatrixState.pangeaController; + + bool isLoadingWordNet = false; + bool isLoadingContextualDefinition = false; + ContextualDefinitionResponseModel? contextualDefinitionRes; + WordData? wordData; + Object? wordNetError; + + Object? definitionError; + LanguageModel? activeL1; + LanguageModel? activeL2; + + Response get noLanguages => Response("", 405); + + @override + void initState() { + if (!mounted) return; + activeL1 = + controller.languageController.activeL1Model(roomID: widget.room.id)!; + activeL2 = + controller.languageController.activeL2Model(roomID: widget.room.id)!; + if (activeL1 == null || activeL2 == null) { + wordNetError = noLanguages; + definitionError = noLanguages; + } else if (!widget.hasInfo) { + getContextualDefinition(); + } else { + getWordNet(); + } + super.initState(); + } + + Future getContextualDefinition() async { + ContextualDefinitionRequestModel? req; + try { + req = ContextualDefinitionRequestModel( + fullText: widget.fullText, + word: widget.word, + feedbackLang: activeL1?.langCode ?? LanguageKeys.defaultLanguage, + fullTextLang: widget.fullTextLang, + wordLang: widget.wordLang, + ); + if (mounted) setState(() => isLoadingContextualDefinition = true); + contextualDefinitionRes = await controller.definitions.get(req); + if (contextualDefinitionRes == null) { + definitionError = Exception("Error getting definition"); + } + GoogleAnalytics.contextualRequest(); + } catch (err, stack) { + debugger(when: kDebugMode); + ErrorHandler.logError(e: err, s: stack, data: req?.toJson()); + definitionError = Exception("Error getting definition"); + } finally { + if (mounted) setState(() => isLoadingContextualDefinition = false); + } + } + + Future getWordNet() async { + if (mounted) setState(() => isLoadingWordNet = true); + try { + wordData = await controller.wordNet.getWordDataGlobal( + word: widget.word, + fullText: widget.fullText, + userL1: activeL1?.langCode, + userL2: activeL2?.langCode, + ); + } catch (err) { + ErrorHandler.logError( + e: err, + s: StackTrace.current, + data: {"word": widget.word, "hasInfo": widget.hasInfo}, + ); + wordNetError = err; + } finally { + if (mounted) { + setState(() => isLoadingWordNet = false); + } + } + } + + void handleGetDefinitionButtonPress() { + if (isLoadingContextualDefinition) return; + getContextualDefinition(); + } + + @override + Widget build(BuildContext context) => WordDataCardView(controller: this); +} + +class WordDataCardView extends StatelessWidget { + const WordDataCardView({ + super.key, + required this.controller, + }); + + final WordDataCardController controller; + + @override + Widget build(BuildContext context) { + if (controller.wordNetError != null) { + return CardErrorWidget(error: controller.wordNetError); + } + if (controller.activeL1 == null || controller.activeL2 == null) { + ErrorHandler.logError(m: "should not be here"); + return CardErrorWidget(error: controller.noLanguages); + } + + final ScrollController scrollController = ScrollController(); + + return Scrollbar( + thumbVisibility: true, + controller: scrollController, + child: SingleChildScrollView( + controller: scrollController, + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + CardHeader( + text: controller.widget.word, + botExpression: BotExpression.down, + ), + if (controller.widget.choiceFeedback != null) + Text( + controller.widget.choiceFeedback!, + style: BotStyle.text(context), + ), + const SizedBox(height: 5.0), + if (controller.wordData != null && controller.wordNetError == null) + WordNetInfo( + wordData: controller.wordData!, + activeL1: controller.activeL1!, + activeL2: controller.activeL2!, + ), + if (controller.isLoadingWordNet) const PCircular(), + const SizedBox(height: 5.0), + // if (controller.widget.hasInfo && + // !controller.isLoadingContextualDefinition && + // controller.contextualDefinitionRes == null) + // Material( + // type: MaterialType.transparency, + // child: ListTile( + // leading: const BotFace( + // width: 40, expression: BotExpression.surprised), + // title: Text(L10n.of(context)!.askPangeaBot), + // onTap: controller.handleGetDefinitionButtonPress, + // ), + // ), + if (controller.isLoadingContextualDefinition) const PCircular(), + if (controller.contextualDefinitionRes != null) + Text( + controller.contextualDefinitionRes!.text, + style: BotStyle.text(context), + ), + if (controller.definitionError != null) + Text( + L10n.of(context)!.sorryNoResults, + style: BotStyle.text(context), + ), + ], + ), + ), + ); + } +} + +class WordNetInfo extends StatelessWidget { + final WordData wordData; + final LanguageModel activeL1; + final LanguageModel activeL2; + + const WordNetInfo({ + super.key, + required this.wordData, + required this.activeL1, + required this.activeL2, + }); + + @override + Widget build(BuildContext context) { + return Column( + children: [ + SensesForLanguage( + wordData: wordData, + languageType: LanguageType.target, + language: activeL2, + ), + SensesForLanguage( + wordData: wordData, + languageType: LanguageType.base, + language: activeL1, + ), + ], + ); + } +} + +enum LanguageType { + target, + base, +} + +class SensesForLanguage extends StatelessWidget { + const SensesForLanguage({ + super.key, + required this.wordData, + required this.languageType, + required this.language, + }); + + final LanguageModel language; + final LanguageType languageType; + final WordData wordData; + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 5), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsets.fromLTRB(7, 0, 0, 0), + child: LanguageFlag( + language: language, + ), + ), + Expanded( + child: PartOfSpeechBlock( + wordData: wordData, + languageType: languageType, + ), + ), + ], + ), + ); + } +} + +class PartOfSpeechBlock extends StatelessWidget { + final WordData wordData; + final LanguageType languageType; + + const PartOfSpeechBlock({ + super.key, + required this.wordData, + required this.languageType, + }); + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.fromLTRB(10, 0, 10, 0), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Align( + alignment: Alignment.centerLeft, + child: Text( + languageType == LanguageType.target + ? "${wordData.targetWord} (${wordData.formattedPartOfSpeech(languageType)})" + : "${wordData.baseWord} (${wordData.formattedPartOfSpeech(languageType)})", + style: BotStyle.text(context, italics: true, bold: false), + ), + ), + const SizedBox(height: 10), + Padding( + padding: const EdgeInsets.only(left: 14.0, bottom: 10.0), + child: Align( + alignment: Alignment.centerLeft, + child: Column( + children: [ + RichText( + text: TextSpan( + style: BotStyle.text( + context, + italics: false, + bold: false, + ), + children: [ + TextSpan( + text: "${L10n.of(context)!.definition}: ", + style: const TextStyle(fontWeight: FontWeight.bold), + ), + TextSpan( + text: languageType == LanguageType.target + ? wordData.targetDefinition + : wordData.baseDefinition, + ), + ], + ), + ), + const SizedBox(height: 10), + RichText( + text: TextSpan( + style: BotStyle.text( + context, + italics: false, + bold: false, + ), + children: [ + TextSpan( + text: "${L10n.of(context)!.exampleSentence}: ", + style: const TextStyle(fontWeight: FontWeight.bold), + ), + TextSpan( + text: languageType == LanguageType.target + ? wordData.targetExampleSentence + : wordData.baseExampleSentence, + ), + ], + ), + ), + ], + ), + ), + ), + ], + ), + ); + } +} diff --git a/lib/pangea/widgets/login/home_picker_logo.dart b/lib/pangea/widgets/login/home_picker_logo.dart new file mode 100644 index 000000000..a1427a449 --- /dev/null +++ b/lib/pangea/widgets/login/home_picker_logo.dart @@ -0,0 +1,40 @@ +import 'package:flutter/material.dart'; + +import '../../../config/app_config.dart'; +import '../common/pangea_logo_svg.dart'; + +class PangeaLogoAndNameWidget extends StatelessWidget { + const PangeaLogoAndNameWidget({super.key}); + + @override + Widget build(BuildContext context) { + return Expanded( + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Container( + alignment: Alignment.center, + height: 120, + child: const PangeaLogoSvg(width: 120, forceColor: Colors.white), + ), + //PTODO - widget to display app name with consistent style + Text( + AppConfig.applicationName, + style: const TextStyle( + fontSize: 26, + color: Colors.white, + fontWeight: FontWeight.w800, + ), + ), + // const Text( + // "Life is Learning", + // style: TextStyle( + // fontSize: 18, + // color: Colors.white, + // ), + // ), + ], + ), + ); + } +} diff --git a/lib/pangea/widgets/new_group/topics_list.dart b/lib/pangea/widgets/new_group/topics_list.dart new file mode 100644 index 000000000..e720b95af --- /dev/null +++ b/lib/pangea/widgets/new_group/topics_list.dart @@ -0,0 +1,172 @@ +import 'dart:convert'; + +import 'package:flutter/material.dart'; + +import '../../models/chat_topic_model.dart'; + +/// the widget loads the list of ChatTopic from assets/chat_data.json +/// displays the topics in a list with image, name and total number of vocab +/// when a topic is selected, the ChatTopic is passed to the parent widget +/// while a topic is selected, it displays expanded details about the topic, +/// including description, bot prompt, and vocab +class SelectTopicList extends StatefulWidget { + final Function(ChatTopic) onTopicSelected; + + const SelectTopicList({super.key, required this.onTopicSelected}); + + @override + SelectTopicListState createState() => SelectTopicListState(); +} + +class SelectTopicListState extends State { + late Future> _futureTopics; + + ChatTopic? selected; + + @override + void initState() { + super.initState(); + _futureTopics = _loadTopics(); + } + + Future> _loadTopics() async { + final String data = await DefaultAssetBundle.of(context) + .loadString("assets/chat_data.json"); + final jsonResult = json.decode(data); + final List topics = []; + for (final topic in jsonResult['chats']) { + topics.add(ChatTopic.fromJson(topic)); + } + return topics; + } + + @override + Widget build(BuildContext context) { + return FutureBuilder>( + future: _futureTopics, + builder: (context, snapshot) { + if (snapshot.hasData) { + return SelectTopicListWidget( + topics: snapshot.data!, + onTopicSelected: ((topic) { + widget.onTopicSelected(topic); + selected = topic; + setState(() {}); + }), + selectedTopicState: this, + ); + } else if (snapshot.hasError) { + return Text("${snapshot.error}"); + } + return const CircularProgressIndicator(); + }, + ); + } +} + +class SelectTopicListWidget extends StatelessWidget { + final List topics; + final Function(ChatTopic) onTopicSelected; + final SelectTopicListState selectedTopicState; + + const SelectTopicListWidget({ + super.key, + required this.topics, + required this.onTopicSelected, + required this.selectedTopicState, + }); + + @override + Widget build(BuildContext context) { + final list = ListView.builder( + itemCount: topics.length, + shrinkWrap: true, + itemBuilder: (context, index) { + return SelectTopicListItem( + topic: topics[index], + isSelected: topics[index] == selectedTopicState.selected, + onTopicSelected: onTopicSelected, + ); + }, + ); + + /// wrap list in scroll area + return SingleChildScrollView( + child: list, + ); + } +} + +/// while a topic is selected, it displays expanded details about the topic, +/// including description, bot prompt, and vocab +/// use ThemeData to get colors, text styles, etc. +class SelectTopicListItem extends StatelessWidget { + final ChatTopic topic; + final Function(ChatTopic) onTopicSelected; + final bool isSelected; + + const SelectTopicListItem({ + super.key, + required this.topic, + required this.isSelected, + required this.onTopicSelected, + }); + + @override + Widget build(BuildContext context) { + return GestureDetector( + onTap: () { + onTopicSelected(topic); + }, + child: Container( + padding: const EdgeInsets.all(8), + decoration: BoxDecoration( + color: isSelected ? Colors.grey[100] : Colors.white, + border: Border.all( + color: isSelected ? Colors.grey[300]! : Colors.white, + ), + ), + child: Row( + children: [ + // Image.asset( + // Icons.airplane_ticket_outlined, + // width: 50, + // height: 50, + // ), + const SizedBox(width: 8), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + topic.name, + style: const TextStyle( + fontWeight: FontWeight.bold, + ), + ), + if (isSelected) ...[ + const SizedBox(height: 8), + Text( + topic.description, + style: const TextStyle( + color: Colors.grey, + ), + ), + const SizedBox(height: 8), + Text( + topic.vocab.join(", "), + style: const TextStyle( + color: Colors.grey, + ), + ), + ], + ], + ), + ), + const Icon(Icons.chevron_right), + ], + ), + ), + ); + } +} diff --git a/lib/pangea/widgets/new_group/vocab_list.dart b/lib/pangea/widgets/new_group/vocab_list.dart new file mode 100644 index 000000000..e6c2675e4 --- /dev/null +++ b/lib/pangea/widgets/new_group/vocab_list.dart @@ -0,0 +1,527 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; + +import 'package:fluffychat/pangea/controllers/pangea_controller.dart'; +import 'package:fluffychat/widgets/matrix.dart'; +import '../../models/chat_topic_model.dart'; +import '../../models/lemma.dart'; +import '../../repo/topic_data_repo.dart'; +import '../common/bot_face_svg.dart'; + +/// stateless widget that displays a list of vocabulary words +/// parameters +/// 1) list of words +/// 2) one callback function that handles all changes to the list (passes full list back to parent) +/// view +/// 1) a list of words (chips) in a wrapped row within a scrollable area with an x button to remove the word +/// 2) in the bottom center is a text field to type a new word and add it to the list on submit +/// 3) at the top right is a button to clear the list with trash icon and confirm dialog +/// 4) at the top left is a button to call an API to get a list of words with the BotFace widget +/// the user can +/// 1) type a new word and add it to the list +/// 2) remove a word from the list +/// 3) clear all words from the list +/// 4) widget button called +/// uses app theme colors, text styles, and icons + +class ChatVocabularyList extends StatelessWidget { + const ChatVocabularyList({ + super.key, + required this.topic, + required this.onChanged, + }); + + final ChatTopic topic; + final ValueChanged> onChanged; + + @override + Widget build(BuildContext context) { + final deleteButton = Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + IconButton( + icon: const Icon(Icons.delete), + onPressed: () { + showDialog( + context: context, + builder: (context) { + return AlertDialog( + title: Text(L10n.of(context)!.clearAll), + actions: [ + TextButton( + child: Text(L10n.of(context)!.cancel), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + TextButton( + child: Text(L10n.of(context)!.confirm), + onPressed: () { + onChanged([]); + Navigator.of(context).pop(); + }, + ), + ], + ); + }, + ); + }, + ), + ], + ); + final words = Wrap( + spacing: 8, + children: [ + for (final word in topic.vocab) + Chip( + labelStyle: Theme.of(context).textTheme.bodyMedium, + label: Text(word.form), + onDeleted: () { + onChanged(topic.vocab..remove(word)); + }, + ), + ], + ); + final vocabColumn = Column( + children: [ + // clear all words button + deleteButton, + // list of words + words, + // add word from text field to words + WordAddTextField( + words: topic.vocab, + onSubmitted: (value) { + //PTODO - error message if + if (value.isEmpty) return; + onChanged(topic.vocab..add(Lemma.create(value))); + }, + ), + GenerateVocabButton( + topic: topic, + onWordsGenerated: (newWords) { + onChanged(topic.vocab..addAll(newWords)); + }, + onPressed: () {}, + ), + ], + ); + + /// return vocabColumn wrapped in a scrollable area with border + return Container( + decoration: BoxDecoration( + border: Border.all( + color: Theme.of(context).colorScheme.secondary, + width: 2, + ), + borderRadius: BorderRadius.circular(8), + ), + child: SingleChildScrollView( + child: vocabColumn, + ), + ); + } +} + +class VocabWord { + final String word; + + VocabWord({ + required this.word, + }); + + factory VocabWord.fromJson(Map json) { + return VocabWord( + word: json['word'], + ); + } + + Map toJson() { + return { + 'word': word, + }; + } + + /// set equals operator + @override + bool operator ==(Object other) => + identical(this, other) || + other is VocabWord && + runtimeType == other.runtimeType && + word == other.word; + + /// set hashcode + @override + int get hashCode => word.hashCode; +} + +/// text field widget for adding a word +/// parameters +/// 1) callback passes the word back to the parent widget +/// 2) word list to check if the word is already in the list +/// new word cn be added by pressing enter or the add button +/// uses app theme colors, text styles, and icons +/// function for checking word, reused in the button and textfield onSubmitted +/// 1) if the word is already in the list, it is not added and an error message is displayed +/// 2) if whitespace is detected anywhere in the word, display an error message + +class WordAddTextField extends StatefulWidget { + const WordAddTextField({ + super.key, + required this.onSubmitted, + required this.words, + }); + + final ValueChanged onSubmitted; + final List words; + + @override + WordAddTextFieldState createState() => WordAddTextFieldState(); +} + +class WordAddTextFieldState extends State { + final _controller = TextEditingController(); + String? _errorText; + + @override + void initState() { + super.initState(); + _controller.addListener(() { + setState(() { + _errorText = null; + }); + }); + } + + @override + Widget build(BuildContext context) { + return TextField( + controller: _controller, + decoration: InputDecoration( + labelText: 'Add a word', + errorText: _errorText, + suffixIcon: IconButton( + icon: const Icon(Icons.add), + onPressed: () { + _addWord(); + }, + ), + ), + onSubmitted: (value) { + _addWord(); + }, + ); + } + + void _addWord() { + final word = _controller.text.trim(); + if (word.isEmpty) { + setState(() { + _errorText = 'Please enter a word'; + }); + return; + } + if (widget.words.map((e) => e.text).contains(word)) { + setState(() { + _errorText = 'Word already in list'; + }); + return; + } + widget.onSubmitted(word); + _controller.clear(); + } +} + +/// widget button to call an API to get a list of words +/// button has a BotFace icon and text saying "Generate Vocabulary", use L10n for copy +/// parameters +/// 1) callback function to pass the list of words back to the parent widget +/// 2) callback function to notify the parent widget that the button was pressed +/// 3) topic information to pass to the API +/// display loading indicator while waiting for response +/// display error message if there is an error +/// uses app theme colors, text styles, and icons +class GenerateVocabButton extends StatefulWidget { + const GenerateVocabButton({ + super.key, + required this.onWordsGenerated, + required this.onPressed, + required this.topic, + }); + + final ChatTopic topic; + final ValueChanged> onWordsGenerated; + final VoidCallback onPressed; + + @override + GenerateVocabButtonState createState() => GenerateVocabButtonState(); +} + +class GenerateVocabButtonState extends State { + bool _loading = false; + String? _errorText; + final PangeaController _pangeaController = MatrixState.pangeaController; + + @override + Widget build(BuildContext context) { + return Column( + children: [ + // button to call API + ElevatedButton.icon( + icon: const BotFace( + width: 50.0, + expression: BotExpression.right, + ), + label: Text(L10n.of(context)!.generateVocabulary), + onPressed: () async { + // if widget.topic.name is null, give error message + if (widget.topic.name.isEmpty) { + setState(() { + _errorText = + 'Please enter a topic name before generating vocabulary'; + }); + return; + } + setState(() { + _loading = true; + _errorText = null; + }); + try { + final words = await _getWords(); + widget.onWordsGenerated(words); + } catch (e) { + setState(() { + _errorText = e.toString(); + }); + } finally { + setState(() { + _loading = false; + }); + } + widget.onPressed(); + }, + ), + + // loading indicator + if (_loading) const CircularProgressIndicator(), + // error message + if (_errorText != null) Text(_errorText!), + ], + ); + } + + Future> _getWords() async { + final ChatTopic topic = await TopicDataRepo.generate( + await _pangeaController.userController.accessToken, + request: TopicDataRequest( + topicInfo: widget.topic, + numWords: 10, + numPrompts: 0, + ), + ); + return topic.vocab; + } +} + +/// text field for entering a chat description, max 250 characters +/// parameters +/// 1) ChatTopic object +/// 2) initial value for the text field +/// 3) onChanged callback function to pass the updated ChatTopic back to the parent widget +class DescriptionField extends StatelessWidget { + const DescriptionField({ + super.key, + required this.topic, + required this.initialValue, + required this.onChanged, + }); + + final ChatTopic topic; + final String initialValue; + final ValueChanged onChanged; + + @override + Widget build(BuildContext context) { + return TextFormField( + initialValue: initialValue, + decoration: InputDecoration( + labelText: L10n.of(context)!.groupDescription, + hintText: L10n.of(context)!.addGroupDescription, + ), + maxLength: 250, + maxLines: 5, + onChanged: (value) { + onChanged(value); + }, + ); + } +} + +/// text field for entering a chat name, max 50 characters +/// parameters +/// 1) ChatTopic object +/// 2) initial value for the text field +/// 3) onChanged callback function to pass the updated ChatTopic back to the parent widget +class NameField extends StatelessWidget { + const NameField({ + super.key, + required this.topic, + required this.onChanged, + }); + + final ChatTopic topic; + final ValueChanged onChanged; + + @override + Widget build(BuildContext context) { + return TextFormField( + initialValue: topic.name, + decoration: InputDecoration( + labelText: L10n.of(context)!.optionalGroupName, + hintText: L10n.of(context)!.enterAGroupName, + ), + maxLength: 50, + onChanged: (value) { + onChanged(value); + }, + ); + } +} + +///widget for displaying, adding, deleting and generating discussion prompts +/// parameters +/// 1) chatTopic object +/// 2) callback function to pass the updated ChatTopic back to the parent widget +class PromptsField extends StatefulWidget { + const PromptsField({ + super.key, + required this.topic, + required this.onChanged, + }); + + final ChatTopic topic; + final ValueChanged onChanged; + + @override + PromptsFieldState createState() => PromptsFieldState(); +} + +class PromptsFieldState extends State { + final TextEditingController _controller = TextEditingController(); + String? _errorText; + + final PangeaController _pangeaController = MatrixState.pangeaController; + + @override + void initState() { + super.initState(); + _controller.addListener(() { + setState(() { + _errorText = null; + }); + }); + } + + @override + Widget build(BuildContext context) { + return Column( + children: [ + // text field for entering a prompt + TextField( + controller: _controller, + decoration: InputDecoration( + labelText: 'Add a prompt', + errorText: _errorText, + suffixIcon: IconButton( + icon: const Icon(Icons.add), + onPressed: () { + _addPrompt(); + }, + ), + ), + onSubmitted: (value) { + _addPrompt(); + }, + ), + + // list of prompts + ListView.builder( + shrinkWrap: true, + itemCount: widget.topic.discussionPrompts.length, + itemBuilder: (context, index) { + return ListTile( + title: Text(widget.topic.discussionPrompts[index].text), + trailing: IconButton( + icon: const Icon(Icons.delete), + onPressed: () { + _deletePrompt(index); + }, + ), + ); + }, + ), + + // button to call API + ElevatedButton.icon( + icon: const BotFace( + width: 50.0, + expression: BotExpression.right, + ), + label: Text(L10n.of(context)!.generatePrompts), + onPressed: () async { + setState(() { + _errorText = null; + }); + try { + final prompts = await _getPrompts(); + widget.topic.discussionPrompts = prompts; + widget.onChanged(widget.topic); + } catch (e) { + setState(() { + _errorText = e.toString(); + }); + } + }, + ), + ], + ); + } + + void _addPrompt() { + final text = _controller.text.trim(); + if (text.isEmpty) { + setState(() { + _errorText = 'Please enter a prompt'; + }); + return; + } + final prompt = DiscussionPrompt(text: text); + if (widget.topic.discussionPrompts.contains(prompt)) { + setState(() { + _errorText = 'Prompt already in list'; + }); + return; + } + widget.topic.discussionPrompts.add(prompt); + widget.onChanged(widget.topic); + _controller.clear(); + } + + void _deletePrompt(int index) { + widget.topic.discussionPrompts.removeAt(index); + widget.onChanged(widget.topic); + } + + Future> _getPrompts() async { + final ChatTopic res = await TopicDataRepo.generate( + await _pangeaController.userController.accessToken, + request: TopicDataRequest( + topicInfo: widget.topic, + numPrompts: 10, + numWords: 0, + ), + ); + return res.discussionPrompts; + } +} diff --git a/lib/pangea/widgets/signup/signup_buttons.dart b/lib/pangea/widgets/signup/signup_buttons.dart new file mode 100644 index 000000000..bd446c037 --- /dev/null +++ b/lib/pangea/widgets/signup/signup_buttons.dart @@ -0,0 +1,223 @@ +import 'dart:typed_data'; + +import 'package:flutter/material.dart'; + +import 'package:adaptive_dialog/adaptive_dialog.dart'; +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:go_router/go_router.dart'; +import 'package:image_picker/image_picker.dart'; +import 'package:matrix/matrix.dart'; + +import 'package:fluffychat/pangea/controllers/pangea_controller.dart'; +import 'package:fluffychat/pangea/widgets/common/pangea_logo_svg.dart'; +import 'package:fluffychat/utils/localized_exception_extension.dart'; +import 'package:fluffychat/utils/platform_infos.dart'; +import 'package:fluffychat/widgets/matrix.dart'; + +class SignupButtons extends StatefulWidget { + const SignupButtons({super.key}); + + @override + State createState() => SignupButtonsState(); +} + +class SignupButtonsState extends State { + final PangeaController pangeaController = MatrixState.pangeaController; + + void pickAvatar() async { + final source = !PlatformInfos.isMobile + ? ImageSource.gallery + : await showModalActionSheet( + context: context, + title: L10n.of(context)!.changeYourAvatar, + actions: [ + SheetAction( + key: ImageSource.camera, + label: L10n.of(context)!.openCamera, + isDefaultAction: true, + icon: Icons.camera_alt_outlined, + ), + SheetAction( + key: ImageSource.gallery, + label: L10n.of(context)!.openGallery, + icon: Icons.photo_outlined, + ), + ], + ); + if (source == null) return; + final picked = await ImagePicker().pickImage( + source: source, + imageQuality: 50, + maxWidth: 512, + maxHeight: 512, + ); + setState(() { + Matrix.of(context).loginAvatar = picked; + }); + } + + final TextEditingController usernameController = TextEditingController(); + String? signupError; + + void signUp() async { + usernameController.text = usernameController.text.trim(); + final localpart = + usernameController.text.toLowerCase().replaceAll(' ', '_'); + if (localpart.isEmpty) { + setState(() { + signupError = L10n.of(context)!.pleaseChooseAUsername; + }); + return; + } + + setState(() { + signupError = null; + }); + + try { + try { + await Matrix.of(context).getLoginClient().register(username: localpart); + } on MatrixException catch (e) { + if (!e.requireAdditionalAuthentication) rethrow; + } + Matrix.of(context).loginUsername = usernameController.text; + context.go('/home/signup'); + } catch (e, s) { + Logs().d('Sign up failed', e, s); + setState(() { + signupError = e.toLocalizedString(context); + }); + } + } + + @override + Widget build(BuildContext context) { + final avatar = Matrix.of(context).loginAvatar; + return Column( + children: [ + Padding( + padding: const EdgeInsets.all(12.0), + child: Center( + child: Stack( + children: [ + Material( + borderRadius: BorderRadius.circular(64), + elevation: + Theme.of(context).appBarTheme.scrolledUnderElevation ?? + 10, + color: Colors.transparent, + shadowColor: + Theme.of(context).colorScheme.onBackground.withAlpha(64), + clipBehavior: Clip.hardEdge, + child: CircleAvatar( + radius: 64, + backgroundColor: Colors.white, + child: avatar == null + ? const Icon( + Icons.person_outlined, + color: Colors.black, + size: 64, + ) + : FutureBuilder( + future: avatar.readAsBytes(), + builder: (context, snapshot) { + final bytes = snapshot.data; + if (bytes == null) { + return const CircularProgressIndicator + .adaptive(); + } + return Image.memory( + bytes, + fit: BoxFit.cover, + width: 128, + height: 128, + ); + }, + ), + ), + ), + Positioned( + bottom: 0, + right: 0, + child: FloatingActionButton( + mini: true, + onPressed: pickAvatar, + backgroundColor: Colors.white, + foregroundColor: Colors.black, + child: const Icon(Icons.camera_alt_outlined), + ), + ), + ], + ), + ), + ), + Padding( + padding: const EdgeInsets.all(12.0), + child: TextField( + controller: usernameController, + onSubmitted: (_) => signUp(), + decoration: InputDecoration( + prefixIcon: const Icon(Icons.account_box_outlined), + hintText: L10n.of(context)!.chooseAUsername, + errorText: signupError, + errorStyle: TextStyle( + color: Theme.of(context).textTheme.bodyMedium?.color, + fontSize: 14, + ), + fillColor: + Theme.of(context).colorScheme.background.withOpacity(0.75), + ), + ), + ), + Padding( + padding: const EdgeInsets.all(12.0), + child: Hero( + tag: 'signUpButton', + child: ElevatedButton( + onPressed: signUp, + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const PangeaLogoSvg(width: 20), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 10), + child: Text(L10n.of(context)!.signUp), + ), + ], + ), + ), + ), + ), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 16.0), + child: Row( + children: [ + const Expanded( + child: Divider( + thickness: 1, + color: Colors.white, + ), + ), + Padding( + padding: const EdgeInsets.all(12.0), + child: Text( + L10n.of(context)!.or, + style: const TextStyle( + color: Colors.white, + fontSize: 18, + ), + ), + ), + const Expanded( + child: Divider( + thickness: 1, + color: Colors.white, + ), + ), + ], + ), + ), + ], + ); + } +} diff --git a/lib/pangea/widgets/signup/tos_checkbox.dart b/lib/pangea/widgets/signup/tos_checkbox.dart new file mode 100644 index 000000000..f5bca72c2 --- /dev/null +++ b/lib/pangea/widgets/signup/tos_checkbox.dart @@ -0,0 +1,67 @@ +// Flutter imports: + +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; + +import 'package:fluffychat/config/app_config.dart'; +import 'package:fluffychat/pangea/pages/sign_up/signup.dart'; +import 'package:fluffychat/utils/url_launcher.dart'; + +class TosCheckbox extends StatelessWidget { + final SignupPageController controller; + const TosCheckbox(this.controller, {super.key}); + + @override + Widget build(BuildContext context) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + CheckboxListTile( + controlAffinity: ListTileControlAffinity.leading, + contentPadding: const EdgeInsets.symmetric( + horizontal: 8.0, + ), + value: controller.isTnCChecked, + activeColor: Theme.of(context).colorScheme.primary, + onChanged: controller.onTncChange, + title: InkWell( + onTap: () => + UrlLauncher(context, AppConfig.termsOfServiceUrl).launchUrl(), + child: RichText( + maxLines: 2, + text: TextSpan( + text: L10n.of(context)!.iAgreeToThe, + children: [ + //PTODO - make sure this is actually a link + TextSpan( + text: L10n.of(context)!.termsAndConditions, + style: const TextStyle(color: Colors.blue), + ), + TextSpan( + text: L10n.of(context)!.andCertifyIAmAtLeast13YearsOfAge, + ), + ], + style: const TextStyle(color: Colors.white), + ), + ), + ), + ), + ConstrainedBox( + constraints: const BoxConstraints(maxWidth: 400), + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 12), + margin: const EdgeInsets.only(top: 5), + child: Text( + controller.signupError ?? '', + style: TextStyle( + color: Theme.of(context).textTheme.bodyMedium?.color, + fontSize: 14, + ), + ), + ), + ), + ], + ); + } +} diff --git a/lib/pangea/widgets/space/class_settings.dart b/lib/pangea/widgets/space/class_settings.dart new file mode 100644 index 000000000..03a139c45 --- /dev/null +++ b/lib/pangea/widgets/space/class_settings.dart @@ -0,0 +1,239 @@ +import 'dart:developer'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; +import 'package:matrix/matrix.dart'; + +import 'package:fluffychat/pangea/models/class_model.dart'; +import '../../../widgets/matrix.dart'; +import '../../constants/language_keys.dart'; +import '../../constants/language_level_type.dart'; +import '../../constants/pangea_event_types.dart'; +import '../../controllers/language_list_controller.dart'; +import '../../controllers/pangea_controller.dart'; +import '../../extensions/pangea_room_extension.dart'; +import '../../models/language_model.dart'; +import '../../utils/error_handler.dart'; +import '../../utils/language_level_copy.dart'; +import '../user_settings/p_language_dropdown.dart'; +import '../user_settings/p_question_container.dart'; + +class ClassSettings extends StatefulWidget { + final String? roomId; + final bool startOpen; + + const ClassSettings({super.key, this.roomId, this.startOpen = false}); + + @override + ClassSettingsState createState() => ClassSettingsState(); +} + +class ClassSettingsState extends State { + Room? room; + late ClassSettingsModel classSettings; + late bool isOpen; + final PangeaController pangeaController = MatrixState.pangeaController; + + final cityController = TextEditingController(); + final countryController = TextEditingController(); + final schoolController = TextEditingController(); + + ClassSettingsState({Key? key}); + + @override + void initState() { + room = widget.roomId != null + ? Matrix.of(context).client.getRoomById(widget.roomId!) + : null; + + classSettings = room?.classSettings ?? ClassSettingsModel(); + + isOpen = widget.startOpen; + + super.initState(); + } + + bool get sameLanguages => + classSettings.targetLanguage == classSettings.dominantLanguage; + + LanguageModel getLanguage({required bool isBase, required String? langCode}) { + final LanguageModel backup = isBase + ? pangeaController.pLanguageStore.baseOptions.first + : pangeaController.pLanguageStore.targetOptions.first; + if (langCode == null) return backup; + final LanguageModel byCode = PangeaLanguage.byLangCode(langCode); + return byCode.langCode != LanguageKeys.unknownLanguage ? byCode : backup; + } + + Future updatePermission(void Function() makeLocalRuleChange) async { + makeLocalRuleChange(); + if (room != null) { + await showFutureLoadingDialog( + context: context, + future: () => setClassSettings(room!.id), + ); + } + setState(() {}); + } + + void setTextControllerValues() { + classSettings.city = cityController.text; + classSettings.country = countryController.text; + classSettings.schoolName = schoolController.text; + } + + Future setClassSettings(String roomId) async { + try { + setTextControllerValues(); + + await Matrix.of(context).client.setRoomStateWithKey( + roomId, + PangeaEventTypes.classSettings, + '', + classSettings.toJson(), + ); + } catch (err, stack) { + debugger(when: kDebugMode); + ErrorHandler.logError(e: err, s: stack); + } + } + + @override + Widget build(BuildContext context) => Column( + children: [ + ListTile( + title: Text( + L10n.of(context)!.classSettings, + style: TextStyle( + color: Theme.of(context).colorScheme.secondary, + fontWeight: FontWeight.bold, + ), + ), + subtitle: Text(L10n.of(context)!.classSettingsDesc), + leading: CircleAvatar( + backgroundColor: Theme.of(context).scaffoldBackgroundColor, + foregroundColor: Theme.of(context).textTheme.bodyLarge!.color, + child: const Icon(Icons.language), + ), + trailing: Icon( + isOpen + ? Icons.keyboard_arrow_down_outlined + : Icons.keyboard_arrow_right_outlined, + ), + onTap: () => setState(() => isOpen = !isOpen), + ), + if (isOpen) + AnimatedContainer( + duration: const Duration(milliseconds: 300), + height: isOpen ? null : 0, + child: Padding( + padding: const EdgeInsets.fromLTRB(16.0, 0, 16.0, 8.0), + child: Column( + children: [ + PQuestionContainer( + title: L10n.of(context)!.selectClassRoomDominantLanguage, + ), + PLanguageDropdown( + onChange: (p0) => updatePermission(() { + classSettings.dominantLanguage = p0.langCode; + }), + initialLanguage: getLanguage( + isBase: true, + langCode: classSettings.dominantLanguage, + ), + languages: pangeaController.pLanguageStore.baseOptions, + showMultilingual: true, + ), + PQuestionContainer( + title: L10n.of(context)!.selectTargetLanguage, + ), + PLanguageDropdown( + onChange: (p0) => updatePermission(() { + classSettings.targetLanguage = p0.langCode; + }), + initialLanguage: getLanguage( + isBase: false, + langCode: classSettings.targetLanguage, + ), + languages: pangeaController.pLanguageStore.targetOptions, + ), + PQuestionContainer( + title: L10n.of(context)!.whatIsYourClassLanguageLevel, + ), + Padding( + padding: const EdgeInsets.all(12.0), + child: Container( + decoration: BoxDecoration( + border: Border.all( + color: Theme.of(context).colorScheme.secondary, + width: 0.5, + ), + borderRadius: + const BorderRadius.all(Radius.circular(10)), + ), + child: DropdownButton( + // Initial Value + hint: Padding( + padding: const EdgeInsets.only(left: 15), + child: Text( + classSettings.languageLevel == null + ? L10n.of(context)!.selectLanguageLevel + : LanguageLevelTextPicker.languageLevelText( + context, + classSettings.languageLevel!, + ), + style: const TextStyle().copyWith( + color: Theme.of(context) + .textTheme + .bodyLarge! + .color, + fontSize: 14, + ), + overflow: TextOverflow.clip, + textAlign: TextAlign.center, + ), + ), + isExpanded: true, + underline: Container(), + // Down Arrow Icon + icon: const Icon(Icons.keyboard_arrow_down), + // Array list of items + items: + LanguageLevelType.allInts.map((int levelOption) { + return DropdownMenuItem( + value: levelOption, + child: Text( + LanguageLevelTextPicker.languageLevelText( + context, + levelOption, + ), + style: const TextStyle().copyWith( + color: Theme.of(context) + .textTheme + .bodyLarge! + .color, + fontSize: 14, + ), + overflow: TextOverflow.clip, + textAlign: TextAlign.center, + ), + ); + }).toList(), + // After selecting the desired option,it will + // change button value to selected value + onChanged: (int? newValue) => updatePermission(() { + classSettings.languageLevel = newValue!; + }), + ), + ), + ), + ], + ), + ), + ), + ], + ); +} diff --git a/lib/pangea/widgets/subscription/subscription_buttons.dart b/lib/pangea/widgets/subscription/subscription_buttons.dart new file mode 100644 index 000000000..7798b5b28 --- /dev/null +++ b/lib/pangea/widgets/subscription/subscription_buttons.dart @@ -0,0 +1,59 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; + +import 'package:fluffychat/pangea/controllers/pangea_controller.dart'; +import 'package:fluffychat/pangea/controllers/subscription_controller.dart'; +import 'package:fluffychat/pangea/pages/settings_subscription/settings_subscription.dart'; +import 'package:fluffychat/widgets/matrix.dart'; + +class SubscriptionButtons extends StatelessWidget { + final SubscriptionManagementController controller; + final PangeaController pangeaController = MatrixState.pangeaController; + SubscriptionButtons({ + required this.controller, + super.key, + }); + + @override + Widget build(BuildContext context) { + return ListView.builder( + shrinkWrap: true, + itemCount: pangeaController + .subscriptionController.subscription!.availableSubscriptions.length, + itemBuilder: (BuildContext context, int i) => Column( + children: [ + ListTile( + title: pangeaController.subscriptionController.subscription! + .availableSubscriptions[i].isTrial + ? Text(L10n.of(context)!.oneWeekTrial) + : Text( + pangeaController.subscriptionController.subscription! + .availableSubscriptions[i] + .displayName(context), + ), + subtitle: Text( + pangeaController.subscriptionController.subscription! + .availableSubscriptions[i] + .displayPrice(context), + ), + trailing: const Icon(Icons.keyboard_arrow_right_outlined), + selected: controller.selectedSubscription == + pangeaController.subscriptionController.subscription! + .availableSubscriptions[i], + selectedTileColor: + Theme.of(context).colorScheme.secondary.withAlpha(16), + onTap: () { + final SubscriptionDetails selected = pangeaController + .subscriptionController + .subscription! + .availableSubscriptions[i]; + controller.selectSubscription(selected); + }, + ), + const Divider(height: 1), + ], + ), + ); + } +} diff --git a/lib/pangea/widgets/subscription/subscription_options.dart b/lib/pangea/widgets/subscription/subscription_options.dart new file mode 100644 index 000000000..e82123638 --- /dev/null +++ b/lib/pangea/widgets/subscription/subscription_options.dart @@ -0,0 +1,93 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; + +import 'package:fluffychat/config/app_config.dart'; +import 'package:fluffychat/pangea/controllers/pangea_controller.dart'; +import 'package:fluffychat/pangea/controllers/subscription_controller.dart'; + +class SubscriptionOptions extends StatelessWidget { + final PangeaController pangeaController; + const SubscriptionOptions({ + super.key, + required this.pangeaController, + }); + + @override + Widget build(BuildContext context) { + return Expanded( + child: ListView( + children: [ + const SizedBox(height: 20), + Wrap( + alignment: WrapAlignment.center, + direction: Axis.horizontal, + children: pangeaController + .subscriptionController.subscription!.availableSubscriptions + .map( + (subscription) => SubscriptionCard( + subscription: subscription, + pangeaController: pangeaController, + ), + ) + .toList(), + ), + ], + ), + ); + } +} + +class SubscriptionCard extends StatelessWidget { + final SubscriptionDetails subscription; + final PangeaController pangeaController; + + const SubscriptionCard({ + super.key, + required this.subscription, + required this.pangeaController, + }); + + @override + Widget build(BuildContext context) { + return Card( + shape: RoundedRectangleBorder( + side: BorderSide( + color: AppConfig.primaryColorLight.withAlpha(64), + ), + borderRadius: const BorderRadius.all(Radius.zero), + ), + child: SizedBox( + height: 250, + width: AppConfig.columnWidth * 0.75, + child: Padding( + padding: const EdgeInsets.all(25), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text( + subscription.isTrial + ? L10n.of(context)!.oneWeekTrial + : subscription.displayName(context), + textAlign: TextAlign.center, + style: const TextStyle(fontSize: 24), + ), + Text( + subscription.displayPrice(context), + textAlign: TextAlign.center, + ), + OutlinedButton( + onPressed: () { + pangeaController.subscriptionController + .submitSubscriptionChange(subscription, context); + }, + child: Text(L10n.of(context)!.subscribe), + ), + ], + ), + ), + ), + ); + } +} diff --git a/lib/pangea/widgets/subscription/subscription_paywall.dart b/lib/pangea/widgets/subscription/subscription_paywall.dart new file mode 100644 index 000000000..0686d38b8 --- /dev/null +++ b/lib/pangea/widgets/subscription/subscription_paywall.dart @@ -0,0 +1,55 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; + +import 'package:fluffychat/pangea/controllers/pangea_controller.dart'; +import 'package:fluffychat/pangea/widgets/subscription/subscription_options.dart'; + +class SubscriptionPaywall extends StatelessWidget { + final PangeaController pangeaController; + const SubscriptionPaywall({ + super.key, + required this.pangeaController, + }); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + centerTitle: true, + leading: CloseButton(onPressed: Navigator.of(context).pop), + title: Text( + L10n.of(context)!.getAccess, + style: const TextStyle( + fontSize: 20, + ), + textAlign: TextAlign.center, + ), + ), + body: Padding( + padding: const EdgeInsets.all(20), + child: Column( + children: [ + if (pangeaController.matrixState.client.rooms.length > 1) ...[ + Text( + L10n.of(context)!.welcomeBack, + textAlign: TextAlign.center, + style: const TextStyle(fontSize: 16), + ), + const SizedBox(height: 20), + ], + Text( + L10n.of(context)!.subscriptionDesc, + textAlign: TextAlign.center, + style: const TextStyle(fontSize: 16), + ), + const SizedBox(height: 20), + SubscriptionOptions( + pangeaController: pangeaController, + ), + ], + ), + ), + ); + } +} diff --git a/lib/pangea/widgets/user_settings/country_picker_tile.dart b/lib/pangea/widgets/user_settings/country_picker_tile.dart new file mode 100644 index 000000000..ec62374e9 --- /dev/null +++ b/lib/pangea/widgets/user_settings/country_picker_tile.dart @@ -0,0 +1,48 @@ +import 'dart:developer'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + +import 'package:country_picker/country_picker.dart'; +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; + +import 'package:fluffychat/pangea/controllers/pangea_controller.dart'; +import 'package:fluffychat/widgets/matrix.dart'; +import '../../models/user_model.dart'; + +class CountryPickerTile extends StatelessWidget { + final PangeaController pangeaController = MatrixState.pangeaController; + + CountryPickerTile({super.key}); + + @override + Widget build(BuildContext context) { + final Profile? profile = pangeaController.userController.userModel?.profile; + return ListTile( + title: Text( + "${L10n.of(context)!.countryInformation}: ${profile?.countryDisplayName(context) ?? ''} ${profile?.flagEmoji}", + ), + trailing: const Icon(Icons.edit_outlined), + onTap: () => showCountryPicker( + context: context, + showPhoneCode: + false, // optional. Shows phone code before the country name. + onSelect: (Country country) async { + showFutureLoadingDialog( + context: context, + future: () async { + try { + await pangeaController.userController.updateUserProfile( + country: country.displayNameNoCountryCode, + ); + } catch (err) { + debugger(when: kDebugMode); + } + }, + ); + }, + ), + ); + } +} diff --git a/lib/pangea/widgets/user_settings/language_tile.dart b/lib/pangea/widgets/user_settings/language_tile.dart new file mode 100644 index 000000000..085779781 --- /dev/null +++ b/lib/pangea/widgets/user_settings/language_tile.dart @@ -0,0 +1,87 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; + +import 'package:fluffychat/pangea/controllers/pangea_controller.dart'; +import 'package:fluffychat/pangea/models/language_model.dart'; +import 'package:fluffychat/widgets/matrix.dart'; +import '../flag.dart'; +import 'p_language_dialog.dart'; + +//PTODO - move this to settings_learning_view.dart and make callback a setState + +class LanguageTile extends StatelessWidget { + final PangeaController pangeaController = MatrixState.pangeaController; + + LanguageTile({super.key}); + + @override + Widget build(BuildContext context) { + final LanguageModel? sourceLanguage = + pangeaController.languageController.userL1; + + final LanguageModel? targetLanguage = + pangeaController.languageController.userL2; + + //PTODO - placeholder saying 'select your languages' + // if (targetLanguage == null || sourceLanguage == null) { + // debugger(when: kDebugMode); + // return const SizedBox(); + // } + + return ListTile( + // title: Row( + // mainAxisSize: MainAxisSize.min, + // crossAxisAlignment: CrossAxisAlignment.center, + // mainAxisAlignment: MainAxisAlignment.start, + // children: const [ + // Text("Source Language"), + // SizedBox( + // width: 10, + // ), + // Icon(Icons.arrow_right_alt_outlined, size: 20), + // SizedBox( + // width: 10, + // ), + // Text("Target Language"), + // ]), + title: Text(L10n.of(context)!.myLanguages), + subtitle: Row( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + LanguageFlag( + language: sourceLanguage, + ), + const SizedBox( + width: 10, + ), + Text( + sourceLanguage?.getDisplayName(context) ?? + L10n.of(context)!.sourceLanguage, + ), + const SizedBox( + width: 10, + ), + const Icon(Icons.arrow_right_alt_outlined, size: 20), + const SizedBox( + width: 10, + ), + LanguageFlag( + language: targetLanguage, + ), + const SizedBox( + width: 10, + ), + Text( + targetLanguage?.getDisplayName(context) ?? + L10n.of(context)!.targetLanguage, + ), + ], + ), + trailing: const Icon(Icons.edit_outlined), + onTap: () => pLanguageDialog(context, () {}), + ); + } +} diff --git a/lib/pangea/widgets/user_settings/languages_i_speak_tile.dart b/lib/pangea/widgets/user_settings/languages_i_speak_tile.dart new file mode 100644 index 000000000..a7482b399 --- /dev/null +++ b/lib/pangea/widgets/user_settings/languages_i_speak_tile.dart @@ -0,0 +1,107 @@ +// import 'package:fluffychat/pangea/models/language_model.dart'; +// import 'package:flutter/material.dart'; +// import 'package:flutter_gen/gen_l10n/l10n.dart'; +// import 'package:future_loading_dialog/future_loading_dialog.dart'; + +// import '../../../widgets/matrix.dart'; +// import '../../controllers/pangea_controller.dart'; + +// class LanguagesISpeakTile extends StatelessWidget { +// final PangeaController pangeaController = MatrixState.pangeaController; + +// LanguagesISpeakTile({ +// Key? key, +// }) : super(key: key); + +// @override +// Widget build(BuildContext context) { +// return ListTile( +// trailing: const Icon(Icons.edit_outlined), +// title: Text(L10n.of(context)!.languagesISpeak), +// //PTODO - make a nice display of flags +// // subtitle: Text( +// // pangeaController.userController.userModel?.profile?.speaks +// // ?.toString() ?? +// // "", +// // ), +// onTap: () => showDialog( +// context: context, +// builder: (BuildContext context) { +// return const MultiSelectDialog(); +// }, +// ), +// ); +// } +// } + +// class MultiSelectDialog extends StatefulWidget { +// const MultiSelectDialog({Key? key}) : super(key: key); + +// @override +// State createState() => _MultiSelectDialogState(); +// } + +// class _MultiSelectDialogState extends State { +// final List _selectedValues = []; +// PangeaController pangeaController = MatrixState.pangeaController; + +// @override +// void initState() { +// super.initState(); +// // _selectedValues.addAll( +// // pangeaController.userController.userModel?.profile?.speaks ?? []); +// } + +// void _onItemCheckedChange(LanguageModel itemValue, bool? checked) { +// if (checked == null) return; +// setState(() { +// if (checked) { +// _selectedValues.add(itemValue.langCode); +// } else { +// _selectedValues.remove(itemValue.langCode); +// } +// }); +// } + +// @override +// Widget build(BuildContext context) { +// return AlertDialog( +// title: Text(L10n.of(context)!.languagesISpeak), +// contentPadding: const EdgeInsets.only(top: 12.0), +// content: SingleChildScrollView( +// child: ListTileTheme( +// contentPadding: const EdgeInsets.fromLTRB(14.0, 0.0, 24.0, 0.0), +// child: ListBody( +// children: +// pangeaController.pLanguageStore.baseOptions.map((language) { +// return CheckboxListTile( +// value: _selectedValues.contains(language.langCode), +// //PTODO - show flag with name +// title: Text(language.displayName), +// controlAffinity: ListTileControlAffinity.leading, +// onChanged: (checked) => _onItemCheckedChange(language, checked), +// ); +// }).toList(), +// ), +// ), +// ), +// actions: [ +// TextButton( +// onPressed: () => Navigator.pop(context), +// child: Text(L10n.of(context)!.cancel), +// ), +// TextButton( +// onPressed: () => showFutureLoadingDialog( +// context: context, +// future: (() async { +// await pangeaController.userController +// .updateUserProfile(speaks: _selectedValues); +// Navigator.pop(context); +// }), +// ), +// child: Text(L10n.of(context)!.ok), +// ) +// ], +// ); +// } +// } diff --git a/lib/pangea/widgets/user_settings/p_language_dialog.dart b/lib/pangea/widgets/user_settings/p_language_dialog.dart new file mode 100644 index 000000000..b914212dc --- /dev/null +++ b/lib/pangea/widgets/user_settings/p_language_dialog.dart @@ -0,0 +1,115 @@ +import 'dart:developer'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; + +import 'package:fluffychat/pangea/controllers/pangea_controller.dart'; +import 'package:fluffychat/pangea/models/language_model.dart'; +import 'package:fluffychat/pangea/utils/error_handler.dart'; +import '../../../config/themes.dart'; +import '../../../widgets/matrix.dart'; +import 'p_language_dropdown.dart'; +import 'p_question_container.dart'; + +pLanguageDialog(BuildContext parentContext, Function callback) { + final PangeaController pangeaController = MatrixState.pangeaController; + //PTODO: if source language not set by user, default to languge from device settings + LanguageModel selectedSourceLanguage = + pangeaController.languageController.userL1 ?? + pangeaController.pLanguageStore.targetOptions[0]; + LanguageModel selectedTargetLanguage = + pangeaController.languageController.userL2 ?? + pangeaController.pLanguageStore.targetOptions[1]; + + return showDialog( + useRootNavigator: false, + context: parentContext, + builder: (BuildContext context) { + return StatefulBuilder( + builder: (BuildContext context, StateSetter setState) { + return Scaffold( + backgroundColor: Colors.transparent, + body: AlertDialog( + title: Text(L10n.of(parentContext)!.updateLanguage), + content: SizedBox( + width: FluffyThemes.columnWidth, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + PQuestionContainer( + title: L10n.of(parentContext)!.whatIsYourBaseLanguage, + ), + PLanguageDropdown( + onChange: (p0) => + setState(() => selectedSourceLanguage = p0), + initialLanguage: selectedSourceLanguage, + languages: pangeaController.pLanguageStore.baseOptions, + ), + PQuestionContainer( + title: L10n.of(parentContext)!.whatLanguageYouWantToLearn, + ), + PLanguageDropdown( + onChange: (p0) => + setState(() => selectedTargetLanguage = p0), + initialLanguage: selectedTargetLanguage, + languages: pangeaController.pLanguageStore.targetOptions, + ), + ], + ), + ), + actions: [ + TextButton( + child: Text(L10n.of(parentContext)!.cancel), + onPressed: () { + Navigator.pop(context); + }, + ), + TextButton( + onPressed: () { + selectedSourceLanguage.langCode != + selectedTargetLanguage.langCode + ? showFutureLoadingDialog( + context: context, + future: () async { + try { + await pangeaController.userController + .updateUserProfile( + sourceLanguage: + selectedSourceLanguage.langCode, + targetLanguage: + selectedTargetLanguage.langCode, + ); + Navigator.pop(context); + } catch (err, s) { + debugger(when: kDebugMode); + //PTODO-Lala add standard error message + ErrorHandler.logError(e: err, s: s); + rethrow; + } finally { + callback(); + } + }, + ) + : ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text( + L10n.of(parentContext)!.noIdenticalLanguages, + ), + backgroundColor: + Theme.of(context).colorScheme.primary, + ), + ); + }, + child: Text(L10n.of(parentContext)!.saveChanges), + ), + ], + ), + ); + }, + ); + }, + ); +} diff --git a/lib/pangea/widgets/user_settings/p_language_dropdown.dart b/lib/pangea/widgets/user_settings/p_language_dropdown.dart new file mode 100644 index 000000000..0694355c5 --- /dev/null +++ b/lib/pangea/widgets/user_settings/p_language_dropdown.dart @@ -0,0 +1,142 @@ +// Flutter imports: + +import 'package:flutter/material.dart'; + +import 'package:fluffychat/pangea/models/language_model.dart'; +import '../../widgets/flag.dart'; + +class PLanguageDropdown extends StatefulWidget { + final List languages; + final LanguageModel initialLanguage; + final Function(LanguageModel) onChange; + final bool showMultilingual; + + const PLanguageDropdown({ + super.key, + required this.languages, + required this.onChange, + required this.initialLanguage, + this.showMultilingual = false, + }); + + @override + State createState() => _PLanguageDropdownState(); +} + +class _PLanguageDropdownState extends State { + @override + Widget build(BuildContext context) { + final List sortedLanguages = widget.languages; + + int sortLanguages(LanguageModel a, LanguageModel b) { + if (a.langCode == 'en') { + return -1; // "English" comes first + } else if (b.langCode == 'en') { + return 1; + } else if (a.langCode == 'es') { + return -1; // "Spanish" comes second + } else if (b.langCode == 'es') { + return 1; + } + return a.getDisplayName(context)!.compareTo(b.getDisplayName(context)!); + } + + sortedLanguages.sort((a, b) => sortLanguages(a, b)); + + return Padding( + padding: const EdgeInsets.all(12), + child: Container( + decoration: BoxDecoration( + border: Border.all( + color: Theme.of(context).colorScheme.secondary, + width: 0.5, + ), + borderRadius: const BorderRadius.all(Radius.circular(10)), + ), + child: DropdownButton( + // Initial Value + hint: Row( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Padding( + padding: const EdgeInsets.only(left: 10), + child: LanguageFlag( + language: widget.initialLanguage, + ), + ), + const SizedBox(width: 10), + Text( + widget.initialLanguage.getDisplayName(context) ?? "", + style: const TextStyle().copyWith( + color: Theme.of(context).textTheme.bodyLarge!.color, + fontSize: 14, + ), + overflow: TextOverflow.clip, + textAlign: TextAlign.center, + ), + ], + ), + + isExpanded: true, + // Down Arrow Icon + icon: const Icon(Icons.keyboard_arrow_down), + underline: Container(), + // Array list of items + items: [ + if (widget.showMultilingual) + DropdownMenuItem( + value: LanguageModel.multiLingual(context), + child: LanguageDropDownEntry( + languageModel: LanguageModel.multiLingual(context), + ), + ), + ...sortedLanguages.map( + (languageModel) => DropdownMenuItem( + value: languageModel, + child: LanguageDropDownEntry( + languageModel: languageModel, + ), + ), + ), + ], + onChanged: (value) => widget.onChange(value!), + ), + ), + ); + } +} + +class LanguageDropDownEntry extends StatelessWidget { + final LanguageModel languageModel; + const LanguageDropDownEntry({ + super.key, + required this.languageModel, + }); + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.only(left: 12), + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + LanguageFlag( + language: languageModel, + ), + const SizedBox(width: 10), + Text( + languageModel.getDisplayName(context) ?? "", + style: const TextStyle().copyWith( + color: Theme.of(context).textTheme.bodyLarge!.color, + fontSize: 14, + ), + overflow: TextOverflow.clip, + textAlign: TextAlign.center, + ), + ], + ), + ); + } +} diff --git a/lib/pangea/widgets/user_settings/p_question_container.dart b/lib/pangea/widgets/user_settings/p_question_container.dart new file mode 100644 index 000000000..95a9b7c20 --- /dev/null +++ b/lib/pangea/widgets/user_settings/p_question_container.dart @@ -0,0 +1,24 @@ +import 'package:flutter/material.dart'; + +class PQuestionContainer extends StatelessWidget { + final String title; + const PQuestionContainer({super.key, required this.title}); + @override + Widget build(BuildContext context) { + final Size size = MediaQuery.of(context).size; + return Container( + constraints: const BoxConstraints(minWidth: 100, maxWidth: 650), + padding: EdgeInsets.all(size.height * 0.01), + alignment: Alignment.centerLeft, + child: Text( + title, + style: const TextStyle().copyWith( + color: Theme.of(context).textTheme.bodyLarge!.color, + fontSize: 14, + ), + overflow: TextOverflow.clip, + textAlign: TextAlign.left, + ), + ); + } +} diff --git a/lib/pangea/widgets/user_settings/p_settings_switch_list_tile.dart b/lib/pangea/widgets/user_settings/p_settings_switch_list_tile.dart new file mode 100644 index 000000000..1ae2277a0 --- /dev/null +++ b/lib/pangea/widgets/user_settings/p_settings_switch_list_tile.dart @@ -0,0 +1,41 @@ +import 'package:flutter/material.dart'; + +import 'package:fluffychat/config/app_config.dart'; +import 'package:fluffychat/pangea/controllers/pangea_controller.dart'; +import 'package:fluffychat/widgets/matrix.dart'; + +class PSettingsSwitchListTile extends StatefulWidget { + final bool defaultValue; + final String pStoreKey; + final String title; + final String? subtitle; + + const PSettingsSwitchListTile.adaptive({ + super.key, + this.defaultValue = false, + required this.pStoreKey, + required this.title, + this.subtitle, + }); + + @override + PSettingsSwitchListTileState createState() => PSettingsSwitchListTileState(); +} + +class PSettingsSwitchListTileState extends State { + @override + Widget build(BuildContext context) { + final PangeaController pangeaController = MatrixState.pangeaController; + return SwitchListTile.adaptive( + value: pangeaController.pStoreService.read(widget.pStoreKey) ?? + widget.defaultValue, + title: Text(widget.title), + activeColor: AppConfig.activeToggleColor, + subtitle: widget.subtitle != null ? Text(widget.subtitle!) : null, + onChanged: (bool newValue) async { + pangeaController.pStoreService.save(widget.pStoreKey, newValue); + setState(() {}); + }, + ); + } +} diff --git a/lib/pangea/word_cloud/word_cloud.dart b/lib/pangea/word_cloud/word_cloud.dart new file mode 100644 index 000000000..d33245a6c --- /dev/null +++ b/lib/pangea/word_cloud/word_cloud.dart @@ -0,0 +1,8 @@ +library word_cloud; + +export 'word_cloud_data.dart'; +export 'word_cloud_setting.dart'; +export 'word_cloud_shape.dart'; +export 'word_cloud_tap_view.dart'; +export 'word_cloud_tap.dart'; +export 'word_cloud_view.dart'; diff --git a/lib/pangea/word_cloud/word_cloud_data.dart b/lib/pangea/word_cloud/word_cloud_data.dart new file mode 100644 index 000000000..abc1c0d1a --- /dev/null +++ b/lib/pangea/word_cloud/word_cloud_data.dart @@ -0,0 +1,29 @@ +class WordCloudData { + List data = []; + + WordCloudData({ + required this.data, + }) { + data = (data..sort((a, b) => (a['value'] ?? 0).compareTo(b['value'] ?? 0))) + .reversed + .toList(); + } + + void addDataAsMapList(List newdata) { + data.addAll(newdata); + data = (data..sort((a, b) => a['value'].compareTo(b['value']))) + .reversed + .toList(); + } + + void addData(String word, double value) { + data.add({'word': word, 'value': value}); + data = (data..sort((a, b) => a['value'].compareTo(b['value']))) + .reversed + .toList(); + } + + List getData() { + return data; + } +} diff --git a/lib/pangea/word_cloud/word_cloud_setting.dart b/lib/pangea/word_cloud/word_cloud_setting.dart new file mode 100644 index 000000000..2e0768991 --- /dev/null +++ b/lib/pangea/word_cloud/word_cloud_setting.dart @@ -0,0 +1,350 @@ +import 'dart:math'; + +import 'package:flutter/material.dart'; + +import 'package:fluffychat/pangea/word_cloud/word_cloud_shape.dart'; + +class WordCloudSetting { + double mapX = 0; + double mapY = 0; + String? fontFamily; + FontStyle? fontStyle; + FontWeight? fontWeight; + List data = []; + List map = [[]]; + List textCenter = []; + List textPoints = []; + List textlist = []; + List isdrawed = []; + double centerX = 0; + double centerY = 0; + double minTextSize; + double maxTextSize; + WordCloudShape shape; + int attempt; + List? colorList = [Colors.black]; + + WordCloudSetting({ + Key? key, + required this.data, + required this.minTextSize, + required this.maxTextSize, + required this.attempt, + required this.shape, + }); + + void setMapSize(double x, double y) { + mapX = x; + mapY = y; + } + + void setColorList(List? colors) { + colorList = colors; + } + + void setFont(String? family, FontStyle? style, FontWeight? weight) { + fontFamily = family; + fontStyle = style; + fontWeight = weight; + } + + List setMap(dynamic shape) { + final List makemap = [[]]; + switch (shape.getType()) { + case 'normal': + for (var i = 0; i < mapX; i++) { + for (var j = 0; j < mapY; j++) { + makemap[i].add(0); + } + makemap.add([]); + } + break; + + case 'circle': + for (var i = 0; i < mapX; i++) { + for (var j = 0; j < mapY; j++) { + if (pow(i - (mapX / 2), 2) + pow(j - (mapY / 2), 2) > + pow(shape.getRadius(), 2)) { + makemap[i].add(1); + } else { + makemap[i].add(0); + } + } + makemap.add([]); + } + break; + + case 'ellipse': + for (var i = 0; i < mapX; i++) { + for (var j = 0; j < mapY; j++) { + if (pow(i - (mapX / 2), 2) / pow(shape.getMajorAxis(), 2) + + pow(j - (mapY / 2), 2) / pow(shape.getMinorAxis(), 2) > + 1) { + makemap[i].add(1); + } else { + makemap[i].add(0); + } + } + makemap.add([]); + } + break; + } + return makemap; + } + + void setInitial() { + //map = [[]]; + textCenter = []; + textPoints = []; + textlist = []; + isdrawed = []; + + centerX = mapX / 2; + centerY = mapY / 2; + + map = setMap(shape); + + // for (var i = 0; i < mapX; i++) { + // for (var j = 0; j < mapY; j++) { + // if (pow(i - (mapX / 2), 2) + pow(j - (mapY / 2), 2) > pow(250, 2)) { + // map[i].add(1); + // } else { + // map[i].add(0); + // } + // } + // map.add([]); + // } + + for (var i = 0; i < data.length; i++) { + final double getTextSize = + (minTextSize * (data[0]['value'] - data[i]['value']) + + maxTextSize * + (data[i]['value'] - data[data.length - 1]['value'])) / + (data[0]['value'] - data[data.length - 1]['value']); + + final textSpan = TextSpan( + text: data[i]['word'], + style: TextStyle( + color: colorList?[Random().nextInt(colorList!.length)], + fontSize: getTextSize, + fontWeight: fontWeight, + fontFamily: fontFamily, + fontStyle: fontStyle, + ), + ); + + final textPainter = TextPainter() + ..text = textSpan + ..textDirection = TextDirection.ltr + ..textAlign = TextAlign.center + ..layout(); + + textlist.add(textPainter); + + final double centerCorrectionX = centerX - textlist[i].width / 2; + final double centerCorrectionY = centerY - textlist[i].height / 2; + textCenter.add([centerCorrectionX, centerCorrectionY]); + textPoints.add([]); + isdrawed.add(false); + } + } + + void setTextStyle(List newstyle) { + //only support color, weight, family, fontstyle + textlist = []; + textCenter = []; + textPoints = []; + isdrawed = []; + + for (var i = 0; i < data.length; i++) { + final double getTextSize = + (minTextSize * (data[0]['value'] - data[i]['value']) + + maxTextSize * + (data[i]['value'] - data[data.length - 1]['value'])) / + (data[0]['value'] - data[data.length - 1]['value']); + + final textSpan = TextSpan( + text: data[i]['word'], + style: TextStyle( + color: newstyle[i].color, + fontSize: getTextSize, + fontWeight: newstyle[i].fontWeight, + fontFamily: newstyle[i].fontFamily, + fontStyle: newstyle[i].fontStyle, + ), + ); + + final textPainter = TextPainter() + ..text = textSpan + ..textDirection = TextDirection.ltr + ..textAlign = TextAlign.center + ..layout(); + + textlist.add(textPainter); + + final double centerCorrectionX = centerX - textlist[i].width / 2; + final double centerCorrectionY = centerY - textlist[i].height / 2; + textCenter.add([centerCorrectionX, centerCorrectionY]); + textPoints.add([]); + isdrawed.add(false); + } + } + + bool checkMap(double x, double y, double w, double h) { + if (mapX - x < w) { + return false; + } + if (mapY - y < h) { + return false; + } + for (int i = x.toInt(); i < x.toInt() + w; i++) { + for (int j = y.toInt(); j < y.toInt() + h; j++) { + if (map[i][j] == 1) { + return false; + } + } + } + return true; + } + + bool checkMapOptimized(int x, int y, double w, double h) { + if (mapX - x < w) { + return false; + } + if (mapY - y < h) { + return false; + } + for (int i = x.toInt(); i < x.toInt() + w; i++) { + if (map[i][y + h - 1] == 1) { + return false; + } + if (map[i][y + 1] == 1) { + return false; + } + } + return true; + } + + void drawIn(int index, double x, double y) { + textPoints[index] = [x, y]; + for (int i = x.toInt(); i < x.toInt() + textlist[index].width; i++) { + for (int j = y.toInt(); + j < y.toInt() + textlist[index].height.floor(); + j++) { + map[i][j] = 1; + } + } + } + + void drawTextOptimized() { + drawIn(0, textCenter[0][0], textCenter[0][1]); + isdrawed[0] = true; + bool checkattempt = false; + for (var i = 1; i < textlist.length; i++) { + final double w = textlist[i].width; + final double h = textlist[i].height; + int attempts = 0; + + bool isadded = false; + + while (!isadded) { + final int getX = Random().nextInt(mapX.toInt() - w.toInt()); + final int direction = Random().nextInt(2); + if (direction == 0) { + for (int y = textCenter[i][1].toInt(); y > 0; y--) { + if (checkMapOptimized(getX, y, w, h)) { + drawIn(i, getX.toDouble(), y.toDouble()); + isadded = true; + isdrawed[i] = true; + break; + } + } + } else if (direction == 1) { + for (int y = textCenter[i][1].toInt(); y < mapY; y++) { + if (checkMapOptimized(getX, y, w, h)) { + drawIn(i, getX.toDouble(), y.toDouble()); + isadded = true; + isdrawed[i] = true; + break; + } + } + } + attempts += 1; + if (attempts > attempt) { + isadded = true; + checkattempt = true; + } + } + if (checkattempt) { + return; + } + } + } + + void drawText() { + drawIn(0, textCenter[0][0], textCenter[0][1]); + for (var i = 1; i < textlist.length; i++) { + final double w = textlist[i].width; + final double h = textlist[i].height; + int attempts = 0; + + bool isadded = false; + + while (!isadded) { + final int getX = Random().nextInt(mapX.toInt() - w.toInt()); + final int direction = Random().nextInt(2); + if (direction == 0) { + for (int y = textCenter[i][1].toInt(); y > 0; y--) { + if (checkMap(getX.toDouble(), y.toDouble(), w, h)) { + drawIn(i, getX.toDouble(), y.toDouble()); + isadded = true; + break; + } + } + if (!isadded) { + for (int y = textCenter[i][1].toInt(); y < mapY; y++) { + if (checkMap(getX.toDouble(), y.toDouble(), w, h)) { + drawIn(i, getX.toDouble(), y.toDouble()); + isadded = true; + break; + } + } + } + } else if (direction == 1) { + for (int y = textCenter[i][1].toInt(); y < mapY; y++) { + if (checkMap(getX.toDouble(), y.toDouble(), w, h)) { + drawIn(i, getX.toDouble(), y.toDouble()); + isadded = true; + break; + } + } + if (!isadded) { + for (int y = textCenter[i][1].toInt(); y > 0; y--) { + if (checkMap(getX.toDouble(), y.toDouble(), w, h)) { + drawIn(i, getX.toDouble(), y.toDouble()); + isadded = true; + break; + } + } + } + } + attempts += 1; + if (attempts > attempt) { + isadded = true; + } + } + } + } + + List getWordPoint() { + return textPoints; + } + + List getTextPainter() { + return textlist; + } + + int getDataLength() { + return data.length; + } +} diff --git a/lib/pangea/word_cloud/word_cloud_shape.dart b/lib/pangea/word_cloud/word_cloud_shape.dart new file mode 100644 index 000000000..afc03b328 --- /dev/null +++ b/lib/pangea/word_cloud/word_cloud_shape.dart @@ -0,0 +1,42 @@ +class WordCloudShape { + double boundaryStartX = 0; + double boundaryEndX = 0; + double boundaryStartY = 0; + double boundaryEndY = 0; + String type = 'normal'; + + String getType() { + return type; + } +} + +class WordCloudCircle extends WordCloudShape { + double radius; + + WordCloudCircle({required this.radius}) { + type = 'circle'; + } + + double getRadius() { + return radius; + } +} + +class WordCloudEllipse extends WordCloudShape { + double majoraxis; + double minoraxis; + WordCloudEllipse({ + required this.majoraxis, + required this.minoraxis, + }) { + type = 'ellipse'; + } + + double getMajorAxis() { + return majoraxis; + } + + double getMinorAxis() { + return minoraxis; + } +} diff --git a/lib/pangea/word_cloud/word_cloud_tap.dart b/lib/pangea/word_cloud/word_cloud_tap.dart new file mode 100644 index 000000000..0583fd214 --- /dev/null +++ b/lib/pangea/word_cloud/word_cloud_tap.dart @@ -0,0 +1,11 @@ +class WordCloudTap { + Map wordtap = {}; + + void addWordtap(String word, Function func) { + wordtap[word] = func; + } + + Map getWordTaps() { + return wordtap; + } +} diff --git a/lib/pangea/word_cloud/word_cloud_tap_view.dart b/lib/pangea/word_cloud/word_cloud_tap_view.dart new file mode 100644 index 000000000..8e1a45124 --- /dev/null +++ b/lib/pangea/word_cloud/word_cloud_tap_view.dart @@ -0,0 +1,133 @@ +import 'package:flutter/material.dart'; + +import 'package:fluffychat/pangea/word_cloud/word_cloud_data.dart'; +import 'package:fluffychat/pangea/word_cloud/word_cloud_setting.dart'; +import 'package:fluffychat/pangea/word_cloud/word_cloud_shape.dart'; +import 'package:fluffychat/pangea/word_cloud/word_cloud_tap.dart'; + +class WordCloudTapView extends StatefulWidget { + final WordCloudData data; + final Color? mapcolor; + final Decoration? decoration; + final double mapwidth; + final String? fontFamily; + final FontStyle? fontStyle; + final FontWeight? fontWeight; + final double mapheight; + final List? colorlist; + final int attempt; + final double mintextsize; + final double maxtextsize; + final WordCloudShape? shape; + final WordCloudTap wordtap; + + const WordCloudTapView({ + super.key, + required this.data, + required this.mapwidth, + required this.mapheight, + required this.wordtap, + this.mintextsize = 10, + this.maxtextsize = 100, + this.attempt = 30, + this.shape, + this.fontFamily, + this.fontStyle, + this.fontWeight, + this.mapcolor, + this.decoration, + this.colorlist, + }); + @override + State createState() => _WordCloudTapViewState(); +} + +class _WordCloudTapViewState extends State { + late WordCloudShape wcshape; + late WordCloudSetting wordcloudsetting; + + @override + void initState() { + super.initState(); + if (widget.shape == null) { + wcshape = WordCloudShape(); + } else { + wcshape = widget.shape!; + } + + wordcloudsetting = WordCloudSetting( + data: widget.data.getData(), + minTextSize: widget.mintextsize, + maxTextSize: widget.maxtextsize, + attempt: widget.attempt, + shape: wcshape, + ); + + wordcloudsetting.setMapSize(widget.mapwidth, widget.mapheight); + wordcloudsetting.setFont( + widget.fontFamily, + widget.fontStyle, + widget.fontWeight, + ); + wordcloudsetting.setColorList(widget.colorlist); + wordcloudsetting.setInitial(); + wordcloudsetting.drawTextOptimized(); + } + + @override + Widget build(BuildContext context) { + return GestureDetector( + onVerticalDragDown: (details) { + for (var i = 0; i < widget.data.getData().length; i++) { + final List points = wordcloudsetting.textPoints; + final double w = wordcloudsetting.textlist[i].width; + final double h = wordcloudsetting.textlist[i].height; + if (points[i][0] < details.localPosition.dx && + details.localPosition.dx < (points[i][0] + w) && + points[i][1] < details.localPosition.dy && + details.localPosition.dy < (points[i][1] + h)) { + if (widget.wordtap + .getWordTaps() + .containsKey(widget.data.getData()[i]['word'])) { + widget.wordtap.getWordTaps()[widget.data.getData()[i]['word']]!(); + } + } + } + }, + child: Container( + width: widget.mapwidth, + height: widget.mapheight, + color: widget.mapcolor, + decoration: widget.decoration, + child: CustomPaint( + painter: WCTpaint(wordcloudpaint: wordcloudsetting), + ), + ), + ); + } +} + +class WCTpaint extends CustomPainter { + final WordCloudSetting wordcloudpaint; + WCTpaint({ + required this.wordcloudpaint, + }); + + @override + void paint(Canvas canvas, Size size) { + for (var i = 0; i < wordcloudpaint.getDataLength(); i++) { + if (wordcloudpaint.isdrawed[i]) { + wordcloudpaint.getTextPainter()[i].paint( + canvas, + Offset( + wordcloudpaint.getWordPoint()[i][0], + wordcloudpaint.getWordPoint()[i][1], + ), + ); + } + } + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) => false; +} diff --git a/lib/pangea/word_cloud/word_cloud_view.dart b/lib/pangea/word_cloud/word_cloud_view.dart new file mode 100644 index 000000000..850b26f8e --- /dev/null +++ b/lib/pangea/word_cloud/word_cloud_view.dart @@ -0,0 +1,112 @@ +import 'package:flutter/material.dart'; + +import 'package:fluffychat/pangea/word_cloud/word_cloud_data.dart'; +import 'package:fluffychat/pangea/word_cloud/word_cloud_setting.dart'; +import 'package:fluffychat/pangea/word_cloud/word_cloud_shape.dart'; + +class WordCloudView extends StatefulWidget { + final WordCloudData data; + final Color? mapcolor; + final Decoration? decoration; + final double mapwidth; + final String? fontFamily; + final FontStyle? fontStyle; + final FontWeight? fontWeight; + final double mapheight; + final List? colorlist; + final int attempt; + final double mintextsize; + final double maxtextsize; + final WordCloudShape? shape; + + const WordCloudView({ + super.key, + required this.data, + required this.mapwidth, + required this.mapheight, + this.mintextsize = 10, + this.maxtextsize = 100, + this.attempt = 30, + this.shape, + this.fontFamily, + this.fontStyle, + this.fontWeight, + this.mapcolor, + this.decoration, + this.colorlist, + }); + @override + State createState() => _WordCloudViewState(); +} + +class _WordCloudViewState extends State { + late WordCloudShape wcshape; + late WordCloudSetting wordcloudsetting; + + @override + void initState() { + super.initState(); + if (widget.shape == null) { + wcshape = WordCloudShape(); + } else { + wcshape = widget.shape!; + } + + wordcloudsetting = WordCloudSetting( + data: widget.data.getData(), + minTextSize: widget.mintextsize, + maxTextSize: widget.maxtextsize, + attempt: widget.attempt, + shape: wcshape, + ); + + wordcloudsetting.setMapSize(widget.mapwidth, widget.mapheight); + wordcloudsetting.setFont( + widget.fontFamily, + widget.fontStyle, + widget.fontWeight, + ); + wordcloudsetting.setColorList(widget.colorlist); + wordcloudsetting.setInitial(); + + wordcloudsetting.drawTextOptimized(); + } + + @override + Widget build(BuildContext context) { + return Container( + width: widget.mapwidth, + height: widget.mapheight, + color: widget.mapcolor, + decoration: widget.decoration, + child: CustomPaint( + painter: WCpaint(wordcloudpaint: wordcloudsetting), + ), + ); + } +} + +class WCpaint extends CustomPainter { + final WordCloudSetting wordcloudpaint; + WCpaint({ + required this.wordcloudpaint, + }); + + @override + void paint(Canvas canvas, Size size) { + for (var i = 0; i < wordcloudpaint.getDataLength(); i++) { + if (wordcloudpaint.isdrawed[i]) { + wordcloudpaint.getTextPainter()[i].paint( + canvas, + Offset( + wordcloudpaint.getWordPoint()[i][0], + wordcloudpaint.getWordPoint()[i][1], + ), + ); + } + } + } + + @override + bool shouldRepaint(CustomPainter oldDelegate) => false; +} diff --git a/lib/utils/background_push.dart b/lib/utils/background_push.dart index 1f04d4d69..2bbcc1f92 100644 --- a/lib/utils/background_push.dart +++ b/lib/utils/background_push.dart @@ -24,6 +24,9 @@ import 'dart:io'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import 'package:fcm_shared_isolate/fcm_shared_isolate.dart'; +import 'package:firebase_core/firebase_core.dart'; +import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter_app_badger/flutter_app_badger.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart'; @@ -31,13 +34,14 @@ import 'package:http/http.dart' as http; import 'package:matrix/matrix.dart'; import 'package:unifiedpush/unifiedpush.dart'; +import 'package:fluffychat/pangea/constants/language_keys.dart'; +import 'package:fluffychat/pangea/utils/error_handler.dart'; import 'package:fluffychat/utils/matrix_sdk_extensions/client_stories_extension.dart'; import 'package:fluffychat/utils/push_helper.dart'; import 'package:fluffychat/widgets/fluffy_chat_app.dart'; import '../config/app_config.dart'; import '../config/setting_keys.dart'; import '../widgets/matrix.dart'; -import 'famedlysdk_store.dart'; import 'platform_infos.dart'; //import 'package:fcm_shared_isolate/fcm_shared_isolate.dart'; @@ -55,8 +59,7 @@ class BackgroundPush { String? _fcmToken; void Function(String errorMsg, {Uri? link})? onFcmError; L10n? l10n; - Store? _store; - Store get store => _store ??= Store(); + Future loadLocale() async { final context = matrix?.context; // inspired by _lookupL10n in .dart_tool/flutter_gen/gen_l10n/l10n.dart @@ -66,13 +69,21 @@ class BackgroundPush { final pendingTests = >{}; - final dynamic firebase = null; //FcmSharedIsolate(); + // final dynamic firebase = null; //FcmSharedIsolate(); + // #Pangea + // uncommented to enable notifications on IOS + final FcmSharedIsolate? firebase = FcmSharedIsolate(); + // Pangea# DateTime? lastReceivedPush; bool upAction = false; BackgroundPush._(this.client) { + // #Pangea + onLogin ??= + client.onLoginStateChanged.stream.listen(handleLoginStateChanged); + // Pangea# onRoomSync ??= client.onSync.stream .where((s) => s.hasRoomUpdate) .listen((s) => _onClearingPush(getFromServer: false)); @@ -86,6 +97,9 @@ class BackgroundPush { activeRoomId: matrix?.activeRoomId, onSelectNotification: goToRoom, ), + // #Pangea + onNewToken: _newFcmToken, + // Pangea# ); if (Platform.isAndroid) { UnifiedPush.initialize( @@ -110,9 +124,27 @@ class BackgroundPush { instance.matrix = matrix; // ignore: prefer_initializing_formals instance.onFcmError = onFcmError; + // #Pangea + instance.fullInit(); + // Pangea# return instance; } + // #Pangea + Future fullInit() => setupPush(); + + void handleLoginStateChanged(_) => setupPush(); + + StreamSubscription? onLogin; + StreamSubscription? onRoomSync; + + void _newFcmToken(String token) { + _fcmToken = token; + debugPrint('Fcm foken $_fcmToken'); + setupPush(); + } + // Pangea# + Future cancelNotification(String roomId) async { Logs().v('Cancel notification for room', roomId); final id = await mapRoomIdToInt(roomId); @@ -132,8 +164,6 @@ class BackgroundPush { } } - StreamSubscription? onRoomSync; - Future setupPusher({ String? gatewayUrl, String? token, @@ -171,6 +201,9 @@ class BackgroundPush { currentPushers.first.appDisplayName == clientName && currentPushers.first.deviceDisplayName == client.deviceName && currentPushers.first.lang == 'en' && + // #Pangea + currentPushers.first.lang == LanguageKeys.defaultLanguage && + // Pangea# currentPushers.first.data.url.toString() == gatewayUrl && currentPushers.first.data.format == AppConfig.pushNotificationsPusherFormat && @@ -210,7 +243,10 @@ class BackgroundPush { appId: thisAppId, appDisplayName: clientName, deviceDisplayName: client.deviceName!, - lang: 'en', + //#Pangea + // lang: 'en', + lang: LanguageKeys.defaultLanguage, + // Pangea# data: PusherData( url: Uri.parse(gatewayUrl!), format: AppConfig.pushNotificationsPusherFormat, @@ -222,6 +258,9 @@ class BackgroundPush { ); } catch (e, s) { Logs().e('[Push] Unable to set pushers', e, s); + // #Pangea + ErrorHandler.logError(e: e, s: s); + // Pangea# } } } @@ -271,7 +310,7 @@ class BackgroundPush { if (matrix == null) { return; } - if (await store.getItemBool(SettingKeys.showNoGoogle, true) == true) { + if ((matrix?.store.getBool(SettingKeys.showNoGoogle) ?? false) == true) { return; } await loadLocale(); @@ -293,7 +332,10 @@ class BackgroundPush { Logs().v('Setup firebase'); if (_fcmToken?.isEmpty ?? true) { try { - _fcmToken = await firebase?.getToken(); + // #Pangea + // _fcmToken = await firebase?.getToken(); + _fcmToken = await _getToken(); + // Pangea# if (_fcmToken == null) throw ('PushToken is null'); } catch (e, s) { Logs().w('[Push] cannot get token', e, e is String ? null : s); @@ -326,6 +368,9 @@ class BackgroundPush { .go('/${isStory ? 'rooms/stories' : 'rooms'}/$roomId'); } catch (e, s) { Logs().e('[Push] Failed to open room', e, s); + // #Pangea + ErrorHandler.logError(e: e, s: s); + // Pangea# } } @@ -365,7 +410,10 @@ class BackgroundPush { Logs().i('[Push] UnifiedPush using endpoint $endpoint'); final oldTokens = {}; try { - final fcmToken = await firebase?.getToken(); + // #Pangea + // final fcmToken = await firebase?.getToken(); + final fcmToken = await _getToken(); + // Pangea# oldTokens.add(fcmToken); } catch (_) {} await setupPusher( @@ -374,16 +422,17 @@ class BackgroundPush { oldTokens: oldTokens, useDeviceSpecificAppId: true, ); - await store.setItem(SettingKeys.unifiedPushEndpoint, newEndpoint); - await store.setItemBool(SettingKeys.unifiedPushRegistered, true); + await matrix?.store.setString(SettingKeys.unifiedPushEndpoint, newEndpoint); + await matrix?.store.setBool(SettingKeys.unifiedPushRegistered, true); } Future _upUnregistered(String i) async { upAction = true; Logs().i('[Push] Removing UnifiedPush endpoint...'); - final oldEndpoint = await store.getItem(SettingKeys.unifiedPushEndpoint); - await store.setItemBool(SettingKeys.unifiedPushRegistered, false); - await store.deleteItem(SettingKeys.unifiedPushEndpoint); + final oldEndpoint = + matrix?.store.getString(SettingKeys.unifiedPushEndpoint); + await matrix?.store.setBool(SettingKeys.unifiedPushRegistered, false); + await matrix?.store.remove(SettingKeys.unifiedPushEndpoint); if (oldEndpoint?.isNotEmpty ?? false) { // remove the old pusher await setupPusher( @@ -409,12 +458,12 @@ class BackgroundPush { /// Workaround for the problem that local notification IDs must be int but we /// sort by [roomId] which is a String. To make sure that we don't have duplicated - /// IDs we map the [roomId] to a number and store this number. + /// IDs we map the [roomId] to a number and matrix?.store this number. late Map idMap; Future _loadIdMap() async { idMap = Map.from( json.decode( - (await store.getItem(SettingKeys.notificationCurrentIds)) ?? '{}', + (matrix?.store.getString(SettingKeys.notificationCurrentIds)) ?? '{}', ), ); } @@ -488,7 +537,7 @@ class BackgroundPush { } } if (changed) { - await store.setItem( + await matrix?.store.setString( SettingKeys.notificationCurrentIds, json.encode(idMap), ); @@ -497,4 +546,16 @@ class BackgroundPush { _clearingPushLock = false; } } + + // #Pangea + Future _getToken() async { + if (Platform.isAndroid) { + await Firebase.initializeApp( + // options: DefaultFirebaseOptions.currentPlatform, + ); + return (await FirebaseMessaging.instance.getToken()); + } + return await firebase?.getToken(); + } + // Pangea# } diff --git a/lib/utils/client_manager.dart b/lib/utils/client_manager.dart index 1ee71d491..0cc5b0051 100644 --- a/lib/utils/client_manager.dart +++ b/lib/utils/client_manager.dart @@ -1,21 +1,23 @@ -import 'dart:convert'; - import 'package:flutter/foundation.dart'; import 'package:hive_flutter/hive_flutter.dart'; import 'package:matrix/encryption/utils/key_verification.dart'; import 'package:matrix/matrix.dart'; import 'package:path_provider/path_provider.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:fluffychat/pangea/constants/pangea_event_types.dart'; import 'package:fluffychat/utils/custom_http_client.dart'; import 'package:fluffychat/utils/custom_image_resizer.dart'; import 'package:fluffychat/utils/matrix_sdk_extensions/flutter_hive_collections_database.dart'; import 'package:fluffychat/utils/platform_infos.dart'; -import 'famedlysdk_store.dart'; abstract class ClientManager { static const String clientNamespace = 'im.fluffychat.store.clients'; - static Future> getClients({bool initialize = true}) async { + static Future> getClients({ + bool initialize = true, + required SharedPreferences store, + }) async { if (PlatformInfos.isLinux) { Hive.init((await getApplicationSupportDirectory()).path); } else { @@ -23,19 +25,15 @@ abstract class ClientManager { } final clientNames = {}; try { - final rawClientNames = await Store().getItem(clientNamespace); - if (rawClientNames != null) { - final clientNamesList = - (jsonDecode(rawClientNames) as List).cast(); - clientNames.addAll(clientNamesList); - } + final clientNamesList = store.getStringList(clientNamespace) ?? []; + clientNames.addAll(clientNamesList); } catch (e, s) { Logs().w('Client names in store are corrupted', e, s); - await Store().deleteItem(clientNamespace); + await store.remove(clientNamespace); } if (clientNames.isEmpty) { clientNames.add(PlatformInfos.clientName); - await Store().setItem(clientNamespace, jsonEncode(clientNames.toList())); + await store.setStringList(clientNamespace, clientNames.toList()); } final clients = clientNames.map(createClient).toList(); if (initialize) { @@ -61,31 +59,27 @@ abstract class ClientManager { clientNames.remove(client.clientName); clients.remove(client); } - await Store().setItem(clientNamespace, jsonEncode(clientNames.toList())); + await store.setStringList(clientNamespace, clientNames.toList()); } return clients; } - static Future addClientNameToStore(String clientName) async { - final clientNamesList = []; - final rawClientNames = await Store().getItem(clientNamespace); - if (rawClientNames != null) { - final stored = (jsonDecode(rawClientNames) as List).cast(); - clientNamesList.addAll(stored); - } + static Future addClientNameToStore( + String clientName, + SharedPreferences store, + ) async { + final clientNamesList = store.getStringList(clientNamespace) ?? []; clientNamesList.add(clientName); - await Store().setItem(clientNamespace, jsonEncode(clientNamesList)); + await store.setStringList(clientNamespace, clientNamesList); } - static Future removeClientNameFromStore(String clientName) async { - final clientNamesList = []; - final rawClientNames = await Store().getItem(clientNamespace); - if (rawClientNames != null) { - final stored = (jsonDecode(rawClientNames) as List).cast(); - clientNamesList.addAll(stored); - } + static Future removeClientNameFromStore( + String clientName, + SharedPreferences store, + ) async { + final clientNamesList = store.getStringList(clientNamespace) ?? []; clientNamesList.remove(clientName); - await Store().setItem(clientNamespace, jsonEncode(clientNamesList)); + await store.setStringList(clientNamespace, clientNamesList); } static NativeImplementations get nativeImplementations => kIsWeb @@ -107,6 +101,13 @@ abstract class ClientManager { 'im.ponies.room_emotes', // To check which story room we can post in EventTypes.RoomPowerLevels, + // #Pangea + PangeaEventTypes.classSettings, + PangeaEventTypes.rules, + PangeaEventTypes.vocab, + EventTypes.RoomTopic, + EventTypes.RoomAvatar, + // Pangea# }, logLevel: kReleaseMode ? Level.warning : Level.verbose, databaseBuilder: FlutterHiveCollectionsDatabase.databaseBuilder, diff --git a/lib/utils/custom_scroll_behaviour.dart b/lib/utils/custom_scroll_behaviour.dart index 719b75473..ba25e9564 100644 --- a/lib/utils/custom_scroll_behaviour.dart +++ b/lib/utils/custom_scroll_behaviour.dart @@ -5,7 +5,6 @@ class CustomScrollBehavior extends MaterialScrollBehavior { @override Set get dragDevices => { PointerDeviceKind.touch, - PointerDeviceKind.mouse, PointerDeviceKind.trackpad, }; } diff --git a/lib/utils/famedlysdk_store.dart b/lib/utils/famedlysdk_store.dart deleted file mode 100644 index 2f16b5963..000000000 --- a/lib/utils/famedlysdk_store.dart +++ /dev/null @@ -1,43 +0,0 @@ -import 'dart:core'; - -import 'package:shared_preferences/shared_preferences.dart'; - -class Store { - SharedPreferences? _prefs; - - Future _setupLocalStorage() async { - _prefs ??= await SharedPreferences.getInstance(); - } - - Future getItem(String key) async { - await _setupLocalStorage(); - return _prefs!.getString(key); - } - - Future getItemBool(String key, [bool? defaultValue]) async { - await _setupLocalStorage(); - return _prefs!.getBool(key) ?? defaultValue ?? true; - } - - Future setItem(String key, String? value) async { - await _setupLocalStorage(); - if (value == null) { - await _prefs!.remove(key); - return; - } - await _prefs!.setString(key, value); - return; - } - - Future setItemBool(String key, bool value) async { - await _setupLocalStorage(); - await _prefs!.setBool(key, value); - return; - } - - Future deleteItem(String key) async { - await _setupLocalStorage(); - await _prefs!.remove(key); - return; - } -} diff --git a/lib/utils/localized_exception_extension.dart b/lib/utils/localized_exception_extension.dart index b3d6093c3..d665c7f10 100644 --- a/lib/utils/localized_exception_extension.dart +++ b/lib/utils/localized_exception_extension.dart @@ -5,6 +5,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:matrix/matrix.dart'; +import 'package:fluffychat/pages/tasks/tasks.dart'; import 'uia_request_manager.dart'; extension LocalizedExceptionExtension on Object { @@ -19,6 +20,9 @@ extension LocalizedExceptionExtension on Object { return (this as MatrixException).errorMessage; } } + if (this is TodoListChangedException) { + return L10n.of(context)!.todoListChangedError; + } if (this is FileTooBigMatrixException) { return L10n.of(context)!.fileIsTooBigForServer; } diff --git a/lib/utils/matrix_sdk_extensions/event_extension.dart b/lib/utils/matrix_sdk_extensions/event_extension.dart index dbd4a4aec..ddd5abe80 100644 --- a/lib/utils/matrix_sdk_extensions/event_extension.dart +++ b/lib/utils/matrix_sdk_extensions/event_extension.dart @@ -3,6 +3,7 @@ import 'dart:developer'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import 'package:async/async.dart' as async; import 'package:future_loading_dialog/future_loading_dialog.dart'; import 'package:matrix/matrix.dart'; @@ -10,7 +11,7 @@ import 'package:fluffychat/utils/size_string.dart'; import 'matrix_file_extension.dart'; extension LocalizedBody on Event { - Future> _getFile(BuildContext context) => + Future> _getFile(BuildContext context) => showFutureLoadingDialog( context: context, future: downloadAndDecryptAttachment, diff --git a/lib/utils/matrix_sdk_extensions/flutter_hive_collections_database.dart b/lib/utils/matrix_sdk_extensions/flutter_hive_collections_database.dart index 241ae1a6f..e930f90c0 100644 --- a/lib/utils/matrix_sdk_extensions/flutter_hive_collections_database.dart +++ b/lib/utils/matrix_sdk_extensions/flutter_hive_collections_database.dart @@ -12,14 +12,10 @@ import 'package:universal_html/html.dart' as html; class FlutterHiveCollectionsDatabase extends HiveCollectionsDatabase { FlutterHiveCollectionsDatabase( - String name, - String path, { - HiveCipher? key, - }) : super( - name, - path, - key: key, - ); + super.name, + String super.path, { + super.key, + }); static const String _cipherStorageKey = 'hive_encryption_key'; diff --git a/lib/utils/matrix_sdk_extensions/ios_badge_client_extension.dart b/lib/utils/matrix_sdk_extensions/ios_badge_client_extension.dart new file mode 100644 index 000000000..bea7713d0 --- /dev/null +++ b/lib/utils/matrix_sdk_extensions/ios_badge_client_extension.dart @@ -0,0 +1,20 @@ +import 'package:flutter_app_badger/flutter_app_badger.dart'; +import 'package:flutter_local_notifications/flutter_local_notifications.dart'; +import 'package:matrix/matrix.dart'; + +import 'package:fluffychat/utils/platform_infos.dart'; + +extension IosBadgeClientExtension on Client { + void updateIosBadge() { + if (PlatformInfos.isIOS) { + // Workaround for iOS not clearing notifications with fcm_shared_isolate + if (!rooms.any( + (r) => r.membership == Membership.invite || (r.notificationCount > 0), + )) { + // ignore: unawaited_futures + FlutterLocalNotificationsPlugin().cancelAll(); + FlutterAppBadger.removeBadge(); + } + } + } +} diff --git a/lib/utils/matrix_sdk_extensions/matrix_locals.dart b/lib/utils/matrix_sdk_extensions/matrix_locals.dart index 44eab72dc..4a9b68274 100644 --- a/lib/utils/matrix_sdk_extensions/matrix_locals.dart +++ b/lib/utils/matrix_sdk_extensions/matrix_locals.dart @@ -317,4 +317,7 @@ class MatrixLocals extends MatrixLocalizations { @override String get unknownUser => l10n.user; + + @override + String hasKnocked(String targetName) => l10n.hasKnocked(targetName); } diff --git a/lib/utils/platform_infos.dart b/lib/utils/platform_infos.dart index b96104df4..9094b774b 100644 --- a/lib/utils/platform_infos.dart +++ b/lib/utils/platform_infos.dart @@ -46,6 +46,9 @@ abstract class PlatformInfos { final version = await PlatformInfos.getVersion(); showAboutDialog( context: context, + // #Pangea + useRootNavigator: false, + // Pangea# children: [ Text('Version: $version'), TextButton.icon( diff --git a/lib/utils/push_helper.dart b/lib/utils/push_helper.dart index b5111c4c0..29683f64c 100644 --- a/lib/utils/push_helper.dart +++ b/lib/utils/push_helper.dart @@ -2,6 +2,8 @@ import 'dart:convert'; import 'dart:io'; import 'dart:ui'; +import 'package:flutter/material.dart'; + import 'package:flutter_cache_manager/flutter_cache_manager.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart'; @@ -10,6 +12,7 @@ import 'package:shared_preferences/shared_preferences.dart'; import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/config/setting_keys.dart'; +import 'package:fluffychat/pangea/utils/error_handler.dart'; import 'package:fluffychat/utils/client_manager.dart'; import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart'; import 'package:fluffychat/utils/platform_infos.dart'; @@ -44,11 +47,14 @@ Future pushHelper( onDidReceiveBackgroundNotificationResponse: onSelectNotification, ); - l10n ??= lookupL10n(const Locale('en')); + // #Pangea + debugPrint('Push notification ${notification.content}'); + // l10n ??= lookupL10n(const Locale('en')); + // Pangea# flutterLocalNotificationsPlugin.show( 0, - l10n.newMessageInFluffyChat, - l10n.openAppToReadMessages, + l10n?.newMessageInFluffyChat, + l10n?.openAppToReadMessages, NotificationDetails( iOS: const DarwinNotificationDetails(), android: AndroidNotificationDetails( @@ -56,7 +62,7 @@ Future pushHelper( AppConfig.pushNotificationsChannelName, channelDescription: AppConfig.pushNotificationsChannelDescription, number: notification.counts?.unread, - ticker: l10n.unreadChats(notification.counts?.unread ?? 1), + ticker: l10n?.unreadChats(notification.counts?.unread ?? 1), importance: Importance.max, priority: Priority.max, ), @@ -98,7 +104,11 @@ Future _tryPushHelper( //onDidReceiveBackgroundNotificationResponse: onSelectNotification, ); - client ??= (await ClientManager.getClients(initialize: false)).first; + client ??= (await ClientManager.getClients( + initialize: false, + store: await SharedPreferences.getInstance(), + )) + .first; final event = await client.getEventByPushNotification( notification, storeInDatabase: isBackgroundMessage, @@ -174,6 +184,9 @@ Future _tryPushHelper( : await DefaultCacheManager().getSingleFile(avatar); } catch (e, s) { Logs().e('Unable to get avatar picture', e, s); + // #Pangea + ErrorHandler.logError(e: e, s: s); + // Pangea# } final id = await mapRoomIdToInt(event.room.id); diff --git a/lib/utils/url_launcher.dart b/lib/utils/url_launcher.dart index d6c868381..808f64f65 100644 --- a/lib/utils/url_launcher.dart +++ b/lib/utils/url_launcher.dart @@ -1,5 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; import 'package:adaptive_dialog/adaptive_dialog.dart'; import 'package:collection/collection.dart' show IterableExtension; @@ -18,10 +17,16 @@ import 'package:fluffychat/widgets/public_room_bottom_sheet.dart'; import 'platform_infos.dart'; class UrlLauncher { + /// The url to open. final String? url; + + /// The visible name in the GUI. For example the name of a markdown link + /// which may differ from the actual url to open. + final String? name; + final BuildContext context; - const UrlLauncher(this.context, this.url); + const UrlLauncher(this.context, this.url, [this.name]); void launchUrl() async { if (url!.toLowerCase().startsWith(AppConfig.deepLinkPrefix) || @@ -38,34 +43,19 @@ class UrlLauncher { ); return; } - final consent = await showModalActionSheet<_LaunchUrlResponse>( - context: context, - title: url, - style: AdaptiveStyle.material, - actions: [ - SheetAction( - key: _LaunchUrlResponse.copy, - icon: Icons.copy_outlined, - label: L10n.of(context)!.copy, - ), - SheetAction( - key: _LaunchUrlResponse.launch, - icon: Icons.launch_outlined, - label: L10n.of(context)!.openLinkInBrowser, - ), - ], - ); - if (consent == _LaunchUrlResponse.copy) { - await Clipboard.setData(ClipboardData(text: uri.toString())); - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text(L10n.of(context)!.copiedToClipboard), - ), - ); - return; - } - if (consent != _LaunchUrlResponse.launch) return; + if (name != null && url != name) { + // If there is a name which differs from the url, we need to make sure + // that the user can see the actual url before opening the browser. + final consent = await showOkCancelAlertDialog( + context: context, + title: L10n.of(context)!.openLinkInBrowser, + message: url, + okLabel: L10n.of(context)!.yes, + cancelLabel: L10n.of(context)!.cancel, + ); + if (consent != OkCancelResult.ok) return; + } if (!{'https', 'http'}.contains(uri.scheme)) { // just launch non-https / non-http uris directly @@ -241,8 +231,3 @@ class UrlLauncher { } } } - -enum _LaunchUrlResponse { - launch, - copy, -} diff --git a/lib/utils/voip_plugin.dart b/lib/utils/voip_plugin.dart index 3cc9d5161..4626c1c49 100644 --- a/lib/utils/voip_plugin.dart +++ b/lib/utils/voip_plugin.dart @@ -11,7 +11,6 @@ import 'package:webrtc_interface/webrtc_interface.dart' hide Navigator; import 'package:fluffychat/pages/chat_list/chat_list.dart'; import 'package:fluffychat/pages/dialer/dialer.dart'; import 'package:fluffychat/utils/platform_infos.dart'; -import '../../utils/famedlysdk_store.dart'; import '../../utils/voip/callkeep_manager.dart'; import '../../utils/voip/user_media_manager.dart'; import '../widgets/matrix.dart'; @@ -133,7 +132,8 @@ class VoipPlugin with WidgetsBindingObserver implements WebRTCDelegate { } else { try { final wasForeground = await FlutterForegroundTask.isAppOnForeground; - await Store().setItem( + + await matrix.store.setString( 'wasForeground', wasForeground == true ? 'true' : 'false', ); @@ -172,7 +172,7 @@ class VoipPlugin with WidgetsBindingObserver implements WebRTCDelegate { if (PlatformInfos.isAndroid) { FlutterForegroundTask.setOnLockScreenVisibility(false); FlutterForegroundTask.stopService(); - final wasForeground = await Store().getItem('wasForeground'); + final wasForeground = matrix.store.getString('wasForeground'); wasForeground == 'false' ? FlutterForegroundTask.minimizeApp() : null; } } diff --git a/lib/widgets/adaptive_flat_button.dart b/lib/widgets/adaptive_flat_button.dart index 7faa7eed4..faed7e951 100644 --- a/lib/widgets/adaptive_flat_button.dart +++ b/lib/widgets/adaptive_flat_button.dart @@ -9,11 +9,11 @@ class AdaptiveFlatButton extends StatelessWidget { final void Function()? onPressed; const AdaptiveFlatButton({ - Key? key, + super.key, required this.label, this.textColor, this.onPressed, - }) : super(key: key); + }); @override Widget build(BuildContext context) { diff --git a/lib/widgets/avatar.dart b/lib/widgets/avatar.dart index 7d43f8f3c..9b19e5613 100644 --- a/lib/widgets/avatar.dart +++ b/lib/widgets/avatar.dart @@ -13,6 +13,11 @@ class Avatar extends StatelessWidget { static const double defaultSize = 44; final Client? client; final double fontSize; + final String? presenceUserId; + final Color? presenceBackgroundColor; + //#Pangea + final IconData? littleIcon; + // Pangea# const Avatar({ this.mxContent, @@ -21,8 +26,13 @@ class Avatar extends StatelessWidget { this.onTap, this.client, this.fontSize = 18, - Key? key, - }) : super(key: key); + this.presenceUserId, + this.presenceBackgroundColor, + //#Pangea + this.littleIcon, + // Pangea# + super.key, + }); @override Widget build(BuildContext context) { @@ -48,26 +58,95 @@ class Avatar extends StatelessWidget { ), ); final borderRadius = BorderRadius.circular(size / 2); - final container = ClipRRect( - borderRadius: borderRadius, - child: Container( - width: size, - height: size, - color: noPic - ? name?.lightColorAvatar - : Theme.of(context).secondaryHeaderColor, - child: noPic - ? textWidget - : MxcImage( - key: Key(mxContent.toString()), - uri: mxContent, - fit: BoxFit.cover, - width: size, - height: size, - placeholder: (_) => textWidget, - cacheKey: mxContent.toString(), + // #Pangea + // final presenceUserId = this.presenceUserId; + // final color = + // noPic ? name?.lightColorAvatar : Theme.of(context).secondaryHeaderColor; + // Pangea# + final container = Stack( + children: [ + ClipRRect( + borderRadius: borderRadius, + child: Container( + width: size, + height: size, + color: noPic + ? name?.lightColorAvatar + : Theme.of(context).secondaryHeaderColor, + child: noPic + ? textWidget + : MxcImage( + key: Key(mxContent.toString()), + uri: mxContent, + fit: BoxFit.cover, + width: size, + height: size, + placeholder: (_) => textWidget, + cacheKey: mxContent.toString(), + ), + ), + ), + // #Pangea + if (littleIcon != null) + Positioned( + bottom: 0, + right: 0, + child: ClipRRect( + borderRadius: borderRadius, + child: Container( + height: 16, + width: 16, + color: Colors.white, + child: Icon( + littleIcon, + color: noPic + ? name?.lightColorAvatar + : Theme.of(context).secondaryHeaderColor, + size: 14, + ), ), - ), + ), + ), + // PresenceBuilder( + // client: client, + // userId: presenceUserId, + // builder: (context, presence) { + // if (presence == null || + // (presence.presence == PresenceType.offline && + // presence.lastActiveTimestamp == null)) { + // return const SizedBox.shrink(); + // } + // final dotColor = presence.presence.isOnline + // ? Colors.green + // : presence.presence.isUnavailable + // ? Colors.red + // : Colors.grey; + // return Positioned( + // bottom: -4, + // right: -4, + // child: Container( + // width: 16, + // height: 16, + // decoration: BoxDecoration( + // color: presenceBackgroundColor ?? + // Theme.of(context).colorScheme.background, + // borderRadius: BorderRadius.circular(32), + // ), + // alignment: Alignment.center, + // child: Container( + // width: 8, + // height: 8, + // decoration: BoxDecoration( + // color: dotColor, + // borderRadius: BorderRadius.circular(16), + // ), + // ), + // ), + // ); + // }, + // ), + // Pangea# + ], ); if (onTap == null) return container; return InkWell( diff --git a/lib/widgets/chat_settings_popup_menu.dart b/lib/widgets/chat_settings_popup_menu.dart index fbbb4978e..d89f60353 100644 --- a/lib/widgets/chat_settings_popup_menu.dart +++ b/lib/widgets/chat_settings_popup_menu.dart @@ -10,14 +10,17 @@ import 'package:go_router/go_router.dart'; import 'package:keyboard_shortcuts/keyboard_shortcuts.dart'; import 'package:matrix/matrix.dart'; +import 'package:fluffychat/pangea/controllers/pangea_controller.dart'; +import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart'; +import 'package:fluffychat/pangea/models/class_model.dart'; +import 'package:fluffychat/pangea/utils/download_chat.dart'; import 'matrix.dart'; class ChatSettingsPopupMenu extends StatefulWidget { final Room room; final bool displayChatDetails; - const ChatSettingsPopupMenu(this.room, this.displayChatDetails, {Key? key}) - : super(key: key); + const ChatSettingsPopupMenu(this.room, this.displayChatDetails, {super.key}); @override ChatSettingsPopupMenuState createState() => ChatSettingsPopupMenuState(); @@ -34,6 +37,13 @@ class ChatSettingsPopupMenuState extends State { @override Widget build(BuildContext context) { + // #Pangea + final PangeaController pangeaController = MatrixState.pangeaController; + final ClassSettingsModel? classSettings = pangeaController + .matrixState.client + .getRoomById(widget.room.id) + ?.firstLanguageSettings; + // Pangea# notificationChangeSub ??= Matrix.of(context) .client .onAccountData @@ -43,6 +53,28 @@ class ChatSettingsPopupMenuState extends State { (u) => setState(() {}), ); final items = >[ + // #Pangea + // PopupMenuItem( + // value: 'widgets', + // child: Row( + // children: [ + // const Icon(Icons.widgets_outlined), + // const SizedBox(width: 12), + // Text(L10n.of(context)!.matrixWidgets), + // ], + // ), + // ), + PopupMenuItem( + value: 'learning_settings', + child: Row( + children: [ + const Icon(Icons.settings), + const SizedBox(width: 12), + Text(L10n.of(context)!.learningSettings), + ], + ), + ), + // Pangea# widget.room.pushRuleState == PushRuleState.notify ? PopupMenuItem( value: 'mute', @@ -64,16 +96,76 @@ class ChatSettingsPopupMenuState extends State { ], ), ), + // #Pangea + // PopupMenuItem( + // value: 'todos', + // child: Row( + // children: [ + // const Icon(Icons.task_alt_outlined), + // const SizedBox(width: 12), + // Text(L10n.of(context)!.todoLists), + // ], + // ), + // ), + // PopupMenuItem( + // value: 'todos', + // child: Row( + // children: [ + // const Icon(Icons.task_alt_outlined), + // const SizedBox(width: 12), + // Text(L10n.of(context)!.todoLists), + // ], + // ), + // ), + // Pangea# PopupMenuItem( value: 'leave', child: Row( children: [ - const Icon(Icons.delete_outlined), + // #Pangea + // const Icon(Icons.delete_outlined), + const Icon(Icons.arrow_forward), + // Pangea# const SizedBox(width: 12), Text(L10n.of(context)!.leave), ], ), ), + // #Pangea + if (classSettings != null) + PopupMenuItem( + value: 'download txt', + child: Row( + children: [ + const Icon(Icons.download_outlined), + const SizedBox(width: 12), + Text(L10n.of(context)!.downloadTxtFile), + ], + ), + ), + if (classSettings != null) + PopupMenuItem( + value: 'download csv', + child: Row( + children: [ + const Icon(Icons.download_outlined), + const SizedBox(width: 12), + Text(L10n.of(context)!.downloadCSVFile), + ], + ), + ), + if (classSettings != null) + PopupMenuItem( + value: 'download xlsx', + child: Row( + children: [ + const Icon(Icons.download_outlined), + const SizedBox(width: 12), + Text(L10n.of(context)!.downloadXLSXFile), + ], + ), + ), + // Pangea# ]; if (widget.displayChatDetails) { items.insert( @@ -112,6 +204,7 @@ class ChatSettingsPopupMenuState extends State { title: L10n.of(context)!.areYouSure, okLabel: L10n.of(context)!.ok, cancelLabel: L10n.of(context)!.cancel, + message: L10n.of(context)!.archiveRoomDescription, ); if (confirmed == OkCancelResult.ok) { final success = await showFutureLoadingDialog( @@ -137,9 +230,55 @@ class ChatSettingsPopupMenuState extends State { widget.room.setPushRuleState(PushRuleState.notify), ); break; + // #Pangea + // case 'todos': + // context.go('/rooms/${widget.room.id}/tasks'); + // break; + // Pangea# case 'details': _showChatDetails(); break; + // #Pangea + case 'download txt': + showFutureLoadingDialog( + context: context, + future: () => downloadChat( + widget.room, + classSettings!, + DownloadType.txt, + Matrix.of(context).client, + context, + ), + ); + break; + case 'download csv': + showFutureLoadingDialog( + context: context, + future: () => downloadChat( + widget.room, + classSettings!, + DownloadType.csv, + Matrix.of(context).client, + context, + ), + ); + break; + case 'download xlsx': + showFutureLoadingDialog( + context: context, + future: () => downloadChat( + widget.room, + classSettings!, + DownloadType.xlsx, + Matrix.of(context).client, + context, + ), + ); + break; + case 'learning_settings': + context.go('/rooms/settings/learning'); + break; + // #Pangea } }, itemBuilder: (BuildContext context) => items, diff --git a/lib/widgets/connection_status_header.dart b/lib/widgets/connection_status_header.dart index 7d58b000f..2283c41bf 100644 --- a/lib/widgets/connection_status_header.dart +++ b/lib/widgets/connection_status_header.dart @@ -10,7 +10,7 @@ import '../utils/localized_exception_extension.dart'; import 'matrix.dart'; class ConnectionStatusHeader extends StatefulWidget { - const ConnectionStatusHeader({Key? key}) : super(key: key); + const ConnectionStatusHeader({super.key}); @override ConnectionStatusHeaderState createState() => ConnectionStatusHeaderState(); diff --git a/lib/widgets/content_banner.dart b/lib/widgets/content_banner.dart index 72a89a5ad..f9e6a6167 100644 --- a/lib/widgets/content_banner.dart +++ b/lib/widgets/content_banner.dart @@ -21,8 +21,8 @@ class ContentBanner extends StatelessWidget { this.client, this.opacity = 0.75, this.placeholder, - Key? key, - }) : super(key: key); + super.key, + }); @override Widget build(BuildContext context) { diff --git a/lib/widgets/error_widget.dart b/lib/widgets/error_widget.dart new file mode 100644 index 000000000..8606c7608 --- /dev/null +++ b/lib/widgets/error_widget.dart @@ -0,0 +1,49 @@ +import 'package:flutter/material.dart'; + +import 'package:fluffychat/utils/error_reporter.dart'; + +class FluffyChatErrorWidget extends StatefulWidget { + final FlutterErrorDetails details; + const FluffyChatErrorWidget(this.details, {super.key}); + + @override + State createState() => _FluffyChatErrorWidgetState(); +} + +class _FluffyChatErrorWidgetState extends State { + @override + void initState() { + super.initState(); + + WidgetsBinding.instance.addPostFrameCallback((_) { + ErrorReporter(context, 'Error Widget').onErrorCallback( + widget.details.exception, + widget.details.stack, + ); + }); + } + + @override + Widget build(BuildContext context) { + return Material( + color: Colors.orange, + child: Placeholder( + child: Center( + child: Material( + color: Colors.white.withOpacity(0.9), + borderRadius: BorderRadius.circular(8), + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Text( + '😲 Oh no! Something is broken 😲\n${widget.details.exception}', + maxLines: 5, + textAlign: TextAlign.center, + style: const TextStyle(color: Colors.black), + ), + ), + ), + ), + ), + ); + } +} diff --git a/lib/widgets/fluffy_chat_app.dart b/lib/widgets/fluffy_chat_app.dart index 45852dfcc..3804a9181 100644 --- a/lib/widgets/fluffy_chat_app.dart +++ b/lib/widgets/fluffy_chat_app.dart @@ -1,11 +1,15 @@ import 'package:flutter/material.dart'; +import 'package:country_picker/country_picker.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:go_router/go_router.dart'; import 'package:matrix/matrix.dart'; +import 'package:shared_preferences/shared_preferences.dart'; import 'package:fluffychat/config/routes.dart'; import 'package:fluffychat/config/themes.dart'; +import 'package:fluffychat/pangea/utils/firebase_analytics.dart'; import 'package:fluffychat/widgets/app_lock.dart'; import 'package:fluffychat/widgets/theme_builder.dart'; import '../config/app_config.dart'; @@ -16,13 +20,15 @@ class FluffyChatApp extends StatelessWidget { final Widget? testWidget; final List clients; final String? pincode; + final SharedPreferences store; const FluffyChatApp({ - Key? key, + super.key, this.testWidget, required this.clients, + required this.store, this.pincode, - }) : super(key: key); + }); /// getInitialLink may rereturn the value multiple times if this view is /// opened multiple times for example if the user logs out after they logged @@ -31,7 +37,14 @@ class FluffyChatApp extends StatelessWidget { // Router must be outside of build method so that hot reload does not reset // the current path. - static final GoRouter router = GoRouter(routes: AppRoutes.routes); + static final GoRouter router = GoRouter( + routes: AppRoutes.routes, + // #Pangea + observers: [ + GoogleAnalytics.getAnalyticsObserver(), + ], + // Pangea# + ); @override Widget build(BuildContext context) { @@ -43,7 +56,16 @@ class FluffyChatApp extends StatelessWidget { darkTheme: FluffyThemes.buildTheme(context, Brightness.dark, primaryColor), scrollBehavior: CustomScrollBehavior(), - localizationsDelegates: L10n.localizationsDelegates, + // #Pangea + // localizationsDelegates: L10n.localizationsDelegates, + localizationsDelegates: const [ + L10n.delegate, + GlobalMaterialLocalizations.delegate, + GlobalCupertinoLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + CountryLocalizations.delegate, + ], + // Pangea# supportedLocales: L10n.supportedLocales, routerConfig: router, builder: (context, child) => AppLockWidget( @@ -55,6 +77,7 @@ class FluffyChatApp extends StatelessWidget { onGenerateRoute: (_) => MaterialPageRoute( builder: (_) => Matrix( clients: clients, + store: store, child: testWidget ?? child, ), ), diff --git a/lib/widgets/hover_builder.dart b/lib/widgets/hover_builder.dart new file mode 100644 index 000000000..f895d8532 --- /dev/null +++ b/lib/widgets/hover_builder.dart @@ -0,0 +1,29 @@ +import 'package:flutter/material.dart'; + +class HoverBuilder extends StatefulWidget { + final Widget Function(BuildContext context, bool hovered) builder; + const HoverBuilder({required this.builder, super.key}); + + @override + State createState() => _HoverBuilderState(); +} + +class _HoverBuilderState extends State { + bool hovered = false; + @override + Widget build(BuildContext context) { + return MouseRegion( + onEnter: (_) => hovered + ? null + : setState(() { + hovered = true; + }), + onExit: (_) => !hovered + ? null + : setState(() { + hovered = false; + }), + child: widget.builder(context, hovered), + ); + } +} diff --git a/lib/widgets/layouts/empty_page.dart b/lib/widgets/layouts/empty_page.dart index 9f377f65b..1a6b42e70 100644 --- a/lib/widgets/layouts/empty_page.dart +++ b/lib/widgets/layouts/empty_page.dart @@ -2,10 +2,12 @@ import 'dart:math'; import 'package:flutter/material.dart'; +import 'package:fluffychat/pangea/widgets/common/pangea_logo_svg.dart'; + class EmptyPage extends StatelessWidget { final bool loading; static const double _width = 300; - const EmptyPage({this.loading = false, Key? key}) : super(key: key); + const EmptyPage({this.loading = false, super.key}); @override Widget build(BuildContext context) { final width = min(MediaQuery.of(context).size.width, EmptyPage._width) / 2; @@ -23,12 +25,15 @@ class EmptyPage extends StatelessWidget { Center( child: Hero( tag: 'info-logo', - child: Image.asset( - 'assets/favicon.png', - width: width, - height: width, - filterQuality: FilterQuality.medium, - ), + // #Pangea + // child: Image.asset( + // 'assets/favicon.png', + // width: width, + // height: width, + // filterQuality: FilterQuality.medium, + // ), + child: PangeaLogoSvg(width: width), + // Pangea# ), ), if (loading) diff --git a/lib/widgets/layouts/login_scaffold.dart b/lib/widgets/layouts/login_scaffold.dart index bc9e04c2d..6123ddf39 100644 --- a/lib/widgets/layouts/login_scaffold.dart +++ b/lib/widgets/layouts/login_scaffold.dart @@ -13,11 +13,11 @@ class LoginScaffold extends StatelessWidget { final bool enforceMobileMode; const LoginScaffold({ - Key? key, + super.key, required this.body, this.appBar, this.enforceMobileMode = false, - }) : super(key: key); + }); @override Widget build(BuildContext context) { @@ -25,84 +25,109 @@ class LoginScaffold extends StatelessWidget { enforceMobileMode || !FluffyThemes.isColumnMode(context); final scaffold = Scaffold( key: const Key('LoginScaffold'), - appBar: appBar == null - ? null - : AppBar( - titleSpacing: appBar?.titleSpacing, - automaticallyImplyLeading: - appBar?.automaticallyImplyLeading ?? true, - centerTitle: appBar?.centerTitle, - title: appBar?.title, - leading: appBar?.leading, - actions: appBar?.actions, - backgroundColor: isMobileMode ? null : Colors.transparent, - ), + // Pangea# + // appBar: appBar == null + // ? null + // : AppBar( + appBar: AppBar( + // Pangea# + titleSpacing: appBar?.titleSpacing, + automaticallyImplyLeading: appBar?.automaticallyImplyLeading ?? true, + centerTitle: appBar?.centerTitle, + title: appBar?.title, + leading: appBar?.leading, + actions: appBar?.actions, + // #Pangea + // backgroundColor: isMobileMode ? null : Colors.transparent, + backgroundColor: Colors.transparent, + // Pangea# + ), extendBodyBehindAppBar: true, extendBody: true, - body: body, - bottomNavigationBar: isMobileMode - ? Material( - elevation: 4, - shadowColor: Theme.of(context).colorScheme.onBackground, - child: const _PrivacyButtons( - mainAxisAlignment: MainAxisAlignment.center, - ), - ) - : null, - ); - if (isMobileMode) return scaffold; - return Container( - decoration: BoxDecoration( - gradient: FluffyThemes.backgroundGradient(context, 255), - ), - child: Column( - children: [ - const SizedBox(height: 16), - Expanded( - child: Center( - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 16.0), - child: Material( - color: Theme.of(context).scaffoldBackgroundColor, - borderRadius: BorderRadius.circular(AppConfig.borderRadius), - clipBehavior: Clip.hardEdge, - elevation: - Theme.of(context).appBarTheme.scrolledUnderElevation ?? 4, - shadowColor: Theme.of(context).appBarTheme.shadowColor, - child: ConstrainedBox( - constraints: isMobileMode - ? const BoxConstraints() - : const BoxConstraints(maxWidth: 960, maxHeight: 640), - child: Row( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - Expanded( - child: Image.asset( - 'assets/login_wallpaper.png', - fit: BoxFit.cover, - ), - ), - Container( - width: 1, - color: Theme.of(context).dividerTheme.color, - ), - Expanded( - child: Padding( - padding: const EdgeInsets.all(8.0), - child: scaffold, - ), - ), - ], - ), - ), - ), - ), - ), + // #Pangea + // body: body, + body: Container( + decoration: const BoxDecoration( + image: DecorationImage( + fit: BoxFit.cover, + image: AssetImage('assets/login_wallpaper.png'), ), - const _PrivacyButtons(mainAxisAlignment: MainAxisAlignment.end), - ], + ), + alignment: Alignment.center, + child: ConstrainedBox( + constraints: const BoxConstraints(maxWidth: 480), + child: body, + ), ), + // bottomNavigationBar: isMobileMode + // ? Material( + // elevation: 4, + // shadowColor: Theme.of(context).colorScheme.onBackground, + // child: const _PrivacyButtons( + // mainAxisAlignment: MainAxisAlignment.center, + // ), + // ) + // : null, ); + + // #Pangea + return scaffold; + // if (isMobileMode) { + // return scaffold; + // } + // return Container( + // decoration: BoxDecoration( + // gradient: FluffyThemes.backgroundGradient(context, 255), + // ), + // child: Column( + // children: [ + // const SizedBox(height: 16), + // Expanded( + // child: Center( + // child: Padding( + // padding: const EdgeInsets.symmetric(horizontal: 16.0), + // child: Material( + // color: Theme.of(context).scaffoldBackgroundColor, + // borderRadius: BorderRadius.circular(AppConfig.borderRadius), + // clipBehavior: Clip.hardEdge, + // elevation: + // Theme.of(context).appBarTheme.scrolledUnderElevation ?? 4, + // shadowColor: Theme.of(context).appBarTheme.shadowColor, + // child: ConstrainedBox( + // constraints: isMobileMode + // ? const BoxConstraints() + // : const BoxConstraints(maxWidth: 960, maxHeight: 640), + // child: Row( + // crossAxisAlignment: CrossAxisAlignment.stretch, + // children: [ + // Expanded( + // child: Image.asset( + // 'assets/login_wallpaper.png', + // fit: BoxFit.cover, + // ), + // ), + // Container( + // width: 1, + // color: Theme.of(context).dividerTheme.color, + // ), + // Expanded( + // child: Padding( + // padding: const EdgeInsets.all(8.0), + // child: scaffold, + // ), + // ), + // ], + // ), + // ), + // ), + // ), + // ), + // ), + // const _PrivacyButtons(mainAxisAlignment: MainAxisAlignment.end), + // ], + // ), + // ); + // Pangea# } } diff --git a/lib/widgets/layouts/max_width_body.dart b/lib/widgets/layouts/max_width_body.dart index 31f1e7bef..a5d9cafe0 100644 --- a/lib/widgets/layouts/max_width_body.dart +++ b/lib/widgets/layouts/max_width_body.dart @@ -15,8 +15,8 @@ class MaxWidthBody extends StatelessWidget { this.maxWidth = 600, this.withFrame = true, this.withScrolling = true, - Key? key, - }) : super(key: key); + super.key, + }); @override Widget build(BuildContext context) { return SafeArea( diff --git a/lib/widgets/layouts/two_column_layout.dart b/lib/widgets/layouts/two_column_layout.dart index f0fdb9912..a6f4c8bdf 100644 --- a/lib/widgets/layouts/two_column_layout.dart +++ b/lib/widgets/layouts/two_column_layout.dart @@ -6,11 +6,11 @@ class TwoColumnLayout extends StatelessWidget { final bool displayNavigationRail; const TwoColumnLayout({ - Key? key, + super.key, required this.mainView, required this.sideView, required this.displayNavigationRail, - }) : super(key: key); + }); @override Widget build(BuildContext context) { return ScaffoldMessenger( diff --git a/lib/widgets/log_view.dart b/lib/widgets/log_view.dart index 4c58f8b4b..6e5e31882 100644 --- a/lib/widgets/log_view.dart +++ b/lib/widgets/log_view.dart @@ -4,7 +4,7 @@ import 'package:go_router/go_router.dart'; import 'package:matrix/matrix.dart'; class LogViewer extends StatefulWidget { - const LogViewer({Key? key}) : super(key: key); + const LogViewer({super.key}); @override LogViewerState createState() => LogViewerState(); diff --git a/lib/widgets/matrix.dart b/lib/widgets/matrix.dart index 2c26de59a..eb80a052f 100644 --- a/lib/widgets/matrix.dart +++ b/lib/widgets/matrix.dart @@ -15,9 +15,12 @@ import 'package:image_picker/image_picker.dart'; import 'package:matrix/encryption.dart'; import 'package:matrix/matrix.dart'; import 'package:provider/provider.dart'; +import 'package:shared_preferences/shared_preferences.dart'; import 'package:universal_html/html.dart' as html; import 'package:url_launcher/url_launcher_string.dart'; +import 'package:fluffychat/pangea/controllers/pangea_controller.dart'; +import 'package:fluffychat/pangea/utils/any_state_holder.dart'; import 'package:fluffychat/utils/client_manager.dart'; import 'package:fluffychat/utils/localized_exception_extension.dart'; import 'package:fluffychat/utils/platform_infos.dart'; @@ -29,7 +32,6 @@ import '../config/setting_keys.dart'; import '../pages/key_verification/key_verification_dialog.dart'; import '../utils/account_bundles.dart'; import '../utils/background_push.dart'; -import '../utils/famedlysdk_store.dart'; import 'local_notifications_extension.dart'; // import 'package:flutter_secure_storage/flutter_secure_storage.dart'; @@ -41,12 +43,15 @@ class Matrix extends StatefulWidget { final Map? queryParameters; + final SharedPreferences store; + const Matrix({ this.child, required this.clients, + required this.store, this.queryParameters, - Key? key, - }) : super(key: key); + super.key, + }); @override MatrixState createState() => MatrixState(); @@ -59,7 +64,11 @@ class Matrix extends StatefulWidget { class MatrixState extends State with WidgetsBindingObserver { int _activeClient = -1; String? activeBundle; - Store store = Store(); + // #Pangea + static late PangeaController pangeaController; + static PangeaAnyState pAnyState = PangeaAnyState(); + // Pangea# + SharedPreferences get store => widget.store; HomeserverSummary? loginHomeserverSummary; XFile? loginAvatar; @@ -158,7 +167,10 @@ class MatrixState extends State with WidgetsBindingObserver { if (!widget.clients.contains(_loginClientCandidate)) { widget.clients.add(_loginClientCandidate!); } - ClientManager.addClientNameToStore(_loginClientCandidate!.clientName); + ClientManager.addClientNameToStore( + _loginClientCandidate!.clientName, + store, + ); _registerSubs(_loginClientCandidate!.clientName); _loginClientCandidate = null; FluffyChatApp.router.go('/rooms'); @@ -187,7 +199,7 @@ class MatrixState extends State with WidgetsBindingObserver { try { if (client.isLogged()) { // TODO: Figure out how this works in multi account - final statusMsg = await store.getItem(SettingKeys.ownStatusMessage); + final statusMsg = store.getString(SettingKeys.ownStatusMessage); if (statusMsg?.isNotEmpty ?? false) { Logs().v('Send cached status message: "$statusMsg"'); await client.setPresence( @@ -249,6 +261,10 @@ class MatrixState extends State with WidgetsBindingObserver { initSettings(); } initLoadingDialog(); + // #Pangea + pangeaController = PangeaController(matrix: widget, matrixState: this); + // PAuthGaurd.isLogged = client.isLogged(); + // Pangea# } void initLoadingDialog() { @@ -309,12 +325,16 @@ class MatrixState extends State with WidgetsBindingObserver { hidPopup = true; await KeyVerificationDialog(request: request).show(context); }); - onLoginStateChanged[name] ??= c.onLoginStateChanged.stream.listen((state) { + onLoginStateChanged[name] ??= + c.onLoginStateChanged.stream.listen((state) async { final loggedInWithMultipleClients = widget.clients.length > 1; + // #Pangea + // PAuthGaurd.isLogged = state == LoginState.loggedIn; + // Pangea# if (loggedInWithMultipleClients && state != LoginState.loggedIn) { _cancelSubs(c.clientName); widget.clients.remove(c); - ClientManager.removeClientNameFromStore(c.clientName); + ClientManager.removeClientNameFromStore(c.clientName, store); ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text(L10n.of(context)!.oneClientLoggedOut), @@ -325,8 +345,23 @@ class MatrixState extends State with WidgetsBindingObserver { FluffyChatApp.router.go('/rooms'); } } else { - FluffyChatApp.router - .go(state == LoginState.loggedIn ? '/rooms' : '/home'); + // #Pangea + if (state == LoginState.loggedIn) { + await (await pangeaController.userController.completer).future; + } + String routeDestination; + if (state == LoginState.loggedIn) { + routeDestination = await pangeaController + .userController.isUserDataAvailableAndDateOfBirthSet + ? '/rooms' + : "/rooms/user_age"; + } else { + routeDestination = '/home'; + } + FluffyChatApp.router.go(routeDestination); + // FluffyChatApp.router + // .go(state == LoginState.loggedIn ? '/rooms' : '/home'); + // Pangea# } }); onUiaRequest[name] ??= c.onUiaRequest.stream.listen(uiaRequestHandler); @@ -376,17 +411,22 @@ class MatrixState extends State with WidgetsBindingObserver { final result = await showOkCancelAlertDialog( barrierDismissible: true, context: context, - title: L10n.of(context)!.oopsSomethingWentWrong, + title: L10n.of(context)!.pushNotificationsNotAvailable, message: errorMsg, - okLabel: - link == null ? L10n.of(context)!.ok : L10n.of(context)!.help, + fullyCapitalizedForMaterial: false, + okLabel: link == null + ? L10n.of(context)!.ok + : L10n.of(context)!.learnMore, cancelLabel: L10n.of(context)!.doNotShowAgain, ); if (result == OkCancelResult.ok && link != null) { - launchUrlString(link.toString()); + launchUrlString( + link.toString(), + mode: LaunchMode.externalApplication, + ); } if (result == OkCancelResult.cancel) { - await store.setItemBool(SettingKeys.showNoGoogle, true); + await store.setBool(SettingKeys.showNoGoogle, true); } }, ); @@ -396,7 +436,7 @@ class MatrixState extends State with WidgetsBindingObserver { } void createVoipPlugin() async { - if (await store.getItemBool(SettingKeys.experimentalVoip) == false) { + if (store.getBool(SettingKeys.experimentalVoip) == false) { voipPlugin = null; return; } @@ -409,58 +449,44 @@ class MatrixState extends State with WidgetsBindingObserver { final foreground = state != AppLifecycleState.detached && state != AppLifecycleState.paused; client.backgroundSync = foreground; - client.syncPresence = foreground ? null : PresenceType.unavailable; client.requestHistoryOnLimitedTimeline = !foreground; } void initSettings() { - store.getItem(SettingKeys.wallpaper).then((final path) async { - if (path == null) return; - final file = File(path); - if (await file.exists()) { - wallpaper = file; - } - }); - store.getItem(SettingKeys.fontSizeFactor).then( - (value) => AppConfig.fontSizeFactor = - double.tryParse(value ?? '') ?? AppConfig.fontSizeFactor, - ); - store - .getItemBool(SettingKeys.renderHtml, AppConfig.renderHtml) - .then((value) => AppConfig.renderHtml = value); - store - .getItemBool( - SettingKeys.hideRedactedEvents, - AppConfig.hideRedactedEvents, - ) - .then((value) => AppConfig.hideRedactedEvents = value); - store - .getItemBool(SettingKeys.hideUnknownEvents, AppConfig.hideUnknownEvents) - .then((value) => AppConfig.hideUnknownEvents = value); - store - .getItemBool( - SettingKeys.showDirectChatsInSpaces, - AppConfig.showDirectChatsInSpaces, - ) - .then((value) => AppConfig.showDirectChatsInSpaces = value); - store - .getItemBool(SettingKeys.separateChatTypes, AppConfig.separateChatTypes) - .then((value) => AppConfig.separateChatTypes = value); - store - .getItemBool(SettingKeys.autoplayImages, AppConfig.autoplayImages) - .then((value) => AppConfig.autoplayImages = value); - store - .getItemBool( - SettingKeys.sendTypingNotifications, - AppConfig.sendTypingNotifications, - ) - .then((value) => AppConfig.sendTypingNotifications = value); - store - .getItemBool(SettingKeys.sendOnEnter, AppConfig.sendOnEnter) - .then((value) => AppConfig.sendOnEnter = value); - store - .getItemBool(SettingKeys.experimentalVoip, AppConfig.experimentalVoip) - .then((value) => AppConfig.experimentalVoip = value); + final path = store.getString(SettingKeys.wallpaper); + if (path != null) wallpaper = File(path); + + AppConfig.fontSizeFactor = + double.tryParse(store.getString(SettingKeys.fontSizeFactor) ?? '') ?? + AppConfig.fontSizeFactor; + + AppConfig.renderHtml = + store.getBool(SettingKeys.renderHtml) ?? AppConfig.renderHtml; + + AppConfig.hideRedactedEvents = + store.getBool(SettingKeys.hideRedactedEvents) ?? + AppConfig.hideRedactedEvents; + + AppConfig.hideUnknownEvents = + store.getBool(SettingKeys.hideUnknownEvents) ?? + AppConfig.hideUnknownEvents; + + AppConfig.separateChatTypes = + store.getBool(SettingKeys.separateChatTypes) ?? + AppConfig.separateChatTypes; + + AppConfig.autoplayImages = + store.getBool(SettingKeys.autoplayImages) ?? AppConfig.autoplayImages; + + AppConfig.sendTypingNotifications = + store.getBool(SettingKeys.sendTypingNotifications) ?? + AppConfig.sendTypingNotifications; + + AppConfig.sendOnEnter = + store.getBool(SettingKeys.sendOnEnter) ?? AppConfig.sendOnEnter; + + AppConfig.experimentalVoip = store.getBool(SettingKeys.experimentalVoip) ?? + AppConfig.experimentalVoip; } @override diff --git a/lib/widgets/mxc_image.dart b/lib/widgets/mxc_image.dart index beb79425a..0aedd1e4f 100644 --- a/lib/widgets/mxc_image.dart +++ b/lib/widgets/mxc_image.dart @@ -38,8 +38,8 @@ class MxcImage extends StatefulWidget { this.animationCurve = FluffyThemes.animationCurve, this.thumbnailMethod = ThumbnailMethod.scale, this.cacheKey, - Key? key, - }) : super(key: key); + super.key, + }); @override State createState() => _MxcImageState(); diff --git a/lib/widgets/permission_slider_dialog.dart b/lib/widgets/permission_slider_dialog.dart index 8f8958982..cc6e9303e 100644 --- a/lib/widgets/permission_slider_dialog.dart +++ b/lib/widgets/permission_slider_dialog.dart @@ -61,6 +61,16 @@ Future showPermissionChooser( initialText: currentLevel.toString(), keyboardType: TextInputType.number, autocorrect: false, + validator: (text) { + if (text == null) { + return L10n.of(context)!.pleaseEnterANumber; + } + final level = int.tryParse(text); + if (level == null || level < 0) { + return L10n.of(context)!.pleaseEnterANumber; + } + return null; + }, ), ], ); diff --git a/lib/widgets/presence_builder.dart b/lib/widgets/presence_builder.dart new file mode 100644 index 000000000..223fe0cc7 --- /dev/null +++ b/lib/widgets/presence_builder.dart @@ -0,0 +1,34 @@ +import 'package:flutter/material.dart'; + +import 'package:matrix/matrix.dart'; + +import 'package:fluffychat/widgets/matrix.dart'; + +class PresenceBuilder extends StatelessWidget { + final Widget Function(BuildContext context, CachedPresence? presence) builder; + final String? userId; + final Client? client; + + const PresenceBuilder({ + required this.builder, + this.userId, + this.client, + super.key, + }); + + @override + Widget build(BuildContext context) { + final userId = this.userId; + if (userId == null) return builder(context, null); + + final client = this.client ?? Matrix.of(context).client; + return StreamBuilder( + stream: client.onPresenceChanged.stream + .where((cachedPresence) => cachedPresence.userid == userId), + builder: (context, snapshot) => builder( + context, + snapshot.data ?? client.presences[userId], + ), + ); + } +} diff --git a/lib/widgets/profile_bottom_sheet.dart b/lib/widgets/profile_bottom_sheet.dart new file mode 100644 index 000000000..3bfbb2029 --- /dev/null +++ b/lib/widgets/profile_bottom_sheet.dart @@ -0,0 +1,101 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; +import 'package:go_router/go_router.dart'; +import 'package:matrix/matrix.dart'; + +import 'package:fluffychat/widgets/avatar.dart'; +import 'package:fluffychat/widgets/matrix.dart'; + +class ProfileBottomSheet extends StatelessWidget { + final String userId; + final BuildContext outerContext; + + const ProfileBottomSheet({ + required this.userId, + required this.outerContext, + super.key, + }); + + void _startDirectChat(BuildContext context) async { + final client = Matrix.of(context).client; + final result = await showFutureLoadingDialog( + context: context, + //#Pangea + // future: () => client.startDirectChat(userId), + future: () => client.startDirectChat(userId, enableEncryption: false), + //Pangea# + ); + if (result.error == null) { + context.go('/rooms/${result.result!}'); + Navigator.of(context, rootNavigator: false).pop(); + return; + } + } + + @override + Widget build(BuildContext context) { + return SafeArea( + child: FutureBuilder( + future: Matrix.of(context).client.getProfileFromUserId(userId), + builder: (context, snapshot) { + final profile = snapshot.data; + return Scaffold( + appBar: AppBar( + leading: CloseButton( + onPressed: Navigator.of(context, rootNavigator: false).pop, + ), + title: ListTile( + contentPadding: const EdgeInsets.only(right: 16.0), + title: Text( + profile?.displayName ?? userId.localpart ?? userId, + style: const TextStyle(fontSize: 18), + ), + subtitle: Text( + userId, + style: const TextStyle(fontSize: 12), + ), + ), + actions: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: OutlinedButton.icon( + onPressed: () => _startDirectChat(context), + icon: Icon(Icons.adaptive.share_outlined), + label: Text(L10n.of(context)!.share), + ), + ), + ], + ), + body: ListView( + children: [ + Center( + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Avatar( + mxContent: profile?.avatarUrl, + name: profile?.displayName ?? userId, + size: Avatar.defaultSize * 3, + fontSize: 36, + ), + ), + ), + Container( + width: double.infinity, + padding: const EdgeInsets.all(12), + child: FloatingActionButton.extended( + onPressed: () => _startDirectChat(context), + label: Text(L10n.of(context)!.newChat), + icon: const Icon(Icons.send_outlined), + ), + ), + const SizedBox(height: 8), + ], + ), + ); + }, + ), + ); + } +} diff --git a/lib/widgets/public_room_bottom_sheet.dart b/lib/widgets/public_room_bottom_sheet.dart index 87ee50256..cfe21c5e3 100644 --- a/lib/widgets/public_room_bottom_sheet.dart +++ b/lib/widgets/public_room_bottom_sheet.dart @@ -22,8 +22,8 @@ class PublicRoomBottomSheet extends StatelessWidget { required this.outerContext, this.chunk, this.onRoomJoined, - Key? key, - }) : super(key: key) { + super.key, + }) { assert(roomAlias != null || chunk != null); } diff --git a/lib/widgets/settings_switch_list_tile.dart b/lib/widgets/settings_switch_list_tile.dart index a3da2dbb6..8f4285a4b 100644 --- a/lib/widgets/settings_switch_list_tile.dart +++ b/lib/widgets/settings_switch_list_tile.dart @@ -9,12 +9,12 @@ class SettingsSwitchListTile extends StatefulWidget { final Function(bool)? onChanged; const SettingsSwitchListTile.adaptive({ - Key? key, + super.key, this.defaultValue = false, required this.storeKey, required this.title, this.onChanged, - }) : super(key: key); + }); @override SettingsSwitchListTileState createState() => SettingsSwitchListTileState(); @@ -23,19 +23,15 @@ class SettingsSwitchListTile extends StatefulWidget { class SettingsSwitchListTileState extends State { @override Widget build(BuildContext context) { - return FutureBuilder( - future: Matrix.of(context) - .store - .getItemBool(widget.storeKey, widget.defaultValue), - builder: (context, snapshot) => SwitchListTile.adaptive( - value: snapshot.data ?? widget.defaultValue, - title: Text(widget.title), - onChanged: (bool newValue) async { - widget.onChanged?.call(newValue); - await Matrix.of(context).store.setItemBool(widget.storeKey, newValue); - setState(() {}); - }, - ), + return SwitchListTile.adaptive( + value: Matrix.of(context).store.getBool(widget.storeKey) ?? + widget.defaultValue, + title: Text(widget.title), + onChanged: (bool newValue) async { + widget.onChanged?.call(newValue); + await Matrix.of(context).store.setBool(widget.storeKey, newValue); + setState(() {}); + }, ); } } diff --git a/lib/widgets/theme_builder.dart b/lib/widgets/theme_builder.dart index b1ca4aa42..b35a0b449 100644 --- a/lib/widgets/theme_builder.dart +++ b/lib/widgets/theme_builder.dart @@ -19,8 +19,8 @@ class ThemeBuilder extends StatefulWidget { required this.builder, this.themeModeSettingsKey = 'theme_mode', this.primaryColorSettingsKey = 'primary_color', - Key? key, - }) : super(key: key); + super.key, + }); @override State createState() => ThemeController(); diff --git a/lib/widgets/unread_rooms_badge.dart b/lib/widgets/unread_rooms_badge.dart index 2110e4e33..72f14b76c 100644 --- a/lib/widgets/unread_rooms_badge.dart +++ b/lib/widgets/unread_rooms_badge.dart @@ -11,11 +11,11 @@ class UnreadRoomsBadge extends StatelessWidget { final Widget? child; const UnreadRoomsBadge({ - Key? key, + super.key, required this.filter, this.badgePosition, this.child, - }) : super(key: key); + }); @override Widget build(BuildContext context) { @@ -26,12 +26,22 @@ class UnreadRoomsBadge extends StatelessWidget { .stream .where((syncUpdate) => syncUpdate.hasRoomUpdate), builder: (context, _) { - final unreadCount = Matrix.of(context) + // #Pangea + // final unreadCount = Matrix.of(context) + // .client + // .rooms + // .where(filter) + // .where((r) => (r.isUnread || r.membership == Membership.invite)) + // .length; + final unreadCounts = Matrix.of(context) .client .rooms .where(filter) .where((r) => (r.isUnread || r.membership == Membership.invite)) - .length; + .map((r) => r.notificationCount); + final unreadCount = + unreadCounts.isEmpty ? 0 : unreadCounts.reduce((a, b) => a + b); + // Pangea# return b.Badge( badgeStyle: b.BadgeStyle( badgeColor: Theme.of(context).colorScheme.primary, diff --git a/linux/CMakeLists.txt b/linux/CMakeLists.txt index 258591b6b..5b46b2157 100644 --- a/linux/CMakeLists.txt +++ b/linux/CMakeLists.txt @@ -86,7 +86,6 @@ set_target_properties(${BINARY_NAME} RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run" ) - # Generated plugin build rules, which manage building the plugins and adding # them to the application. include(flutter/generated_plugins.cmake) diff --git a/linux/flutter/generated_plugin_registrant.cc b/linux/flutter/generated_plugin_registrant.cc index 6af12d051..eb3c11cf1 100644 --- a/linux/flutter/generated_plugin_registrant.cc +++ b/linux/flutter/generated_plugin_registrant.cc @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -46,6 +47,9 @@ void fl_register_plugins(FlPluginRegistry* registry) { g_autoptr(FlPluginRegistrar) record_linux_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "RecordLinuxPlugin"); record_linux_plugin_register_with_registrar(record_linux_registrar); + g_autoptr(FlPluginRegistrar) sentry_flutter_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "SentryFlutterPlugin"); + sentry_flutter_plugin_register_with_registrar(sentry_flutter_registrar); g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin"); url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar); diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake index d24b1b225..044576a2d 100644 --- a/linux/flutter/generated_plugins.cmake +++ b/linux/flutter/generated_plugins.cmake @@ -12,6 +12,7 @@ list(APPEND FLUTTER_PLUGIN_LIST flutter_webrtc pasteboard record_linux + sentry_flutter url_launcher_linux window_to_front ) diff --git a/linux/my_application.cc b/linux/my_application.cc index 269a85872..6dea055f2 100644 --- a/linux/my_application.cc +++ b/linux/my_application.cc @@ -53,11 +53,11 @@ static void my_application_activate(GApplication* application) { if (use_header_bar) { GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new()); gtk_widget_show(GTK_WIDGET(header_bar)); - gtk_header_bar_set_title(header_bar, "fluffychat"); + gtk_header_bar_set_title(header_bar, "FluffyChat"); gtk_header_bar_set_show_close_button(header_bar, TRUE); gtk_window_set_titlebar(window, GTK_WIDGET(header_bar)); } else { - gtk_window_set_title(window, "fluffychat"); + gtk_window_set_title(window, "FluffyChat"); } gtk_window_set_default_size(window, 864, 680); diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index e47880af4..f6c93f34f 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -5,60 +5,78 @@ import FlutterMacOS import Foundation +import appkit_ui_element_colors import audio_session +import connectivity_plus import desktop_drop import desktop_lifecycle import device_info_plus import dynamic_color import emoji_picker_flutter import file_selector_macos +import firebase_analytics +import firebase_core +import firebase_messaging import flutter_app_badger import flutter_local_notifications import flutter_secure_storage_macos import flutter_web_auth_2 import flutter_webrtc import geolocator_apple +import in_app_purchase_storekit import just_audio import macos_ui import macos_window_utils import package_info_plus import pasteboard import path_provider_foundation +import purchases_flutter import record_macos +import sentry_flutter import share_plus import shared_preferences_foundation import sqflite import url_launcher_macos import video_compress +import video_player_avfoundation import wakelock_plus import window_to_front func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { + AppkitUiElementColorsPlugin.register(with: registry.registrar(forPlugin: "AppkitUiElementColorsPlugin")) AudioSessionPlugin.register(with: registry.registrar(forPlugin: "AudioSessionPlugin")) + ConnectivityPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlugin")) DesktopDropPlugin.register(with: registry.registrar(forPlugin: "DesktopDropPlugin")) DesktopLifecyclePlugin.register(with: registry.registrar(forPlugin: "DesktopLifecyclePlugin")) DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin")) DynamicColorPlugin.register(with: registry.registrar(forPlugin: "DynamicColorPlugin")) EmojiPickerFlutterPlugin.register(with: registry.registrar(forPlugin: "EmojiPickerFlutterPlugin")) FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin")) + FLTFirebaseAnalyticsPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseAnalyticsPlugin")) + FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin")) + FLTFirebaseMessagingPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseMessagingPlugin")) FlutterAppBadgerPlugin.register(with: registry.registrar(forPlugin: "FlutterAppBadgerPlugin")) FlutterLocalNotificationsPlugin.register(with: registry.registrar(forPlugin: "FlutterLocalNotificationsPlugin")) FlutterSecureStoragePlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStoragePlugin")) FlutterWebAuth2Plugin.register(with: registry.registrar(forPlugin: "FlutterWebAuth2Plugin")) FlutterWebRTCPlugin.register(with: registry.registrar(forPlugin: "FlutterWebRTCPlugin")) GeolocatorPlugin.register(with: registry.registrar(forPlugin: "GeolocatorPlugin")) + InAppPurchasePlugin.register(with: registry.registrar(forPlugin: "InAppPurchasePlugin")) JustAudioPlugin.register(with: registry.registrar(forPlugin: "JustAudioPlugin")) MacOSUiPlugin.register(with: registry.registrar(forPlugin: "MacOSUiPlugin")) MacOSWindowUtilsPlugin.register(with: registry.registrar(forPlugin: "MacOSWindowUtilsPlugin")) - FLTPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlusPlugin")) + FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin")) PasteboardPlugin.register(with: registry.registrar(forPlugin: "PasteboardPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) + PurchasesFlutterPlugin.register(with: registry.registrar(forPlugin: "PurchasesFlutterPlugin")) RecordMacosPlugin.register(with: registry.registrar(forPlugin: "RecordMacosPlugin")) + SentryFlutterPlugin.register(with: registry.registrar(forPlugin: "SentryFlutterPlugin")) SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin")) UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) VideoCompressPlugin.register(with: registry.registrar(forPlugin: "VideoCompressPlugin")) + FVPVideoPlayerPlugin.register(with: registry.registrar(forPlugin: "FVPVideoPlayerPlugin")) WakelockPlusMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockPlusMacosPlugin")) WindowToFrontPlugin.register(with: registry.registrar(forPlugin: "WindowToFrontPlugin")) } diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json index eba1335b9..0eaf115df 100644 --- a/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -1 +1 @@ -{"images":[{"size":"1024x1024","filename":"1024-mac.png","expected-size":"1024","idiom":"ios-marketing","folder":"Assets.xcassets/AppIcon.appiconset/","scale":"1x"},{"size":"128x128","expected-size":"128","filename":"128-mac.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"256x256","expected-size":"256","filename":"256-mac.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"128x128","expected-size":"256","filename":"256-mac.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"},{"size":"256x256","expected-size":"512","filename":"512-mac.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"},{"size":"32x32","expected-size":"32","filename":"32-mac.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"512x512","expected-size":"512","filename":"512-mac.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"16x16","expected-size":"16","filename":"16-mac.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"16x16","expected-size":"32","filename":"32-mac.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"},{"size":"32x32","expected-size":"64","filename":"64-mac.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"},{"size":"512x512","expected-size":"1024","filename":"1024-mac.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"}]} \ No newline at end of file +{"images":[{"size":"1024x1024","filename":"1024-mac.png","expected-size":"1024","idiom":"ios-marketing","folder":"Assets.xcassets/AppIcon.appiconset/","scale":"1x"},{"size":"128x128","expected-size":"128","filename":"128-mac.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"256x256","expected-size":"256","filename":"256-mac.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"128x128","expected-size":"256","filename":"256-mac.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"},{"size":"256x256","expected-size":"512","filename":"512-mac.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"},{"size":"32x32","expected-size":"32","filename":"32-mac.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"512x512","expected-size":"512","filename":"512-mac.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"16x16","expected-size":"16","filename":"16-mac.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"16x16","expected-size":"32","filename":"32-mac.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"},{"size":"32x32","expected-size":"64","filename":"64-mac.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"},{"size":"512x512","expected-size":"1024","filename":"1024-mac.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"}]} diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png new file mode 100644 index 000000000..fb1434bfe Binary files /dev/null and b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png differ diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png new file mode 100644 index 000000000..34d07d5ea Binary files /dev/null and b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png differ diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png new file mode 100644 index 000000000..e78ba9054 Binary files /dev/null and b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png differ diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png new file mode 100644 index 000000000..f7508e359 Binary files /dev/null and b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png differ diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png new file mode 100644 index 000000000..6154ba14c Binary files /dev/null and b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png differ diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png new file mode 100644 index 000000000..6245280ee Binary files /dev/null and b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png differ diff --git a/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png new file mode 100644 index 000000000..7de4d1f3e Binary files /dev/null and b/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png differ diff --git a/needed-translations.txt b/needed-translations.txt new file mode 100644 index 000000000..22219e8b3 --- /dev/null +++ b/needed-translations.txt @@ -0,0 +1,34274 @@ +{ + "ar": [ + "accountInformation", + "addNewFriend", + "alreadyHaveAnAccount", + "classes", + "allCorrect", + "newWayAllGood", + "othersAreBetter", + "holdForInfo", + "greenFeedback", + "yellowFeedback", + "redFeedback", + "customInputFeedbackChoice", + "itInstructionsTitle", + "itInstructionsBody", + "toggleLanguages", + "classWelcomeChat", + "deleteSpace", + "deleteGroup", + "areYouSureDeleteClass", + "areYouSureDeleteGroup", + "cannotBeReversed", + "enterDeletedClassName", + "incorrectClassName", + "oneday", + "oneweek", + "onemonth", + "sixmonth", + "oneyear", + "gaTooltip", + "taTooltip", + "unTooltip", + "interactiveTranslatorSliderHeader", + "interactiveGrammarSliderHeader", + "interactiveTranslatorNotAllowed", + "interactiveTranslatorAllowed", + "interactiveTranslatorRequired", + "interactiveTranslatorNotAllowedDesc", + "interactiveTranslatorAllowedDesc", + "interactiveTranslatorRequiredDesc", + "notYetSet", + "multiLingualClass", + "classAnalytics", + "allClasses", + "myLearning", + "allChatsAndClasses", + "timeOfLastMessage", + "totalMessages", + "waTooltip", + "changeDateRange", + "numberOfStudents", + "classDescription", + "classDescriptionDesc", + "requestToEnroll", + "requestAnExchange", + "findLanguageExchange", + "classAnalyticsDesc", + "addStudents", + "copyClassLink", + "copyClassLinkDesc", + "copyClassCode", + "inviteStudentByUserName", + "classSettings", + "classSettingsDesc", + "selectClassRoomDominantLanguage", + "selectTargetLanguage", + "whatIsYourClassLanguageLevel", + "studentPermissions", + "interactiveTranslator", + "oneToOneChatsWithinClass", + "oneToOneChatsWithinClassDesc", + "createGroupChats", + "createGroupChatsDesc", + "shareVideo", + "shareVideoDesc", + "sharePhotos", + "sharePhotosDesc", + "shareFiles", + "shareFilesDesc", + "shareLocationDesc", + "selectLanguageLevel", + "noIdenticalLanguages", + "iWantALanguagePartnerFrom", + "worldWide", + "noResults", + "searchBy", + "iWantAConversationPartner", + "iWantALanguagePartnerWhoSpeaks", + "iWantALanguagePartnerWhoIsLearning", + "yourBirthdayPlease", + "invalidDob", + "enterYourDob", + "getStarted", + "mustBe13", + "yourBirthdayPleaseShort", + "errorPleaseRefresh", + "joinWithClassCode", + "joinWithClassCodeDesc", + "joinWithClassCodeHint", + "unableToFindClass", + "languageLevelPreA1", + "languageLevelA1", + "languageLevelA2", + "languageLevelB1", + "languageLevelB2", + "languageLevelC1", + "languageLevelC2", + "changeTheNameOfTheClass", + "changeTheNameOfTheChat", + "welcomeToYourNewClass", + "welcomeToClass", + "welcomeToPangea18Plus", + "welcomeToPangeaMinor", + "findALanguagePartner", + "setToPublicSettingsTitle", + "setToPublicSettingsDesc", + "accountSettings", + "unableToFindClassCode", + "askPangeaBot", + "sorryNoResults", + "ignoreInThisText", + "helpMeTranslate", + "needsItShortMessage", + "needsIGCShortMessage", + "needsItMessage", + "needsIgcMessage", + "tokenTranslationTitle", + "spanTranslationDesc", + "spanTranslationTitle", + "l1SpanAndGrammarTitle", + "l1SpanAndGrammarDesc", + "otherTitle", + "otherDesc", + "countryInformation", + "myLanguages", + "targetLanguage", + "sourceLanguage", + "languagesISpeak", + "updateLanguage", + "whatLanguageYouWantToLearn", + "whatIsYourBaseLanguage", + "saveChanges", + "publicProfileTitle", + "publicProfileDesc", + "error502504Title", + "error502504Desc", + "error404Title", + "error404Desc", + "errorDisableIT", + "errorDisableIGC", + "errorDisableLanguageAssistance", + "errorDisableITUserDesc", + "errorDisableIGCUserDesc", + "errorDisableLanguageAssistanceUserDesc", + "errorDisableITClassDesc", + "errorDisableIGCClassDesc", + "errorDisableLanguageAssistanceClassDesc", + "itIsDisabled", + "igcIsDisabled", + "goToLearningSettings", + "error405Title", + "error405Desc", + "loginOrSignup", + "iAgreeToThe", + "termsAndConditions", + "andCertifyIAmAtLeast13YearsOfAge", + "findAClass", + "toggleIT", + "toggleIGC", + "toggleToolSettingsDescription", + "connectedToStaging", + "learningSettings", + "classNameRequired", + "sendVoiceNotes", + "sendVoiceNotesDesc", + "chatTopic", + "chatTopicDesc", + "inviteStudentByUserNameDesc", + "classRoster", + "almostPerfect", + "prettyGood", + "letMeThink", + "clickMessageTitle", + "clickMessageBody", + "understandingMessagesTitle", + "addToClass", + "understandingMessagesBody", + "allDone", + "vocab", + "low", + "medium", + "high", + "unknownProficiency", + "changeView", + "clearAll", + "generateVocabulary", + "generatePrompts", + "subscribe", + "getAccess", + "subscriptionDesc", + "subscriptionManagement", + "currentSubscription", + "changeSubscription", + "cancelSubscription", + "selectYourPlan", + "subsciptionPlatformTooltip", + "subscriptionManagementUnavailable", + "paymentMethod", + "paymentHistory", + "emptyChatDownloadWarning", + "appUpdateAvailable", + "update", + "updateDesc", + "maybeLater", + "mainMenu", + "toggleImmersionMode", + "toggleImmersionModeDesc", + "itToggleDescription", + "igcToggleDescription", + "sendOnEnterDescription", + "alreadyInClass", + "pleaseLoginFirst", + "originalMessage", + "sentMessage", + "useType", + "notAvailable", + "taAndGaTooltip", + "definitionsToolName", + "messageTranslationsToolName", + "definitionsToolDescription", + "translationsToolDescrption", + "welcomeBack", + "classExchanges", + "createNewClass", + "newExchange", + "kickAllStudents", + "kickAllStudentsConfirmation", + "inviteAllStudents", + "inviteAllStudentsConfirmation", + "inviteStudentsFromOtherClasses", + "inviteUsersFromPangea", + "allExchanges", + "redeemPromoCode", + "enterPromoCode", + "downloadTxtFile", + "downloadCSVFile", + "promotionalSubscriptionDesc", + "originalSubscriptionPlatform", + "oneWeekTrial", + "creatingSpacePleaseWait", + "downloadXLSXFile", + "abDisplayName", + "aaDisplayName", + "afDisplayName", + "akDisplayName", + "sqDisplayName", + "amDisplayName", + "arDisplayName", + "anDisplayName", + "hyDisplayName", + "asDisplayName", + "avDisplayName", + "aeDisplayName", + "ayDisplayName", + "azDisplayName", + "bmDisplayName", + "baDisplayName", + "euDisplayName", + "beDisplayName", + "bnDisplayName", + "bhDisplayName", + "biDisplayName", + "bsDisplayName", + "brDisplayName", + "bgDisplayName", + "myDisplayName", + "caDisplayName", + "chDisplayName", + "ceDisplayName", + "nyDisplayName", + "zhDisplayName", + "cvDisplayName", + "kwDisplayName", + "coDisplayName", + "crDisplayName", + "hrDisplayName", + "csDisplayName", + "daDisplayName", + "dvDisplayName", + "nlDisplayName", + "enDisplayName", + "eoDisplayName", + "etDisplayName", + "eeDisplayName", + "foDisplayName", + "fjDisplayName", + "fiDisplayName", + "frDisplayName", + "ffDisplayName", + "glDisplayName", + "kaDisplayName", + "deDisplayName", + "elDisplayName", + "gnDisplayName", + "guDisplayName", + "htDisplayName", + "haDisplayName", + "heDisplayName", + "hzDisplayName", + "hiDisplayName", + "hoDisplayName", + "huDisplayName", + "iaDisplayName", + "idDisplayName", + "ieDisplayName", + "gaDisplayName", + "igDisplayName", + "ikDisplayName", + "ioDisplayName", + "isDisplayName", + "itDisplayName", + "iuDisplayName", + "jaDisplayName", + "jvDisplayName", + "klDisplayName", + "knDisplayName", + "krDisplayName", + "ksDisplayName", + "kkDisplayName", + "kmDisplayName", + "kiDisplayName", + "rwDisplayName", + "kyDisplayName", + "kvDisplayName", + "kgDisplayName", + "koDisplayName", + "kuDisplayName", + "kjDisplayName", + "laDisplayName", + "lbDisplayName", + "lgDisplayName", + "liDisplayName", + "lnDisplayName", + "loDisplayName", + "ltDisplayName", + "luDisplayName", + "lvDisplayName", + "gvDisplayName", + "mkDisplayName", + "mgDisplayName", + "msDisplayName", + "mlDisplayName", + "mtDisplayName", + "miDisplayName", + "mrDisplayName", + "mhDisplayName", + "mnDisplayName", + "naDisplayName", + "nvDisplayName", + "nbDisplayName", + "ndDisplayName", + "neDisplayName", + "ngDisplayName", + "nnDisplayName", + "noDisplayName", + "iiDisplayName", + "nrDisplayName", + "ocDisplayName", + "ojDisplayName", + "cuDisplayName", + "omDisplayName", + "orDisplayName", + "osDisplayName", + "paDisplayName", + "piDisplayName", + "faDisplayName", + "plDisplayName", + "psDisplayName", + "ptDisplayName", + "quDisplayName", + "rmDisplayName", + "rnDisplayName", + "roDisplayName", + "ruDisplayName", + "saDisplayName", + "scDisplayName", + "sdDisplayName", + "seDisplayName", + "smDisplayName", + "sgDisplayName", + "srDisplayName", + "gdDisplayName", + "snDisplayName", + "siDisplayName", + "skDisplayName", + "slDisplayName", + "soDisplayName", + "stDisplayName", + "esDisplayName", + "suDisplayName", + "swDisplayName", + "ssDisplayName", + "svDisplayName", + "taDisplayName", + "teDisplayName", + "tgDisplayName", + "thDisplayName", + "tiDisplayName", + "boDisplayName", + "tkDisplayName", + "tlDisplayName", + "tnDisplayName", + "toDisplayName", + "trDisplayName", + "tsDisplayName", + "ttDisplayName", + "twDisplayName", + "tyDisplayName", + "ugDisplayName", + "ukDisplayName", + "urDisplayName", + "uzDisplayName", + "veDisplayName", + "viDisplayName", + "voDisplayName", + "waDisplayName", + "cyDisplayName", + "woDisplayName", + "fyDisplayName", + "xhDisplayName", + "yiDisplayName", + "yoDisplayName", + "zaDisplayName", + "unkDisplayName", + "zuDisplayName", + "hawDisplayName", + "hmnDisplayName", + "multiDisplayName", + "cebDisplayName", + "dzDisplayName", + "iwDisplayName", + "jwDisplayName", + "moDisplayName", + "shDisplayName", + "wwCountryDisplayName", + "afCountryDisplayName", + "axCountryDisplayName", + "alCountryDisplayName", + "dzCountryDisplayName", + "asCountryDisplayName", + "adCountryDisplayName", + "aoCountryDisplayName", + "aiCountryDisplayName", + "agCountryDisplayName", + "arCountryDisplayName", + "amCountryDisplayName", + "awCountryDisplayName", + "acCountryDisplayName", + "auCountryDisplayName", + "atCountryDisplayName", + "azCountryDisplayName", + "bsCountryDisplayName", + "bhCountryDisplayName", + "bdCountryDisplayName", + "bbCountryDisplayName", + "byCountryDisplayName", + "beCountryDisplayName", + "bzCountryDisplayName", + "bjCountryDisplayName", + "bmCountryDisplayName", + "btCountryDisplayName", + "boCountryDisplayName", + "baCountryDisplayName", + "bwCountryDisplayName", + "brCountryDisplayName", + "ioCountryDisplayName", + "vgCountryDisplayName", + "bnCountryDisplayName", + "bgCountryDisplayName", + "bfCountryDisplayName", + "biCountryDisplayName", + "khCountryDisplayName", + "cmCountryDisplayName", + "caCountryDisplayName", + "cvCountryDisplayName", + "bqCountryDisplayName", + "kyCountryDisplayName", + "cfCountryDisplayName", + "tdCountryDisplayName", + "clCountryDisplayName", + "cnCountryDisplayName", + "cxCountryDisplayName", + "ccCountryDisplayName", + "coCountryDisplayName", + "kmCountryDisplayName", + "cdCountryDisplayName", + "cgCountryDisplayName", + "ckCountryDisplayName", + "crCountryDisplayName", + "ciCountryDisplayName", + "hrCountryDisplayName", + "cuCountryDisplayName", + "cwCountryDisplayName", + "cyCountryDisplayName", + "czCountryDisplayName", + "dkCountryDisplayName", + "djCountryDisplayName", + "dmCountryDisplayName", + "doCountryDisplayName", + "tlCountryDisplayName", + "ecCountryDisplayName", + "egCountryDisplayName", + "svCountryDisplayName", + "gqCountryDisplayName", + "erCountryDisplayName", + "eeCountryDisplayName", + "szCountryDisplayName", + "etCountryDisplayName", + "fkCountryDisplayName", + "foCountryDisplayName", + "fjCountryDisplayName", + "fiCountryDisplayName", + "frCountryDisplayName", + "gfCountryDisplayName", + "pfCountryDisplayName", + "gaCountryDisplayName", + "gmCountryDisplayName", + "geCountryDisplayName", + "deCountryDisplayName", + "ghCountryDisplayName", + "giCountryDisplayName", + "grCountryDisplayName", + "glCountryDisplayName", + "gdCountryDisplayName", + "gpCountryDisplayName", + "guCountryDisplayName", + "gtCountryDisplayName", + "ggCountryDisplayName", + "gnCountryDisplayName", + "gwCountryDisplayName", + "gyCountryDisplayName", + "htCountryDisplayName", + "hmCountryDisplayName", + "hnCountryDisplayName", + "hkCountryDisplayName", + "huCountryDisplayName", + "isCountryDisplayName", + "inCountryDisplayName", + "idCountryDisplayName", + "irCountryDisplayName", + "iqCountryDisplayName", + "ieCountryDisplayName", + "imCountryDisplayName", + "ilCountryDisplayName", + "itCountryDisplayName", + "jmCountryDisplayName", + "jpCountryDisplayName", + "jeCountryDisplayName", + "joCountryDisplayName", + "kzCountryDisplayName", + "keCountryDisplayName", + "kiCountryDisplayName", + "xkCountryDisplayName", + "kwCountryDisplayName", + "kgCountryDisplayName", + "laCountryDisplayName", + "lvCountryDisplayName", + "lbCountryDisplayName", + "lsCountryDisplayName", + "lrCountryDisplayName", + "lyCountryDisplayName", + "liCountryDisplayName", + "ltCountryDisplayName", + "luCountryDisplayName", + "moCountryDisplayName", + "mkCountryDisplayName", + "mgCountryDisplayName", + "mwCountryDisplayName", + "myCountryDisplayName", + "mvCountryDisplayName", + "mlCountryDisplayName", + "mtCountryDisplayName", + "mhCountryDisplayName", + "mqCountryDisplayName", + "mrCountryDisplayName", + "muCountryDisplayName", + "ytCountryDisplayName", + "mxCountryDisplayName", + "fmCountryDisplayName", + "mdCountryDisplayName", + "mcCountryDisplayName", + "mnCountryDisplayName", + "meCountryDisplayName", + "msCountryDisplayName", + "maCountryDisplayName", + "mzCountryDisplayName", + "mmCountryDisplayName", + "naCountryDisplayName", + "nrCountryDisplayName", + "npCountryDisplayName", + "nlCountryDisplayName", + "ncCountryDisplayName", + "nzCountryDisplayName", + "niCountryDisplayName", + "neCountryDisplayName", + "ngCountryDisplayName", + "nuCountryDisplayName", + "nfCountryDisplayName", + "kpCountryDisplayName", + "mpCountryDisplayName", + "noCountryDisplayName", + "omCountryDisplayName", + "pkCountryDisplayName", + "pwCountryDisplayName", + "psCountryDisplayName", + "paCountryDisplayName", + "pgCountryDisplayName", + "pyCountryDisplayName", + "peCountryDisplayName", + "phCountryDisplayName", + "plCountryDisplayName", + "ptCountryDisplayName", + "prCountryDisplayName", + "qaCountryDisplayName", + "reCountryDisplayName", + "roCountryDisplayName", + "ruCountryDisplayName", + "rwCountryDisplayName", + "blCountryDisplayName", + "shCountryDisplayName", + "knCountryDisplayName", + "lcCountryDisplayName", + "mfCountryDisplayName", + "pmCountryDisplayName", + "vcCountryDisplayName", + "wsCountryDisplayName", + "smCountryDisplayName", + "stCountryDisplayName", + "saCountryDisplayName", + "snCountryDisplayName", + "rsCountryDisplayName", + "scCountryDisplayName", + "slCountryDisplayName", + "sgCountryDisplayName", + "sxCountryDisplayName", + "skCountryDisplayName", + "siCountryDisplayName", + "sbCountryDisplayName", + "soCountryDisplayName", + "zaCountryDisplayName", + "gsCountryDisplayName", + "krCountryDisplayName", + "ssCountryDisplayName", + "esCountryDisplayName", + "lkCountryDisplayName", + "sdCountryDisplayName", + "srCountryDisplayName", + "sjCountryDisplayName", + "seCountryDisplayName", + "chCountryDisplayName", + "syCountryDisplayName", + "twCountryDisplayName", + "tjCountryDisplayName", + "tzCountryDisplayName", + "thCountryDisplayName", + "tgCountryDisplayName", + "tkCountryDisplayName", + "toCountryDisplayName", + "ttCountryDisplayName", + "tnCountryDisplayName", + "trCountryDisplayName", + "tmCountryDisplayName", + "tcCountryDisplayName", + "tvCountryDisplayName", + "viCountryDisplayName", + "ugCountryDisplayName", + "uaCountryDisplayName", + "aeCountryDisplayName", + "gbCountryDisplayName", + "usCountryDisplayName", + "uyCountryDisplayName", + "uzCountryDisplayName", + "vuCountryDisplayName", + "vaCountryDisplayName", + "veCountryDisplayName", + "vnCountryDisplayName", + "wfCountryDisplayName", + "ehCountryDisplayName", + "yeCountryDisplayName", + "zmCountryDisplayName", + "zwCountryDisplayName", + "pay", + "allPrivateChats", + "unknownPrivateChat", + "copyClassCodeDesc", + "addToClassDesc", + "addToClassOrExchange", + "addToClassOrExchangeDesc", + "invitedToClassOrExchange", + "decline", + "declinedInvitation", + "acceptedInvitation", + "youreInvited", + "studentPermissionsDesc", + "noEligibleSpaces", + "youAddedToSpace", + "youRemovedFromSpace", + "invitedToChat", + "monthlySubscription", + "yearlySubscription", + "defaultSubscription", + "freeTrial", + "grammarAnalytics", + "total", + "noDataFound", + "promoSubscriptionExpirationDesc", + "emptyChatNameWarning", + "emptyClassNameWarning", + "emptyExchangeNameWarning", + "blurMeansTranslateTitle", + "blurMeansTranslateBody", + "someErrorTitle", + "someErrorBody", + "bestCorrectionFeedback", + "distractorFeedback", + "bestAnswerFeedback", + "definitionDefaultPrompt", + "practiceDefaultPrompt", + "correctionDefaultPrompt", + "itStartDefaultPrompt", + "languageLevelWarning", + "lockedChatWarning", + "lockSpace", + "lockChat", + "archiveSpace", + "suggestTo", + "suggestChatDesc", + "suggestExchangeDesc", + "acceptSelection", + "acceptSelectionAnyway", + "makingActivity", + "why", + "definition", + "exampleSentence", + "addToClassTitle", + "reportToTeacher", + "reportMessageTitle", + "reportMessageBody", + "noTeachersFound", + "noAddToSpacePermissions", + "alreadyInSpace", + "yourGlobalUserIdIs", + "noUsersFoundWithQuery", + "searchChatsRooms", + "groupName", + "createGroupAndInviteUsers", + "groupCanBeFoundViaSearch", + "inNoSpaces" + ], + + "bn": [ + "accountInformation", + "addGroupDescription", + "addNewFriend", + "alreadyHaveAnAccount", + "classes", + "createNewGroup", + "editChatPermissions", + "groupDescription", + "groupDescriptionHasBeenChanged", + "allCorrect", + "newWayAllGood", + "othersAreBetter", + "holdForInfo", + "greenFeedback", + "yellowFeedback", + "redFeedback", + "customInputFeedbackChoice", + "itInstructionsTitle", + "itInstructionsBody", + "toggleLanguages", + "classWelcomeChat", + "deleteSpace", + "deleteGroup", + "areYouSureDeleteClass", + "areYouSureDeleteGroup", + "cannotBeReversed", + "enterDeletedClassName", + "incorrectClassName", + "oneday", + "oneweek", + "onemonth", + "sixmonth", + "oneyear", + "gaTooltip", + "taTooltip", + "unTooltip", + "interactiveTranslatorSliderHeader", + "interactiveGrammarSliderHeader", + "interactiveTranslatorNotAllowed", + "interactiveTranslatorAllowed", + "interactiveTranslatorRequired", + "interactiveTranslatorNotAllowedDesc", + "interactiveTranslatorAllowedDesc", + "interactiveTranslatorRequiredDesc", + "notYetSet", + "multiLingualClass", + "classAnalytics", + "allClasses", + "myLearning", + "allChatsAndClasses", + "timeOfLastMessage", + "totalMessages", + "waTooltip", + "changeDateRange", + "numberOfStudents", + "classDescription", + "classDescriptionDesc", + "requestToEnroll", + "requestAnExchange", + "findLanguageExchange", + "classAnalyticsDesc", + "addStudents", + "copyClassLink", + "copyClassLinkDesc", + "copyClassCode", + "inviteStudentByUserName", + "classSettings", + "classSettingsDesc", + "selectClassRoomDominantLanguage", + "selectTargetLanguage", + "whatIsYourClassLanguageLevel", + "studentPermissions", + "interactiveTranslator", + "oneToOneChatsWithinClass", + "oneToOneChatsWithinClassDesc", + "createGroupChats", + "createGroupChatsDesc", + "shareVideo", + "shareVideoDesc", + "sharePhotos", + "sharePhotosDesc", + "shareFiles", + "shareFilesDesc", + "shareLocationDesc", + "selectLanguageLevel", + "noIdenticalLanguages", + "iWantALanguagePartnerFrom", + "worldWide", + "noResults", + "searchBy", + "iWantAConversationPartner", + "iWantALanguagePartnerWhoSpeaks", + "iWantALanguagePartnerWhoIsLearning", + "yourBirthdayPlease", + "invalidDob", + "enterYourDob", + "getStarted", + "mustBe13", + "yourBirthdayPleaseShort", + "errorPleaseRefresh", + "joinWithClassCode", + "joinWithClassCodeDesc", + "joinWithClassCodeHint", + "unableToFindClass", + "languageLevelPreA1", + "languageLevelA1", + "languageLevelA2", + "languageLevelB1", + "languageLevelB2", + "languageLevelC1", + "languageLevelC2", + "changeTheNameOfTheClass", + "changeTheNameOfTheChat", + "welcomeToYourNewClass", + "welcomeToClass", + "welcomeToPangea18Plus", + "welcomeToPangeaMinor", + "findALanguagePartner", + "setToPublicSettingsTitle", + "setToPublicSettingsDesc", + "accountSettings", + "unableToFindClassCode", + "askPangeaBot", + "sorryNoResults", + "ignoreInThisText", + "helpMeTranslate", + "needsItShortMessage", + "needsIGCShortMessage", + "needsItMessage", + "needsIgcMessage", + "tokenTranslationTitle", + "spanTranslationDesc", + "spanTranslationTitle", + "l1SpanAndGrammarTitle", + "l1SpanAndGrammarDesc", + "otherTitle", + "otherDesc", + "countryInformation", + "myLanguages", + "targetLanguage", + "sourceLanguage", + "languagesISpeak", + "updateLanguage", + "whatLanguageYouWantToLearn", + "whatIsYourBaseLanguage", + "saveChanges", + "publicProfileTitle", + "publicProfileDesc", + "error502504Title", + "error502504Desc", + "error404Title", + "error404Desc", + "errorDisableIT", + "errorDisableIGC", + "errorDisableLanguageAssistance", + "errorDisableITUserDesc", + "errorDisableIGCUserDesc", + "errorDisableLanguageAssistanceUserDesc", + "errorDisableITClassDesc", + "errorDisableIGCClassDesc", + "errorDisableLanguageAssistanceClassDesc", + "itIsDisabled", + "igcIsDisabled", + "goToLearningSettings", + "error405Title", + "error405Desc", + "loginOrSignup", + "iAgreeToThe", + "termsAndConditions", + "andCertifyIAmAtLeast13YearsOfAge", + "findAClass", + "toggleIT", + "toggleIGC", + "toggleToolSettingsDescription", + "connectedToStaging", + "learningSettings", + "classNameRequired", + "sendVoiceNotes", + "sendVoiceNotesDesc", + "chatTopic", + "chatTopicDesc", + "inviteStudentByUserNameDesc", + "classRoster", + "almostPerfect", + "prettyGood", + "letMeThink", + "clickMessageTitle", + "clickMessageBody", + "understandingMessagesTitle", + "addToClass", + "understandingMessagesBody", + "allDone", + "vocab", + "low", + "medium", + "high", + "unknownProficiency", + "changeView", + "clearAll", + "generateVocabulary", + "generatePrompts", + "subscribe", + "getAccess", + "subscriptionDesc", + "subscriptionManagement", + "currentSubscription", + "changeSubscription", + "cancelSubscription", + "selectYourPlan", + "subsciptionPlatformTooltip", + "subscriptionManagementUnavailable", + "paymentMethod", + "paymentHistory", + "emptyChatDownloadWarning", + "appUpdateAvailable", + "update", + "updateDesc", + "maybeLater", + "mainMenu", + "toggleImmersionMode", + "toggleImmersionModeDesc", + "itToggleDescription", + "igcToggleDescription", + "sendOnEnterDescription", + "alreadyInClass", + "pleaseLoginFirst", + "originalMessage", + "sentMessage", + "useType", + "notAvailable", + "taAndGaTooltip", + "definitionsToolName", + "messageTranslationsToolName", + "definitionsToolDescription", + "translationsToolDescrption", + "welcomeBack", + "classExchanges", + "createNewClass", + "newExchange", + "kickAllStudents", + "kickAllStudentsConfirmation", + "inviteAllStudents", + "inviteAllStudentsConfirmation", + "inviteStudentsFromOtherClasses", + "inviteUsersFromPangea", + "allExchanges", + "redeemPromoCode", + "enterPromoCode", + "downloadTxtFile", + "downloadCSVFile", + "promotionalSubscriptionDesc", + "originalSubscriptionPlatform", + "oneWeekTrial", + "creatingSpacePleaseWait", + "downloadXLSXFile", + "abDisplayName", + "aaDisplayName", + "afDisplayName", + "akDisplayName", + "sqDisplayName", + "amDisplayName", + "arDisplayName", + "anDisplayName", + "hyDisplayName", + "asDisplayName", + "avDisplayName", + "aeDisplayName", + "ayDisplayName", + "azDisplayName", + "bmDisplayName", + "baDisplayName", + "euDisplayName", + "beDisplayName", + "bnDisplayName", + "bhDisplayName", + "biDisplayName", + "bsDisplayName", + "brDisplayName", + "bgDisplayName", + "myDisplayName", + "caDisplayName", + "chDisplayName", + "ceDisplayName", + "nyDisplayName", + "zhDisplayName", + "cvDisplayName", + "kwDisplayName", + "coDisplayName", + "crDisplayName", + "hrDisplayName", + "csDisplayName", + "daDisplayName", + "dvDisplayName", + "nlDisplayName", + "enDisplayName", + "eoDisplayName", + "etDisplayName", + "eeDisplayName", + "foDisplayName", + "fjDisplayName", + "fiDisplayName", + "frDisplayName", + "ffDisplayName", + "glDisplayName", + "kaDisplayName", + "deDisplayName", + "elDisplayName", + "gnDisplayName", + "guDisplayName", + "htDisplayName", + "haDisplayName", + "heDisplayName", + "hzDisplayName", + "hiDisplayName", + "hoDisplayName", + "huDisplayName", + "iaDisplayName", + "idDisplayName", + "ieDisplayName", + "gaDisplayName", + "igDisplayName", + "ikDisplayName", + "ioDisplayName", + "isDisplayName", + "itDisplayName", + "iuDisplayName", + "jaDisplayName", + "jvDisplayName", + "klDisplayName", + "knDisplayName", + "krDisplayName", + "ksDisplayName", + "kkDisplayName", + "kmDisplayName", + "kiDisplayName", + "rwDisplayName", + "kyDisplayName", + "kvDisplayName", + "kgDisplayName", + "koDisplayName", + "kuDisplayName", + "kjDisplayName", + "laDisplayName", + "lbDisplayName", + "lgDisplayName", + "liDisplayName", + "lnDisplayName", + "loDisplayName", + "ltDisplayName", + "luDisplayName", + "lvDisplayName", + "gvDisplayName", + "mkDisplayName", + "mgDisplayName", + "msDisplayName", + "mlDisplayName", + "mtDisplayName", + "miDisplayName", + "mrDisplayName", + "mhDisplayName", + "mnDisplayName", + "naDisplayName", + "nvDisplayName", + "nbDisplayName", + "ndDisplayName", + "neDisplayName", + "ngDisplayName", + "nnDisplayName", + "noDisplayName", + "iiDisplayName", + "nrDisplayName", + "ocDisplayName", + "ojDisplayName", + "cuDisplayName", + "omDisplayName", + "orDisplayName", + "osDisplayName", + "paDisplayName", + "piDisplayName", + "faDisplayName", + "plDisplayName", + "psDisplayName", + "ptDisplayName", + "quDisplayName", + "rmDisplayName", + "rnDisplayName", + "roDisplayName", + "ruDisplayName", + "saDisplayName", + "scDisplayName", + "sdDisplayName", + "seDisplayName", + "smDisplayName", + "sgDisplayName", + "srDisplayName", + "gdDisplayName", + "snDisplayName", + "siDisplayName", + "skDisplayName", + "slDisplayName", + "soDisplayName", + "stDisplayName", + "esDisplayName", + "suDisplayName", + "swDisplayName", + "ssDisplayName", + "svDisplayName", + "taDisplayName", + "teDisplayName", + "tgDisplayName", + "thDisplayName", + "tiDisplayName", + "boDisplayName", + "tkDisplayName", + "tlDisplayName", + "tnDisplayName", + "toDisplayName", + "trDisplayName", + "tsDisplayName", + "ttDisplayName", + "twDisplayName", + "tyDisplayName", + "ugDisplayName", + "ukDisplayName", + "urDisplayName", + "uzDisplayName", + "veDisplayName", + "viDisplayName", + "voDisplayName", + "waDisplayName", + "cyDisplayName", + "woDisplayName", + "fyDisplayName", + "xhDisplayName", + "yiDisplayName", + "yoDisplayName", + "zaDisplayName", + "unkDisplayName", + "zuDisplayName", + "hawDisplayName", + "hmnDisplayName", + "multiDisplayName", + "cebDisplayName", + "dzDisplayName", + "iwDisplayName", + "jwDisplayName", + "moDisplayName", + "shDisplayName", + "wwCountryDisplayName", + "afCountryDisplayName", + "axCountryDisplayName", + "alCountryDisplayName", + "dzCountryDisplayName", + "asCountryDisplayName", + "adCountryDisplayName", + "aoCountryDisplayName", + "aiCountryDisplayName", + "agCountryDisplayName", + "arCountryDisplayName", + "amCountryDisplayName", + "awCountryDisplayName", + "acCountryDisplayName", + "auCountryDisplayName", + "atCountryDisplayName", + "azCountryDisplayName", + "bsCountryDisplayName", + "bhCountryDisplayName", + "bdCountryDisplayName", + "bbCountryDisplayName", + "byCountryDisplayName", + "beCountryDisplayName", + "bzCountryDisplayName", + "bjCountryDisplayName", + "bmCountryDisplayName", + "btCountryDisplayName", + "boCountryDisplayName", + "baCountryDisplayName", + "bwCountryDisplayName", + "brCountryDisplayName", + "ioCountryDisplayName", + "vgCountryDisplayName", + "bnCountryDisplayName", + "bgCountryDisplayName", + "bfCountryDisplayName", + "biCountryDisplayName", + "khCountryDisplayName", + "cmCountryDisplayName", + "caCountryDisplayName", + "cvCountryDisplayName", + "bqCountryDisplayName", + "kyCountryDisplayName", + "cfCountryDisplayName", + "tdCountryDisplayName", + "clCountryDisplayName", + "cnCountryDisplayName", + "cxCountryDisplayName", + "ccCountryDisplayName", + "coCountryDisplayName", + "kmCountryDisplayName", + "cdCountryDisplayName", + "cgCountryDisplayName", + "ckCountryDisplayName", + "crCountryDisplayName", + "ciCountryDisplayName", + "hrCountryDisplayName", + "cuCountryDisplayName", + "cwCountryDisplayName", + "cyCountryDisplayName", + "czCountryDisplayName", + "dkCountryDisplayName", + "djCountryDisplayName", + "dmCountryDisplayName", + "doCountryDisplayName", + "tlCountryDisplayName", + "ecCountryDisplayName", + "egCountryDisplayName", + "svCountryDisplayName", + "gqCountryDisplayName", + "erCountryDisplayName", + "eeCountryDisplayName", + "szCountryDisplayName", + "etCountryDisplayName", + "fkCountryDisplayName", + "foCountryDisplayName", + "fjCountryDisplayName", + "fiCountryDisplayName", + "frCountryDisplayName", + "gfCountryDisplayName", + "pfCountryDisplayName", + "gaCountryDisplayName", + "gmCountryDisplayName", + "geCountryDisplayName", + "deCountryDisplayName", + "ghCountryDisplayName", + "giCountryDisplayName", + "grCountryDisplayName", + "glCountryDisplayName", + "gdCountryDisplayName", + "gpCountryDisplayName", + "guCountryDisplayName", + "gtCountryDisplayName", + "ggCountryDisplayName", + "gnCountryDisplayName", + "gwCountryDisplayName", + "gyCountryDisplayName", + "htCountryDisplayName", + "hmCountryDisplayName", + "hnCountryDisplayName", + "hkCountryDisplayName", + "huCountryDisplayName", + "isCountryDisplayName", + "inCountryDisplayName", + "idCountryDisplayName", + "irCountryDisplayName", + "iqCountryDisplayName", + "ieCountryDisplayName", + "imCountryDisplayName", + "ilCountryDisplayName", + "itCountryDisplayName", + "jmCountryDisplayName", + "jpCountryDisplayName", + "jeCountryDisplayName", + "joCountryDisplayName", + "kzCountryDisplayName", + "keCountryDisplayName", + "kiCountryDisplayName", + "xkCountryDisplayName", + "kwCountryDisplayName", + "kgCountryDisplayName", + "laCountryDisplayName", + "lvCountryDisplayName", + "lbCountryDisplayName", + "lsCountryDisplayName", + "lrCountryDisplayName", + "lyCountryDisplayName", + "liCountryDisplayName", + "ltCountryDisplayName", + "luCountryDisplayName", + "moCountryDisplayName", + "mkCountryDisplayName", + "mgCountryDisplayName", + "mwCountryDisplayName", + "myCountryDisplayName", + "mvCountryDisplayName", + "mlCountryDisplayName", + "mtCountryDisplayName", + "mhCountryDisplayName", + "mqCountryDisplayName", + "mrCountryDisplayName", + "muCountryDisplayName", + "ytCountryDisplayName", + "mxCountryDisplayName", + "fmCountryDisplayName", + "mdCountryDisplayName", + "mcCountryDisplayName", + "mnCountryDisplayName", + "meCountryDisplayName", + "msCountryDisplayName", + "maCountryDisplayName", + "mzCountryDisplayName", + "mmCountryDisplayName", + "naCountryDisplayName", + "nrCountryDisplayName", + "npCountryDisplayName", + "nlCountryDisplayName", + "ncCountryDisplayName", + "nzCountryDisplayName", + "niCountryDisplayName", + "neCountryDisplayName", + "ngCountryDisplayName", + "nuCountryDisplayName", + "nfCountryDisplayName", + "kpCountryDisplayName", + "mpCountryDisplayName", + "noCountryDisplayName", + "omCountryDisplayName", + "pkCountryDisplayName", + "pwCountryDisplayName", + "psCountryDisplayName", + "paCountryDisplayName", + "pgCountryDisplayName", + "pyCountryDisplayName", + "peCountryDisplayName", + "phCountryDisplayName", + "plCountryDisplayName", + "ptCountryDisplayName", + "prCountryDisplayName", + "qaCountryDisplayName", + "reCountryDisplayName", + "roCountryDisplayName", + "ruCountryDisplayName", + "rwCountryDisplayName", + "blCountryDisplayName", + "shCountryDisplayName", + "knCountryDisplayName", + "lcCountryDisplayName", + "mfCountryDisplayName", + "pmCountryDisplayName", + "vcCountryDisplayName", + "wsCountryDisplayName", + "smCountryDisplayName", + "stCountryDisplayName", + "saCountryDisplayName", + "snCountryDisplayName", + "rsCountryDisplayName", + "scCountryDisplayName", + "slCountryDisplayName", + "sgCountryDisplayName", + "sxCountryDisplayName", + "skCountryDisplayName", + "siCountryDisplayName", + "sbCountryDisplayName", + "soCountryDisplayName", + "zaCountryDisplayName", + "gsCountryDisplayName", + "krCountryDisplayName", + "ssCountryDisplayName", + "esCountryDisplayName", + "lkCountryDisplayName", + "sdCountryDisplayName", + "srCountryDisplayName", + "sjCountryDisplayName", + "seCountryDisplayName", + "chCountryDisplayName", + "syCountryDisplayName", + "twCountryDisplayName", + "tjCountryDisplayName", + "tzCountryDisplayName", + "thCountryDisplayName", + "tgCountryDisplayName", + "tkCountryDisplayName", + "toCountryDisplayName", + "ttCountryDisplayName", + "tnCountryDisplayName", + "trCountryDisplayName", + "tmCountryDisplayName", + "tcCountryDisplayName", + "tvCountryDisplayName", + "viCountryDisplayName", + "ugCountryDisplayName", + "uaCountryDisplayName", + "aeCountryDisplayName", + "gbCountryDisplayName", + "usCountryDisplayName", + "uyCountryDisplayName", + "uzCountryDisplayName", + "vuCountryDisplayName", + "vaCountryDisplayName", + "veCountryDisplayName", + "vnCountryDisplayName", + "wfCountryDisplayName", + "ehCountryDisplayName", + "yeCountryDisplayName", + "zmCountryDisplayName", + "zwCountryDisplayName", + "pay", + "allPrivateChats", + "unknownPrivateChat", + "copyClassCodeDesc", + "addToClassDesc", + "addToClassOrExchange", + "addToClassOrExchangeDesc", + "invitedToClassOrExchange", + "decline", + "declinedInvitation", + "acceptedInvitation", + "youreInvited", + "studentPermissionsDesc", + "noEligibleSpaces", + "youAddedToSpace", + "youRemovedFromSpace", + "invitedToChat", + "monthlySubscription", + "yearlySubscription", + "defaultSubscription", + "freeTrial", + "grammarAnalytics", + "total", + "noDataFound", + "promoSubscriptionExpirationDesc", + "emptyChatNameWarning", + "emptyClassNameWarning", + "emptyExchangeNameWarning", + "blurMeansTranslateTitle", + "blurMeansTranslateBody", + "someErrorTitle", + "someErrorBody", + "bestCorrectionFeedback", + "distractorFeedback", + "bestAnswerFeedback", + "definitionDefaultPrompt", + "practiceDefaultPrompt", + "correctionDefaultPrompt", + "itStartDefaultPrompt", + "languageLevelWarning", + "lockedChatWarning", + "lockSpace", + "lockChat", + "archiveSpace", + "suggestTo", + "suggestChatDesc", + "suggestExchangeDesc", + "acceptSelection", + "acceptSelectionAnyway", + "makingActivity", + "why", + "definition", + "exampleSentence", + "addToClassTitle", + "reportToTeacher", + "reportMessageTitle", + "reportMessageBody", + "noTeachersFound", + "noAddToSpacePermissions", + "alreadyInSpace", + "yourGlobalUserIdIs", + "noUsersFoundWithQuery", + "searchChatsRooms", + "groupName", + "createGroupAndInviteUsers", + "groupCanBeFoundViaSearch", + "inNoSpaces" + ], + + "bo": [ + "accountInformation", + "addGroupDescription", + "addNewFriend", + "alreadyHaveAnAccount", + "classes", + "createNewGroup", + "editChatPermissions", + "groupDescription", + "groupDescriptionHasBeenChanged", + "allCorrect", + "newWayAllGood", + "othersAreBetter", + "holdForInfo", + "greenFeedback", + "yellowFeedback", + "redFeedback", + "customInputFeedbackChoice", + "itInstructionsTitle", + "itInstructionsBody", + "toggleLanguages", + "classWelcomeChat", + "deleteSpace", + "deleteGroup", + "areYouSureDeleteClass", + "areYouSureDeleteGroup", + "cannotBeReversed", + "enterDeletedClassName", + "incorrectClassName", + "oneday", + "oneweek", + "onemonth", + "sixmonth", + "oneyear", + "gaTooltip", + "taTooltip", + "unTooltip", + "interactiveTranslatorSliderHeader", + "interactiveGrammarSliderHeader", + "interactiveTranslatorNotAllowed", + "interactiveTranslatorAllowed", + "interactiveTranslatorRequired", + "interactiveTranslatorNotAllowedDesc", + "interactiveTranslatorAllowedDesc", + "interactiveTranslatorRequiredDesc", + "notYetSet", + "multiLingualClass", + "classAnalytics", + "allClasses", + "myLearning", + "allChatsAndClasses", + "timeOfLastMessage", + "totalMessages", + "waTooltip", + "changeDateRange", + "numberOfStudents", + "classDescription", + "classDescriptionDesc", + "requestToEnroll", + "requestAnExchange", + "findLanguageExchange", + "classAnalyticsDesc", + "addStudents", + "copyClassLink", + "copyClassLinkDesc", + "copyClassCode", + "inviteStudentByUserName", + "classSettings", + "classSettingsDesc", + "selectClassRoomDominantLanguage", + "selectTargetLanguage", + "whatIsYourClassLanguageLevel", + "studentPermissions", + "interactiveTranslator", + "oneToOneChatsWithinClass", + "oneToOneChatsWithinClassDesc", + "createGroupChats", + "createGroupChatsDesc", + "shareVideo", + "shareVideoDesc", + "sharePhotos", + "sharePhotosDesc", + "shareFiles", + "shareFilesDesc", + "shareLocationDesc", + "selectLanguageLevel", + "noIdenticalLanguages", + "iWantALanguagePartnerFrom", + "worldWide", + "noResults", + "searchBy", + "iWantAConversationPartner", + "iWantALanguagePartnerWhoSpeaks", + "iWantALanguagePartnerWhoIsLearning", + "yourBirthdayPlease", + "invalidDob", + "enterYourDob", + "getStarted", + "mustBe13", + "yourBirthdayPleaseShort", + "errorPleaseRefresh", + "joinWithClassCode", + "joinWithClassCodeDesc", + "joinWithClassCodeHint", + "unableToFindClass", + "languageLevelPreA1", + "languageLevelA1", + "languageLevelA2", + "languageLevelB1", + "languageLevelB2", + "languageLevelC1", + "languageLevelC2", + "changeTheNameOfTheClass", + "changeTheNameOfTheChat", + "welcomeToYourNewClass", + "welcomeToClass", + "welcomeToPangea18Plus", + "welcomeToPangeaMinor", + "findALanguagePartner", + "setToPublicSettingsTitle", + "setToPublicSettingsDesc", + "accountSettings", + "unableToFindClassCode", + "askPangeaBot", + "sorryNoResults", + "ignoreInThisText", + "helpMeTranslate", + "needsItShortMessage", + "needsIGCShortMessage", + "needsItMessage", + "needsIgcMessage", + "tokenTranslationTitle", + "spanTranslationDesc", + "spanTranslationTitle", + "l1SpanAndGrammarTitle", + "l1SpanAndGrammarDesc", + "otherTitle", + "otherDesc", + "countryInformation", + "myLanguages", + "targetLanguage", + "sourceLanguage", + "languagesISpeak", + "updateLanguage", + "whatLanguageYouWantToLearn", + "whatIsYourBaseLanguage", + "saveChanges", + "publicProfileTitle", + "publicProfileDesc", + "error502504Title", + "error502504Desc", + "error404Title", + "error404Desc", + "errorDisableIT", + "errorDisableIGC", + "errorDisableLanguageAssistance", + "errorDisableITUserDesc", + "errorDisableIGCUserDesc", + "errorDisableLanguageAssistanceUserDesc", + "errorDisableITClassDesc", + "errorDisableIGCClassDesc", + "errorDisableLanguageAssistanceClassDesc", + "itIsDisabled", + "igcIsDisabled", + "goToLearningSettings", + "error405Title", + "error405Desc", + "loginOrSignup", + "iAgreeToThe", + "termsAndConditions", + "andCertifyIAmAtLeast13YearsOfAge", + "findAClass", + "toggleIT", + "toggleIGC", + "toggleToolSettingsDescription", + "connectedToStaging", + "learningSettings", + "classNameRequired", + "sendVoiceNotes", + "sendVoiceNotesDesc", + "chatTopic", + "chatTopicDesc", + "inviteStudentByUserNameDesc", + "classRoster", + "almostPerfect", + "prettyGood", + "letMeThink", + "clickMessageTitle", + "clickMessageBody", + "understandingMessagesTitle", + "addToClass", + "understandingMessagesBody", + "allDone", + "vocab", + "low", + "medium", + "high", + "unknownProficiency", + "changeView", + "clearAll", + "generateVocabulary", + "generatePrompts", + "subscribe", + "getAccess", + "subscriptionDesc", + "subscriptionManagement", + "currentSubscription", + "changeSubscription", + "cancelSubscription", + "selectYourPlan", + "subsciptionPlatformTooltip", + "subscriptionManagementUnavailable", + "paymentMethod", + "paymentHistory", + "emptyChatDownloadWarning", + "appUpdateAvailable", + "update", + "updateDesc", + "maybeLater", + "mainMenu", + "toggleImmersionMode", + "toggleImmersionModeDesc", + "itToggleDescription", + "igcToggleDescription", + "sendOnEnterDescription", + "alreadyInClass", + "pleaseLoginFirst", + "originalMessage", + "sentMessage", + "useType", + "notAvailable", + "taAndGaTooltip", + "definitionsToolName", + "messageTranslationsToolName", + "definitionsToolDescription", + "translationsToolDescrption", + "welcomeBack", + "classExchanges", + "createNewClass", + "newExchange", + "kickAllStudents", + "kickAllStudentsConfirmation", + "inviteAllStudents", + "inviteAllStudentsConfirmation", + "inviteStudentsFromOtherClasses", + "inviteUsersFromPangea", + "allExchanges", + "redeemPromoCode", + "enterPromoCode", + "downloadTxtFile", + "downloadCSVFile", + "promotionalSubscriptionDesc", + "originalSubscriptionPlatform", + "oneWeekTrial", + "creatingSpacePleaseWait", + "downloadXLSXFile", + "abDisplayName", + "aaDisplayName", + "afDisplayName", + "akDisplayName", + "sqDisplayName", + "amDisplayName", + "arDisplayName", + "anDisplayName", + "hyDisplayName", + "asDisplayName", + "avDisplayName", + "aeDisplayName", + "ayDisplayName", + "azDisplayName", + "bmDisplayName", + "baDisplayName", + "euDisplayName", + "beDisplayName", + "bnDisplayName", + "bhDisplayName", + "biDisplayName", + "bsDisplayName", + "brDisplayName", + "bgDisplayName", + "myDisplayName", + "caDisplayName", + "chDisplayName", + "ceDisplayName", + "nyDisplayName", + "zhDisplayName", + "cvDisplayName", + "kwDisplayName", + "coDisplayName", + "crDisplayName", + "hrDisplayName", + "csDisplayName", + "daDisplayName", + "dvDisplayName", + "nlDisplayName", + "enDisplayName", + "eoDisplayName", + "etDisplayName", + "eeDisplayName", + "foDisplayName", + "fjDisplayName", + "fiDisplayName", + "frDisplayName", + "ffDisplayName", + "glDisplayName", + "kaDisplayName", + "deDisplayName", + "elDisplayName", + "gnDisplayName", + "guDisplayName", + "htDisplayName", + "haDisplayName", + "heDisplayName", + "hzDisplayName", + "hiDisplayName", + "hoDisplayName", + "huDisplayName", + "iaDisplayName", + "idDisplayName", + "ieDisplayName", + "gaDisplayName", + "igDisplayName", + "ikDisplayName", + "ioDisplayName", + "isDisplayName", + "itDisplayName", + "iuDisplayName", + "jaDisplayName", + "jvDisplayName", + "klDisplayName", + "knDisplayName", + "krDisplayName", + "ksDisplayName", + "kkDisplayName", + "kmDisplayName", + "kiDisplayName", + "rwDisplayName", + "kyDisplayName", + "kvDisplayName", + "kgDisplayName", + "koDisplayName", + "kuDisplayName", + "kjDisplayName", + "laDisplayName", + "lbDisplayName", + "lgDisplayName", + "liDisplayName", + "lnDisplayName", + "loDisplayName", + "ltDisplayName", + "luDisplayName", + "lvDisplayName", + "gvDisplayName", + "mkDisplayName", + "mgDisplayName", + "msDisplayName", + "mlDisplayName", + "mtDisplayName", + "miDisplayName", + "mrDisplayName", + "mhDisplayName", + "mnDisplayName", + "naDisplayName", + "nvDisplayName", + "nbDisplayName", + "ndDisplayName", + "neDisplayName", + "ngDisplayName", + "nnDisplayName", + "noDisplayName", + "iiDisplayName", + "nrDisplayName", + "ocDisplayName", + "ojDisplayName", + "cuDisplayName", + "omDisplayName", + "orDisplayName", + "osDisplayName", + "paDisplayName", + "piDisplayName", + "faDisplayName", + "plDisplayName", + "psDisplayName", + "ptDisplayName", + "quDisplayName", + "rmDisplayName", + "rnDisplayName", + "roDisplayName", + "ruDisplayName", + "saDisplayName", + "scDisplayName", + "sdDisplayName", + "seDisplayName", + "smDisplayName", + "sgDisplayName", + "srDisplayName", + "gdDisplayName", + "snDisplayName", + "siDisplayName", + "skDisplayName", + "slDisplayName", + "soDisplayName", + "stDisplayName", + "esDisplayName", + "suDisplayName", + "swDisplayName", + "ssDisplayName", + "svDisplayName", + "taDisplayName", + "teDisplayName", + "tgDisplayName", + "thDisplayName", + "tiDisplayName", + "boDisplayName", + "tkDisplayName", + "tlDisplayName", + "tnDisplayName", + "toDisplayName", + "trDisplayName", + "tsDisplayName", + "ttDisplayName", + "twDisplayName", + "tyDisplayName", + "ugDisplayName", + "ukDisplayName", + "urDisplayName", + "uzDisplayName", + "veDisplayName", + "viDisplayName", + "voDisplayName", + "waDisplayName", + "cyDisplayName", + "woDisplayName", + "fyDisplayName", + "xhDisplayName", + "yiDisplayName", + "yoDisplayName", + "zaDisplayName", + "unkDisplayName", + "zuDisplayName", + "hawDisplayName", + "hmnDisplayName", + "multiDisplayName", + "cebDisplayName", + "dzDisplayName", + "iwDisplayName", + "jwDisplayName", + "moDisplayName", + "shDisplayName", + "wwCountryDisplayName", + "afCountryDisplayName", + "axCountryDisplayName", + "alCountryDisplayName", + "dzCountryDisplayName", + "asCountryDisplayName", + "adCountryDisplayName", + "aoCountryDisplayName", + "aiCountryDisplayName", + "agCountryDisplayName", + "arCountryDisplayName", + "amCountryDisplayName", + "awCountryDisplayName", + "acCountryDisplayName", + "auCountryDisplayName", + "atCountryDisplayName", + "azCountryDisplayName", + "bsCountryDisplayName", + "bhCountryDisplayName", + "bdCountryDisplayName", + "bbCountryDisplayName", + "byCountryDisplayName", + "beCountryDisplayName", + "bzCountryDisplayName", + "bjCountryDisplayName", + "bmCountryDisplayName", + "btCountryDisplayName", + "boCountryDisplayName", + "baCountryDisplayName", + "bwCountryDisplayName", + "brCountryDisplayName", + "ioCountryDisplayName", + "vgCountryDisplayName", + "bnCountryDisplayName", + "bgCountryDisplayName", + "bfCountryDisplayName", + "biCountryDisplayName", + "khCountryDisplayName", + "cmCountryDisplayName", + "caCountryDisplayName", + "cvCountryDisplayName", + "bqCountryDisplayName", + "kyCountryDisplayName", + "cfCountryDisplayName", + "tdCountryDisplayName", + "clCountryDisplayName", + "cnCountryDisplayName", + "cxCountryDisplayName", + "ccCountryDisplayName", + "coCountryDisplayName", + "kmCountryDisplayName", + "cdCountryDisplayName", + "cgCountryDisplayName", + "ckCountryDisplayName", + "crCountryDisplayName", + "ciCountryDisplayName", + "hrCountryDisplayName", + "cuCountryDisplayName", + "cwCountryDisplayName", + "cyCountryDisplayName", + "czCountryDisplayName", + "dkCountryDisplayName", + "djCountryDisplayName", + "dmCountryDisplayName", + "doCountryDisplayName", + "tlCountryDisplayName", + "ecCountryDisplayName", + "egCountryDisplayName", + "svCountryDisplayName", + "gqCountryDisplayName", + "erCountryDisplayName", + "eeCountryDisplayName", + "szCountryDisplayName", + "etCountryDisplayName", + "fkCountryDisplayName", + "foCountryDisplayName", + "fjCountryDisplayName", + "fiCountryDisplayName", + "frCountryDisplayName", + "gfCountryDisplayName", + "pfCountryDisplayName", + "gaCountryDisplayName", + "gmCountryDisplayName", + "geCountryDisplayName", + "deCountryDisplayName", + "ghCountryDisplayName", + "giCountryDisplayName", + "grCountryDisplayName", + "glCountryDisplayName", + "gdCountryDisplayName", + "gpCountryDisplayName", + "guCountryDisplayName", + "gtCountryDisplayName", + "ggCountryDisplayName", + "gnCountryDisplayName", + "gwCountryDisplayName", + "gyCountryDisplayName", + "htCountryDisplayName", + "hmCountryDisplayName", + "hnCountryDisplayName", + "hkCountryDisplayName", + "huCountryDisplayName", + "isCountryDisplayName", + "inCountryDisplayName", + "idCountryDisplayName", + "irCountryDisplayName", + "iqCountryDisplayName", + "ieCountryDisplayName", + "imCountryDisplayName", + "ilCountryDisplayName", + "itCountryDisplayName", + "jmCountryDisplayName", + "jpCountryDisplayName", + "jeCountryDisplayName", + "joCountryDisplayName", + "kzCountryDisplayName", + "keCountryDisplayName", + "kiCountryDisplayName", + "xkCountryDisplayName", + "kwCountryDisplayName", + "kgCountryDisplayName", + "laCountryDisplayName", + "lvCountryDisplayName", + "lbCountryDisplayName", + "lsCountryDisplayName", + "lrCountryDisplayName", + "lyCountryDisplayName", + "liCountryDisplayName", + "ltCountryDisplayName", + "luCountryDisplayName", + "moCountryDisplayName", + "mkCountryDisplayName", + "mgCountryDisplayName", + "mwCountryDisplayName", + "myCountryDisplayName", + "mvCountryDisplayName", + "mlCountryDisplayName", + "mtCountryDisplayName", + "mhCountryDisplayName", + "mqCountryDisplayName", + "mrCountryDisplayName", + "muCountryDisplayName", + "ytCountryDisplayName", + "mxCountryDisplayName", + "fmCountryDisplayName", + "mdCountryDisplayName", + "mcCountryDisplayName", + "mnCountryDisplayName", + "meCountryDisplayName", + "msCountryDisplayName", + "maCountryDisplayName", + "mzCountryDisplayName", + "mmCountryDisplayName", + "naCountryDisplayName", + "nrCountryDisplayName", + "npCountryDisplayName", + "nlCountryDisplayName", + "ncCountryDisplayName", + "nzCountryDisplayName", + "niCountryDisplayName", + "neCountryDisplayName", + "ngCountryDisplayName", + "nuCountryDisplayName", + "nfCountryDisplayName", + "kpCountryDisplayName", + "mpCountryDisplayName", + "noCountryDisplayName", + "omCountryDisplayName", + "pkCountryDisplayName", + "pwCountryDisplayName", + "psCountryDisplayName", + "paCountryDisplayName", + "pgCountryDisplayName", + "pyCountryDisplayName", + "peCountryDisplayName", + "phCountryDisplayName", + "plCountryDisplayName", + "ptCountryDisplayName", + "prCountryDisplayName", + "qaCountryDisplayName", + "reCountryDisplayName", + "roCountryDisplayName", + "ruCountryDisplayName", + "rwCountryDisplayName", + "blCountryDisplayName", + "shCountryDisplayName", + "knCountryDisplayName", + "lcCountryDisplayName", + "mfCountryDisplayName", + "pmCountryDisplayName", + "vcCountryDisplayName", + "wsCountryDisplayName", + "smCountryDisplayName", + "stCountryDisplayName", + "saCountryDisplayName", + "snCountryDisplayName", + "rsCountryDisplayName", + "scCountryDisplayName", + "slCountryDisplayName", + "sgCountryDisplayName", + "sxCountryDisplayName", + "skCountryDisplayName", + "siCountryDisplayName", + "sbCountryDisplayName", + "soCountryDisplayName", + "zaCountryDisplayName", + "gsCountryDisplayName", + "krCountryDisplayName", + "ssCountryDisplayName", + "esCountryDisplayName", + "lkCountryDisplayName", + "sdCountryDisplayName", + "srCountryDisplayName", + "sjCountryDisplayName", + "seCountryDisplayName", + "chCountryDisplayName", + "syCountryDisplayName", + "twCountryDisplayName", + "tjCountryDisplayName", + "tzCountryDisplayName", + "thCountryDisplayName", + "tgCountryDisplayName", + "tkCountryDisplayName", + "toCountryDisplayName", + "ttCountryDisplayName", + "tnCountryDisplayName", + "trCountryDisplayName", + "tmCountryDisplayName", + "tcCountryDisplayName", + "tvCountryDisplayName", + "viCountryDisplayName", + "ugCountryDisplayName", + "uaCountryDisplayName", + "aeCountryDisplayName", + "gbCountryDisplayName", + "usCountryDisplayName", + "uyCountryDisplayName", + "uzCountryDisplayName", + "vuCountryDisplayName", + "vaCountryDisplayName", + "veCountryDisplayName", + "vnCountryDisplayName", + "wfCountryDisplayName", + "ehCountryDisplayName", + "yeCountryDisplayName", + "zmCountryDisplayName", + "zwCountryDisplayName", + "pay", + "allPrivateChats", + "unknownPrivateChat", + "copyClassCodeDesc", + "addToClassDesc", + "addToClassOrExchange", + "addToClassOrExchangeDesc", + "invitedToClassOrExchange", + "decline", + "declinedInvitation", + "acceptedInvitation", + "youreInvited", + "studentPermissionsDesc", + "noEligibleSpaces", + "youAddedToSpace", + "youRemovedFromSpace", + "invitedToChat", + "monthlySubscription", + "yearlySubscription", + "defaultSubscription", + "freeTrial", + "grammarAnalytics", + "total", + "noDataFound", + "promoSubscriptionExpirationDesc", + "emptyChatNameWarning", + "emptyClassNameWarning", + "emptyExchangeNameWarning", + "blurMeansTranslateTitle", + "blurMeansTranslateBody", + "someErrorTitle", + "someErrorBody", + "bestCorrectionFeedback", + "distractorFeedback", + "bestAnswerFeedback", + "definitionDefaultPrompt", + "practiceDefaultPrompt", + "correctionDefaultPrompt", + "itStartDefaultPrompt", + "languageLevelWarning", + "lockedChatWarning", + "lockSpace", + "lockChat", + "archiveSpace", + "suggestTo", + "suggestChatDesc", + "suggestExchangeDesc", + "acceptSelection", + "acceptSelectionAnyway", + "makingActivity", + "why", + "definition", + "exampleSentence", + "addToClassTitle", + "reportToTeacher", + "reportMessageTitle", + "reportMessageBody", + "noTeachersFound", + "noAddToSpacePermissions", + "alreadyInSpace", + "yourGlobalUserIdIs", + "noUsersFoundWithQuery", + "searchChatsRooms", + "groupName", + "createGroupAndInviteUsers", + "groupCanBeFoundViaSearch", + "inNoSpaces" + ], + + "ca": [ + "accountInformation", + "addNewFriend", + "alreadyHaveAnAccount", + "classes", + "allCorrect", + "newWayAllGood", + "othersAreBetter", + "holdForInfo", + "greenFeedback", + "yellowFeedback", + "redFeedback", + "customInputFeedbackChoice", + "itInstructionsTitle", + "itInstructionsBody", + "toggleLanguages", + "classWelcomeChat", + "deleteSpace", + "deleteGroup", + "areYouSureDeleteClass", + "areYouSureDeleteGroup", + "cannotBeReversed", + "enterDeletedClassName", + "incorrectClassName", + "oneday", + "oneweek", + "onemonth", + "sixmonth", + "oneyear", + "gaTooltip", + "taTooltip", + "unTooltip", + "interactiveTranslatorSliderHeader", + "interactiveGrammarSliderHeader", + "interactiveTranslatorNotAllowed", + "interactiveTranslatorAllowed", + "interactiveTranslatorRequired", + "interactiveTranslatorNotAllowedDesc", + "interactiveTranslatorAllowedDesc", + "interactiveTranslatorRequiredDesc", + "notYetSet", + "multiLingualClass", + "classAnalytics", + "allClasses", + "myLearning", + "allChatsAndClasses", + "timeOfLastMessage", + "totalMessages", + "waTooltip", + "changeDateRange", + "numberOfStudents", + "classDescription", + "classDescriptionDesc", + "requestToEnroll", + "requestAnExchange", + "findLanguageExchange", + "classAnalyticsDesc", + "addStudents", + "copyClassLink", + "copyClassLinkDesc", + "copyClassCode", + "inviteStudentByUserName", + "classSettings", + "classSettingsDesc", + "selectClassRoomDominantLanguage", + "selectTargetLanguage", + "whatIsYourClassLanguageLevel", + "studentPermissions", + "interactiveTranslator", + "oneToOneChatsWithinClass", + "oneToOneChatsWithinClassDesc", + "createGroupChats", + "createGroupChatsDesc", + "shareVideo", + "shareVideoDesc", + "sharePhotos", + "sharePhotosDesc", + "shareFiles", + "shareFilesDesc", + "shareLocationDesc", + "selectLanguageLevel", + "noIdenticalLanguages", + "iWantALanguagePartnerFrom", + "worldWide", + "noResults", + "searchBy", + "iWantAConversationPartner", + "iWantALanguagePartnerWhoSpeaks", + "iWantALanguagePartnerWhoIsLearning", + "yourBirthdayPlease", + "invalidDob", + "enterYourDob", + "getStarted", + "mustBe13", + "yourBirthdayPleaseShort", + "errorPleaseRefresh", + "joinWithClassCode", + "joinWithClassCodeDesc", + "joinWithClassCodeHint", + "unableToFindClass", + "languageLevelPreA1", + "languageLevelA1", + "languageLevelA2", + "languageLevelB1", + "languageLevelB2", + "languageLevelC1", + "languageLevelC2", + "changeTheNameOfTheClass", + "changeTheNameOfTheChat", + "welcomeToYourNewClass", + "welcomeToClass", + "welcomeToPangea18Plus", + "welcomeToPangeaMinor", + "findALanguagePartner", + "setToPublicSettingsTitle", + "setToPublicSettingsDesc", + "accountSettings", + "unableToFindClassCode", + "askPangeaBot", + "sorryNoResults", + "ignoreInThisText", + "helpMeTranslate", + "needsItShortMessage", + "needsIGCShortMessage", + "needsItMessage", + "needsIgcMessage", + "tokenTranslationTitle", + "spanTranslationDesc", + "spanTranslationTitle", + "l1SpanAndGrammarTitle", + "l1SpanAndGrammarDesc", + "otherTitle", + "otherDesc", + "countryInformation", + "myLanguages", + "targetLanguage", + "sourceLanguage", + "languagesISpeak", + "updateLanguage", + "whatLanguageYouWantToLearn", + "whatIsYourBaseLanguage", + "saveChanges", + "publicProfileTitle", + "publicProfileDesc", + "error502504Title", + "error502504Desc", + "error404Title", + "error404Desc", + "errorDisableIT", + "errorDisableIGC", + "errorDisableLanguageAssistance", + "errorDisableITUserDesc", + "errorDisableIGCUserDesc", + "errorDisableLanguageAssistanceUserDesc", + "errorDisableITClassDesc", + "errorDisableIGCClassDesc", + "errorDisableLanguageAssistanceClassDesc", + "itIsDisabled", + "igcIsDisabled", + "goToLearningSettings", + "error405Title", + "error405Desc", + "loginOrSignup", + "iAgreeToThe", + "termsAndConditions", + "andCertifyIAmAtLeast13YearsOfAge", + "findAClass", + "toggleIT", + "toggleIGC", + "toggleToolSettingsDescription", + "connectedToStaging", + "learningSettings", + "classNameRequired", + "sendVoiceNotes", + "sendVoiceNotesDesc", + "chatTopic", + "chatTopicDesc", + "inviteStudentByUserNameDesc", + "classRoster", + "almostPerfect", + "prettyGood", + "letMeThink", + "clickMessageTitle", + "clickMessageBody", + "understandingMessagesTitle", + "addToClass", + "understandingMessagesBody", + "allDone", + "vocab", + "low", + "medium", + "high", + "unknownProficiency", + "changeView", + "clearAll", + "generateVocabulary", + "generatePrompts", + "subscribe", + "getAccess", + "subscriptionDesc", + "subscriptionManagement", + "currentSubscription", + "changeSubscription", + "cancelSubscription", + "selectYourPlan", + "subsciptionPlatformTooltip", + "subscriptionManagementUnavailable", + "paymentMethod", + "paymentHistory", + "emptyChatDownloadWarning", + "appUpdateAvailable", + "update", + "updateDesc", + "maybeLater", + "mainMenu", + "toggleImmersionMode", + "toggleImmersionModeDesc", + "itToggleDescription", + "igcToggleDescription", + "sendOnEnterDescription", + "alreadyInClass", + "pleaseLoginFirst", + "originalMessage", + "sentMessage", + "useType", + "notAvailable", + "taAndGaTooltip", + "definitionsToolName", + "messageTranslationsToolName", + "definitionsToolDescription", + "translationsToolDescrption", + "welcomeBack", + "classExchanges", + "createNewClass", + "newExchange", + "kickAllStudents", + "kickAllStudentsConfirmation", + "inviteAllStudents", + "inviteAllStudentsConfirmation", + "inviteStudentsFromOtherClasses", + "inviteUsersFromPangea", + "allExchanges", + "redeemPromoCode", + "enterPromoCode", + "downloadTxtFile", + "downloadCSVFile", + "promotionalSubscriptionDesc", + "originalSubscriptionPlatform", + "oneWeekTrial", + "creatingSpacePleaseWait", + "downloadXLSXFile", + "abDisplayName", + "aaDisplayName", + "afDisplayName", + "akDisplayName", + "sqDisplayName", + "amDisplayName", + "arDisplayName", + "anDisplayName", + "hyDisplayName", + "asDisplayName", + "avDisplayName", + "aeDisplayName", + "ayDisplayName", + "azDisplayName", + "bmDisplayName", + "baDisplayName", + "euDisplayName", + "beDisplayName", + "bnDisplayName", + "bhDisplayName", + "biDisplayName", + "bsDisplayName", + "brDisplayName", + "bgDisplayName", + "myDisplayName", + "caDisplayName", + "chDisplayName", + "ceDisplayName", + "nyDisplayName", + "zhDisplayName", + "cvDisplayName", + "kwDisplayName", + "coDisplayName", + "crDisplayName", + "hrDisplayName", + "csDisplayName", + "daDisplayName", + "dvDisplayName", + "nlDisplayName", + "enDisplayName", + "eoDisplayName", + "etDisplayName", + "eeDisplayName", + "foDisplayName", + "fjDisplayName", + "fiDisplayName", + "frDisplayName", + "ffDisplayName", + "glDisplayName", + "kaDisplayName", + "deDisplayName", + "elDisplayName", + "gnDisplayName", + "guDisplayName", + "htDisplayName", + "haDisplayName", + "heDisplayName", + "hzDisplayName", + "hiDisplayName", + "hoDisplayName", + "huDisplayName", + "iaDisplayName", + "idDisplayName", + "ieDisplayName", + "gaDisplayName", + "igDisplayName", + "ikDisplayName", + "ioDisplayName", + "isDisplayName", + "itDisplayName", + "iuDisplayName", + "jaDisplayName", + "jvDisplayName", + "klDisplayName", + "knDisplayName", + "krDisplayName", + "ksDisplayName", + "kkDisplayName", + "kmDisplayName", + "kiDisplayName", + "rwDisplayName", + "kyDisplayName", + "kvDisplayName", + "kgDisplayName", + "koDisplayName", + "kuDisplayName", + "kjDisplayName", + "laDisplayName", + "lbDisplayName", + "lgDisplayName", + "liDisplayName", + "lnDisplayName", + "loDisplayName", + "ltDisplayName", + "luDisplayName", + "lvDisplayName", + "gvDisplayName", + "mkDisplayName", + "mgDisplayName", + "msDisplayName", + "mlDisplayName", + "mtDisplayName", + "miDisplayName", + "mrDisplayName", + "mhDisplayName", + "mnDisplayName", + "naDisplayName", + "nvDisplayName", + "nbDisplayName", + "ndDisplayName", + "neDisplayName", + "ngDisplayName", + "nnDisplayName", + "noDisplayName", + "iiDisplayName", + "nrDisplayName", + "ocDisplayName", + "ojDisplayName", + "cuDisplayName", + "omDisplayName", + "orDisplayName", + "osDisplayName", + "paDisplayName", + "piDisplayName", + "faDisplayName", + "plDisplayName", + "psDisplayName", + "ptDisplayName", + "quDisplayName", + "rmDisplayName", + "rnDisplayName", + "roDisplayName", + "ruDisplayName", + "saDisplayName", + "scDisplayName", + "sdDisplayName", + "seDisplayName", + "smDisplayName", + "sgDisplayName", + "srDisplayName", + "gdDisplayName", + "snDisplayName", + "siDisplayName", + "skDisplayName", + "slDisplayName", + "soDisplayName", + "stDisplayName", + "esDisplayName", + "suDisplayName", + "swDisplayName", + "ssDisplayName", + "svDisplayName", + "taDisplayName", + "teDisplayName", + "tgDisplayName", + "thDisplayName", + "tiDisplayName", + "boDisplayName", + "tkDisplayName", + "tlDisplayName", + "tnDisplayName", + "toDisplayName", + "trDisplayName", + "tsDisplayName", + "ttDisplayName", + "twDisplayName", + "tyDisplayName", + "ugDisplayName", + "ukDisplayName", + "urDisplayName", + "uzDisplayName", + "veDisplayName", + "viDisplayName", + "voDisplayName", + "waDisplayName", + "cyDisplayName", + "woDisplayName", + "fyDisplayName", + "xhDisplayName", + "yiDisplayName", + "yoDisplayName", + "zaDisplayName", + "unkDisplayName", + "zuDisplayName", + "hawDisplayName", + "hmnDisplayName", + "multiDisplayName", + "cebDisplayName", + "dzDisplayName", + "iwDisplayName", + "jwDisplayName", + "moDisplayName", + "shDisplayName", + "wwCountryDisplayName", + "afCountryDisplayName", + "axCountryDisplayName", + "alCountryDisplayName", + "dzCountryDisplayName", + "asCountryDisplayName", + "adCountryDisplayName", + "aoCountryDisplayName", + "aiCountryDisplayName", + "agCountryDisplayName", + "arCountryDisplayName", + "amCountryDisplayName", + "awCountryDisplayName", + "acCountryDisplayName", + "auCountryDisplayName", + "atCountryDisplayName", + "azCountryDisplayName", + "bsCountryDisplayName", + "bhCountryDisplayName", + "bdCountryDisplayName", + "bbCountryDisplayName", + "byCountryDisplayName", + "beCountryDisplayName", + "bzCountryDisplayName", + "bjCountryDisplayName", + "bmCountryDisplayName", + "btCountryDisplayName", + "boCountryDisplayName", + "baCountryDisplayName", + "bwCountryDisplayName", + "brCountryDisplayName", + "ioCountryDisplayName", + "vgCountryDisplayName", + "bnCountryDisplayName", + "bgCountryDisplayName", + "bfCountryDisplayName", + "biCountryDisplayName", + "khCountryDisplayName", + "cmCountryDisplayName", + "caCountryDisplayName", + "cvCountryDisplayName", + "bqCountryDisplayName", + "kyCountryDisplayName", + "cfCountryDisplayName", + "tdCountryDisplayName", + "clCountryDisplayName", + "cnCountryDisplayName", + "cxCountryDisplayName", + "ccCountryDisplayName", + "coCountryDisplayName", + "kmCountryDisplayName", + "cdCountryDisplayName", + "cgCountryDisplayName", + "ckCountryDisplayName", + "crCountryDisplayName", + "ciCountryDisplayName", + "hrCountryDisplayName", + "cuCountryDisplayName", + "cwCountryDisplayName", + "cyCountryDisplayName", + "czCountryDisplayName", + "dkCountryDisplayName", + "djCountryDisplayName", + "dmCountryDisplayName", + "doCountryDisplayName", + "tlCountryDisplayName", + "ecCountryDisplayName", + "egCountryDisplayName", + "svCountryDisplayName", + "gqCountryDisplayName", + "erCountryDisplayName", + "eeCountryDisplayName", + "szCountryDisplayName", + "etCountryDisplayName", + "fkCountryDisplayName", + "foCountryDisplayName", + "fjCountryDisplayName", + "fiCountryDisplayName", + "frCountryDisplayName", + "gfCountryDisplayName", + "pfCountryDisplayName", + "gaCountryDisplayName", + "gmCountryDisplayName", + "geCountryDisplayName", + "deCountryDisplayName", + "ghCountryDisplayName", + "giCountryDisplayName", + "grCountryDisplayName", + "glCountryDisplayName", + "gdCountryDisplayName", + "gpCountryDisplayName", + "guCountryDisplayName", + "gtCountryDisplayName", + "ggCountryDisplayName", + "gnCountryDisplayName", + "gwCountryDisplayName", + "gyCountryDisplayName", + "htCountryDisplayName", + "hmCountryDisplayName", + "hnCountryDisplayName", + "hkCountryDisplayName", + "huCountryDisplayName", + "isCountryDisplayName", + "inCountryDisplayName", + "idCountryDisplayName", + "irCountryDisplayName", + "iqCountryDisplayName", + "ieCountryDisplayName", + "imCountryDisplayName", + "ilCountryDisplayName", + "itCountryDisplayName", + "jmCountryDisplayName", + "jpCountryDisplayName", + "jeCountryDisplayName", + "joCountryDisplayName", + "kzCountryDisplayName", + "keCountryDisplayName", + "kiCountryDisplayName", + "xkCountryDisplayName", + "kwCountryDisplayName", + "kgCountryDisplayName", + "laCountryDisplayName", + "lvCountryDisplayName", + "lbCountryDisplayName", + "lsCountryDisplayName", + "lrCountryDisplayName", + "lyCountryDisplayName", + "liCountryDisplayName", + "ltCountryDisplayName", + "luCountryDisplayName", + "moCountryDisplayName", + "mkCountryDisplayName", + "mgCountryDisplayName", + "mwCountryDisplayName", + "myCountryDisplayName", + "mvCountryDisplayName", + "mlCountryDisplayName", + "mtCountryDisplayName", + "mhCountryDisplayName", + "mqCountryDisplayName", + "mrCountryDisplayName", + "muCountryDisplayName", + "ytCountryDisplayName", + "mxCountryDisplayName", + "fmCountryDisplayName", + "mdCountryDisplayName", + "mcCountryDisplayName", + "mnCountryDisplayName", + "meCountryDisplayName", + "msCountryDisplayName", + "maCountryDisplayName", + "mzCountryDisplayName", + "mmCountryDisplayName", + "naCountryDisplayName", + "nrCountryDisplayName", + "npCountryDisplayName", + "nlCountryDisplayName", + "ncCountryDisplayName", + "nzCountryDisplayName", + "niCountryDisplayName", + "neCountryDisplayName", + "ngCountryDisplayName", + "nuCountryDisplayName", + "nfCountryDisplayName", + "kpCountryDisplayName", + "mpCountryDisplayName", + "noCountryDisplayName", + "omCountryDisplayName", + "pkCountryDisplayName", + "pwCountryDisplayName", + "psCountryDisplayName", + "paCountryDisplayName", + "pgCountryDisplayName", + "pyCountryDisplayName", + "peCountryDisplayName", + "phCountryDisplayName", + "plCountryDisplayName", + "ptCountryDisplayName", + "prCountryDisplayName", + "qaCountryDisplayName", + "reCountryDisplayName", + "roCountryDisplayName", + "ruCountryDisplayName", + "rwCountryDisplayName", + "blCountryDisplayName", + "shCountryDisplayName", + "knCountryDisplayName", + "lcCountryDisplayName", + "mfCountryDisplayName", + "pmCountryDisplayName", + "vcCountryDisplayName", + "wsCountryDisplayName", + "smCountryDisplayName", + "stCountryDisplayName", + "saCountryDisplayName", + "snCountryDisplayName", + "rsCountryDisplayName", + "scCountryDisplayName", + "slCountryDisplayName", + "sgCountryDisplayName", + "sxCountryDisplayName", + "skCountryDisplayName", + "siCountryDisplayName", + "sbCountryDisplayName", + "soCountryDisplayName", + "zaCountryDisplayName", + "gsCountryDisplayName", + "krCountryDisplayName", + "ssCountryDisplayName", + "esCountryDisplayName", + "lkCountryDisplayName", + "sdCountryDisplayName", + "srCountryDisplayName", + "sjCountryDisplayName", + "seCountryDisplayName", + "chCountryDisplayName", + "syCountryDisplayName", + "twCountryDisplayName", + "tjCountryDisplayName", + "tzCountryDisplayName", + "thCountryDisplayName", + "tgCountryDisplayName", + "tkCountryDisplayName", + "toCountryDisplayName", + "ttCountryDisplayName", + "tnCountryDisplayName", + "trCountryDisplayName", + "tmCountryDisplayName", + "tcCountryDisplayName", + "tvCountryDisplayName", + "viCountryDisplayName", + "ugCountryDisplayName", + "uaCountryDisplayName", + "aeCountryDisplayName", + "gbCountryDisplayName", + "usCountryDisplayName", + "uyCountryDisplayName", + "uzCountryDisplayName", + "vuCountryDisplayName", + "vaCountryDisplayName", + "veCountryDisplayName", + "vnCountryDisplayName", + "wfCountryDisplayName", + "ehCountryDisplayName", + "yeCountryDisplayName", + "zmCountryDisplayName", + "zwCountryDisplayName", + "pay", + "allPrivateChats", + "unknownPrivateChat", + "copyClassCodeDesc", + "addToClassDesc", + "addToClassOrExchange", + "addToClassOrExchangeDesc", + "invitedToClassOrExchange", + "decline", + "declinedInvitation", + "acceptedInvitation", + "youreInvited", + "studentPermissionsDesc", + "noEligibleSpaces", + "youAddedToSpace", + "youRemovedFromSpace", + "invitedToChat", + "monthlySubscription", + "yearlySubscription", + "defaultSubscription", + "freeTrial", + "grammarAnalytics", + "total", + "noDataFound", + "promoSubscriptionExpirationDesc", + "emptyChatNameWarning", + "emptyClassNameWarning", + "emptyExchangeNameWarning", + "blurMeansTranslateTitle", + "blurMeansTranslateBody", + "someErrorTitle", + "someErrorBody", + "bestCorrectionFeedback", + "distractorFeedback", + "bestAnswerFeedback", + "definitionDefaultPrompt", + "practiceDefaultPrompt", + "correctionDefaultPrompt", + "itStartDefaultPrompt", + "languageLevelWarning", + "lockedChatWarning", + "lockSpace", + "lockChat", + "archiveSpace", + "suggestTo", + "suggestChatDesc", + "suggestExchangeDesc", + "acceptSelection", + "acceptSelectionAnyway", + "makingActivity", + "why", + "definition", + "exampleSentence", + "addToClassTitle", + "reportToTeacher", + "reportMessageTitle", + "reportMessageBody", + "noTeachersFound", + "noAddToSpacePermissions", + "alreadyInSpace", + "yourGlobalUserIdIs", + "noUsersFoundWithQuery", + "searchChatsRooms", + "groupName", + "createGroupAndInviteUsers", + "groupCanBeFoundViaSearch", + "inNoSpaces" + ], + + "cs": [ + "accountInformation", + "addNewFriend", + "alreadyHaveAnAccount", + "classes", + "allCorrect", + "newWayAllGood", + "othersAreBetter", + "holdForInfo", + "greenFeedback", + "yellowFeedback", + "redFeedback", + "customInputFeedbackChoice", + "itInstructionsTitle", + "itInstructionsBody", + "toggleLanguages", + "classWelcomeChat", + "deleteSpace", + "deleteGroup", + "areYouSureDeleteClass", + "areYouSureDeleteGroup", + "cannotBeReversed", + "enterDeletedClassName", + "incorrectClassName", + "oneday", + "oneweek", + "onemonth", + "sixmonth", + "oneyear", + "gaTooltip", + "taTooltip", + "unTooltip", + "interactiveTranslatorSliderHeader", + "interactiveGrammarSliderHeader", + "interactiveTranslatorNotAllowed", + "interactiveTranslatorAllowed", + "interactiveTranslatorRequired", + "interactiveTranslatorNotAllowedDesc", + "interactiveTranslatorAllowedDesc", + "interactiveTranslatorRequiredDesc", + "notYetSet", + "multiLingualClass", + "classAnalytics", + "allClasses", + "myLearning", + "allChatsAndClasses", + "timeOfLastMessage", + "totalMessages", + "waTooltip", + "changeDateRange", + "numberOfStudents", + "classDescription", + "classDescriptionDesc", + "requestToEnroll", + "requestAnExchange", + "findLanguageExchange", + "classAnalyticsDesc", + "addStudents", + "copyClassLink", + "copyClassLinkDesc", + "copyClassCode", + "inviteStudentByUserName", + "classSettings", + "classSettingsDesc", + "selectClassRoomDominantLanguage", + "selectTargetLanguage", + "whatIsYourClassLanguageLevel", + "studentPermissions", + "interactiveTranslator", + "oneToOneChatsWithinClass", + "oneToOneChatsWithinClassDesc", + "createGroupChats", + "createGroupChatsDesc", + "shareVideo", + "shareVideoDesc", + "sharePhotos", + "sharePhotosDesc", + "shareFiles", + "shareFilesDesc", + "shareLocationDesc", + "selectLanguageLevel", + "noIdenticalLanguages", + "iWantALanguagePartnerFrom", + "worldWide", + "noResults", + "searchBy", + "iWantAConversationPartner", + "iWantALanguagePartnerWhoSpeaks", + "iWantALanguagePartnerWhoIsLearning", + "yourBirthdayPlease", + "invalidDob", + "enterYourDob", + "getStarted", + "mustBe13", + "yourBirthdayPleaseShort", + "errorPleaseRefresh", + "joinWithClassCode", + "joinWithClassCodeDesc", + "joinWithClassCodeHint", + "unableToFindClass", + "languageLevelPreA1", + "languageLevelA1", + "languageLevelA2", + "languageLevelB1", + "languageLevelB2", + "languageLevelC1", + "languageLevelC2", + "changeTheNameOfTheClass", + "changeTheNameOfTheChat", + "welcomeToYourNewClass", + "welcomeToClass", + "welcomeToPangea18Plus", + "welcomeToPangeaMinor", + "findALanguagePartner", + "setToPublicSettingsTitle", + "setToPublicSettingsDesc", + "accountSettings", + "unableToFindClassCode", + "askPangeaBot", + "sorryNoResults", + "ignoreInThisText", + "helpMeTranslate", + "needsItShortMessage", + "needsIGCShortMessage", + "needsItMessage", + "needsIgcMessage", + "tokenTranslationTitle", + "spanTranslationDesc", + "spanTranslationTitle", + "l1SpanAndGrammarTitle", + "l1SpanAndGrammarDesc", + "otherTitle", + "otherDesc", + "countryInformation", + "myLanguages", + "targetLanguage", + "sourceLanguage", + "languagesISpeak", + "updateLanguage", + "whatLanguageYouWantToLearn", + "whatIsYourBaseLanguage", + "saveChanges", + "publicProfileTitle", + "publicProfileDesc", + "error502504Title", + "error502504Desc", + "error404Title", + "error404Desc", + "errorDisableIT", + "errorDisableIGC", + "errorDisableLanguageAssistance", + "errorDisableITUserDesc", + "errorDisableIGCUserDesc", + "errorDisableLanguageAssistanceUserDesc", + "errorDisableITClassDesc", + "errorDisableIGCClassDesc", + "errorDisableLanguageAssistanceClassDesc", + "itIsDisabled", + "igcIsDisabled", + "goToLearningSettings", + "error405Title", + "error405Desc", + "loginOrSignup", + "iAgreeToThe", + "termsAndConditions", + "andCertifyIAmAtLeast13YearsOfAge", + "findAClass", + "toggleIT", + "toggleIGC", + "toggleToolSettingsDescription", + "connectedToStaging", + "learningSettings", + "classNameRequired", + "sendVoiceNotes", + "sendVoiceNotesDesc", + "chatTopic", + "chatTopicDesc", + "inviteStudentByUserNameDesc", + "classRoster", + "almostPerfect", + "prettyGood", + "letMeThink", + "clickMessageTitle", + "clickMessageBody", + "understandingMessagesTitle", + "addToClass", + "understandingMessagesBody", + "allDone", + "vocab", + "low", + "medium", + "high", + "unknownProficiency", + "changeView", + "clearAll", + "generateVocabulary", + "generatePrompts", + "subscribe", + "getAccess", + "subscriptionDesc", + "subscriptionManagement", + "currentSubscription", + "changeSubscription", + "cancelSubscription", + "selectYourPlan", + "subsciptionPlatformTooltip", + "subscriptionManagementUnavailable", + "paymentMethod", + "paymentHistory", + "emptyChatDownloadWarning", + "appUpdateAvailable", + "update", + "updateDesc", + "maybeLater", + "mainMenu", + "toggleImmersionMode", + "toggleImmersionModeDesc", + "itToggleDescription", + "igcToggleDescription", + "sendOnEnterDescription", + "alreadyInClass", + "pleaseLoginFirst", + "originalMessage", + "sentMessage", + "useType", + "notAvailable", + "taAndGaTooltip", + "definitionsToolName", + "messageTranslationsToolName", + "definitionsToolDescription", + "translationsToolDescrption", + "welcomeBack", + "classExchanges", + "createNewClass", + "newExchange", + "kickAllStudents", + "kickAllStudentsConfirmation", + "inviteAllStudents", + "inviteAllStudentsConfirmation", + "inviteStudentsFromOtherClasses", + "inviteUsersFromPangea", + "allExchanges", + "redeemPromoCode", + "enterPromoCode", + "downloadTxtFile", + "downloadCSVFile", + "promotionalSubscriptionDesc", + "originalSubscriptionPlatform", + "oneWeekTrial", + "creatingSpacePleaseWait", + "downloadXLSXFile", + "abDisplayName", + "aaDisplayName", + "afDisplayName", + "akDisplayName", + "sqDisplayName", + "amDisplayName", + "arDisplayName", + "anDisplayName", + "hyDisplayName", + "asDisplayName", + "avDisplayName", + "aeDisplayName", + "ayDisplayName", + "azDisplayName", + "bmDisplayName", + "baDisplayName", + "euDisplayName", + "beDisplayName", + "bnDisplayName", + "bhDisplayName", + "biDisplayName", + "bsDisplayName", + "brDisplayName", + "bgDisplayName", + "myDisplayName", + "caDisplayName", + "chDisplayName", + "ceDisplayName", + "nyDisplayName", + "zhDisplayName", + "cvDisplayName", + "kwDisplayName", + "coDisplayName", + "crDisplayName", + "hrDisplayName", + "csDisplayName", + "daDisplayName", + "dvDisplayName", + "nlDisplayName", + "enDisplayName", + "eoDisplayName", + "etDisplayName", + "eeDisplayName", + "foDisplayName", + "fjDisplayName", + "fiDisplayName", + "frDisplayName", + "ffDisplayName", + "glDisplayName", + "kaDisplayName", + "deDisplayName", + "elDisplayName", + "gnDisplayName", + "guDisplayName", + "htDisplayName", + "haDisplayName", + "heDisplayName", + "hzDisplayName", + "hiDisplayName", + "hoDisplayName", + "huDisplayName", + "iaDisplayName", + "idDisplayName", + "ieDisplayName", + "gaDisplayName", + "igDisplayName", + "ikDisplayName", + "ioDisplayName", + "isDisplayName", + "itDisplayName", + "iuDisplayName", + "jaDisplayName", + "jvDisplayName", + "klDisplayName", + "knDisplayName", + "krDisplayName", + "ksDisplayName", + "kkDisplayName", + "kmDisplayName", + "kiDisplayName", + "rwDisplayName", + "kyDisplayName", + "kvDisplayName", + "kgDisplayName", + "koDisplayName", + "kuDisplayName", + "kjDisplayName", + "laDisplayName", + "lbDisplayName", + "lgDisplayName", + "liDisplayName", + "lnDisplayName", + "loDisplayName", + "ltDisplayName", + "luDisplayName", + "lvDisplayName", + "gvDisplayName", + "mkDisplayName", + "mgDisplayName", + "msDisplayName", + "mlDisplayName", + "mtDisplayName", + "miDisplayName", + "mrDisplayName", + "mhDisplayName", + "mnDisplayName", + "naDisplayName", + "nvDisplayName", + "nbDisplayName", + "ndDisplayName", + "neDisplayName", + "ngDisplayName", + "nnDisplayName", + "noDisplayName", + "iiDisplayName", + "nrDisplayName", + "ocDisplayName", + "ojDisplayName", + "cuDisplayName", + "omDisplayName", + "orDisplayName", + "osDisplayName", + "paDisplayName", + "piDisplayName", + "faDisplayName", + "plDisplayName", + "psDisplayName", + "ptDisplayName", + "quDisplayName", + "rmDisplayName", + "rnDisplayName", + "roDisplayName", + "ruDisplayName", + "saDisplayName", + "scDisplayName", + "sdDisplayName", + "seDisplayName", + "smDisplayName", + "sgDisplayName", + "srDisplayName", + "gdDisplayName", + "snDisplayName", + "siDisplayName", + "skDisplayName", + "slDisplayName", + "soDisplayName", + "stDisplayName", + "esDisplayName", + "suDisplayName", + "swDisplayName", + "ssDisplayName", + "svDisplayName", + "taDisplayName", + "teDisplayName", + "tgDisplayName", + "thDisplayName", + "tiDisplayName", + "boDisplayName", + "tkDisplayName", + "tlDisplayName", + "tnDisplayName", + "toDisplayName", + "trDisplayName", + "tsDisplayName", + "ttDisplayName", + "twDisplayName", + "tyDisplayName", + "ugDisplayName", + "ukDisplayName", + "urDisplayName", + "uzDisplayName", + "veDisplayName", + "viDisplayName", + "voDisplayName", + "waDisplayName", + "cyDisplayName", + "woDisplayName", + "fyDisplayName", + "xhDisplayName", + "yiDisplayName", + "yoDisplayName", + "zaDisplayName", + "unkDisplayName", + "zuDisplayName", + "hawDisplayName", + "hmnDisplayName", + "multiDisplayName", + "cebDisplayName", + "dzDisplayName", + "iwDisplayName", + "jwDisplayName", + "moDisplayName", + "shDisplayName", + "wwCountryDisplayName", + "afCountryDisplayName", + "axCountryDisplayName", + "alCountryDisplayName", + "dzCountryDisplayName", + "asCountryDisplayName", + "adCountryDisplayName", + "aoCountryDisplayName", + "aiCountryDisplayName", + "agCountryDisplayName", + "arCountryDisplayName", + "amCountryDisplayName", + "awCountryDisplayName", + "acCountryDisplayName", + "auCountryDisplayName", + "atCountryDisplayName", + "azCountryDisplayName", + "bsCountryDisplayName", + "bhCountryDisplayName", + "bdCountryDisplayName", + "bbCountryDisplayName", + "byCountryDisplayName", + "beCountryDisplayName", + "bzCountryDisplayName", + "bjCountryDisplayName", + "bmCountryDisplayName", + "btCountryDisplayName", + "boCountryDisplayName", + "baCountryDisplayName", + "bwCountryDisplayName", + "brCountryDisplayName", + "ioCountryDisplayName", + "vgCountryDisplayName", + "bnCountryDisplayName", + "bgCountryDisplayName", + "bfCountryDisplayName", + "biCountryDisplayName", + "khCountryDisplayName", + "cmCountryDisplayName", + "caCountryDisplayName", + "cvCountryDisplayName", + "bqCountryDisplayName", + "kyCountryDisplayName", + "cfCountryDisplayName", + "tdCountryDisplayName", + "clCountryDisplayName", + "cnCountryDisplayName", + "cxCountryDisplayName", + "ccCountryDisplayName", + "coCountryDisplayName", + "kmCountryDisplayName", + "cdCountryDisplayName", + "cgCountryDisplayName", + "ckCountryDisplayName", + "crCountryDisplayName", + "ciCountryDisplayName", + "hrCountryDisplayName", + "cuCountryDisplayName", + "cwCountryDisplayName", + "cyCountryDisplayName", + "czCountryDisplayName", + "dkCountryDisplayName", + "djCountryDisplayName", + "dmCountryDisplayName", + "doCountryDisplayName", + "tlCountryDisplayName", + "ecCountryDisplayName", + "egCountryDisplayName", + "svCountryDisplayName", + "gqCountryDisplayName", + "erCountryDisplayName", + "eeCountryDisplayName", + "szCountryDisplayName", + "etCountryDisplayName", + "fkCountryDisplayName", + "foCountryDisplayName", + "fjCountryDisplayName", + "fiCountryDisplayName", + "frCountryDisplayName", + "gfCountryDisplayName", + "pfCountryDisplayName", + "gaCountryDisplayName", + "gmCountryDisplayName", + "geCountryDisplayName", + "deCountryDisplayName", + "ghCountryDisplayName", + "giCountryDisplayName", + "grCountryDisplayName", + "glCountryDisplayName", + "gdCountryDisplayName", + "gpCountryDisplayName", + "guCountryDisplayName", + "gtCountryDisplayName", + "ggCountryDisplayName", + "gnCountryDisplayName", + "gwCountryDisplayName", + "gyCountryDisplayName", + "htCountryDisplayName", + "hmCountryDisplayName", + "hnCountryDisplayName", + "hkCountryDisplayName", + "huCountryDisplayName", + "isCountryDisplayName", + "inCountryDisplayName", + "idCountryDisplayName", + "irCountryDisplayName", + "iqCountryDisplayName", + "ieCountryDisplayName", + "imCountryDisplayName", + "ilCountryDisplayName", + "itCountryDisplayName", + "jmCountryDisplayName", + "jpCountryDisplayName", + "jeCountryDisplayName", + "joCountryDisplayName", + "kzCountryDisplayName", + "keCountryDisplayName", + "kiCountryDisplayName", + "xkCountryDisplayName", + "kwCountryDisplayName", + "kgCountryDisplayName", + "laCountryDisplayName", + "lvCountryDisplayName", + "lbCountryDisplayName", + "lsCountryDisplayName", + "lrCountryDisplayName", + "lyCountryDisplayName", + "liCountryDisplayName", + "ltCountryDisplayName", + "luCountryDisplayName", + "moCountryDisplayName", + "mkCountryDisplayName", + "mgCountryDisplayName", + "mwCountryDisplayName", + "myCountryDisplayName", + "mvCountryDisplayName", + "mlCountryDisplayName", + "mtCountryDisplayName", + "mhCountryDisplayName", + "mqCountryDisplayName", + "mrCountryDisplayName", + "muCountryDisplayName", + "ytCountryDisplayName", + "mxCountryDisplayName", + "fmCountryDisplayName", + "mdCountryDisplayName", + "mcCountryDisplayName", + "mnCountryDisplayName", + "meCountryDisplayName", + "msCountryDisplayName", + "maCountryDisplayName", + "mzCountryDisplayName", + "mmCountryDisplayName", + "naCountryDisplayName", + "nrCountryDisplayName", + "npCountryDisplayName", + "nlCountryDisplayName", + "ncCountryDisplayName", + "nzCountryDisplayName", + "niCountryDisplayName", + "neCountryDisplayName", + "ngCountryDisplayName", + "nuCountryDisplayName", + "nfCountryDisplayName", + "kpCountryDisplayName", + "mpCountryDisplayName", + "noCountryDisplayName", + "omCountryDisplayName", + "pkCountryDisplayName", + "pwCountryDisplayName", + "psCountryDisplayName", + "paCountryDisplayName", + "pgCountryDisplayName", + "pyCountryDisplayName", + "peCountryDisplayName", + "phCountryDisplayName", + "plCountryDisplayName", + "ptCountryDisplayName", + "prCountryDisplayName", + "qaCountryDisplayName", + "reCountryDisplayName", + "roCountryDisplayName", + "ruCountryDisplayName", + "rwCountryDisplayName", + "blCountryDisplayName", + "shCountryDisplayName", + "knCountryDisplayName", + "lcCountryDisplayName", + "mfCountryDisplayName", + "pmCountryDisplayName", + "vcCountryDisplayName", + "wsCountryDisplayName", + "smCountryDisplayName", + "stCountryDisplayName", + "saCountryDisplayName", + "snCountryDisplayName", + "rsCountryDisplayName", + "scCountryDisplayName", + "slCountryDisplayName", + "sgCountryDisplayName", + "sxCountryDisplayName", + "skCountryDisplayName", + "siCountryDisplayName", + "sbCountryDisplayName", + "soCountryDisplayName", + "zaCountryDisplayName", + "gsCountryDisplayName", + "krCountryDisplayName", + "ssCountryDisplayName", + "esCountryDisplayName", + "lkCountryDisplayName", + "sdCountryDisplayName", + "srCountryDisplayName", + "sjCountryDisplayName", + "seCountryDisplayName", + "chCountryDisplayName", + "syCountryDisplayName", + "twCountryDisplayName", + "tjCountryDisplayName", + "tzCountryDisplayName", + "thCountryDisplayName", + "tgCountryDisplayName", + "tkCountryDisplayName", + "toCountryDisplayName", + "ttCountryDisplayName", + "tnCountryDisplayName", + "trCountryDisplayName", + "tmCountryDisplayName", + "tcCountryDisplayName", + "tvCountryDisplayName", + "viCountryDisplayName", + "ugCountryDisplayName", + "uaCountryDisplayName", + "aeCountryDisplayName", + "gbCountryDisplayName", + "usCountryDisplayName", + "uyCountryDisplayName", + "uzCountryDisplayName", + "vuCountryDisplayName", + "vaCountryDisplayName", + "veCountryDisplayName", + "vnCountryDisplayName", + "wfCountryDisplayName", + "ehCountryDisplayName", + "yeCountryDisplayName", + "zmCountryDisplayName", + "zwCountryDisplayName", + "pay", + "allPrivateChats", + "unknownPrivateChat", + "copyClassCodeDesc", + "addToClassDesc", + "addToClassOrExchange", + "addToClassOrExchangeDesc", + "invitedToClassOrExchange", + "decline", + "declinedInvitation", + "acceptedInvitation", + "youreInvited", + "studentPermissionsDesc", + "noEligibleSpaces", + "youAddedToSpace", + "youRemovedFromSpace", + "invitedToChat", + "monthlySubscription", + "yearlySubscription", + "defaultSubscription", + "freeTrial", + "grammarAnalytics", + "total", + "noDataFound", + "promoSubscriptionExpirationDesc", + "emptyChatNameWarning", + "emptyClassNameWarning", + "emptyExchangeNameWarning", + "blurMeansTranslateTitle", + "blurMeansTranslateBody", + "someErrorTitle", + "someErrorBody", + "bestCorrectionFeedback", + "distractorFeedback", + "bestAnswerFeedback", + "definitionDefaultPrompt", + "practiceDefaultPrompt", + "correctionDefaultPrompt", + "itStartDefaultPrompt", + "languageLevelWarning", + "lockedChatWarning", + "lockSpace", + "lockChat", + "archiveSpace", + "suggestTo", + "suggestChatDesc", + "suggestExchangeDesc", + "acceptSelection", + "acceptSelectionAnyway", + "makingActivity", + "why", + "definition", + "exampleSentence", + "addToClassTitle", + "reportToTeacher", + "reportMessageTitle", + "reportMessageBody", + "noTeachersFound", + "noAddToSpacePermissions", + "alreadyInSpace", + "yourGlobalUserIdIs", + "noUsersFoundWithQuery", + "searchChatsRooms", + "groupName", + "createGroupAndInviteUsers", + "groupCanBeFoundViaSearch", + "inNoSpaces" + ], + + "de": [ + "accountInformation", + "addNewFriend", + "alreadyHaveAnAccount", + "classes", + "allCorrect", + "newWayAllGood", + "othersAreBetter", + "holdForInfo", + "greenFeedback", + "yellowFeedback", + "redFeedback", + "customInputFeedbackChoice", + "itInstructionsTitle", + "itInstructionsBody", + "toggleLanguages", + "classWelcomeChat", + "deleteSpace", + "deleteGroup", + "areYouSureDeleteClass", + "areYouSureDeleteGroup", + "cannotBeReversed", + "enterDeletedClassName", + "incorrectClassName", + "oneday", + "oneweek", + "onemonth", + "sixmonth", + "oneyear", + "gaTooltip", + "taTooltip", + "unTooltip", + "interactiveTranslatorSliderHeader", + "interactiveGrammarSliderHeader", + "interactiveTranslatorNotAllowed", + "interactiveTranslatorAllowed", + "interactiveTranslatorRequired", + "interactiveTranslatorNotAllowedDesc", + "interactiveTranslatorAllowedDesc", + "interactiveTranslatorRequiredDesc", + "notYetSet", + "multiLingualClass", + "classAnalytics", + "allClasses", + "myLearning", + "allChatsAndClasses", + "timeOfLastMessage", + "totalMessages", + "waTooltip", + "changeDateRange", + "numberOfStudents", + "classDescription", + "classDescriptionDesc", + "requestToEnroll", + "requestAnExchange", + "findLanguageExchange", + "classAnalyticsDesc", + "addStudents", + "copyClassLink", + "copyClassLinkDesc", + "copyClassCode", + "inviteStudentByUserName", + "classSettings", + "classSettingsDesc", + "selectClassRoomDominantLanguage", + "selectTargetLanguage", + "whatIsYourClassLanguageLevel", + "studentPermissions", + "interactiveTranslator", + "oneToOneChatsWithinClass", + "oneToOneChatsWithinClassDesc", + "createGroupChats", + "createGroupChatsDesc", + "shareVideo", + "shareVideoDesc", + "sharePhotos", + "sharePhotosDesc", + "shareFiles", + "shareFilesDesc", + "shareLocationDesc", + "selectLanguageLevel", + "noIdenticalLanguages", + "iWantALanguagePartnerFrom", + "worldWide", + "noResults", + "searchBy", + "iWantAConversationPartner", + "iWantALanguagePartnerWhoSpeaks", + "iWantALanguagePartnerWhoIsLearning", + "yourBirthdayPlease", + "invalidDob", + "enterYourDob", + "getStarted", + "mustBe13", + "yourBirthdayPleaseShort", + "errorPleaseRefresh", + "joinWithClassCode", + "joinWithClassCodeDesc", + "joinWithClassCodeHint", + "unableToFindClass", + "languageLevelPreA1", + "languageLevelA1", + "languageLevelA2", + "languageLevelB1", + "languageLevelB2", + "languageLevelC1", + "languageLevelC2", + "changeTheNameOfTheClass", + "changeTheNameOfTheChat", + "welcomeToYourNewClass", + "welcomeToClass", + "welcomeToPangea18Plus", + "welcomeToPangeaMinor", + "findALanguagePartner", + "setToPublicSettingsTitle", + "setToPublicSettingsDesc", + "accountSettings", + "unableToFindClassCode", + "askPangeaBot", + "sorryNoResults", + "ignoreInThisText", + "helpMeTranslate", + "needsItShortMessage", + "needsIGCShortMessage", + "needsItMessage", + "needsIgcMessage", + "tokenTranslationTitle", + "spanTranslationDesc", + "spanTranslationTitle", + "l1SpanAndGrammarTitle", + "l1SpanAndGrammarDesc", + "otherTitle", + "otherDesc", + "countryInformation", + "myLanguages", + "targetLanguage", + "sourceLanguage", + "languagesISpeak", + "updateLanguage", + "whatLanguageYouWantToLearn", + "whatIsYourBaseLanguage", + "saveChanges", + "publicProfileTitle", + "publicProfileDesc", + "error502504Title", + "error502504Desc", + "error404Title", + "error404Desc", + "errorDisableIT", + "errorDisableIGC", + "errorDisableLanguageAssistance", + "errorDisableITUserDesc", + "errorDisableIGCUserDesc", + "errorDisableLanguageAssistanceUserDesc", + "errorDisableITClassDesc", + "errorDisableIGCClassDesc", + "errorDisableLanguageAssistanceClassDesc", + "itIsDisabled", + "igcIsDisabled", + "goToLearningSettings", + "error405Title", + "error405Desc", + "loginOrSignup", + "iAgreeToThe", + "termsAndConditions", + "andCertifyIAmAtLeast13YearsOfAge", + "findAClass", + "toggleIT", + "toggleIGC", + "toggleToolSettingsDescription", + "connectedToStaging", + "learningSettings", + "classNameRequired", + "sendVoiceNotes", + "sendVoiceNotesDesc", + "chatTopic", + "chatTopicDesc", + "inviteStudentByUserNameDesc", + "classRoster", + "almostPerfect", + "prettyGood", + "letMeThink", + "clickMessageTitle", + "clickMessageBody", + "understandingMessagesTitle", + "addToClass", + "understandingMessagesBody", + "allDone", + "vocab", + "low", + "medium", + "high", + "unknownProficiency", + "changeView", + "clearAll", + "generateVocabulary", + "generatePrompts", + "subscribe", + "getAccess", + "subscriptionDesc", + "subscriptionManagement", + "currentSubscription", + "changeSubscription", + "cancelSubscription", + "selectYourPlan", + "subsciptionPlatformTooltip", + "subscriptionManagementUnavailable", + "paymentMethod", + "paymentHistory", + "emptyChatDownloadWarning", + "appUpdateAvailable", + "update", + "updateDesc", + "maybeLater", + "mainMenu", + "toggleImmersionMode", + "toggleImmersionModeDesc", + "itToggleDescription", + "igcToggleDescription", + "sendOnEnterDescription", + "alreadyInClass", + "pleaseLoginFirst", + "originalMessage", + "sentMessage", + "useType", + "notAvailable", + "taAndGaTooltip", + "definitionsToolName", + "messageTranslationsToolName", + "definitionsToolDescription", + "translationsToolDescrption", + "welcomeBack", + "classExchanges", + "createNewClass", + "newExchange", + "kickAllStudents", + "kickAllStudentsConfirmation", + "inviteAllStudents", + "inviteAllStudentsConfirmation", + "inviteStudentsFromOtherClasses", + "inviteUsersFromPangea", + "allExchanges", + "redeemPromoCode", + "enterPromoCode", + "downloadTxtFile", + "downloadCSVFile", + "promotionalSubscriptionDesc", + "originalSubscriptionPlatform", + "oneWeekTrial", + "creatingSpacePleaseWait", + "downloadXLSXFile", + "abDisplayName", + "aaDisplayName", + "afDisplayName", + "akDisplayName", + "sqDisplayName", + "amDisplayName", + "arDisplayName", + "anDisplayName", + "hyDisplayName", + "asDisplayName", + "avDisplayName", + "aeDisplayName", + "ayDisplayName", + "azDisplayName", + "bmDisplayName", + "baDisplayName", + "euDisplayName", + "beDisplayName", + "bnDisplayName", + "bhDisplayName", + "biDisplayName", + "bsDisplayName", + "brDisplayName", + "bgDisplayName", + "myDisplayName", + "caDisplayName", + "chDisplayName", + "ceDisplayName", + "nyDisplayName", + "zhDisplayName", + "cvDisplayName", + "kwDisplayName", + "coDisplayName", + "crDisplayName", + "hrDisplayName", + "csDisplayName", + "daDisplayName", + "dvDisplayName", + "nlDisplayName", + "enDisplayName", + "eoDisplayName", + "etDisplayName", + "eeDisplayName", + "foDisplayName", + "fjDisplayName", + "fiDisplayName", + "frDisplayName", + "ffDisplayName", + "glDisplayName", + "kaDisplayName", + "deDisplayName", + "elDisplayName", + "gnDisplayName", + "guDisplayName", + "htDisplayName", + "haDisplayName", + "heDisplayName", + "hzDisplayName", + "hiDisplayName", + "hoDisplayName", + "huDisplayName", + "iaDisplayName", + "idDisplayName", + "ieDisplayName", + "gaDisplayName", + "igDisplayName", + "ikDisplayName", + "ioDisplayName", + "isDisplayName", + "itDisplayName", + "iuDisplayName", + "jaDisplayName", + "jvDisplayName", + "klDisplayName", + "knDisplayName", + "krDisplayName", + "ksDisplayName", + "kkDisplayName", + "kmDisplayName", + "kiDisplayName", + "rwDisplayName", + "kyDisplayName", + "kvDisplayName", + "kgDisplayName", + "koDisplayName", + "kuDisplayName", + "kjDisplayName", + "laDisplayName", + "lbDisplayName", + "lgDisplayName", + "liDisplayName", + "lnDisplayName", + "loDisplayName", + "ltDisplayName", + "luDisplayName", + "lvDisplayName", + "gvDisplayName", + "mkDisplayName", + "mgDisplayName", + "msDisplayName", + "mlDisplayName", + "mtDisplayName", + "miDisplayName", + "mrDisplayName", + "mhDisplayName", + "mnDisplayName", + "naDisplayName", + "nvDisplayName", + "nbDisplayName", + "ndDisplayName", + "neDisplayName", + "ngDisplayName", + "nnDisplayName", + "noDisplayName", + "iiDisplayName", + "nrDisplayName", + "ocDisplayName", + "ojDisplayName", + "cuDisplayName", + "omDisplayName", + "orDisplayName", + "osDisplayName", + "paDisplayName", + "piDisplayName", + "faDisplayName", + "plDisplayName", + "psDisplayName", + "ptDisplayName", + "quDisplayName", + "rmDisplayName", + "rnDisplayName", + "roDisplayName", + "ruDisplayName", + "saDisplayName", + "scDisplayName", + "sdDisplayName", + "seDisplayName", + "smDisplayName", + "sgDisplayName", + "srDisplayName", + "gdDisplayName", + "snDisplayName", + "siDisplayName", + "skDisplayName", + "slDisplayName", + "soDisplayName", + "stDisplayName", + "esDisplayName", + "suDisplayName", + "swDisplayName", + "ssDisplayName", + "svDisplayName", + "taDisplayName", + "teDisplayName", + "tgDisplayName", + "thDisplayName", + "tiDisplayName", + "boDisplayName", + "tkDisplayName", + "tlDisplayName", + "tnDisplayName", + "toDisplayName", + "trDisplayName", + "tsDisplayName", + "ttDisplayName", + "twDisplayName", + "tyDisplayName", + "ugDisplayName", + "ukDisplayName", + "urDisplayName", + "uzDisplayName", + "veDisplayName", + "viDisplayName", + "voDisplayName", + "waDisplayName", + "cyDisplayName", + "woDisplayName", + "fyDisplayName", + "xhDisplayName", + "yiDisplayName", + "yoDisplayName", + "zaDisplayName", + "unkDisplayName", + "zuDisplayName", + "hawDisplayName", + "hmnDisplayName", + "multiDisplayName", + "cebDisplayName", + "dzDisplayName", + "iwDisplayName", + "jwDisplayName", + "moDisplayName", + "shDisplayName", + "wwCountryDisplayName", + "afCountryDisplayName", + "axCountryDisplayName", + "alCountryDisplayName", + "dzCountryDisplayName", + "asCountryDisplayName", + "adCountryDisplayName", + "aoCountryDisplayName", + "aiCountryDisplayName", + "agCountryDisplayName", + "arCountryDisplayName", + "amCountryDisplayName", + "awCountryDisplayName", + "acCountryDisplayName", + "auCountryDisplayName", + "atCountryDisplayName", + "azCountryDisplayName", + "bsCountryDisplayName", + "bhCountryDisplayName", + "bdCountryDisplayName", + "bbCountryDisplayName", + "byCountryDisplayName", + "beCountryDisplayName", + "bzCountryDisplayName", + "bjCountryDisplayName", + "bmCountryDisplayName", + "btCountryDisplayName", + "boCountryDisplayName", + "baCountryDisplayName", + "bwCountryDisplayName", + "brCountryDisplayName", + "ioCountryDisplayName", + "vgCountryDisplayName", + "bnCountryDisplayName", + "bgCountryDisplayName", + "bfCountryDisplayName", + "biCountryDisplayName", + "khCountryDisplayName", + "cmCountryDisplayName", + "caCountryDisplayName", + "cvCountryDisplayName", + "bqCountryDisplayName", + "kyCountryDisplayName", + "cfCountryDisplayName", + "tdCountryDisplayName", + "clCountryDisplayName", + "cnCountryDisplayName", + "cxCountryDisplayName", + "ccCountryDisplayName", + "coCountryDisplayName", + "kmCountryDisplayName", + "cdCountryDisplayName", + "cgCountryDisplayName", + "ckCountryDisplayName", + "crCountryDisplayName", + "ciCountryDisplayName", + "hrCountryDisplayName", + "cuCountryDisplayName", + "cwCountryDisplayName", + "cyCountryDisplayName", + "czCountryDisplayName", + "dkCountryDisplayName", + "djCountryDisplayName", + "dmCountryDisplayName", + "doCountryDisplayName", + "tlCountryDisplayName", + "ecCountryDisplayName", + "egCountryDisplayName", + "svCountryDisplayName", + "gqCountryDisplayName", + "erCountryDisplayName", + "eeCountryDisplayName", + "szCountryDisplayName", + "etCountryDisplayName", + "fkCountryDisplayName", + "foCountryDisplayName", + "fjCountryDisplayName", + "fiCountryDisplayName", + "frCountryDisplayName", + "gfCountryDisplayName", + "pfCountryDisplayName", + "gaCountryDisplayName", + "gmCountryDisplayName", + "geCountryDisplayName", + "deCountryDisplayName", + "ghCountryDisplayName", + "giCountryDisplayName", + "grCountryDisplayName", + "glCountryDisplayName", + "gdCountryDisplayName", + "gpCountryDisplayName", + "guCountryDisplayName", + "gtCountryDisplayName", + "ggCountryDisplayName", + "gnCountryDisplayName", + "gwCountryDisplayName", + "gyCountryDisplayName", + "htCountryDisplayName", + "hmCountryDisplayName", + "hnCountryDisplayName", + "hkCountryDisplayName", + "huCountryDisplayName", + "isCountryDisplayName", + "inCountryDisplayName", + "idCountryDisplayName", + "irCountryDisplayName", + "iqCountryDisplayName", + "ieCountryDisplayName", + "imCountryDisplayName", + "ilCountryDisplayName", + "itCountryDisplayName", + "jmCountryDisplayName", + "jpCountryDisplayName", + "jeCountryDisplayName", + "joCountryDisplayName", + "kzCountryDisplayName", + "keCountryDisplayName", + "kiCountryDisplayName", + "xkCountryDisplayName", + "kwCountryDisplayName", + "kgCountryDisplayName", + "laCountryDisplayName", + "lvCountryDisplayName", + "lbCountryDisplayName", + "lsCountryDisplayName", + "lrCountryDisplayName", + "lyCountryDisplayName", + "liCountryDisplayName", + "ltCountryDisplayName", + "luCountryDisplayName", + "moCountryDisplayName", + "mkCountryDisplayName", + "mgCountryDisplayName", + "mwCountryDisplayName", + "myCountryDisplayName", + "mvCountryDisplayName", + "mlCountryDisplayName", + "mtCountryDisplayName", + "mhCountryDisplayName", + "mqCountryDisplayName", + "mrCountryDisplayName", + "muCountryDisplayName", + "ytCountryDisplayName", + "mxCountryDisplayName", + "fmCountryDisplayName", + "mdCountryDisplayName", + "mcCountryDisplayName", + "mnCountryDisplayName", + "meCountryDisplayName", + "msCountryDisplayName", + "maCountryDisplayName", + "mzCountryDisplayName", + "mmCountryDisplayName", + "naCountryDisplayName", + "nrCountryDisplayName", + "npCountryDisplayName", + "nlCountryDisplayName", + "ncCountryDisplayName", + "nzCountryDisplayName", + "niCountryDisplayName", + "neCountryDisplayName", + "ngCountryDisplayName", + "nuCountryDisplayName", + "nfCountryDisplayName", + "kpCountryDisplayName", + "mpCountryDisplayName", + "noCountryDisplayName", + "omCountryDisplayName", + "pkCountryDisplayName", + "pwCountryDisplayName", + "psCountryDisplayName", + "paCountryDisplayName", + "pgCountryDisplayName", + "pyCountryDisplayName", + "peCountryDisplayName", + "phCountryDisplayName", + "plCountryDisplayName", + "ptCountryDisplayName", + "prCountryDisplayName", + "qaCountryDisplayName", + "reCountryDisplayName", + "roCountryDisplayName", + "ruCountryDisplayName", + "rwCountryDisplayName", + "blCountryDisplayName", + "shCountryDisplayName", + "knCountryDisplayName", + "lcCountryDisplayName", + "mfCountryDisplayName", + "pmCountryDisplayName", + "vcCountryDisplayName", + "wsCountryDisplayName", + "smCountryDisplayName", + "stCountryDisplayName", + "saCountryDisplayName", + "snCountryDisplayName", + "rsCountryDisplayName", + "scCountryDisplayName", + "slCountryDisplayName", + "sgCountryDisplayName", + "sxCountryDisplayName", + "skCountryDisplayName", + "siCountryDisplayName", + "sbCountryDisplayName", + "soCountryDisplayName", + "zaCountryDisplayName", + "gsCountryDisplayName", + "krCountryDisplayName", + "ssCountryDisplayName", + "esCountryDisplayName", + "lkCountryDisplayName", + "sdCountryDisplayName", + "srCountryDisplayName", + "sjCountryDisplayName", + "seCountryDisplayName", + "chCountryDisplayName", + "syCountryDisplayName", + "twCountryDisplayName", + "tjCountryDisplayName", + "tzCountryDisplayName", + "thCountryDisplayName", + "tgCountryDisplayName", + "tkCountryDisplayName", + "toCountryDisplayName", + "ttCountryDisplayName", + "tnCountryDisplayName", + "trCountryDisplayName", + "tmCountryDisplayName", + "tcCountryDisplayName", + "tvCountryDisplayName", + "viCountryDisplayName", + "ugCountryDisplayName", + "uaCountryDisplayName", + "aeCountryDisplayName", + "gbCountryDisplayName", + "usCountryDisplayName", + "uyCountryDisplayName", + "uzCountryDisplayName", + "vuCountryDisplayName", + "vaCountryDisplayName", + "veCountryDisplayName", + "vnCountryDisplayName", + "wfCountryDisplayName", + "ehCountryDisplayName", + "yeCountryDisplayName", + "zmCountryDisplayName", + "zwCountryDisplayName", + "pay", + "allPrivateChats", + "unknownPrivateChat", + "copyClassCodeDesc", + "addToClassDesc", + "addToClassOrExchange", + "addToClassOrExchangeDesc", + "invitedToClassOrExchange", + "decline", + "declinedInvitation", + "acceptedInvitation", + "youreInvited", + "studentPermissionsDesc", + "noEligibleSpaces", + "youAddedToSpace", + "youRemovedFromSpace", + "invitedToChat", + "monthlySubscription", + "yearlySubscription", + "defaultSubscription", + "freeTrial", + "grammarAnalytics", + "total", + "noDataFound", + "promoSubscriptionExpirationDesc", + "emptyChatNameWarning", + "emptyClassNameWarning", + "emptyExchangeNameWarning", + "blurMeansTranslateTitle", + "blurMeansTranslateBody", + "someErrorTitle", + "someErrorBody", + "bestCorrectionFeedback", + "distractorFeedback", + "bestAnswerFeedback", + "definitionDefaultPrompt", + "practiceDefaultPrompt", + "correctionDefaultPrompt", + "itStartDefaultPrompt", + "languageLevelWarning", + "lockedChatWarning", + "lockSpace", + "lockChat", + "archiveSpace", + "suggestTo", + "suggestChatDesc", + "suggestExchangeDesc", + "acceptSelection", + "acceptSelectionAnyway", + "makingActivity", + "why", + "definition", + "exampleSentence", + "addToClassTitle", + "reportToTeacher", + "reportMessageTitle", + "reportMessageBody", + "noTeachersFound", + "noAddToSpacePermissions", + "alreadyInSpace", + "yourGlobalUserIdIs", + "noUsersFoundWithQuery", + "searchChatsRooms", + "groupName", + "createGroupAndInviteUsers", + "groupCanBeFoundViaSearch", + "inNoSpaces" + ], + + "el": [ + "accountInformation", + "addGroupDescription", + "addNewFriend", + "alreadyHaveAnAccount", + "classes", + "createNewGroup", + "editChatPermissions", + "groupDescription", + "groupDescriptionHasBeenChanged", + "allCorrect", + "newWayAllGood", + "othersAreBetter", + "holdForInfo", + "greenFeedback", + "yellowFeedback", + "redFeedback", + "customInputFeedbackChoice", + "itInstructionsTitle", + "itInstructionsBody", + "toggleLanguages", + "classWelcomeChat", + "deleteSpace", + "deleteGroup", + "areYouSureDeleteClass", + "areYouSureDeleteGroup", + "cannotBeReversed", + "enterDeletedClassName", + "incorrectClassName", + "oneday", + "oneweek", + "onemonth", + "sixmonth", + "oneyear", + "gaTooltip", + "taTooltip", + "unTooltip", + "interactiveTranslatorSliderHeader", + "interactiveGrammarSliderHeader", + "interactiveTranslatorNotAllowed", + "interactiveTranslatorAllowed", + "interactiveTranslatorRequired", + "interactiveTranslatorNotAllowedDesc", + "interactiveTranslatorAllowedDesc", + "interactiveTranslatorRequiredDesc", + "notYetSet", + "multiLingualClass", + "classAnalytics", + "allClasses", + "myLearning", + "allChatsAndClasses", + "timeOfLastMessage", + "totalMessages", + "waTooltip", + "changeDateRange", + "numberOfStudents", + "classDescription", + "classDescriptionDesc", + "requestToEnroll", + "requestAnExchange", + "findLanguageExchange", + "classAnalyticsDesc", + "addStudents", + "copyClassLink", + "copyClassLinkDesc", + "copyClassCode", + "inviteStudentByUserName", + "classSettings", + "classSettingsDesc", + "selectClassRoomDominantLanguage", + "selectTargetLanguage", + "whatIsYourClassLanguageLevel", + "studentPermissions", + "interactiveTranslator", + "oneToOneChatsWithinClass", + "oneToOneChatsWithinClassDesc", + "createGroupChats", + "createGroupChatsDesc", + "shareVideo", + "shareVideoDesc", + "sharePhotos", + "sharePhotosDesc", + "shareFiles", + "shareFilesDesc", + "shareLocationDesc", + "selectLanguageLevel", + "noIdenticalLanguages", + "iWantALanguagePartnerFrom", + "worldWide", + "noResults", + "searchBy", + "iWantAConversationPartner", + "iWantALanguagePartnerWhoSpeaks", + "iWantALanguagePartnerWhoIsLearning", + "yourBirthdayPlease", + "invalidDob", + "enterYourDob", + "getStarted", + "mustBe13", + "yourBirthdayPleaseShort", + "errorPleaseRefresh", + "joinWithClassCode", + "joinWithClassCodeDesc", + "joinWithClassCodeHint", + "unableToFindClass", + "languageLevelPreA1", + "languageLevelA1", + "languageLevelA2", + "languageLevelB1", + "languageLevelB2", + "languageLevelC1", + "languageLevelC2", + "changeTheNameOfTheClass", + "changeTheNameOfTheChat", + "welcomeToYourNewClass", + "welcomeToClass", + "welcomeToPangea18Plus", + "welcomeToPangeaMinor", + "findALanguagePartner", + "setToPublicSettingsTitle", + "setToPublicSettingsDesc", + "accountSettings", + "unableToFindClassCode", + "askPangeaBot", + "sorryNoResults", + "ignoreInThisText", + "helpMeTranslate", + "needsItShortMessage", + "needsIGCShortMessage", + "needsItMessage", + "needsIgcMessage", + "tokenTranslationTitle", + "spanTranslationDesc", + "spanTranslationTitle", + "l1SpanAndGrammarTitle", + "l1SpanAndGrammarDesc", + "otherTitle", + "otherDesc", + "countryInformation", + "myLanguages", + "targetLanguage", + "sourceLanguage", + "languagesISpeak", + "updateLanguage", + "whatLanguageYouWantToLearn", + "whatIsYourBaseLanguage", + "saveChanges", + "publicProfileTitle", + "publicProfileDesc", + "error502504Title", + "error502504Desc", + "error404Title", + "error404Desc", + "errorDisableIT", + "errorDisableIGC", + "errorDisableLanguageAssistance", + "errorDisableITUserDesc", + "errorDisableIGCUserDesc", + "errorDisableLanguageAssistanceUserDesc", + "errorDisableITClassDesc", + "errorDisableIGCClassDesc", + "errorDisableLanguageAssistanceClassDesc", + "itIsDisabled", + "igcIsDisabled", + "goToLearningSettings", + "error405Title", + "error405Desc", + "loginOrSignup", + "iAgreeToThe", + "termsAndConditions", + "andCertifyIAmAtLeast13YearsOfAge", + "findAClass", + "toggleIT", + "toggleIGC", + "toggleToolSettingsDescription", + "connectedToStaging", + "learningSettings", + "classNameRequired", + "sendVoiceNotes", + "sendVoiceNotesDesc", + "chatTopic", + "chatTopicDesc", + "inviteStudentByUserNameDesc", + "classRoster", + "almostPerfect", + "prettyGood", + "letMeThink", + "clickMessageTitle", + "clickMessageBody", + "understandingMessagesTitle", + "addToClass", + "understandingMessagesBody", + "allDone", + "vocab", + "low", + "medium", + "high", + "unknownProficiency", + "changeView", + "clearAll", + "generateVocabulary", + "generatePrompts", + "subscribe", + "getAccess", + "subscriptionDesc", + "subscriptionManagement", + "currentSubscription", + "changeSubscription", + "cancelSubscription", + "selectYourPlan", + "subsciptionPlatformTooltip", + "subscriptionManagementUnavailable", + "paymentMethod", + "paymentHistory", + "emptyChatDownloadWarning", + "appUpdateAvailable", + "update", + "updateDesc", + "maybeLater", + "mainMenu", + "toggleImmersionMode", + "toggleImmersionModeDesc", + "itToggleDescription", + "igcToggleDescription", + "sendOnEnterDescription", + "alreadyInClass", + "pleaseLoginFirst", + "originalMessage", + "sentMessage", + "useType", + "notAvailable", + "taAndGaTooltip", + "definitionsToolName", + "messageTranslationsToolName", + "definitionsToolDescription", + "translationsToolDescrption", + "welcomeBack", + "classExchanges", + "createNewClass", + "newExchange", + "kickAllStudents", + "kickAllStudentsConfirmation", + "inviteAllStudents", + "inviteAllStudentsConfirmation", + "inviteStudentsFromOtherClasses", + "inviteUsersFromPangea", + "allExchanges", + "redeemPromoCode", + "enterPromoCode", + "downloadTxtFile", + "downloadCSVFile", + "promotionalSubscriptionDesc", + "originalSubscriptionPlatform", + "oneWeekTrial", + "creatingSpacePleaseWait", + "downloadXLSXFile", + "abDisplayName", + "aaDisplayName", + "afDisplayName", + "akDisplayName", + "sqDisplayName", + "amDisplayName", + "arDisplayName", + "anDisplayName", + "hyDisplayName", + "asDisplayName", + "avDisplayName", + "aeDisplayName", + "ayDisplayName", + "azDisplayName", + "bmDisplayName", + "baDisplayName", + "euDisplayName", + "beDisplayName", + "bnDisplayName", + "bhDisplayName", + "biDisplayName", + "bsDisplayName", + "brDisplayName", + "bgDisplayName", + "myDisplayName", + "caDisplayName", + "chDisplayName", + "ceDisplayName", + "nyDisplayName", + "zhDisplayName", + "cvDisplayName", + "kwDisplayName", + "coDisplayName", + "crDisplayName", + "hrDisplayName", + "csDisplayName", + "daDisplayName", + "dvDisplayName", + "nlDisplayName", + "enDisplayName", + "eoDisplayName", + "etDisplayName", + "eeDisplayName", + "foDisplayName", + "fjDisplayName", + "fiDisplayName", + "frDisplayName", + "ffDisplayName", + "glDisplayName", + "kaDisplayName", + "deDisplayName", + "elDisplayName", + "gnDisplayName", + "guDisplayName", + "htDisplayName", + "haDisplayName", + "heDisplayName", + "hzDisplayName", + "hiDisplayName", + "hoDisplayName", + "huDisplayName", + "iaDisplayName", + "idDisplayName", + "ieDisplayName", + "gaDisplayName", + "igDisplayName", + "ikDisplayName", + "ioDisplayName", + "isDisplayName", + "itDisplayName", + "iuDisplayName", + "jaDisplayName", + "jvDisplayName", + "klDisplayName", + "knDisplayName", + "krDisplayName", + "ksDisplayName", + "kkDisplayName", + "kmDisplayName", + "kiDisplayName", + "rwDisplayName", + "kyDisplayName", + "kvDisplayName", + "kgDisplayName", + "koDisplayName", + "kuDisplayName", + "kjDisplayName", + "laDisplayName", + "lbDisplayName", + "lgDisplayName", + "liDisplayName", + "lnDisplayName", + "loDisplayName", + "ltDisplayName", + "luDisplayName", + "lvDisplayName", + "gvDisplayName", + "mkDisplayName", + "mgDisplayName", + "msDisplayName", + "mlDisplayName", + "mtDisplayName", + "miDisplayName", + "mrDisplayName", + "mhDisplayName", + "mnDisplayName", + "naDisplayName", + "nvDisplayName", + "nbDisplayName", + "ndDisplayName", + "neDisplayName", + "ngDisplayName", + "nnDisplayName", + "noDisplayName", + "iiDisplayName", + "nrDisplayName", + "ocDisplayName", + "ojDisplayName", + "cuDisplayName", + "omDisplayName", + "orDisplayName", + "osDisplayName", + "paDisplayName", + "piDisplayName", + "faDisplayName", + "plDisplayName", + "psDisplayName", + "ptDisplayName", + "quDisplayName", + "rmDisplayName", + "rnDisplayName", + "roDisplayName", + "ruDisplayName", + "saDisplayName", + "scDisplayName", + "sdDisplayName", + "seDisplayName", + "smDisplayName", + "sgDisplayName", + "srDisplayName", + "gdDisplayName", + "snDisplayName", + "siDisplayName", + "skDisplayName", + "slDisplayName", + "soDisplayName", + "stDisplayName", + "esDisplayName", + "suDisplayName", + "swDisplayName", + "ssDisplayName", + "svDisplayName", + "taDisplayName", + "teDisplayName", + "tgDisplayName", + "thDisplayName", + "tiDisplayName", + "boDisplayName", + "tkDisplayName", + "tlDisplayName", + "tnDisplayName", + "toDisplayName", + "trDisplayName", + "tsDisplayName", + "ttDisplayName", + "twDisplayName", + "tyDisplayName", + "ugDisplayName", + "ukDisplayName", + "urDisplayName", + "uzDisplayName", + "veDisplayName", + "viDisplayName", + "voDisplayName", + "waDisplayName", + "cyDisplayName", + "woDisplayName", + "fyDisplayName", + "xhDisplayName", + "yiDisplayName", + "yoDisplayName", + "zaDisplayName", + "unkDisplayName", + "zuDisplayName", + "hawDisplayName", + "hmnDisplayName", + "multiDisplayName", + "cebDisplayName", + "dzDisplayName", + "iwDisplayName", + "jwDisplayName", + "moDisplayName", + "shDisplayName", + "wwCountryDisplayName", + "afCountryDisplayName", + "axCountryDisplayName", + "alCountryDisplayName", + "dzCountryDisplayName", + "asCountryDisplayName", + "adCountryDisplayName", + "aoCountryDisplayName", + "aiCountryDisplayName", + "agCountryDisplayName", + "arCountryDisplayName", + "amCountryDisplayName", + "awCountryDisplayName", + "acCountryDisplayName", + "auCountryDisplayName", + "atCountryDisplayName", + "azCountryDisplayName", + "bsCountryDisplayName", + "bhCountryDisplayName", + "bdCountryDisplayName", + "bbCountryDisplayName", + "byCountryDisplayName", + "beCountryDisplayName", + "bzCountryDisplayName", + "bjCountryDisplayName", + "bmCountryDisplayName", + "btCountryDisplayName", + "boCountryDisplayName", + "baCountryDisplayName", + "bwCountryDisplayName", + "brCountryDisplayName", + "ioCountryDisplayName", + "vgCountryDisplayName", + "bnCountryDisplayName", + "bgCountryDisplayName", + "bfCountryDisplayName", + "biCountryDisplayName", + "khCountryDisplayName", + "cmCountryDisplayName", + "caCountryDisplayName", + "cvCountryDisplayName", + "bqCountryDisplayName", + "kyCountryDisplayName", + "cfCountryDisplayName", + "tdCountryDisplayName", + "clCountryDisplayName", + "cnCountryDisplayName", + "cxCountryDisplayName", + "ccCountryDisplayName", + "coCountryDisplayName", + "kmCountryDisplayName", + "cdCountryDisplayName", + "cgCountryDisplayName", + "ckCountryDisplayName", + "crCountryDisplayName", + "ciCountryDisplayName", + "hrCountryDisplayName", + "cuCountryDisplayName", + "cwCountryDisplayName", + "cyCountryDisplayName", + "czCountryDisplayName", + "dkCountryDisplayName", + "djCountryDisplayName", + "dmCountryDisplayName", + "doCountryDisplayName", + "tlCountryDisplayName", + "ecCountryDisplayName", + "egCountryDisplayName", + "svCountryDisplayName", + "gqCountryDisplayName", + "erCountryDisplayName", + "eeCountryDisplayName", + "szCountryDisplayName", + "etCountryDisplayName", + "fkCountryDisplayName", + "foCountryDisplayName", + "fjCountryDisplayName", + "fiCountryDisplayName", + "frCountryDisplayName", + "gfCountryDisplayName", + "pfCountryDisplayName", + "gaCountryDisplayName", + "gmCountryDisplayName", + "geCountryDisplayName", + "deCountryDisplayName", + "ghCountryDisplayName", + "giCountryDisplayName", + "grCountryDisplayName", + "glCountryDisplayName", + "gdCountryDisplayName", + "gpCountryDisplayName", + "guCountryDisplayName", + "gtCountryDisplayName", + "ggCountryDisplayName", + "gnCountryDisplayName", + "gwCountryDisplayName", + "gyCountryDisplayName", + "htCountryDisplayName", + "hmCountryDisplayName", + "hnCountryDisplayName", + "hkCountryDisplayName", + "huCountryDisplayName", + "isCountryDisplayName", + "inCountryDisplayName", + "idCountryDisplayName", + "irCountryDisplayName", + "iqCountryDisplayName", + "ieCountryDisplayName", + "imCountryDisplayName", + "ilCountryDisplayName", + "itCountryDisplayName", + "jmCountryDisplayName", + "jpCountryDisplayName", + "jeCountryDisplayName", + "joCountryDisplayName", + "kzCountryDisplayName", + "keCountryDisplayName", + "kiCountryDisplayName", + "xkCountryDisplayName", + "kwCountryDisplayName", + "kgCountryDisplayName", + "laCountryDisplayName", + "lvCountryDisplayName", + "lbCountryDisplayName", + "lsCountryDisplayName", + "lrCountryDisplayName", + "lyCountryDisplayName", + "liCountryDisplayName", + "ltCountryDisplayName", + "luCountryDisplayName", + "moCountryDisplayName", + "mkCountryDisplayName", + "mgCountryDisplayName", + "mwCountryDisplayName", + "myCountryDisplayName", + "mvCountryDisplayName", + "mlCountryDisplayName", + "mtCountryDisplayName", + "mhCountryDisplayName", + "mqCountryDisplayName", + "mrCountryDisplayName", + "muCountryDisplayName", + "ytCountryDisplayName", + "mxCountryDisplayName", + "fmCountryDisplayName", + "mdCountryDisplayName", + "mcCountryDisplayName", + "mnCountryDisplayName", + "meCountryDisplayName", + "msCountryDisplayName", + "maCountryDisplayName", + "mzCountryDisplayName", + "mmCountryDisplayName", + "naCountryDisplayName", + "nrCountryDisplayName", + "npCountryDisplayName", + "nlCountryDisplayName", + "ncCountryDisplayName", + "nzCountryDisplayName", + "niCountryDisplayName", + "neCountryDisplayName", + "ngCountryDisplayName", + "nuCountryDisplayName", + "nfCountryDisplayName", + "kpCountryDisplayName", + "mpCountryDisplayName", + "noCountryDisplayName", + "omCountryDisplayName", + "pkCountryDisplayName", + "pwCountryDisplayName", + "psCountryDisplayName", + "paCountryDisplayName", + "pgCountryDisplayName", + "pyCountryDisplayName", + "peCountryDisplayName", + "phCountryDisplayName", + "plCountryDisplayName", + "ptCountryDisplayName", + "prCountryDisplayName", + "qaCountryDisplayName", + "reCountryDisplayName", + "roCountryDisplayName", + "ruCountryDisplayName", + "rwCountryDisplayName", + "blCountryDisplayName", + "shCountryDisplayName", + "knCountryDisplayName", + "lcCountryDisplayName", + "mfCountryDisplayName", + "pmCountryDisplayName", + "vcCountryDisplayName", + "wsCountryDisplayName", + "smCountryDisplayName", + "stCountryDisplayName", + "saCountryDisplayName", + "snCountryDisplayName", + "rsCountryDisplayName", + "scCountryDisplayName", + "slCountryDisplayName", + "sgCountryDisplayName", + "sxCountryDisplayName", + "skCountryDisplayName", + "siCountryDisplayName", + "sbCountryDisplayName", + "soCountryDisplayName", + "zaCountryDisplayName", + "gsCountryDisplayName", + "krCountryDisplayName", + "ssCountryDisplayName", + "esCountryDisplayName", + "lkCountryDisplayName", + "sdCountryDisplayName", + "srCountryDisplayName", + "sjCountryDisplayName", + "seCountryDisplayName", + "chCountryDisplayName", + "syCountryDisplayName", + "twCountryDisplayName", + "tjCountryDisplayName", + "tzCountryDisplayName", + "thCountryDisplayName", + "tgCountryDisplayName", + "tkCountryDisplayName", + "toCountryDisplayName", + "ttCountryDisplayName", + "tnCountryDisplayName", + "trCountryDisplayName", + "tmCountryDisplayName", + "tcCountryDisplayName", + "tvCountryDisplayName", + "viCountryDisplayName", + "ugCountryDisplayName", + "uaCountryDisplayName", + "aeCountryDisplayName", + "gbCountryDisplayName", + "usCountryDisplayName", + "uyCountryDisplayName", + "uzCountryDisplayName", + "vuCountryDisplayName", + "vaCountryDisplayName", + "veCountryDisplayName", + "vnCountryDisplayName", + "wfCountryDisplayName", + "ehCountryDisplayName", + "yeCountryDisplayName", + "zmCountryDisplayName", + "zwCountryDisplayName", + "pay", + "allPrivateChats", + "unknownPrivateChat", + "copyClassCodeDesc", + "addToClassDesc", + "addToClassOrExchange", + "addToClassOrExchangeDesc", + "invitedToClassOrExchange", + "decline", + "declinedInvitation", + "acceptedInvitation", + "youreInvited", + "studentPermissionsDesc", + "noEligibleSpaces", + "youAddedToSpace", + "youRemovedFromSpace", + "invitedToChat", + "monthlySubscription", + "yearlySubscription", + "defaultSubscription", + "freeTrial", + "grammarAnalytics", + "total", + "noDataFound", + "promoSubscriptionExpirationDesc", + "emptyChatNameWarning", + "emptyClassNameWarning", + "emptyExchangeNameWarning", + "blurMeansTranslateTitle", + "blurMeansTranslateBody", + "someErrorTitle", + "someErrorBody", + "bestCorrectionFeedback", + "distractorFeedback", + "bestAnswerFeedback", + "definitionDefaultPrompt", + "practiceDefaultPrompt", + "correctionDefaultPrompt", + "itStartDefaultPrompt", + "languageLevelWarning", + "lockedChatWarning", + "lockSpace", + "lockChat", + "archiveSpace", + "suggestTo", + "suggestChatDesc", + "suggestExchangeDesc", + "acceptSelection", + "acceptSelectionAnyway", + "makingActivity", + "why", + "definition", + "exampleSentence", + "addToClassTitle", + "reportToTeacher", + "reportMessageTitle", + "reportMessageBody", + "noTeachersFound", + "noAddToSpacePermissions", + "alreadyInSpace", + "yourGlobalUserIdIs", + "noUsersFoundWithQuery", + "searchChatsRooms", + "groupName", + "createGroupAndInviteUsers", + "groupCanBeFoundViaSearch", + "inNoSpaces" + ], + + "eo": [ + "accountInformation", + "addNewFriend", + "alreadyHaveAnAccount", + "classes", + "allCorrect", + "newWayAllGood", + "othersAreBetter", + "holdForInfo", + "greenFeedback", + "yellowFeedback", + "redFeedback", + "customInputFeedbackChoice", + "itInstructionsTitle", + "itInstructionsBody", + "toggleLanguages", + "classWelcomeChat", + "deleteSpace", + "deleteGroup", + "areYouSureDeleteClass", + "areYouSureDeleteGroup", + "cannotBeReversed", + "enterDeletedClassName", + "incorrectClassName", + "oneday", + "oneweek", + "onemonth", + "sixmonth", + "oneyear", + "gaTooltip", + "taTooltip", + "unTooltip", + "interactiveTranslatorSliderHeader", + "interactiveGrammarSliderHeader", + "interactiveTranslatorNotAllowed", + "interactiveTranslatorAllowed", + "interactiveTranslatorRequired", + "interactiveTranslatorNotAllowedDesc", + "interactiveTranslatorAllowedDesc", + "interactiveTranslatorRequiredDesc", + "notYetSet", + "multiLingualClass", + "classAnalytics", + "allClasses", + "myLearning", + "allChatsAndClasses", + "timeOfLastMessage", + "totalMessages", + "waTooltip", + "changeDateRange", + "numberOfStudents", + "classDescription", + "classDescriptionDesc", + "requestToEnroll", + "requestAnExchange", + "findLanguageExchange", + "classAnalyticsDesc", + "addStudents", + "copyClassLink", + "copyClassLinkDesc", + "copyClassCode", + "inviteStudentByUserName", + "classSettings", + "classSettingsDesc", + "selectClassRoomDominantLanguage", + "selectTargetLanguage", + "whatIsYourClassLanguageLevel", + "studentPermissions", + "interactiveTranslator", + "oneToOneChatsWithinClass", + "oneToOneChatsWithinClassDesc", + "createGroupChats", + "createGroupChatsDesc", + "shareVideo", + "shareVideoDesc", + "sharePhotos", + "sharePhotosDesc", + "shareFiles", + "shareFilesDesc", + "shareLocationDesc", + "selectLanguageLevel", + "noIdenticalLanguages", + "iWantALanguagePartnerFrom", + "worldWide", + "noResults", + "searchBy", + "iWantAConversationPartner", + "iWantALanguagePartnerWhoSpeaks", + "iWantALanguagePartnerWhoIsLearning", + "yourBirthdayPlease", + "invalidDob", + "enterYourDob", + "getStarted", + "mustBe13", + "yourBirthdayPleaseShort", + "errorPleaseRefresh", + "joinWithClassCode", + "joinWithClassCodeDesc", + "joinWithClassCodeHint", + "unableToFindClass", + "languageLevelPreA1", + "languageLevelA1", + "languageLevelA2", + "languageLevelB1", + "languageLevelB2", + "languageLevelC1", + "languageLevelC2", + "changeTheNameOfTheClass", + "changeTheNameOfTheChat", + "welcomeToYourNewClass", + "welcomeToClass", + "welcomeToPangea18Plus", + "welcomeToPangeaMinor", + "findALanguagePartner", + "setToPublicSettingsTitle", + "setToPublicSettingsDesc", + "accountSettings", + "unableToFindClassCode", + "askPangeaBot", + "sorryNoResults", + "ignoreInThisText", + "helpMeTranslate", + "needsItShortMessage", + "needsIGCShortMessage", + "needsItMessage", + "needsIgcMessage", + "tokenTranslationTitle", + "spanTranslationDesc", + "spanTranslationTitle", + "l1SpanAndGrammarTitle", + "l1SpanAndGrammarDesc", + "otherTitle", + "otherDesc", + "countryInformation", + "myLanguages", + "targetLanguage", + "sourceLanguage", + "languagesISpeak", + "updateLanguage", + "whatLanguageYouWantToLearn", + "whatIsYourBaseLanguage", + "saveChanges", + "publicProfileTitle", + "publicProfileDesc", + "error502504Title", + "error502504Desc", + "error404Title", + "error404Desc", + "errorDisableIT", + "errorDisableIGC", + "errorDisableLanguageAssistance", + "errorDisableITUserDesc", + "errorDisableIGCUserDesc", + "errorDisableLanguageAssistanceUserDesc", + "errorDisableITClassDesc", + "errorDisableIGCClassDesc", + "errorDisableLanguageAssistanceClassDesc", + "itIsDisabled", + "igcIsDisabled", + "goToLearningSettings", + "error405Title", + "error405Desc", + "loginOrSignup", + "iAgreeToThe", + "termsAndConditions", + "andCertifyIAmAtLeast13YearsOfAge", + "findAClass", + "toggleIT", + "toggleIGC", + "toggleToolSettingsDescription", + "connectedToStaging", + "learningSettings", + "classNameRequired", + "sendVoiceNotes", + "sendVoiceNotesDesc", + "chatTopic", + "chatTopicDesc", + "inviteStudentByUserNameDesc", + "classRoster", + "almostPerfect", + "prettyGood", + "letMeThink", + "clickMessageTitle", + "clickMessageBody", + "understandingMessagesTitle", + "addToClass", + "understandingMessagesBody", + "allDone", + "vocab", + "low", + "medium", + "high", + "unknownProficiency", + "changeView", + "clearAll", + "generateVocabulary", + "generatePrompts", + "subscribe", + "getAccess", + "subscriptionDesc", + "subscriptionManagement", + "currentSubscription", + "changeSubscription", + "cancelSubscription", + "selectYourPlan", + "subsciptionPlatformTooltip", + "subscriptionManagementUnavailable", + "paymentMethod", + "paymentHistory", + "emptyChatDownloadWarning", + "appUpdateAvailable", + "update", + "updateDesc", + "maybeLater", + "mainMenu", + "toggleImmersionMode", + "toggleImmersionModeDesc", + "itToggleDescription", + "igcToggleDescription", + "sendOnEnterDescription", + "alreadyInClass", + "pleaseLoginFirst", + "originalMessage", + "sentMessage", + "useType", + "notAvailable", + "taAndGaTooltip", + "definitionsToolName", + "messageTranslationsToolName", + "definitionsToolDescription", + "translationsToolDescrption", + "welcomeBack", + "classExchanges", + "createNewClass", + "newExchange", + "kickAllStudents", + "kickAllStudentsConfirmation", + "inviteAllStudents", + "inviteAllStudentsConfirmation", + "inviteStudentsFromOtherClasses", + "inviteUsersFromPangea", + "allExchanges", + "redeemPromoCode", + "enterPromoCode", + "downloadTxtFile", + "downloadCSVFile", + "promotionalSubscriptionDesc", + "originalSubscriptionPlatform", + "oneWeekTrial", + "creatingSpacePleaseWait", + "downloadXLSXFile", + "abDisplayName", + "aaDisplayName", + "afDisplayName", + "akDisplayName", + "sqDisplayName", + "amDisplayName", + "arDisplayName", + "anDisplayName", + "hyDisplayName", + "asDisplayName", + "avDisplayName", + "aeDisplayName", + "ayDisplayName", + "azDisplayName", + "bmDisplayName", + "baDisplayName", + "euDisplayName", + "beDisplayName", + "bnDisplayName", + "bhDisplayName", + "biDisplayName", + "bsDisplayName", + "brDisplayName", + "bgDisplayName", + "myDisplayName", + "caDisplayName", + "chDisplayName", + "ceDisplayName", + "nyDisplayName", + "zhDisplayName", + "cvDisplayName", + "kwDisplayName", + "coDisplayName", + "crDisplayName", + "hrDisplayName", + "csDisplayName", + "daDisplayName", + "dvDisplayName", + "nlDisplayName", + "enDisplayName", + "eoDisplayName", + "etDisplayName", + "eeDisplayName", + "foDisplayName", + "fjDisplayName", + "fiDisplayName", + "frDisplayName", + "ffDisplayName", + "glDisplayName", + "kaDisplayName", + "deDisplayName", + "elDisplayName", + "gnDisplayName", + "guDisplayName", + "htDisplayName", + "haDisplayName", + "heDisplayName", + "hzDisplayName", + "hiDisplayName", + "hoDisplayName", + "huDisplayName", + "iaDisplayName", + "idDisplayName", + "ieDisplayName", + "gaDisplayName", + "igDisplayName", + "ikDisplayName", + "ioDisplayName", + "isDisplayName", + "itDisplayName", + "iuDisplayName", + "jaDisplayName", + "jvDisplayName", + "klDisplayName", + "knDisplayName", + "krDisplayName", + "ksDisplayName", + "kkDisplayName", + "kmDisplayName", + "kiDisplayName", + "rwDisplayName", + "kyDisplayName", + "kvDisplayName", + "kgDisplayName", + "koDisplayName", + "kuDisplayName", + "kjDisplayName", + "laDisplayName", + "lbDisplayName", + "lgDisplayName", + "liDisplayName", + "lnDisplayName", + "loDisplayName", + "ltDisplayName", + "luDisplayName", + "lvDisplayName", + "gvDisplayName", + "mkDisplayName", + "mgDisplayName", + "msDisplayName", + "mlDisplayName", + "mtDisplayName", + "miDisplayName", + "mrDisplayName", + "mhDisplayName", + "mnDisplayName", + "naDisplayName", + "nvDisplayName", + "nbDisplayName", + "ndDisplayName", + "neDisplayName", + "ngDisplayName", + "nnDisplayName", + "noDisplayName", + "iiDisplayName", + "nrDisplayName", + "ocDisplayName", + "ojDisplayName", + "cuDisplayName", + "omDisplayName", + "orDisplayName", + "osDisplayName", + "paDisplayName", + "piDisplayName", + "faDisplayName", + "plDisplayName", + "psDisplayName", + "ptDisplayName", + "quDisplayName", + "rmDisplayName", + "rnDisplayName", + "roDisplayName", + "ruDisplayName", + "saDisplayName", + "scDisplayName", + "sdDisplayName", + "seDisplayName", + "smDisplayName", + "sgDisplayName", + "srDisplayName", + "gdDisplayName", + "snDisplayName", + "siDisplayName", + "skDisplayName", + "slDisplayName", + "soDisplayName", + "stDisplayName", + "esDisplayName", + "suDisplayName", + "swDisplayName", + "ssDisplayName", + "svDisplayName", + "taDisplayName", + "teDisplayName", + "tgDisplayName", + "thDisplayName", + "tiDisplayName", + "boDisplayName", + "tkDisplayName", + "tlDisplayName", + "tnDisplayName", + "toDisplayName", + "trDisplayName", + "tsDisplayName", + "ttDisplayName", + "twDisplayName", + "tyDisplayName", + "ugDisplayName", + "ukDisplayName", + "urDisplayName", + "uzDisplayName", + "veDisplayName", + "viDisplayName", + "voDisplayName", + "waDisplayName", + "cyDisplayName", + "woDisplayName", + "fyDisplayName", + "xhDisplayName", + "yiDisplayName", + "yoDisplayName", + "zaDisplayName", + "unkDisplayName", + "zuDisplayName", + "hawDisplayName", + "hmnDisplayName", + "multiDisplayName", + "cebDisplayName", + "dzDisplayName", + "iwDisplayName", + "jwDisplayName", + "moDisplayName", + "shDisplayName", + "wwCountryDisplayName", + "afCountryDisplayName", + "axCountryDisplayName", + "alCountryDisplayName", + "dzCountryDisplayName", + "asCountryDisplayName", + "adCountryDisplayName", + "aoCountryDisplayName", + "aiCountryDisplayName", + "agCountryDisplayName", + "arCountryDisplayName", + "amCountryDisplayName", + "awCountryDisplayName", + "acCountryDisplayName", + "auCountryDisplayName", + "atCountryDisplayName", + "azCountryDisplayName", + "bsCountryDisplayName", + "bhCountryDisplayName", + "bdCountryDisplayName", + "bbCountryDisplayName", + "byCountryDisplayName", + "beCountryDisplayName", + "bzCountryDisplayName", + "bjCountryDisplayName", + "bmCountryDisplayName", + "btCountryDisplayName", + "boCountryDisplayName", + "baCountryDisplayName", + "bwCountryDisplayName", + "brCountryDisplayName", + "ioCountryDisplayName", + "vgCountryDisplayName", + "bnCountryDisplayName", + "bgCountryDisplayName", + "bfCountryDisplayName", + "biCountryDisplayName", + "khCountryDisplayName", + "cmCountryDisplayName", + "caCountryDisplayName", + "cvCountryDisplayName", + "bqCountryDisplayName", + "kyCountryDisplayName", + "cfCountryDisplayName", + "tdCountryDisplayName", + "clCountryDisplayName", + "cnCountryDisplayName", + "cxCountryDisplayName", + "ccCountryDisplayName", + "coCountryDisplayName", + "kmCountryDisplayName", + "cdCountryDisplayName", + "cgCountryDisplayName", + "ckCountryDisplayName", + "crCountryDisplayName", + "ciCountryDisplayName", + "hrCountryDisplayName", + "cuCountryDisplayName", + "cwCountryDisplayName", + "cyCountryDisplayName", + "czCountryDisplayName", + "dkCountryDisplayName", + "djCountryDisplayName", + "dmCountryDisplayName", + "doCountryDisplayName", + "tlCountryDisplayName", + "ecCountryDisplayName", + "egCountryDisplayName", + "svCountryDisplayName", + "gqCountryDisplayName", + "erCountryDisplayName", + "eeCountryDisplayName", + "szCountryDisplayName", + "etCountryDisplayName", + "fkCountryDisplayName", + "foCountryDisplayName", + "fjCountryDisplayName", + "fiCountryDisplayName", + "frCountryDisplayName", + "gfCountryDisplayName", + "pfCountryDisplayName", + "gaCountryDisplayName", + "gmCountryDisplayName", + "geCountryDisplayName", + "deCountryDisplayName", + "ghCountryDisplayName", + "giCountryDisplayName", + "grCountryDisplayName", + "glCountryDisplayName", + "gdCountryDisplayName", + "gpCountryDisplayName", + "guCountryDisplayName", + "gtCountryDisplayName", + "ggCountryDisplayName", + "gnCountryDisplayName", + "gwCountryDisplayName", + "gyCountryDisplayName", + "htCountryDisplayName", + "hmCountryDisplayName", + "hnCountryDisplayName", + "hkCountryDisplayName", + "huCountryDisplayName", + "isCountryDisplayName", + "inCountryDisplayName", + "idCountryDisplayName", + "irCountryDisplayName", + "iqCountryDisplayName", + "ieCountryDisplayName", + "imCountryDisplayName", + "ilCountryDisplayName", + "itCountryDisplayName", + "jmCountryDisplayName", + "jpCountryDisplayName", + "jeCountryDisplayName", + "joCountryDisplayName", + "kzCountryDisplayName", + "keCountryDisplayName", + "kiCountryDisplayName", + "xkCountryDisplayName", + "kwCountryDisplayName", + "kgCountryDisplayName", + "laCountryDisplayName", + "lvCountryDisplayName", + "lbCountryDisplayName", + "lsCountryDisplayName", + "lrCountryDisplayName", + "lyCountryDisplayName", + "liCountryDisplayName", + "ltCountryDisplayName", + "luCountryDisplayName", + "moCountryDisplayName", + "mkCountryDisplayName", + "mgCountryDisplayName", + "mwCountryDisplayName", + "myCountryDisplayName", + "mvCountryDisplayName", + "mlCountryDisplayName", + "mtCountryDisplayName", + "mhCountryDisplayName", + "mqCountryDisplayName", + "mrCountryDisplayName", + "muCountryDisplayName", + "ytCountryDisplayName", + "mxCountryDisplayName", + "fmCountryDisplayName", + "mdCountryDisplayName", + "mcCountryDisplayName", + "mnCountryDisplayName", + "meCountryDisplayName", + "msCountryDisplayName", + "maCountryDisplayName", + "mzCountryDisplayName", + "mmCountryDisplayName", + "naCountryDisplayName", + "nrCountryDisplayName", + "npCountryDisplayName", + "nlCountryDisplayName", + "ncCountryDisplayName", + "nzCountryDisplayName", + "niCountryDisplayName", + "neCountryDisplayName", + "ngCountryDisplayName", + "nuCountryDisplayName", + "nfCountryDisplayName", + "kpCountryDisplayName", + "mpCountryDisplayName", + "noCountryDisplayName", + "omCountryDisplayName", + "pkCountryDisplayName", + "pwCountryDisplayName", + "psCountryDisplayName", + "paCountryDisplayName", + "pgCountryDisplayName", + "pyCountryDisplayName", + "peCountryDisplayName", + "phCountryDisplayName", + "plCountryDisplayName", + "ptCountryDisplayName", + "prCountryDisplayName", + "qaCountryDisplayName", + "reCountryDisplayName", + "roCountryDisplayName", + "ruCountryDisplayName", + "rwCountryDisplayName", + "blCountryDisplayName", + "shCountryDisplayName", + "knCountryDisplayName", + "lcCountryDisplayName", + "mfCountryDisplayName", + "pmCountryDisplayName", + "vcCountryDisplayName", + "wsCountryDisplayName", + "smCountryDisplayName", + "stCountryDisplayName", + "saCountryDisplayName", + "snCountryDisplayName", + "rsCountryDisplayName", + "scCountryDisplayName", + "slCountryDisplayName", + "sgCountryDisplayName", + "sxCountryDisplayName", + "skCountryDisplayName", + "siCountryDisplayName", + "sbCountryDisplayName", + "soCountryDisplayName", + "zaCountryDisplayName", + "gsCountryDisplayName", + "krCountryDisplayName", + "ssCountryDisplayName", + "esCountryDisplayName", + "lkCountryDisplayName", + "sdCountryDisplayName", + "srCountryDisplayName", + "sjCountryDisplayName", + "seCountryDisplayName", + "chCountryDisplayName", + "syCountryDisplayName", + "twCountryDisplayName", + "tjCountryDisplayName", + "tzCountryDisplayName", + "thCountryDisplayName", + "tgCountryDisplayName", + "tkCountryDisplayName", + "toCountryDisplayName", + "ttCountryDisplayName", + "tnCountryDisplayName", + "trCountryDisplayName", + "tmCountryDisplayName", + "tcCountryDisplayName", + "tvCountryDisplayName", + "viCountryDisplayName", + "ugCountryDisplayName", + "uaCountryDisplayName", + "aeCountryDisplayName", + "gbCountryDisplayName", + "usCountryDisplayName", + "uyCountryDisplayName", + "uzCountryDisplayName", + "vuCountryDisplayName", + "vaCountryDisplayName", + "veCountryDisplayName", + "vnCountryDisplayName", + "wfCountryDisplayName", + "ehCountryDisplayName", + "yeCountryDisplayName", + "zmCountryDisplayName", + "zwCountryDisplayName", + "pay", + "allPrivateChats", + "unknownPrivateChat", + "copyClassCodeDesc", + "addToClassDesc", + "addToClassOrExchange", + "addToClassOrExchangeDesc", + "invitedToClassOrExchange", + "decline", + "declinedInvitation", + "acceptedInvitation", + "youreInvited", + "studentPermissionsDesc", + "noEligibleSpaces", + "youAddedToSpace", + "youRemovedFromSpace", + "invitedToChat", + "monthlySubscription", + "yearlySubscription", + "defaultSubscription", + "freeTrial", + "grammarAnalytics", + "total", + "noDataFound", + "promoSubscriptionExpirationDesc", + "emptyChatNameWarning", + "emptyClassNameWarning", + "emptyExchangeNameWarning", + "blurMeansTranslateTitle", + "blurMeansTranslateBody", + "someErrorTitle", + "someErrorBody", + "bestCorrectionFeedback", + "distractorFeedback", + "bestAnswerFeedback", + "definitionDefaultPrompt", + "practiceDefaultPrompt", + "correctionDefaultPrompt", + "itStartDefaultPrompt", + "languageLevelWarning", + "lockedChatWarning", + "lockSpace", + "lockChat", + "archiveSpace", + "suggestTo", + "suggestChatDesc", + "suggestExchangeDesc", + "acceptSelection", + "acceptSelectionAnyway", + "makingActivity", + "why", + "definition", + "exampleSentence", + "addToClassTitle", + "reportToTeacher", + "reportMessageTitle", + "reportMessageBody", + "noTeachersFound", + "noAddToSpacePermissions", + "alreadyInSpace", + "yourGlobalUserIdIs", + "noUsersFoundWithQuery", + "searchChatsRooms", + "groupName", + "createGroupAndInviteUsers", + "groupCanBeFoundViaSearch", + "inNoSpaces" + ], + + "es": [ + "notAnImage", + "importNow", + "importEmojis", + "importFromZipFile", + "importZipFile", + "exportEmotePack", + "savedEmotePack", + "sendTypingNotifications", + "reportToTeacher", + "reportMessageTitle", + "reportMessageBody", + "noTeachersFound", + "noAddToSpacePermissions", + "alreadyInSpace", + "yourGlobalUserIdIs", + "noUsersFoundWithQuery", + "searchChatsRooms", + "groupName", + "createGroupAndInviteUsers", + "groupCanBeFoundViaSearch", + "inNoSpaces" + ], + + "et": [ + "accountInformation", + "addNewFriend", + "alreadyHaveAnAccount", + "classes", + "allCorrect", + "newWayAllGood", + "othersAreBetter", + "holdForInfo", + "greenFeedback", + "yellowFeedback", + "redFeedback", + "customInputFeedbackChoice", + "itInstructionsTitle", + "itInstructionsBody", + "toggleLanguages", + "classWelcomeChat", + "deleteSpace", + "deleteGroup", + "areYouSureDeleteClass", + "areYouSureDeleteGroup", + "cannotBeReversed", + "enterDeletedClassName", + "incorrectClassName", + "oneday", + "oneweek", + "onemonth", + "sixmonth", + "oneyear", + "gaTooltip", + "taTooltip", + "unTooltip", + "interactiveTranslatorSliderHeader", + "interactiveGrammarSliderHeader", + "interactiveTranslatorNotAllowed", + "interactiveTranslatorAllowed", + "interactiveTranslatorRequired", + "interactiveTranslatorNotAllowedDesc", + "interactiveTranslatorAllowedDesc", + "interactiveTranslatorRequiredDesc", + "notYetSet", + "multiLingualClass", + "classAnalytics", + "allClasses", + "myLearning", + "allChatsAndClasses", + "timeOfLastMessage", + "totalMessages", + "waTooltip", + "changeDateRange", + "numberOfStudents", + "classDescription", + "classDescriptionDesc", + "requestToEnroll", + "requestAnExchange", + "findLanguageExchange", + "classAnalyticsDesc", + "addStudents", + "copyClassLink", + "copyClassLinkDesc", + "copyClassCode", + "inviteStudentByUserName", + "classSettings", + "classSettingsDesc", + "selectClassRoomDominantLanguage", + "selectTargetLanguage", + "whatIsYourClassLanguageLevel", + "studentPermissions", + "interactiveTranslator", + "oneToOneChatsWithinClass", + "oneToOneChatsWithinClassDesc", + "createGroupChats", + "createGroupChatsDesc", + "shareVideo", + "shareVideoDesc", + "sharePhotos", + "sharePhotosDesc", + "shareFiles", + "shareFilesDesc", + "shareLocationDesc", + "selectLanguageLevel", + "noIdenticalLanguages", + "iWantALanguagePartnerFrom", + "worldWide", + "noResults", + "searchBy", + "iWantAConversationPartner", + "iWantALanguagePartnerWhoSpeaks", + "iWantALanguagePartnerWhoIsLearning", + "yourBirthdayPlease", + "invalidDob", + "enterYourDob", + "getStarted", + "mustBe13", + "yourBirthdayPleaseShort", + "errorPleaseRefresh", + "joinWithClassCode", + "joinWithClassCodeDesc", + "joinWithClassCodeHint", + "unableToFindClass", + "languageLevelPreA1", + "languageLevelA1", + "languageLevelA2", + "languageLevelB1", + "languageLevelB2", + "languageLevelC1", + "languageLevelC2", + "changeTheNameOfTheClass", + "changeTheNameOfTheChat", + "welcomeToYourNewClass", + "welcomeToClass", + "welcomeToPangea18Plus", + "welcomeToPangeaMinor", + "findALanguagePartner", + "setToPublicSettingsTitle", + "setToPublicSettingsDesc", + "accountSettings", + "unableToFindClassCode", + "askPangeaBot", + "sorryNoResults", + "ignoreInThisText", + "helpMeTranslate", + "needsItShortMessage", + "needsIGCShortMessage", + "needsItMessage", + "needsIgcMessage", + "tokenTranslationTitle", + "spanTranslationDesc", + "spanTranslationTitle", + "l1SpanAndGrammarTitle", + "l1SpanAndGrammarDesc", + "otherTitle", + "otherDesc", + "countryInformation", + "myLanguages", + "targetLanguage", + "sourceLanguage", + "languagesISpeak", + "updateLanguage", + "whatLanguageYouWantToLearn", + "whatIsYourBaseLanguage", + "saveChanges", + "publicProfileTitle", + "publicProfileDesc", + "error502504Title", + "error502504Desc", + "error404Title", + "error404Desc", + "errorDisableIT", + "errorDisableIGC", + "errorDisableLanguageAssistance", + "errorDisableITUserDesc", + "errorDisableIGCUserDesc", + "errorDisableLanguageAssistanceUserDesc", + "errorDisableITClassDesc", + "errorDisableIGCClassDesc", + "errorDisableLanguageAssistanceClassDesc", + "itIsDisabled", + "igcIsDisabled", + "goToLearningSettings", + "error405Title", + "error405Desc", + "loginOrSignup", + "iAgreeToThe", + "termsAndConditions", + "andCertifyIAmAtLeast13YearsOfAge", + "findAClass", + "toggleIT", + "toggleIGC", + "toggleToolSettingsDescription", + "connectedToStaging", + "learningSettings", + "classNameRequired", + "sendVoiceNotes", + "sendVoiceNotesDesc", + "chatTopic", + "chatTopicDesc", + "inviteStudentByUserNameDesc", + "classRoster", + "almostPerfect", + "prettyGood", + "letMeThink", + "clickMessageTitle", + "clickMessageBody", + "understandingMessagesTitle", + "addToClass", + "understandingMessagesBody", + "allDone", + "vocab", + "low", + "medium", + "high", + "unknownProficiency", + "changeView", + "clearAll", + "generateVocabulary", + "generatePrompts", + "subscribe", + "getAccess", + "subscriptionDesc", + "subscriptionManagement", + "currentSubscription", + "changeSubscription", + "cancelSubscription", + "selectYourPlan", + "subsciptionPlatformTooltip", + "subscriptionManagementUnavailable", + "paymentMethod", + "paymentHistory", + "emptyChatDownloadWarning", + "appUpdateAvailable", + "update", + "updateDesc", + "maybeLater", + "mainMenu", + "toggleImmersionMode", + "toggleImmersionModeDesc", + "itToggleDescription", + "igcToggleDescription", + "sendOnEnterDescription", + "alreadyInClass", + "pleaseLoginFirst", + "originalMessage", + "sentMessage", + "useType", + "notAvailable", + "taAndGaTooltip", + "definitionsToolName", + "messageTranslationsToolName", + "definitionsToolDescription", + "translationsToolDescrption", + "welcomeBack", + "classExchanges", + "createNewClass", + "newExchange", + "kickAllStudents", + "kickAllStudentsConfirmation", + "inviteAllStudents", + "inviteAllStudentsConfirmation", + "inviteStudentsFromOtherClasses", + "inviteUsersFromPangea", + "allExchanges", + "redeemPromoCode", + "enterPromoCode", + "downloadTxtFile", + "downloadCSVFile", + "promotionalSubscriptionDesc", + "originalSubscriptionPlatform", + "oneWeekTrial", + "creatingSpacePleaseWait", + "downloadXLSXFile", + "abDisplayName", + "aaDisplayName", + "afDisplayName", + "akDisplayName", + "sqDisplayName", + "amDisplayName", + "arDisplayName", + "anDisplayName", + "hyDisplayName", + "asDisplayName", + "avDisplayName", + "aeDisplayName", + "ayDisplayName", + "azDisplayName", + "bmDisplayName", + "baDisplayName", + "euDisplayName", + "beDisplayName", + "bnDisplayName", + "bhDisplayName", + "biDisplayName", + "bsDisplayName", + "brDisplayName", + "bgDisplayName", + "myDisplayName", + "caDisplayName", + "chDisplayName", + "ceDisplayName", + "nyDisplayName", + "zhDisplayName", + "cvDisplayName", + "kwDisplayName", + "coDisplayName", + "crDisplayName", + "hrDisplayName", + "csDisplayName", + "daDisplayName", + "dvDisplayName", + "nlDisplayName", + "enDisplayName", + "eoDisplayName", + "etDisplayName", + "eeDisplayName", + "foDisplayName", + "fjDisplayName", + "fiDisplayName", + "frDisplayName", + "ffDisplayName", + "glDisplayName", + "kaDisplayName", + "deDisplayName", + "elDisplayName", + "gnDisplayName", + "guDisplayName", + "htDisplayName", + "haDisplayName", + "heDisplayName", + "hzDisplayName", + "hiDisplayName", + "hoDisplayName", + "huDisplayName", + "iaDisplayName", + "idDisplayName", + "ieDisplayName", + "gaDisplayName", + "igDisplayName", + "ikDisplayName", + "ioDisplayName", + "isDisplayName", + "itDisplayName", + "iuDisplayName", + "jaDisplayName", + "jvDisplayName", + "klDisplayName", + "knDisplayName", + "krDisplayName", + "ksDisplayName", + "kkDisplayName", + "kmDisplayName", + "kiDisplayName", + "rwDisplayName", + "kyDisplayName", + "kvDisplayName", + "kgDisplayName", + "koDisplayName", + "kuDisplayName", + "kjDisplayName", + "laDisplayName", + "lbDisplayName", + "lgDisplayName", + "liDisplayName", + "lnDisplayName", + "loDisplayName", + "ltDisplayName", + "luDisplayName", + "lvDisplayName", + "gvDisplayName", + "mkDisplayName", + "mgDisplayName", + "msDisplayName", + "mlDisplayName", + "mtDisplayName", + "miDisplayName", + "mrDisplayName", + "mhDisplayName", + "mnDisplayName", + "naDisplayName", + "nvDisplayName", + "nbDisplayName", + "ndDisplayName", + "neDisplayName", + "ngDisplayName", + "nnDisplayName", + "noDisplayName", + "iiDisplayName", + "nrDisplayName", + "ocDisplayName", + "ojDisplayName", + "cuDisplayName", + "omDisplayName", + "orDisplayName", + "osDisplayName", + "paDisplayName", + "piDisplayName", + "faDisplayName", + "plDisplayName", + "psDisplayName", + "ptDisplayName", + "quDisplayName", + "rmDisplayName", + "rnDisplayName", + "roDisplayName", + "ruDisplayName", + "saDisplayName", + "scDisplayName", + "sdDisplayName", + "seDisplayName", + "smDisplayName", + "sgDisplayName", + "srDisplayName", + "gdDisplayName", + "snDisplayName", + "siDisplayName", + "skDisplayName", + "slDisplayName", + "soDisplayName", + "stDisplayName", + "esDisplayName", + "suDisplayName", + "swDisplayName", + "ssDisplayName", + "svDisplayName", + "taDisplayName", + "teDisplayName", + "tgDisplayName", + "thDisplayName", + "tiDisplayName", + "boDisplayName", + "tkDisplayName", + "tlDisplayName", + "tnDisplayName", + "toDisplayName", + "trDisplayName", + "tsDisplayName", + "ttDisplayName", + "twDisplayName", + "tyDisplayName", + "ugDisplayName", + "ukDisplayName", + "urDisplayName", + "uzDisplayName", + "veDisplayName", + "viDisplayName", + "voDisplayName", + "waDisplayName", + "cyDisplayName", + "woDisplayName", + "fyDisplayName", + "xhDisplayName", + "yiDisplayName", + "yoDisplayName", + "zaDisplayName", + "unkDisplayName", + "zuDisplayName", + "hawDisplayName", + "hmnDisplayName", + "multiDisplayName", + "cebDisplayName", + "dzDisplayName", + "iwDisplayName", + "jwDisplayName", + "moDisplayName", + "shDisplayName", + "wwCountryDisplayName", + "afCountryDisplayName", + "axCountryDisplayName", + "alCountryDisplayName", + "dzCountryDisplayName", + "asCountryDisplayName", + "adCountryDisplayName", + "aoCountryDisplayName", + "aiCountryDisplayName", + "agCountryDisplayName", + "arCountryDisplayName", + "amCountryDisplayName", + "awCountryDisplayName", + "acCountryDisplayName", + "auCountryDisplayName", + "atCountryDisplayName", + "azCountryDisplayName", + "bsCountryDisplayName", + "bhCountryDisplayName", + "bdCountryDisplayName", + "bbCountryDisplayName", + "byCountryDisplayName", + "beCountryDisplayName", + "bzCountryDisplayName", + "bjCountryDisplayName", + "bmCountryDisplayName", + "btCountryDisplayName", + "boCountryDisplayName", + "baCountryDisplayName", + "bwCountryDisplayName", + "brCountryDisplayName", + "ioCountryDisplayName", + "vgCountryDisplayName", + "bnCountryDisplayName", + "bgCountryDisplayName", + "bfCountryDisplayName", + "biCountryDisplayName", + "khCountryDisplayName", + "cmCountryDisplayName", + "caCountryDisplayName", + "cvCountryDisplayName", + "bqCountryDisplayName", + "kyCountryDisplayName", + "cfCountryDisplayName", + "tdCountryDisplayName", + "clCountryDisplayName", + "cnCountryDisplayName", + "cxCountryDisplayName", + "ccCountryDisplayName", + "coCountryDisplayName", + "kmCountryDisplayName", + "cdCountryDisplayName", + "cgCountryDisplayName", + "ckCountryDisplayName", + "crCountryDisplayName", + "ciCountryDisplayName", + "hrCountryDisplayName", + "cuCountryDisplayName", + "cwCountryDisplayName", + "cyCountryDisplayName", + "czCountryDisplayName", + "dkCountryDisplayName", + "djCountryDisplayName", + "dmCountryDisplayName", + "doCountryDisplayName", + "tlCountryDisplayName", + "ecCountryDisplayName", + "egCountryDisplayName", + "svCountryDisplayName", + "gqCountryDisplayName", + "erCountryDisplayName", + "eeCountryDisplayName", + "szCountryDisplayName", + "etCountryDisplayName", + "fkCountryDisplayName", + "foCountryDisplayName", + "fjCountryDisplayName", + "fiCountryDisplayName", + "frCountryDisplayName", + "gfCountryDisplayName", + "pfCountryDisplayName", + "gaCountryDisplayName", + "gmCountryDisplayName", + "geCountryDisplayName", + "deCountryDisplayName", + "ghCountryDisplayName", + "giCountryDisplayName", + "grCountryDisplayName", + "glCountryDisplayName", + "gdCountryDisplayName", + "gpCountryDisplayName", + "guCountryDisplayName", + "gtCountryDisplayName", + "ggCountryDisplayName", + "gnCountryDisplayName", + "gwCountryDisplayName", + "gyCountryDisplayName", + "htCountryDisplayName", + "hmCountryDisplayName", + "hnCountryDisplayName", + "hkCountryDisplayName", + "huCountryDisplayName", + "isCountryDisplayName", + "inCountryDisplayName", + "idCountryDisplayName", + "irCountryDisplayName", + "iqCountryDisplayName", + "ieCountryDisplayName", + "imCountryDisplayName", + "ilCountryDisplayName", + "itCountryDisplayName", + "jmCountryDisplayName", + "jpCountryDisplayName", + "jeCountryDisplayName", + "joCountryDisplayName", + "kzCountryDisplayName", + "keCountryDisplayName", + "kiCountryDisplayName", + "xkCountryDisplayName", + "kwCountryDisplayName", + "kgCountryDisplayName", + "laCountryDisplayName", + "lvCountryDisplayName", + "lbCountryDisplayName", + "lsCountryDisplayName", + "lrCountryDisplayName", + "lyCountryDisplayName", + "liCountryDisplayName", + "ltCountryDisplayName", + "luCountryDisplayName", + "moCountryDisplayName", + "mkCountryDisplayName", + "mgCountryDisplayName", + "mwCountryDisplayName", + "myCountryDisplayName", + "mvCountryDisplayName", + "mlCountryDisplayName", + "mtCountryDisplayName", + "mhCountryDisplayName", + "mqCountryDisplayName", + "mrCountryDisplayName", + "muCountryDisplayName", + "ytCountryDisplayName", + "mxCountryDisplayName", + "fmCountryDisplayName", + "mdCountryDisplayName", + "mcCountryDisplayName", + "mnCountryDisplayName", + "meCountryDisplayName", + "msCountryDisplayName", + "maCountryDisplayName", + "mzCountryDisplayName", + "mmCountryDisplayName", + "naCountryDisplayName", + "nrCountryDisplayName", + "npCountryDisplayName", + "nlCountryDisplayName", + "ncCountryDisplayName", + "nzCountryDisplayName", + "niCountryDisplayName", + "neCountryDisplayName", + "ngCountryDisplayName", + "nuCountryDisplayName", + "nfCountryDisplayName", + "kpCountryDisplayName", + "mpCountryDisplayName", + "noCountryDisplayName", + "omCountryDisplayName", + "pkCountryDisplayName", + "pwCountryDisplayName", + "psCountryDisplayName", + "paCountryDisplayName", + "pgCountryDisplayName", + "pyCountryDisplayName", + "peCountryDisplayName", + "phCountryDisplayName", + "plCountryDisplayName", + "ptCountryDisplayName", + "prCountryDisplayName", + "qaCountryDisplayName", + "reCountryDisplayName", + "roCountryDisplayName", + "ruCountryDisplayName", + "rwCountryDisplayName", + "blCountryDisplayName", + "shCountryDisplayName", + "knCountryDisplayName", + "lcCountryDisplayName", + "mfCountryDisplayName", + "pmCountryDisplayName", + "vcCountryDisplayName", + "wsCountryDisplayName", + "smCountryDisplayName", + "stCountryDisplayName", + "saCountryDisplayName", + "snCountryDisplayName", + "rsCountryDisplayName", + "scCountryDisplayName", + "slCountryDisplayName", + "sgCountryDisplayName", + "sxCountryDisplayName", + "skCountryDisplayName", + "siCountryDisplayName", + "sbCountryDisplayName", + "soCountryDisplayName", + "zaCountryDisplayName", + "gsCountryDisplayName", + "krCountryDisplayName", + "ssCountryDisplayName", + "esCountryDisplayName", + "lkCountryDisplayName", + "sdCountryDisplayName", + "srCountryDisplayName", + "sjCountryDisplayName", + "seCountryDisplayName", + "chCountryDisplayName", + "syCountryDisplayName", + "twCountryDisplayName", + "tjCountryDisplayName", + "tzCountryDisplayName", + "thCountryDisplayName", + "tgCountryDisplayName", + "tkCountryDisplayName", + "toCountryDisplayName", + "ttCountryDisplayName", + "tnCountryDisplayName", + "trCountryDisplayName", + "tmCountryDisplayName", + "tcCountryDisplayName", + "tvCountryDisplayName", + "viCountryDisplayName", + "ugCountryDisplayName", + "uaCountryDisplayName", + "aeCountryDisplayName", + "gbCountryDisplayName", + "usCountryDisplayName", + "uyCountryDisplayName", + "uzCountryDisplayName", + "vuCountryDisplayName", + "vaCountryDisplayName", + "veCountryDisplayName", + "vnCountryDisplayName", + "wfCountryDisplayName", + "ehCountryDisplayName", + "yeCountryDisplayName", + "zmCountryDisplayName", + "zwCountryDisplayName", + "pay", + "allPrivateChats", + "unknownPrivateChat", + "copyClassCodeDesc", + "addToClassDesc", + "addToClassOrExchange", + "addToClassOrExchangeDesc", + "invitedToClassOrExchange", + "decline", + "declinedInvitation", + "acceptedInvitation", + "youreInvited", + "studentPermissionsDesc", + "noEligibleSpaces", + "youAddedToSpace", + "youRemovedFromSpace", + "invitedToChat", + "monthlySubscription", + "yearlySubscription", + "defaultSubscription", + "freeTrial", + "grammarAnalytics", + "total", + "noDataFound", + "promoSubscriptionExpirationDesc", + "emptyChatNameWarning", + "emptyClassNameWarning", + "emptyExchangeNameWarning", + "blurMeansTranslateTitle", + "blurMeansTranslateBody", + "someErrorTitle", + "someErrorBody", + "bestCorrectionFeedback", + "distractorFeedback", + "bestAnswerFeedback", + "definitionDefaultPrompt", + "practiceDefaultPrompt", + "correctionDefaultPrompt", + "itStartDefaultPrompt", + "languageLevelWarning", + "lockedChatWarning", + "lockSpace", + "lockChat", + "archiveSpace", + "suggestTo", + "suggestChatDesc", + "suggestExchangeDesc", + "acceptSelection", + "acceptSelectionAnyway", + "makingActivity", + "why", + "definition", + "exampleSentence", + "addToClassTitle", + "reportToTeacher", + "reportMessageTitle", + "reportMessageBody", + "noTeachersFound", + "noAddToSpacePermissions", + "alreadyInSpace", + "yourGlobalUserIdIs", + "noUsersFoundWithQuery", + "searchChatsRooms", + "groupName", + "createGroupAndInviteUsers", + "groupCanBeFoundViaSearch", + "inNoSpaces" + ], + + "eu": [ + "accountInformation", + "addNewFriend", + "alreadyHaveAnAccount", + "classes", + "allCorrect", + "newWayAllGood", + "othersAreBetter", + "holdForInfo", + "greenFeedback", + "yellowFeedback", + "redFeedback", + "customInputFeedbackChoice", + "itInstructionsTitle", + "itInstructionsBody", + "toggleLanguages", + "classWelcomeChat", + "deleteSpace", + "deleteGroup", + "areYouSureDeleteClass", + "areYouSureDeleteGroup", + "cannotBeReversed", + "enterDeletedClassName", + "incorrectClassName", + "oneday", + "oneweek", + "onemonth", + "sixmonth", + "oneyear", + "gaTooltip", + "taTooltip", + "unTooltip", + "interactiveTranslatorSliderHeader", + "interactiveGrammarSliderHeader", + "interactiveTranslatorNotAllowed", + "interactiveTranslatorAllowed", + "interactiveTranslatorRequired", + "interactiveTranslatorNotAllowedDesc", + "interactiveTranslatorAllowedDesc", + "interactiveTranslatorRequiredDesc", + "notYetSet", + "multiLingualClass", + "classAnalytics", + "allClasses", + "myLearning", + "allChatsAndClasses", + "timeOfLastMessage", + "totalMessages", + "waTooltip", + "changeDateRange", + "numberOfStudents", + "classDescription", + "classDescriptionDesc", + "requestToEnroll", + "requestAnExchange", + "findLanguageExchange", + "classAnalyticsDesc", + "addStudents", + "copyClassLink", + "copyClassLinkDesc", + "copyClassCode", + "inviteStudentByUserName", + "classSettings", + "classSettingsDesc", + "selectClassRoomDominantLanguage", + "selectTargetLanguage", + "whatIsYourClassLanguageLevel", + "studentPermissions", + "interactiveTranslator", + "oneToOneChatsWithinClass", + "oneToOneChatsWithinClassDesc", + "createGroupChats", + "createGroupChatsDesc", + "shareVideo", + "shareVideoDesc", + "sharePhotos", + "sharePhotosDesc", + "shareFiles", + "shareFilesDesc", + "shareLocationDesc", + "selectLanguageLevel", + "noIdenticalLanguages", + "iWantALanguagePartnerFrom", + "worldWide", + "noResults", + "searchBy", + "iWantAConversationPartner", + "iWantALanguagePartnerWhoSpeaks", + "iWantALanguagePartnerWhoIsLearning", + "yourBirthdayPlease", + "invalidDob", + "enterYourDob", + "getStarted", + "mustBe13", + "yourBirthdayPleaseShort", + "errorPleaseRefresh", + "joinWithClassCode", + "joinWithClassCodeDesc", + "joinWithClassCodeHint", + "unableToFindClass", + "languageLevelPreA1", + "languageLevelA1", + "languageLevelA2", + "languageLevelB1", + "languageLevelB2", + "languageLevelC1", + "languageLevelC2", + "changeTheNameOfTheClass", + "changeTheNameOfTheChat", + "welcomeToYourNewClass", + "welcomeToClass", + "welcomeToPangea18Plus", + "welcomeToPangeaMinor", + "findALanguagePartner", + "setToPublicSettingsTitle", + "setToPublicSettingsDesc", + "accountSettings", + "unableToFindClassCode", + "askPangeaBot", + "sorryNoResults", + "ignoreInThisText", + "helpMeTranslate", + "needsItShortMessage", + "needsIGCShortMessage", + "needsItMessage", + "needsIgcMessage", + "tokenTranslationTitle", + "spanTranslationDesc", + "spanTranslationTitle", + "l1SpanAndGrammarTitle", + "l1SpanAndGrammarDesc", + "otherTitle", + "otherDesc", + "countryInformation", + "myLanguages", + "targetLanguage", + "sourceLanguage", + "languagesISpeak", + "updateLanguage", + "whatLanguageYouWantToLearn", + "whatIsYourBaseLanguage", + "saveChanges", + "publicProfileTitle", + "publicProfileDesc", + "error502504Title", + "error502504Desc", + "error404Title", + "error404Desc", + "errorDisableIT", + "errorDisableIGC", + "errorDisableLanguageAssistance", + "errorDisableITUserDesc", + "errorDisableIGCUserDesc", + "errorDisableLanguageAssistanceUserDesc", + "errorDisableITClassDesc", + "errorDisableIGCClassDesc", + "errorDisableLanguageAssistanceClassDesc", + "itIsDisabled", + "igcIsDisabled", + "goToLearningSettings", + "error405Title", + "error405Desc", + "loginOrSignup", + "iAgreeToThe", + "termsAndConditions", + "andCertifyIAmAtLeast13YearsOfAge", + "findAClass", + "toggleIT", + "toggleIGC", + "toggleToolSettingsDescription", + "connectedToStaging", + "learningSettings", + "classNameRequired", + "sendVoiceNotes", + "sendVoiceNotesDesc", + "chatTopic", + "chatTopicDesc", + "inviteStudentByUserNameDesc", + "classRoster", + "almostPerfect", + "prettyGood", + "letMeThink", + "clickMessageTitle", + "clickMessageBody", + "understandingMessagesTitle", + "addToClass", + "understandingMessagesBody", + "allDone", + "vocab", + "low", + "medium", + "high", + "unknownProficiency", + "changeView", + "clearAll", + "generateVocabulary", + "generatePrompts", + "subscribe", + "getAccess", + "subscriptionDesc", + "subscriptionManagement", + "currentSubscription", + "changeSubscription", + "cancelSubscription", + "selectYourPlan", + "subsciptionPlatformTooltip", + "subscriptionManagementUnavailable", + "paymentMethod", + "paymentHistory", + "emptyChatDownloadWarning", + "appUpdateAvailable", + "update", + "updateDesc", + "maybeLater", + "mainMenu", + "toggleImmersionMode", + "toggleImmersionModeDesc", + "itToggleDescription", + "igcToggleDescription", + "sendOnEnterDescription", + "alreadyInClass", + "pleaseLoginFirst", + "originalMessage", + "sentMessage", + "useType", + "notAvailable", + "taAndGaTooltip", + "definitionsToolName", + "messageTranslationsToolName", + "definitionsToolDescription", + "translationsToolDescrption", + "welcomeBack", + "classExchanges", + "createNewClass", + "newExchange", + "kickAllStudents", + "kickAllStudentsConfirmation", + "inviteAllStudents", + "inviteAllStudentsConfirmation", + "inviteStudentsFromOtherClasses", + "inviteUsersFromPangea", + "allExchanges", + "redeemPromoCode", + "enterPromoCode", + "downloadTxtFile", + "downloadCSVFile", + "promotionalSubscriptionDesc", + "originalSubscriptionPlatform", + "oneWeekTrial", + "creatingSpacePleaseWait", + "downloadXLSXFile", + "abDisplayName", + "aaDisplayName", + "afDisplayName", + "akDisplayName", + "sqDisplayName", + "amDisplayName", + "arDisplayName", + "anDisplayName", + "hyDisplayName", + "asDisplayName", + "avDisplayName", + "aeDisplayName", + "ayDisplayName", + "azDisplayName", + "bmDisplayName", + "baDisplayName", + "euDisplayName", + "beDisplayName", + "bnDisplayName", + "bhDisplayName", + "biDisplayName", + "bsDisplayName", + "brDisplayName", + "bgDisplayName", + "myDisplayName", + "caDisplayName", + "chDisplayName", + "ceDisplayName", + "nyDisplayName", + "zhDisplayName", + "cvDisplayName", + "kwDisplayName", + "coDisplayName", + "crDisplayName", + "hrDisplayName", + "csDisplayName", + "daDisplayName", + "dvDisplayName", + "nlDisplayName", + "enDisplayName", + "eoDisplayName", + "etDisplayName", + "eeDisplayName", + "foDisplayName", + "fjDisplayName", + "fiDisplayName", + "frDisplayName", + "ffDisplayName", + "glDisplayName", + "kaDisplayName", + "deDisplayName", + "elDisplayName", + "gnDisplayName", + "guDisplayName", + "htDisplayName", + "haDisplayName", + "heDisplayName", + "hzDisplayName", + "hiDisplayName", + "hoDisplayName", + "huDisplayName", + "iaDisplayName", + "idDisplayName", + "ieDisplayName", + "gaDisplayName", + "igDisplayName", + "ikDisplayName", + "ioDisplayName", + "isDisplayName", + "itDisplayName", + "iuDisplayName", + "jaDisplayName", + "jvDisplayName", + "klDisplayName", + "knDisplayName", + "krDisplayName", + "ksDisplayName", + "kkDisplayName", + "kmDisplayName", + "kiDisplayName", + "rwDisplayName", + "kyDisplayName", + "kvDisplayName", + "kgDisplayName", + "koDisplayName", + "kuDisplayName", + "kjDisplayName", + "laDisplayName", + "lbDisplayName", + "lgDisplayName", + "liDisplayName", + "lnDisplayName", + "loDisplayName", + "ltDisplayName", + "luDisplayName", + "lvDisplayName", + "gvDisplayName", + "mkDisplayName", + "mgDisplayName", + "msDisplayName", + "mlDisplayName", + "mtDisplayName", + "miDisplayName", + "mrDisplayName", + "mhDisplayName", + "mnDisplayName", + "naDisplayName", + "nvDisplayName", + "nbDisplayName", + "ndDisplayName", + "neDisplayName", + "ngDisplayName", + "nnDisplayName", + "noDisplayName", + "iiDisplayName", + "nrDisplayName", + "ocDisplayName", + "ojDisplayName", + "cuDisplayName", + "omDisplayName", + "orDisplayName", + "osDisplayName", + "paDisplayName", + "piDisplayName", + "faDisplayName", + "plDisplayName", + "psDisplayName", + "ptDisplayName", + "quDisplayName", + "rmDisplayName", + "rnDisplayName", + "roDisplayName", + "ruDisplayName", + "saDisplayName", + "scDisplayName", + "sdDisplayName", + "seDisplayName", + "smDisplayName", + "sgDisplayName", + "srDisplayName", + "gdDisplayName", + "snDisplayName", + "siDisplayName", + "skDisplayName", + "slDisplayName", + "soDisplayName", + "stDisplayName", + "esDisplayName", + "suDisplayName", + "swDisplayName", + "ssDisplayName", + "svDisplayName", + "taDisplayName", + "teDisplayName", + "tgDisplayName", + "thDisplayName", + "tiDisplayName", + "boDisplayName", + "tkDisplayName", + "tlDisplayName", + "tnDisplayName", + "toDisplayName", + "trDisplayName", + "tsDisplayName", + "ttDisplayName", + "twDisplayName", + "tyDisplayName", + "ugDisplayName", + "ukDisplayName", + "urDisplayName", + "uzDisplayName", + "veDisplayName", + "viDisplayName", + "voDisplayName", + "waDisplayName", + "cyDisplayName", + "woDisplayName", + "fyDisplayName", + "xhDisplayName", + "yiDisplayName", + "yoDisplayName", + "zaDisplayName", + "unkDisplayName", + "zuDisplayName", + "hawDisplayName", + "hmnDisplayName", + "multiDisplayName", + "cebDisplayName", + "dzDisplayName", + "iwDisplayName", + "jwDisplayName", + "moDisplayName", + "shDisplayName", + "wwCountryDisplayName", + "afCountryDisplayName", + "axCountryDisplayName", + "alCountryDisplayName", + "dzCountryDisplayName", + "asCountryDisplayName", + "adCountryDisplayName", + "aoCountryDisplayName", + "aiCountryDisplayName", + "agCountryDisplayName", + "arCountryDisplayName", + "amCountryDisplayName", + "awCountryDisplayName", + "acCountryDisplayName", + "auCountryDisplayName", + "atCountryDisplayName", + "azCountryDisplayName", + "bsCountryDisplayName", + "bhCountryDisplayName", + "bdCountryDisplayName", + "bbCountryDisplayName", + "byCountryDisplayName", + "beCountryDisplayName", + "bzCountryDisplayName", + "bjCountryDisplayName", + "bmCountryDisplayName", + "btCountryDisplayName", + "boCountryDisplayName", + "baCountryDisplayName", + "bwCountryDisplayName", + "brCountryDisplayName", + "ioCountryDisplayName", + "vgCountryDisplayName", + "bnCountryDisplayName", + "bgCountryDisplayName", + "bfCountryDisplayName", + "biCountryDisplayName", + "khCountryDisplayName", + "cmCountryDisplayName", + "caCountryDisplayName", + "cvCountryDisplayName", + "bqCountryDisplayName", + "kyCountryDisplayName", + "cfCountryDisplayName", + "tdCountryDisplayName", + "clCountryDisplayName", + "cnCountryDisplayName", + "cxCountryDisplayName", + "ccCountryDisplayName", + "coCountryDisplayName", + "kmCountryDisplayName", + "cdCountryDisplayName", + "cgCountryDisplayName", + "ckCountryDisplayName", + "crCountryDisplayName", + "ciCountryDisplayName", + "hrCountryDisplayName", + "cuCountryDisplayName", + "cwCountryDisplayName", + "cyCountryDisplayName", + "czCountryDisplayName", + "dkCountryDisplayName", + "djCountryDisplayName", + "dmCountryDisplayName", + "doCountryDisplayName", + "tlCountryDisplayName", + "ecCountryDisplayName", + "egCountryDisplayName", + "svCountryDisplayName", + "gqCountryDisplayName", + "erCountryDisplayName", + "eeCountryDisplayName", + "szCountryDisplayName", + "etCountryDisplayName", + "fkCountryDisplayName", + "foCountryDisplayName", + "fjCountryDisplayName", + "fiCountryDisplayName", + "frCountryDisplayName", + "gfCountryDisplayName", + "pfCountryDisplayName", + "gaCountryDisplayName", + "gmCountryDisplayName", + "geCountryDisplayName", + "deCountryDisplayName", + "ghCountryDisplayName", + "giCountryDisplayName", + "grCountryDisplayName", + "glCountryDisplayName", + "gdCountryDisplayName", + "gpCountryDisplayName", + "guCountryDisplayName", + "gtCountryDisplayName", + "ggCountryDisplayName", + "gnCountryDisplayName", + "gwCountryDisplayName", + "gyCountryDisplayName", + "htCountryDisplayName", + "hmCountryDisplayName", + "hnCountryDisplayName", + "hkCountryDisplayName", + "huCountryDisplayName", + "isCountryDisplayName", + "inCountryDisplayName", + "idCountryDisplayName", + "irCountryDisplayName", + "iqCountryDisplayName", + "ieCountryDisplayName", + "imCountryDisplayName", + "ilCountryDisplayName", + "itCountryDisplayName", + "jmCountryDisplayName", + "jpCountryDisplayName", + "jeCountryDisplayName", + "joCountryDisplayName", + "kzCountryDisplayName", + "keCountryDisplayName", + "kiCountryDisplayName", + "xkCountryDisplayName", + "kwCountryDisplayName", + "kgCountryDisplayName", + "laCountryDisplayName", + "lvCountryDisplayName", + "lbCountryDisplayName", + "lsCountryDisplayName", + "lrCountryDisplayName", + "lyCountryDisplayName", + "liCountryDisplayName", + "ltCountryDisplayName", + "luCountryDisplayName", + "moCountryDisplayName", + "mkCountryDisplayName", + "mgCountryDisplayName", + "mwCountryDisplayName", + "myCountryDisplayName", + "mvCountryDisplayName", + "mlCountryDisplayName", + "mtCountryDisplayName", + "mhCountryDisplayName", + "mqCountryDisplayName", + "mrCountryDisplayName", + "muCountryDisplayName", + "ytCountryDisplayName", + "mxCountryDisplayName", + "fmCountryDisplayName", + "mdCountryDisplayName", + "mcCountryDisplayName", + "mnCountryDisplayName", + "meCountryDisplayName", + "msCountryDisplayName", + "maCountryDisplayName", + "mzCountryDisplayName", + "mmCountryDisplayName", + "naCountryDisplayName", + "nrCountryDisplayName", + "npCountryDisplayName", + "nlCountryDisplayName", + "ncCountryDisplayName", + "nzCountryDisplayName", + "niCountryDisplayName", + "neCountryDisplayName", + "ngCountryDisplayName", + "nuCountryDisplayName", + "nfCountryDisplayName", + "kpCountryDisplayName", + "mpCountryDisplayName", + "noCountryDisplayName", + "omCountryDisplayName", + "pkCountryDisplayName", + "pwCountryDisplayName", + "psCountryDisplayName", + "paCountryDisplayName", + "pgCountryDisplayName", + "pyCountryDisplayName", + "peCountryDisplayName", + "phCountryDisplayName", + "plCountryDisplayName", + "ptCountryDisplayName", + "prCountryDisplayName", + "qaCountryDisplayName", + "reCountryDisplayName", + "roCountryDisplayName", + "ruCountryDisplayName", + "rwCountryDisplayName", + "blCountryDisplayName", + "shCountryDisplayName", + "knCountryDisplayName", + "lcCountryDisplayName", + "mfCountryDisplayName", + "pmCountryDisplayName", + "vcCountryDisplayName", + "wsCountryDisplayName", + "smCountryDisplayName", + "stCountryDisplayName", + "saCountryDisplayName", + "snCountryDisplayName", + "rsCountryDisplayName", + "scCountryDisplayName", + "slCountryDisplayName", + "sgCountryDisplayName", + "sxCountryDisplayName", + "skCountryDisplayName", + "siCountryDisplayName", + "sbCountryDisplayName", + "soCountryDisplayName", + "zaCountryDisplayName", + "gsCountryDisplayName", + "krCountryDisplayName", + "ssCountryDisplayName", + "esCountryDisplayName", + "lkCountryDisplayName", + "sdCountryDisplayName", + "srCountryDisplayName", + "sjCountryDisplayName", + "seCountryDisplayName", + "chCountryDisplayName", + "syCountryDisplayName", + "twCountryDisplayName", + "tjCountryDisplayName", + "tzCountryDisplayName", + "thCountryDisplayName", + "tgCountryDisplayName", + "tkCountryDisplayName", + "toCountryDisplayName", + "ttCountryDisplayName", + "tnCountryDisplayName", + "trCountryDisplayName", + "tmCountryDisplayName", + "tcCountryDisplayName", + "tvCountryDisplayName", + "viCountryDisplayName", + "ugCountryDisplayName", + "uaCountryDisplayName", + "aeCountryDisplayName", + "gbCountryDisplayName", + "usCountryDisplayName", + "uyCountryDisplayName", + "uzCountryDisplayName", + "vuCountryDisplayName", + "vaCountryDisplayName", + "veCountryDisplayName", + "vnCountryDisplayName", + "wfCountryDisplayName", + "ehCountryDisplayName", + "yeCountryDisplayName", + "zmCountryDisplayName", + "zwCountryDisplayName", + "pay", + "allPrivateChats", + "unknownPrivateChat", + "copyClassCodeDesc", + "addToClassDesc", + "addToClassOrExchange", + "addToClassOrExchangeDesc", + "invitedToClassOrExchange", + "decline", + "declinedInvitation", + "acceptedInvitation", + "youreInvited", + "studentPermissionsDesc", + "noEligibleSpaces", + "youAddedToSpace", + "youRemovedFromSpace", + "invitedToChat", + "monthlySubscription", + "yearlySubscription", + "defaultSubscription", + "freeTrial", + "grammarAnalytics", + "total", + "noDataFound", + "promoSubscriptionExpirationDesc", + "emptyChatNameWarning", + "emptyClassNameWarning", + "emptyExchangeNameWarning", + "blurMeansTranslateTitle", + "blurMeansTranslateBody", + "someErrorTitle", + "someErrorBody", + "bestCorrectionFeedback", + "distractorFeedback", + "bestAnswerFeedback", + "definitionDefaultPrompt", + "practiceDefaultPrompt", + "correctionDefaultPrompt", + "itStartDefaultPrompt", + "languageLevelWarning", + "lockedChatWarning", + "lockSpace", + "lockChat", + "archiveSpace", + "suggestTo", + "suggestChatDesc", + "suggestExchangeDesc", + "acceptSelection", + "acceptSelectionAnyway", + "makingActivity", + "why", + "definition", + "exampleSentence", + "addToClassTitle", + "reportToTeacher", + "reportMessageTitle", + "reportMessageBody", + "noTeachersFound", + "noAddToSpacePermissions", + "alreadyInSpace", + "yourGlobalUserIdIs", + "noUsersFoundWithQuery", + "searchChatsRooms", + "groupName", + "createGroupAndInviteUsers", + "groupCanBeFoundViaSearch", + "inNoSpaces" + ], + + "fa": [ + "accountInformation", + "addNewFriend", + "alreadyHaveAnAccount", + "classes", + "allCorrect", + "newWayAllGood", + "othersAreBetter", + "holdForInfo", + "greenFeedback", + "yellowFeedback", + "redFeedback", + "customInputFeedbackChoice", + "itInstructionsTitle", + "itInstructionsBody", + "toggleLanguages", + "classWelcomeChat", + "deleteSpace", + "deleteGroup", + "areYouSureDeleteClass", + "areYouSureDeleteGroup", + "cannotBeReversed", + "enterDeletedClassName", + "incorrectClassName", + "oneday", + "oneweek", + "onemonth", + "sixmonth", + "oneyear", + "gaTooltip", + "taTooltip", + "unTooltip", + "interactiveTranslatorSliderHeader", + "interactiveGrammarSliderHeader", + "interactiveTranslatorNotAllowed", + "interactiveTranslatorAllowed", + "interactiveTranslatorRequired", + "interactiveTranslatorNotAllowedDesc", + "interactiveTranslatorAllowedDesc", + "interactiveTranslatorRequiredDesc", + "notYetSet", + "multiLingualClass", + "classAnalytics", + "allClasses", + "myLearning", + "allChatsAndClasses", + "timeOfLastMessage", + "totalMessages", + "waTooltip", + "changeDateRange", + "numberOfStudents", + "classDescription", + "classDescriptionDesc", + "requestToEnroll", + "requestAnExchange", + "findLanguageExchange", + "classAnalyticsDesc", + "addStudents", + "copyClassLink", + "copyClassLinkDesc", + "copyClassCode", + "inviteStudentByUserName", + "classSettings", + "classSettingsDesc", + "selectClassRoomDominantLanguage", + "selectTargetLanguage", + "whatIsYourClassLanguageLevel", + "studentPermissions", + "interactiveTranslator", + "oneToOneChatsWithinClass", + "oneToOneChatsWithinClassDesc", + "createGroupChats", + "createGroupChatsDesc", + "shareVideo", + "shareVideoDesc", + "sharePhotos", + "sharePhotosDesc", + "shareFiles", + "shareFilesDesc", + "shareLocationDesc", + "selectLanguageLevel", + "noIdenticalLanguages", + "iWantALanguagePartnerFrom", + "worldWide", + "noResults", + "searchBy", + "iWantAConversationPartner", + "iWantALanguagePartnerWhoSpeaks", + "iWantALanguagePartnerWhoIsLearning", + "yourBirthdayPlease", + "invalidDob", + "enterYourDob", + "getStarted", + "mustBe13", + "yourBirthdayPleaseShort", + "errorPleaseRefresh", + "joinWithClassCode", + "joinWithClassCodeDesc", + "joinWithClassCodeHint", + "unableToFindClass", + "languageLevelPreA1", + "languageLevelA1", + "languageLevelA2", + "languageLevelB1", + "languageLevelB2", + "languageLevelC1", + "languageLevelC2", + "changeTheNameOfTheClass", + "changeTheNameOfTheChat", + "welcomeToYourNewClass", + "welcomeToClass", + "welcomeToPangea18Plus", + "welcomeToPangeaMinor", + "findALanguagePartner", + "setToPublicSettingsTitle", + "setToPublicSettingsDesc", + "accountSettings", + "unableToFindClassCode", + "askPangeaBot", + "sorryNoResults", + "ignoreInThisText", + "helpMeTranslate", + "needsItShortMessage", + "needsIGCShortMessage", + "needsItMessage", + "needsIgcMessage", + "tokenTranslationTitle", + "spanTranslationDesc", + "spanTranslationTitle", + "l1SpanAndGrammarTitle", + "l1SpanAndGrammarDesc", + "otherTitle", + "otherDesc", + "countryInformation", + "myLanguages", + "targetLanguage", + "sourceLanguage", + "languagesISpeak", + "updateLanguage", + "whatLanguageYouWantToLearn", + "whatIsYourBaseLanguage", + "saveChanges", + "publicProfileTitle", + "publicProfileDesc", + "error502504Title", + "error502504Desc", + "error404Title", + "error404Desc", + "errorDisableIT", + "errorDisableIGC", + "errorDisableLanguageAssistance", + "errorDisableITUserDesc", + "errorDisableIGCUserDesc", + "errorDisableLanguageAssistanceUserDesc", + "errorDisableITClassDesc", + "errorDisableIGCClassDesc", + "errorDisableLanguageAssistanceClassDesc", + "itIsDisabled", + "igcIsDisabled", + "goToLearningSettings", + "error405Title", + "error405Desc", + "loginOrSignup", + "iAgreeToThe", + "termsAndConditions", + "andCertifyIAmAtLeast13YearsOfAge", + "findAClass", + "toggleIT", + "toggleIGC", + "toggleToolSettingsDescription", + "connectedToStaging", + "learningSettings", + "classNameRequired", + "sendVoiceNotes", + "sendVoiceNotesDesc", + "chatTopic", + "chatTopicDesc", + "inviteStudentByUserNameDesc", + "classRoster", + "almostPerfect", + "prettyGood", + "letMeThink", + "clickMessageTitle", + "clickMessageBody", + "understandingMessagesTitle", + "addToClass", + "understandingMessagesBody", + "allDone", + "vocab", + "low", + "medium", + "high", + "unknownProficiency", + "changeView", + "clearAll", + "generateVocabulary", + "generatePrompts", + "subscribe", + "getAccess", + "subscriptionDesc", + "subscriptionManagement", + "currentSubscription", + "changeSubscription", + "cancelSubscription", + "selectYourPlan", + "subsciptionPlatformTooltip", + "subscriptionManagementUnavailable", + "paymentMethod", + "paymentHistory", + "emptyChatDownloadWarning", + "appUpdateAvailable", + "update", + "updateDesc", + "maybeLater", + "mainMenu", + "toggleImmersionMode", + "toggleImmersionModeDesc", + "itToggleDescription", + "igcToggleDescription", + "sendOnEnterDescription", + "alreadyInClass", + "pleaseLoginFirst", + "originalMessage", + "sentMessage", + "useType", + "notAvailable", + "taAndGaTooltip", + "definitionsToolName", + "messageTranslationsToolName", + "definitionsToolDescription", + "translationsToolDescrption", + "welcomeBack", + "classExchanges", + "createNewClass", + "newExchange", + "kickAllStudents", + "kickAllStudentsConfirmation", + "inviteAllStudents", + "inviteAllStudentsConfirmation", + "inviteStudentsFromOtherClasses", + "inviteUsersFromPangea", + "allExchanges", + "redeemPromoCode", + "enterPromoCode", + "downloadTxtFile", + "downloadCSVFile", + "promotionalSubscriptionDesc", + "originalSubscriptionPlatform", + "oneWeekTrial", + "creatingSpacePleaseWait", + "downloadXLSXFile", + "abDisplayName", + "aaDisplayName", + "afDisplayName", + "akDisplayName", + "sqDisplayName", + "amDisplayName", + "arDisplayName", + "anDisplayName", + "hyDisplayName", + "asDisplayName", + "avDisplayName", + "aeDisplayName", + "ayDisplayName", + "azDisplayName", + "bmDisplayName", + "baDisplayName", + "euDisplayName", + "beDisplayName", + "bnDisplayName", + "bhDisplayName", + "biDisplayName", + "bsDisplayName", + "brDisplayName", + "bgDisplayName", + "myDisplayName", + "caDisplayName", + "chDisplayName", + "ceDisplayName", + "nyDisplayName", + "zhDisplayName", + "cvDisplayName", + "kwDisplayName", + "coDisplayName", + "crDisplayName", + "hrDisplayName", + "csDisplayName", + "daDisplayName", + "dvDisplayName", + "nlDisplayName", + "enDisplayName", + "eoDisplayName", + "etDisplayName", + "eeDisplayName", + "foDisplayName", + "fjDisplayName", + "fiDisplayName", + "frDisplayName", + "ffDisplayName", + "glDisplayName", + "kaDisplayName", + "deDisplayName", + "elDisplayName", + "gnDisplayName", + "guDisplayName", + "htDisplayName", + "haDisplayName", + "heDisplayName", + "hzDisplayName", + "hiDisplayName", + "hoDisplayName", + "huDisplayName", + "iaDisplayName", + "idDisplayName", + "ieDisplayName", + "gaDisplayName", + "igDisplayName", + "ikDisplayName", + "ioDisplayName", + "isDisplayName", + "itDisplayName", + "iuDisplayName", + "jaDisplayName", + "jvDisplayName", + "klDisplayName", + "knDisplayName", + "krDisplayName", + "ksDisplayName", + "kkDisplayName", + "kmDisplayName", + "kiDisplayName", + "rwDisplayName", + "kyDisplayName", + "kvDisplayName", + "kgDisplayName", + "koDisplayName", + "kuDisplayName", + "kjDisplayName", + "laDisplayName", + "lbDisplayName", + "lgDisplayName", + "liDisplayName", + "lnDisplayName", + "loDisplayName", + "ltDisplayName", + "luDisplayName", + "lvDisplayName", + "gvDisplayName", + "mkDisplayName", + "mgDisplayName", + "msDisplayName", + "mlDisplayName", + "mtDisplayName", + "miDisplayName", + "mrDisplayName", + "mhDisplayName", + "mnDisplayName", + "naDisplayName", + "nvDisplayName", + "nbDisplayName", + "ndDisplayName", + "neDisplayName", + "ngDisplayName", + "nnDisplayName", + "noDisplayName", + "iiDisplayName", + "nrDisplayName", + "ocDisplayName", + "ojDisplayName", + "cuDisplayName", + "omDisplayName", + "orDisplayName", + "osDisplayName", + "paDisplayName", + "piDisplayName", + "faDisplayName", + "plDisplayName", + "psDisplayName", + "ptDisplayName", + "quDisplayName", + "rmDisplayName", + "rnDisplayName", + "roDisplayName", + "ruDisplayName", + "saDisplayName", + "scDisplayName", + "sdDisplayName", + "seDisplayName", + "smDisplayName", + "sgDisplayName", + "srDisplayName", + "gdDisplayName", + "snDisplayName", + "siDisplayName", + "skDisplayName", + "slDisplayName", + "soDisplayName", + "stDisplayName", + "esDisplayName", + "suDisplayName", + "swDisplayName", + "ssDisplayName", + "svDisplayName", + "taDisplayName", + "teDisplayName", + "tgDisplayName", + "thDisplayName", + "tiDisplayName", + "boDisplayName", + "tkDisplayName", + "tlDisplayName", + "tnDisplayName", + "toDisplayName", + "trDisplayName", + "tsDisplayName", + "ttDisplayName", + "twDisplayName", + "tyDisplayName", + "ugDisplayName", + "ukDisplayName", + "urDisplayName", + "uzDisplayName", + "veDisplayName", + "viDisplayName", + "voDisplayName", + "waDisplayName", + "cyDisplayName", + "woDisplayName", + "fyDisplayName", + "xhDisplayName", + "yiDisplayName", + "yoDisplayName", + "zaDisplayName", + "unkDisplayName", + "zuDisplayName", + "hawDisplayName", + "hmnDisplayName", + "multiDisplayName", + "cebDisplayName", + "dzDisplayName", + "iwDisplayName", + "jwDisplayName", + "moDisplayName", + "shDisplayName", + "wwCountryDisplayName", + "afCountryDisplayName", + "axCountryDisplayName", + "alCountryDisplayName", + "dzCountryDisplayName", + "asCountryDisplayName", + "adCountryDisplayName", + "aoCountryDisplayName", + "aiCountryDisplayName", + "agCountryDisplayName", + "arCountryDisplayName", + "amCountryDisplayName", + "awCountryDisplayName", + "acCountryDisplayName", + "auCountryDisplayName", + "atCountryDisplayName", + "azCountryDisplayName", + "bsCountryDisplayName", + "bhCountryDisplayName", + "bdCountryDisplayName", + "bbCountryDisplayName", + "byCountryDisplayName", + "beCountryDisplayName", + "bzCountryDisplayName", + "bjCountryDisplayName", + "bmCountryDisplayName", + "btCountryDisplayName", + "boCountryDisplayName", + "baCountryDisplayName", + "bwCountryDisplayName", + "brCountryDisplayName", + "ioCountryDisplayName", + "vgCountryDisplayName", + "bnCountryDisplayName", + "bgCountryDisplayName", + "bfCountryDisplayName", + "biCountryDisplayName", + "khCountryDisplayName", + "cmCountryDisplayName", + "caCountryDisplayName", + "cvCountryDisplayName", + "bqCountryDisplayName", + "kyCountryDisplayName", + "cfCountryDisplayName", + "tdCountryDisplayName", + "clCountryDisplayName", + "cnCountryDisplayName", + "cxCountryDisplayName", + "ccCountryDisplayName", + "coCountryDisplayName", + "kmCountryDisplayName", + "cdCountryDisplayName", + "cgCountryDisplayName", + "ckCountryDisplayName", + "crCountryDisplayName", + "ciCountryDisplayName", + "hrCountryDisplayName", + "cuCountryDisplayName", + "cwCountryDisplayName", + "cyCountryDisplayName", + "czCountryDisplayName", + "dkCountryDisplayName", + "djCountryDisplayName", + "dmCountryDisplayName", + "doCountryDisplayName", + "tlCountryDisplayName", + "ecCountryDisplayName", + "egCountryDisplayName", + "svCountryDisplayName", + "gqCountryDisplayName", + "erCountryDisplayName", + "eeCountryDisplayName", + "szCountryDisplayName", + "etCountryDisplayName", + "fkCountryDisplayName", + "foCountryDisplayName", + "fjCountryDisplayName", + "fiCountryDisplayName", + "frCountryDisplayName", + "gfCountryDisplayName", + "pfCountryDisplayName", + "gaCountryDisplayName", + "gmCountryDisplayName", + "geCountryDisplayName", + "deCountryDisplayName", + "ghCountryDisplayName", + "giCountryDisplayName", + "grCountryDisplayName", + "glCountryDisplayName", + "gdCountryDisplayName", + "gpCountryDisplayName", + "guCountryDisplayName", + "gtCountryDisplayName", + "ggCountryDisplayName", + "gnCountryDisplayName", + "gwCountryDisplayName", + "gyCountryDisplayName", + "htCountryDisplayName", + "hmCountryDisplayName", + "hnCountryDisplayName", + "hkCountryDisplayName", + "huCountryDisplayName", + "isCountryDisplayName", + "inCountryDisplayName", + "idCountryDisplayName", + "irCountryDisplayName", + "iqCountryDisplayName", + "ieCountryDisplayName", + "imCountryDisplayName", + "ilCountryDisplayName", + "itCountryDisplayName", + "jmCountryDisplayName", + "jpCountryDisplayName", + "jeCountryDisplayName", + "joCountryDisplayName", + "kzCountryDisplayName", + "keCountryDisplayName", + "kiCountryDisplayName", + "xkCountryDisplayName", + "kwCountryDisplayName", + "kgCountryDisplayName", + "laCountryDisplayName", + "lvCountryDisplayName", + "lbCountryDisplayName", + "lsCountryDisplayName", + "lrCountryDisplayName", + "lyCountryDisplayName", + "liCountryDisplayName", + "ltCountryDisplayName", + "luCountryDisplayName", + "moCountryDisplayName", + "mkCountryDisplayName", + "mgCountryDisplayName", + "mwCountryDisplayName", + "myCountryDisplayName", + "mvCountryDisplayName", + "mlCountryDisplayName", + "mtCountryDisplayName", + "mhCountryDisplayName", + "mqCountryDisplayName", + "mrCountryDisplayName", + "muCountryDisplayName", + "ytCountryDisplayName", + "mxCountryDisplayName", + "fmCountryDisplayName", + "mdCountryDisplayName", + "mcCountryDisplayName", + "mnCountryDisplayName", + "meCountryDisplayName", + "msCountryDisplayName", + "maCountryDisplayName", + "mzCountryDisplayName", + "mmCountryDisplayName", + "naCountryDisplayName", + "nrCountryDisplayName", + "npCountryDisplayName", + "nlCountryDisplayName", + "ncCountryDisplayName", + "nzCountryDisplayName", + "niCountryDisplayName", + "neCountryDisplayName", + "ngCountryDisplayName", + "nuCountryDisplayName", + "nfCountryDisplayName", + "kpCountryDisplayName", + "mpCountryDisplayName", + "noCountryDisplayName", + "omCountryDisplayName", + "pkCountryDisplayName", + "pwCountryDisplayName", + "psCountryDisplayName", + "paCountryDisplayName", + "pgCountryDisplayName", + "pyCountryDisplayName", + "peCountryDisplayName", + "phCountryDisplayName", + "plCountryDisplayName", + "ptCountryDisplayName", + "prCountryDisplayName", + "qaCountryDisplayName", + "reCountryDisplayName", + "roCountryDisplayName", + "ruCountryDisplayName", + "rwCountryDisplayName", + "blCountryDisplayName", + "shCountryDisplayName", + "knCountryDisplayName", + "lcCountryDisplayName", + "mfCountryDisplayName", + "pmCountryDisplayName", + "vcCountryDisplayName", + "wsCountryDisplayName", + "smCountryDisplayName", + "stCountryDisplayName", + "saCountryDisplayName", + "snCountryDisplayName", + "rsCountryDisplayName", + "scCountryDisplayName", + "slCountryDisplayName", + "sgCountryDisplayName", + "sxCountryDisplayName", + "skCountryDisplayName", + "siCountryDisplayName", + "sbCountryDisplayName", + "soCountryDisplayName", + "zaCountryDisplayName", + "gsCountryDisplayName", + "krCountryDisplayName", + "ssCountryDisplayName", + "esCountryDisplayName", + "lkCountryDisplayName", + "sdCountryDisplayName", + "srCountryDisplayName", + "sjCountryDisplayName", + "seCountryDisplayName", + "chCountryDisplayName", + "syCountryDisplayName", + "twCountryDisplayName", + "tjCountryDisplayName", + "tzCountryDisplayName", + "thCountryDisplayName", + "tgCountryDisplayName", + "tkCountryDisplayName", + "toCountryDisplayName", + "ttCountryDisplayName", + "tnCountryDisplayName", + "trCountryDisplayName", + "tmCountryDisplayName", + "tcCountryDisplayName", + "tvCountryDisplayName", + "viCountryDisplayName", + "ugCountryDisplayName", + "uaCountryDisplayName", + "aeCountryDisplayName", + "gbCountryDisplayName", + "usCountryDisplayName", + "uyCountryDisplayName", + "uzCountryDisplayName", + "vuCountryDisplayName", + "vaCountryDisplayName", + "veCountryDisplayName", + "vnCountryDisplayName", + "wfCountryDisplayName", + "ehCountryDisplayName", + "yeCountryDisplayName", + "zmCountryDisplayName", + "zwCountryDisplayName", + "pay", + "allPrivateChats", + "unknownPrivateChat", + "copyClassCodeDesc", + "addToClassDesc", + "addToClassOrExchange", + "addToClassOrExchangeDesc", + "invitedToClassOrExchange", + "decline", + "declinedInvitation", + "acceptedInvitation", + "youreInvited", + "studentPermissionsDesc", + "noEligibleSpaces", + "youAddedToSpace", + "youRemovedFromSpace", + "invitedToChat", + "monthlySubscription", + "yearlySubscription", + "defaultSubscription", + "freeTrial", + "grammarAnalytics", + "total", + "noDataFound", + "promoSubscriptionExpirationDesc", + "emptyChatNameWarning", + "emptyClassNameWarning", + "emptyExchangeNameWarning", + "blurMeansTranslateTitle", + "blurMeansTranslateBody", + "someErrorTitle", + "someErrorBody", + "bestCorrectionFeedback", + "distractorFeedback", + "bestAnswerFeedback", + "definitionDefaultPrompt", + "practiceDefaultPrompt", + "correctionDefaultPrompt", + "itStartDefaultPrompt", + "languageLevelWarning", + "lockedChatWarning", + "lockSpace", + "lockChat", + "archiveSpace", + "suggestTo", + "suggestChatDesc", + "suggestExchangeDesc", + "acceptSelection", + "acceptSelectionAnyway", + "makingActivity", + "why", + "definition", + "exampleSentence", + "addToClassTitle", + "reportToTeacher", + "reportMessageTitle", + "reportMessageBody", + "noTeachersFound", + "noAddToSpacePermissions", + "alreadyInSpace", + "yourGlobalUserIdIs", + "noUsersFoundWithQuery", + "searchChatsRooms", + "groupName", + "createGroupAndInviteUsers", + "groupCanBeFoundViaSearch", + "inNoSpaces" + ], + + "fi": [ + "accountInformation", + "addNewFriend", + "alreadyHaveAnAccount", + "classes", + "allCorrect", + "newWayAllGood", + "othersAreBetter", + "holdForInfo", + "greenFeedback", + "yellowFeedback", + "redFeedback", + "customInputFeedbackChoice", + "itInstructionsTitle", + "itInstructionsBody", + "toggleLanguages", + "classWelcomeChat", + "deleteSpace", + "deleteGroup", + "areYouSureDeleteClass", + "areYouSureDeleteGroup", + "cannotBeReversed", + "enterDeletedClassName", + "incorrectClassName", + "oneday", + "oneweek", + "onemonth", + "sixmonth", + "oneyear", + "gaTooltip", + "taTooltip", + "unTooltip", + "interactiveTranslatorSliderHeader", + "interactiveGrammarSliderHeader", + "interactiveTranslatorNotAllowed", + "interactiveTranslatorAllowed", + "interactiveTranslatorRequired", + "interactiveTranslatorNotAllowedDesc", + "interactiveTranslatorAllowedDesc", + "interactiveTranslatorRequiredDesc", + "notYetSet", + "multiLingualClass", + "classAnalytics", + "allClasses", + "myLearning", + "allChatsAndClasses", + "timeOfLastMessage", + "totalMessages", + "waTooltip", + "changeDateRange", + "numberOfStudents", + "classDescription", + "classDescriptionDesc", + "requestToEnroll", + "requestAnExchange", + "findLanguageExchange", + "classAnalyticsDesc", + "addStudents", + "copyClassLink", + "copyClassLinkDesc", + "copyClassCode", + "inviteStudentByUserName", + "classSettings", + "classSettingsDesc", + "selectClassRoomDominantLanguage", + "selectTargetLanguage", + "whatIsYourClassLanguageLevel", + "studentPermissions", + "interactiveTranslator", + "oneToOneChatsWithinClass", + "oneToOneChatsWithinClassDesc", + "createGroupChats", + "createGroupChatsDesc", + "shareVideo", + "shareVideoDesc", + "sharePhotos", + "sharePhotosDesc", + "shareFiles", + "shareFilesDesc", + "shareLocationDesc", + "selectLanguageLevel", + "noIdenticalLanguages", + "iWantALanguagePartnerFrom", + "worldWide", + "noResults", + "searchBy", + "iWantAConversationPartner", + "iWantALanguagePartnerWhoSpeaks", + "iWantALanguagePartnerWhoIsLearning", + "yourBirthdayPlease", + "invalidDob", + "enterYourDob", + "getStarted", + "mustBe13", + "yourBirthdayPleaseShort", + "errorPleaseRefresh", + "joinWithClassCode", + "joinWithClassCodeDesc", + "joinWithClassCodeHint", + "unableToFindClass", + "languageLevelPreA1", + "languageLevelA1", + "languageLevelA2", + "languageLevelB1", + "languageLevelB2", + "languageLevelC1", + "languageLevelC2", + "changeTheNameOfTheClass", + "changeTheNameOfTheChat", + "welcomeToYourNewClass", + "welcomeToClass", + "welcomeToPangea18Plus", + "welcomeToPangeaMinor", + "findALanguagePartner", + "setToPublicSettingsTitle", + "setToPublicSettingsDesc", + "accountSettings", + "unableToFindClassCode", + "askPangeaBot", + "sorryNoResults", + "ignoreInThisText", + "helpMeTranslate", + "needsItShortMessage", + "needsIGCShortMessage", + "needsItMessage", + "needsIgcMessage", + "tokenTranslationTitle", + "spanTranslationDesc", + "spanTranslationTitle", + "l1SpanAndGrammarTitle", + "l1SpanAndGrammarDesc", + "otherTitle", + "otherDesc", + "countryInformation", + "myLanguages", + "targetLanguage", + "sourceLanguage", + "languagesISpeak", + "updateLanguage", + "whatLanguageYouWantToLearn", + "whatIsYourBaseLanguage", + "saveChanges", + "publicProfileTitle", + "publicProfileDesc", + "error502504Title", + "error502504Desc", + "error404Title", + "error404Desc", + "errorDisableIT", + "errorDisableIGC", + "errorDisableLanguageAssistance", + "errorDisableITUserDesc", + "errorDisableIGCUserDesc", + "errorDisableLanguageAssistanceUserDesc", + "errorDisableITClassDesc", + "errorDisableIGCClassDesc", + "errorDisableLanguageAssistanceClassDesc", + "itIsDisabled", + "igcIsDisabled", + "goToLearningSettings", + "error405Title", + "error405Desc", + "loginOrSignup", + "iAgreeToThe", + "termsAndConditions", + "andCertifyIAmAtLeast13YearsOfAge", + "findAClass", + "toggleIT", + "toggleIGC", + "toggleToolSettingsDescription", + "connectedToStaging", + "learningSettings", + "classNameRequired", + "sendVoiceNotes", + "sendVoiceNotesDesc", + "chatTopic", + "chatTopicDesc", + "inviteStudentByUserNameDesc", + "classRoster", + "almostPerfect", + "prettyGood", + "letMeThink", + "clickMessageTitle", + "clickMessageBody", + "understandingMessagesTitle", + "addToClass", + "understandingMessagesBody", + "allDone", + "vocab", + "low", + "medium", + "high", + "unknownProficiency", + "changeView", + "clearAll", + "generateVocabulary", + "generatePrompts", + "subscribe", + "getAccess", + "subscriptionDesc", + "subscriptionManagement", + "currentSubscription", + "changeSubscription", + "cancelSubscription", + "selectYourPlan", + "subsciptionPlatformTooltip", + "subscriptionManagementUnavailable", + "paymentMethod", + "paymentHistory", + "emptyChatDownloadWarning", + "appUpdateAvailable", + "update", + "updateDesc", + "maybeLater", + "mainMenu", + "toggleImmersionMode", + "toggleImmersionModeDesc", + "itToggleDescription", + "igcToggleDescription", + "sendOnEnterDescription", + "alreadyInClass", + "pleaseLoginFirst", + "originalMessage", + "sentMessage", + "useType", + "notAvailable", + "taAndGaTooltip", + "definitionsToolName", + "messageTranslationsToolName", + "definitionsToolDescription", + "translationsToolDescrption", + "welcomeBack", + "classExchanges", + "createNewClass", + "newExchange", + "kickAllStudents", + "kickAllStudentsConfirmation", + "inviteAllStudents", + "inviteAllStudentsConfirmation", + "inviteStudentsFromOtherClasses", + "inviteUsersFromPangea", + "allExchanges", + "redeemPromoCode", + "enterPromoCode", + "downloadTxtFile", + "downloadCSVFile", + "promotionalSubscriptionDesc", + "originalSubscriptionPlatform", + "oneWeekTrial", + "creatingSpacePleaseWait", + "downloadXLSXFile", + "abDisplayName", + "aaDisplayName", + "afDisplayName", + "akDisplayName", + "sqDisplayName", + "amDisplayName", + "arDisplayName", + "anDisplayName", + "hyDisplayName", + "asDisplayName", + "avDisplayName", + "aeDisplayName", + "ayDisplayName", + "azDisplayName", + "bmDisplayName", + "baDisplayName", + "euDisplayName", + "beDisplayName", + "bnDisplayName", + "bhDisplayName", + "biDisplayName", + "bsDisplayName", + "brDisplayName", + "bgDisplayName", + "myDisplayName", + "caDisplayName", + "chDisplayName", + "ceDisplayName", + "nyDisplayName", + "zhDisplayName", + "cvDisplayName", + "kwDisplayName", + "coDisplayName", + "crDisplayName", + "hrDisplayName", + "csDisplayName", + "daDisplayName", + "dvDisplayName", + "nlDisplayName", + "enDisplayName", + "eoDisplayName", + "etDisplayName", + "eeDisplayName", + "foDisplayName", + "fjDisplayName", + "fiDisplayName", + "frDisplayName", + "ffDisplayName", + "glDisplayName", + "kaDisplayName", + "deDisplayName", + "elDisplayName", + "gnDisplayName", + "guDisplayName", + "htDisplayName", + "haDisplayName", + "heDisplayName", + "hzDisplayName", + "hiDisplayName", + "hoDisplayName", + "huDisplayName", + "iaDisplayName", + "idDisplayName", + "ieDisplayName", + "gaDisplayName", + "igDisplayName", + "ikDisplayName", + "ioDisplayName", + "isDisplayName", + "itDisplayName", + "iuDisplayName", + "jaDisplayName", + "jvDisplayName", + "klDisplayName", + "knDisplayName", + "krDisplayName", + "ksDisplayName", + "kkDisplayName", + "kmDisplayName", + "kiDisplayName", + "rwDisplayName", + "kyDisplayName", + "kvDisplayName", + "kgDisplayName", + "koDisplayName", + "kuDisplayName", + "kjDisplayName", + "laDisplayName", + "lbDisplayName", + "lgDisplayName", + "liDisplayName", + "lnDisplayName", + "loDisplayName", + "ltDisplayName", + "luDisplayName", + "lvDisplayName", + "gvDisplayName", + "mkDisplayName", + "mgDisplayName", + "msDisplayName", + "mlDisplayName", + "mtDisplayName", + "miDisplayName", + "mrDisplayName", + "mhDisplayName", + "mnDisplayName", + "naDisplayName", + "nvDisplayName", + "nbDisplayName", + "ndDisplayName", + "neDisplayName", + "ngDisplayName", + "nnDisplayName", + "noDisplayName", + "iiDisplayName", + "nrDisplayName", + "ocDisplayName", + "ojDisplayName", + "cuDisplayName", + "omDisplayName", + "orDisplayName", + "osDisplayName", + "paDisplayName", + "piDisplayName", + "faDisplayName", + "plDisplayName", + "psDisplayName", + "ptDisplayName", + "quDisplayName", + "rmDisplayName", + "rnDisplayName", + "roDisplayName", + "ruDisplayName", + "saDisplayName", + "scDisplayName", + "sdDisplayName", + "seDisplayName", + "smDisplayName", + "sgDisplayName", + "srDisplayName", + "gdDisplayName", + "snDisplayName", + "siDisplayName", + "skDisplayName", + "slDisplayName", + "soDisplayName", + "stDisplayName", + "esDisplayName", + "suDisplayName", + "swDisplayName", + "ssDisplayName", + "svDisplayName", + "taDisplayName", + "teDisplayName", + "tgDisplayName", + "thDisplayName", + "tiDisplayName", + "boDisplayName", + "tkDisplayName", + "tlDisplayName", + "tnDisplayName", + "toDisplayName", + "trDisplayName", + "tsDisplayName", + "ttDisplayName", + "twDisplayName", + "tyDisplayName", + "ugDisplayName", + "ukDisplayName", + "urDisplayName", + "uzDisplayName", + "veDisplayName", + "viDisplayName", + "voDisplayName", + "waDisplayName", + "cyDisplayName", + "woDisplayName", + "fyDisplayName", + "xhDisplayName", + "yiDisplayName", + "yoDisplayName", + "zaDisplayName", + "unkDisplayName", + "zuDisplayName", + "hawDisplayName", + "hmnDisplayName", + "multiDisplayName", + "cebDisplayName", + "dzDisplayName", + "iwDisplayName", + "jwDisplayName", + "moDisplayName", + "shDisplayName", + "wwCountryDisplayName", + "afCountryDisplayName", + "axCountryDisplayName", + "alCountryDisplayName", + "dzCountryDisplayName", + "asCountryDisplayName", + "adCountryDisplayName", + "aoCountryDisplayName", + "aiCountryDisplayName", + "agCountryDisplayName", + "arCountryDisplayName", + "amCountryDisplayName", + "awCountryDisplayName", + "acCountryDisplayName", + "auCountryDisplayName", + "atCountryDisplayName", + "azCountryDisplayName", + "bsCountryDisplayName", + "bhCountryDisplayName", + "bdCountryDisplayName", + "bbCountryDisplayName", + "byCountryDisplayName", + "beCountryDisplayName", + "bzCountryDisplayName", + "bjCountryDisplayName", + "bmCountryDisplayName", + "btCountryDisplayName", + "boCountryDisplayName", + "baCountryDisplayName", + "bwCountryDisplayName", + "brCountryDisplayName", + "ioCountryDisplayName", + "vgCountryDisplayName", + "bnCountryDisplayName", + "bgCountryDisplayName", + "bfCountryDisplayName", + "biCountryDisplayName", + "khCountryDisplayName", + "cmCountryDisplayName", + "caCountryDisplayName", + "cvCountryDisplayName", + "bqCountryDisplayName", + "kyCountryDisplayName", + "cfCountryDisplayName", + "tdCountryDisplayName", + "clCountryDisplayName", + "cnCountryDisplayName", + "cxCountryDisplayName", + "ccCountryDisplayName", + "coCountryDisplayName", + "kmCountryDisplayName", + "cdCountryDisplayName", + "cgCountryDisplayName", + "ckCountryDisplayName", + "crCountryDisplayName", + "ciCountryDisplayName", + "hrCountryDisplayName", + "cuCountryDisplayName", + "cwCountryDisplayName", + "cyCountryDisplayName", + "czCountryDisplayName", + "dkCountryDisplayName", + "djCountryDisplayName", + "dmCountryDisplayName", + "doCountryDisplayName", + "tlCountryDisplayName", + "ecCountryDisplayName", + "egCountryDisplayName", + "svCountryDisplayName", + "gqCountryDisplayName", + "erCountryDisplayName", + "eeCountryDisplayName", + "szCountryDisplayName", + "etCountryDisplayName", + "fkCountryDisplayName", + "foCountryDisplayName", + "fjCountryDisplayName", + "fiCountryDisplayName", + "frCountryDisplayName", + "gfCountryDisplayName", + "pfCountryDisplayName", + "gaCountryDisplayName", + "gmCountryDisplayName", + "geCountryDisplayName", + "deCountryDisplayName", + "ghCountryDisplayName", + "giCountryDisplayName", + "grCountryDisplayName", + "glCountryDisplayName", + "gdCountryDisplayName", + "gpCountryDisplayName", + "guCountryDisplayName", + "gtCountryDisplayName", + "ggCountryDisplayName", + "gnCountryDisplayName", + "gwCountryDisplayName", + "gyCountryDisplayName", + "htCountryDisplayName", + "hmCountryDisplayName", + "hnCountryDisplayName", + "hkCountryDisplayName", + "huCountryDisplayName", + "isCountryDisplayName", + "inCountryDisplayName", + "idCountryDisplayName", + "irCountryDisplayName", + "iqCountryDisplayName", + "ieCountryDisplayName", + "imCountryDisplayName", + "ilCountryDisplayName", + "itCountryDisplayName", + "jmCountryDisplayName", + "jpCountryDisplayName", + "jeCountryDisplayName", + "joCountryDisplayName", + "kzCountryDisplayName", + "keCountryDisplayName", + "kiCountryDisplayName", + "xkCountryDisplayName", + "kwCountryDisplayName", + "kgCountryDisplayName", + "laCountryDisplayName", + "lvCountryDisplayName", + "lbCountryDisplayName", + "lsCountryDisplayName", + "lrCountryDisplayName", + "lyCountryDisplayName", + "liCountryDisplayName", + "ltCountryDisplayName", + "luCountryDisplayName", + "moCountryDisplayName", + "mkCountryDisplayName", + "mgCountryDisplayName", + "mwCountryDisplayName", + "myCountryDisplayName", + "mvCountryDisplayName", + "mlCountryDisplayName", + "mtCountryDisplayName", + "mhCountryDisplayName", + "mqCountryDisplayName", + "mrCountryDisplayName", + "muCountryDisplayName", + "ytCountryDisplayName", + "mxCountryDisplayName", + "fmCountryDisplayName", + "mdCountryDisplayName", + "mcCountryDisplayName", + "mnCountryDisplayName", + "meCountryDisplayName", + "msCountryDisplayName", + "maCountryDisplayName", + "mzCountryDisplayName", + "mmCountryDisplayName", + "naCountryDisplayName", + "nrCountryDisplayName", + "npCountryDisplayName", + "nlCountryDisplayName", + "ncCountryDisplayName", + "nzCountryDisplayName", + "niCountryDisplayName", + "neCountryDisplayName", + "ngCountryDisplayName", + "nuCountryDisplayName", + "nfCountryDisplayName", + "kpCountryDisplayName", + "mpCountryDisplayName", + "noCountryDisplayName", + "omCountryDisplayName", + "pkCountryDisplayName", + "pwCountryDisplayName", + "psCountryDisplayName", + "paCountryDisplayName", + "pgCountryDisplayName", + "pyCountryDisplayName", + "peCountryDisplayName", + "phCountryDisplayName", + "plCountryDisplayName", + "ptCountryDisplayName", + "prCountryDisplayName", + "qaCountryDisplayName", + "reCountryDisplayName", + "roCountryDisplayName", + "ruCountryDisplayName", + "rwCountryDisplayName", + "blCountryDisplayName", + "shCountryDisplayName", + "knCountryDisplayName", + "lcCountryDisplayName", + "mfCountryDisplayName", + "pmCountryDisplayName", + "vcCountryDisplayName", + "wsCountryDisplayName", + "smCountryDisplayName", + "stCountryDisplayName", + "saCountryDisplayName", + "snCountryDisplayName", + "rsCountryDisplayName", + "scCountryDisplayName", + "slCountryDisplayName", + "sgCountryDisplayName", + "sxCountryDisplayName", + "skCountryDisplayName", + "siCountryDisplayName", + "sbCountryDisplayName", + "soCountryDisplayName", + "zaCountryDisplayName", + "gsCountryDisplayName", + "krCountryDisplayName", + "ssCountryDisplayName", + "esCountryDisplayName", + "lkCountryDisplayName", + "sdCountryDisplayName", + "srCountryDisplayName", + "sjCountryDisplayName", + "seCountryDisplayName", + "chCountryDisplayName", + "syCountryDisplayName", + "twCountryDisplayName", + "tjCountryDisplayName", + "tzCountryDisplayName", + "thCountryDisplayName", + "tgCountryDisplayName", + "tkCountryDisplayName", + "toCountryDisplayName", + "ttCountryDisplayName", + "tnCountryDisplayName", + "trCountryDisplayName", + "tmCountryDisplayName", + "tcCountryDisplayName", + "tvCountryDisplayName", + "viCountryDisplayName", + "ugCountryDisplayName", + "uaCountryDisplayName", + "aeCountryDisplayName", + "gbCountryDisplayName", + "usCountryDisplayName", + "uyCountryDisplayName", + "uzCountryDisplayName", + "vuCountryDisplayName", + "vaCountryDisplayName", + "veCountryDisplayName", + "vnCountryDisplayName", + "wfCountryDisplayName", + "ehCountryDisplayName", + "yeCountryDisplayName", + "zmCountryDisplayName", + "zwCountryDisplayName", + "pay", + "allPrivateChats", + "unknownPrivateChat", + "copyClassCodeDesc", + "addToClassDesc", + "addToClassOrExchange", + "addToClassOrExchangeDesc", + "invitedToClassOrExchange", + "decline", + "declinedInvitation", + "acceptedInvitation", + "youreInvited", + "studentPermissionsDesc", + "noEligibleSpaces", + "youAddedToSpace", + "youRemovedFromSpace", + "invitedToChat", + "monthlySubscription", + "yearlySubscription", + "defaultSubscription", + "freeTrial", + "grammarAnalytics", + "total", + "noDataFound", + "promoSubscriptionExpirationDesc", + "emptyChatNameWarning", + "emptyClassNameWarning", + "emptyExchangeNameWarning", + "blurMeansTranslateTitle", + "blurMeansTranslateBody", + "someErrorTitle", + "someErrorBody", + "bestCorrectionFeedback", + "distractorFeedback", + "bestAnswerFeedback", + "definitionDefaultPrompt", + "practiceDefaultPrompt", + "correctionDefaultPrompt", + "itStartDefaultPrompt", + "languageLevelWarning", + "lockedChatWarning", + "lockSpace", + "lockChat", + "archiveSpace", + "suggestTo", + "suggestChatDesc", + "suggestExchangeDesc", + "acceptSelection", + "acceptSelectionAnyway", + "makingActivity", + "why", + "definition", + "exampleSentence", + "addToClassTitle", + "reportToTeacher", + "reportMessageTitle", + "reportMessageBody", + "noTeachersFound", + "noAddToSpacePermissions", + "alreadyInSpace", + "yourGlobalUserIdIs", + "noUsersFoundWithQuery", + "searchChatsRooms", + "groupName", + "createGroupAndInviteUsers", + "groupCanBeFoundViaSearch", + "inNoSpaces" + ], + + "fr": [ + "accountInformation", + "addNewFriend", + "alreadyHaveAnAccount", + "classes", + "allCorrect", + "newWayAllGood", + "othersAreBetter", + "holdForInfo", + "greenFeedback", + "yellowFeedback", + "redFeedback", + "customInputFeedbackChoice", + "itInstructionsTitle", + "itInstructionsBody", + "toggleLanguages", + "classWelcomeChat", + "deleteSpace", + "deleteGroup", + "areYouSureDeleteClass", + "areYouSureDeleteGroup", + "cannotBeReversed", + "enterDeletedClassName", + "incorrectClassName", + "oneday", + "oneweek", + "onemonth", + "sixmonth", + "oneyear", + "gaTooltip", + "taTooltip", + "unTooltip", + "interactiveTranslatorSliderHeader", + "interactiveGrammarSliderHeader", + "interactiveTranslatorNotAllowed", + "interactiveTranslatorAllowed", + "interactiveTranslatorRequired", + "interactiveTranslatorNotAllowedDesc", + "interactiveTranslatorAllowedDesc", + "interactiveTranslatorRequiredDesc", + "notYetSet", + "multiLingualClass", + "classAnalytics", + "allClasses", + "myLearning", + "allChatsAndClasses", + "timeOfLastMessage", + "totalMessages", + "waTooltip", + "changeDateRange", + "numberOfStudents", + "classDescription", + "classDescriptionDesc", + "requestToEnroll", + "requestAnExchange", + "findLanguageExchange", + "classAnalyticsDesc", + "addStudents", + "copyClassLink", + "copyClassLinkDesc", + "copyClassCode", + "inviteStudentByUserName", + "classSettings", + "classSettingsDesc", + "selectClassRoomDominantLanguage", + "selectTargetLanguage", + "whatIsYourClassLanguageLevel", + "studentPermissions", + "interactiveTranslator", + "oneToOneChatsWithinClass", + "oneToOneChatsWithinClassDesc", + "createGroupChats", + "createGroupChatsDesc", + "shareVideo", + "shareVideoDesc", + "sharePhotos", + "sharePhotosDesc", + "shareFiles", + "shareFilesDesc", + "shareLocationDesc", + "selectLanguageLevel", + "noIdenticalLanguages", + "iWantALanguagePartnerFrom", + "worldWide", + "noResults", + "searchBy", + "iWantAConversationPartner", + "iWantALanguagePartnerWhoSpeaks", + "iWantALanguagePartnerWhoIsLearning", + "yourBirthdayPlease", + "invalidDob", + "enterYourDob", + "getStarted", + "mustBe13", + "yourBirthdayPleaseShort", + "errorPleaseRefresh", + "joinWithClassCode", + "joinWithClassCodeDesc", + "joinWithClassCodeHint", + "unableToFindClass", + "languageLevelPreA1", + "languageLevelA1", + "languageLevelA2", + "languageLevelB1", + "languageLevelB2", + "languageLevelC1", + "languageLevelC2", + "changeTheNameOfTheClass", + "changeTheNameOfTheChat", + "welcomeToYourNewClass", + "welcomeToClass", + "welcomeToPangea18Plus", + "welcomeToPangeaMinor", + "findALanguagePartner", + "setToPublicSettingsTitle", + "setToPublicSettingsDesc", + "accountSettings", + "unableToFindClassCode", + "askPangeaBot", + "sorryNoResults", + "ignoreInThisText", + "helpMeTranslate", + "needsItShortMessage", + "needsIGCShortMessage", + "needsItMessage", + "needsIgcMessage", + "tokenTranslationTitle", + "spanTranslationDesc", + "spanTranslationTitle", + "l1SpanAndGrammarTitle", + "l1SpanAndGrammarDesc", + "otherTitle", + "otherDesc", + "countryInformation", + "myLanguages", + "targetLanguage", + "sourceLanguage", + "languagesISpeak", + "updateLanguage", + "whatLanguageYouWantToLearn", + "whatIsYourBaseLanguage", + "saveChanges", + "publicProfileTitle", + "publicProfileDesc", + "error502504Title", + "error502504Desc", + "error404Title", + "error404Desc", + "errorDisableIT", + "errorDisableIGC", + "errorDisableLanguageAssistance", + "errorDisableITUserDesc", + "errorDisableIGCUserDesc", + "errorDisableLanguageAssistanceUserDesc", + "errorDisableITClassDesc", + "errorDisableIGCClassDesc", + "errorDisableLanguageAssistanceClassDesc", + "itIsDisabled", + "igcIsDisabled", + "goToLearningSettings", + "error405Title", + "error405Desc", + "loginOrSignup", + "iAgreeToThe", + "termsAndConditions", + "andCertifyIAmAtLeast13YearsOfAge", + "findAClass", + "toggleIT", + "toggleIGC", + "toggleToolSettingsDescription", + "connectedToStaging", + "learningSettings", + "classNameRequired", + "sendVoiceNotes", + "sendVoiceNotesDesc", + "chatTopic", + "chatTopicDesc", + "inviteStudentByUserNameDesc", + "classRoster", + "almostPerfect", + "prettyGood", + "letMeThink", + "clickMessageTitle", + "clickMessageBody", + "understandingMessagesTitle", + "addToClass", + "understandingMessagesBody", + "allDone", + "vocab", + "low", + "medium", + "high", + "unknownProficiency", + "changeView", + "clearAll", + "generateVocabulary", + "generatePrompts", + "subscribe", + "getAccess", + "subscriptionDesc", + "subscriptionManagement", + "currentSubscription", + "changeSubscription", + "cancelSubscription", + "selectYourPlan", + "subsciptionPlatformTooltip", + "subscriptionManagementUnavailable", + "paymentMethod", + "paymentHistory", + "emptyChatDownloadWarning", + "appUpdateAvailable", + "update", + "updateDesc", + "maybeLater", + "mainMenu", + "toggleImmersionMode", + "toggleImmersionModeDesc", + "itToggleDescription", + "igcToggleDescription", + "sendOnEnterDescription", + "alreadyInClass", + "pleaseLoginFirst", + "originalMessage", + "sentMessage", + "useType", + "notAvailable", + "taAndGaTooltip", + "definitionsToolName", + "messageTranslationsToolName", + "definitionsToolDescription", + "translationsToolDescrption", + "welcomeBack", + "classExchanges", + "createNewClass", + "newExchange", + "kickAllStudents", + "kickAllStudentsConfirmation", + "inviteAllStudents", + "inviteAllStudentsConfirmation", + "inviteStudentsFromOtherClasses", + "inviteUsersFromPangea", + "allExchanges", + "redeemPromoCode", + "enterPromoCode", + "downloadTxtFile", + "downloadCSVFile", + "promotionalSubscriptionDesc", + "originalSubscriptionPlatform", + "oneWeekTrial", + "creatingSpacePleaseWait", + "downloadXLSXFile", + "abDisplayName", + "aaDisplayName", + "afDisplayName", + "akDisplayName", + "sqDisplayName", + "amDisplayName", + "arDisplayName", + "anDisplayName", + "hyDisplayName", + "asDisplayName", + "avDisplayName", + "aeDisplayName", + "ayDisplayName", + "azDisplayName", + "bmDisplayName", + "baDisplayName", + "euDisplayName", + "beDisplayName", + "bnDisplayName", + "bhDisplayName", + "biDisplayName", + "bsDisplayName", + "brDisplayName", + "bgDisplayName", + "myDisplayName", + "caDisplayName", + "chDisplayName", + "ceDisplayName", + "nyDisplayName", + "zhDisplayName", + "cvDisplayName", + "kwDisplayName", + "coDisplayName", + "crDisplayName", + "hrDisplayName", + "csDisplayName", + "daDisplayName", + "dvDisplayName", + "nlDisplayName", + "enDisplayName", + "eoDisplayName", + "etDisplayName", + "eeDisplayName", + "foDisplayName", + "fjDisplayName", + "fiDisplayName", + "frDisplayName", + "ffDisplayName", + "glDisplayName", + "kaDisplayName", + "deDisplayName", + "elDisplayName", + "gnDisplayName", + "guDisplayName", + "htDisplayName", + "haDisplayName", + "heDisplayName", + "hzDisplayName", + "hiDisplayName", + "hoDisplayName", + "huDisplayName", + "iaDisplayName", + "idDisplayName", + "ieDisplayName", + "gaDisplayName", + "igDisplayName", + "ikDisplayName", + "ioDisplayName", + "isDisplayName", + "itDisplayName", + "iuDisplayName", + "jaDisplayName", + "jvDisplayName", + "klDisplayName", + "knDisplayName", + "krDisplayName", + "ksDisplayName", + "kkDisplayName", + "kmDisplayName", + "kiDisplayName", + "rwDisplayName", + "kyDisplayName", + "kvDisplayName", + "kgDisplayName", + "koDisplayName", + "kuDisplayName", + "kjDisplayName", + "laDisplayName", + "lbDisplayName", + "lgDisplayName", + "liDisplayName", + "lnDisplayName", + "loDisplayName", + "ltDisplayName", + "luDisplayName", + "lvDisplayName", + "gvDisplayName", + "mkDisplayName", + "mgDisplayName", + "msDisplayName", + "mlDisplayName", + "mtDisplayName", + "miDisplayName", + "mrDisplayName", + "mhDisplayName", + "mnDisplayName", + "naDisplayName", + "nvDisplayName", + "nbDisplayName", + "ndDisplayName", + "neDisplayName", + "ngDisplayName", + "nnDisplayName", + "noDisplayName", + "iiDisplayName", + "nrDisplayName", + "ocDisplayName", + "ojDisplayName", + "cuDisplayName", + "omDisplayName", + "orDisplayName", + "osDisplayName", + "paDisplayName", + "piDisplayName", + "faDisplayName", + "plDisplayName", + "psDisplayName", + "ptDisplayName", + "quDisplayName", + "rmDisplayName", + "rnDisplayName", + "roDisplayName", + "ruDisplayName", + "saDisplayName", + "scDisplayName", + "sdDisplayName", + "seDisplayName", + "smDisplayName", + "sgDisplayName", + "srDisplayName", + "gdDisplayName", + "snDisplayName", + "siDisplayName", + "skDisplayName", + "slDisplayName", + "soDisplayName", + "stDisplayName", + "esDisplayName", + "suDisplayName", + "swDisplayName", + "ssDisplayName", + "svDisplayName", + "taDisplayName", + "teDisplayName", + "tgDisplayName", + "thDisplayName", + "tiDisplayName", + "boDisplayName", + "tkDisplayName", + "tlDisplayName", + "tnDisplayName", + "toDisplayName", + "trDisplayName", + "tsDisplayName", + "ttDisplayName", + "twDisplayName", + "tyDisplayName", + "ugDisplayName", + "ukDisplayName", + "urDisplayName", + "uzDisplayName", + "veDisplayName", + "viDisplayName", + "voDisplayName", + "waDisplayName", + "cyDisplayName", + "woDisplayName", + "fyDisplayName", + "xhDisplayName", + "yiDisplayName", + "yoDisplayName", + "zaDisplayName", + "unkDisplayName", + "zuDisplayName", + "hawDisplayName", + "hmnDisplayName", + "multiDisplayName", + "cebDisplayName", + "dzDisplayName", + "iwDisplayName", + "jwDisplayName", + "moDisplayName", + "shDisplayName", + "wwCountryDisplayName", + "afCountryDisplayName", + "axCountryDisplayName", + "alCountryDisplayName", + "dzCountryDisplayName", + "asCountryDisplayName", + "adCountryDisplayName", + "aoCountryDisplayName", + "aiCountryDisplayName", + "agCountryDisplayName", + "arCountryDisplayName", + "amCountryDisplayName", + "awCountryDisplayName", + "acCountryDisplayName", + "auCountryDisplayName", + "atCountryDisplayName", + "azCountryDisplayName", + "bsCountryDisplayName", + "bhCountryDisplayName", + "bdCountryDisplayName", + "bbCountryDisplayName", + "byCountryDisplayName", + "beCountryDisplayName", + "bzCountryDisplayName", + "bjCountryDisplayName", + "bmCountryDisplayName", + "btCountryDisplayName", + "boCountryDisplayName", + "baCountryDisplayName", + "bwCountryDisplayName", + "brCountryDisplayName", + "ioCountryDisplayName", + "vgCountryDisplayName", + "bnCountryDisplayName", + "bgCountryDisplayName", + "bfCountryDisplayName", + "biCountryDisplayName", + "khCountryDisplayName", + "cmCountryDisplayName", + "caCountryDisplayName", + "cvCountryDisplayName", + "bqCountryDisplayName", + "kyCountryDisplayName", + "cfCountryDisplayName", + "tdCountryDisplayName", + "clCountryDisplayName", + "cnCountryDisplayName", + "cxCountryDisplayName", + "ccCountryDisplayName", + "coCountryDisplayName", + "kmCountryDisplayName", + "cdCountryDisplayName", + "cgCountryDisplayName", + "ckCountryDisplayName", + "crCountryDisplayName", + "ciCountryDisplayName", + "hrCountryDisplayName", + "cuCountryDisplayName", + "cwCountryDisplayName", + "cyCountryDisplayName", + "czCountryDisplayName", + "dkCountryDisplayName", + "djCountryDisplayName", + "dmCountryDisplayName", + "doCountryDisplayName", + "tlCountryDisplayName", + "ecCountryDisplayName", + "egCountryDisplayName", + "svCountryDisplayName", + "gqCountryDisplayName", + "erCountryDisplayName", + "eeCountryDisplayName", + "szCountryDisplayName", + "etCountryDisplayName", + "fkCountryDisplayName", + "foCountryDisplayName", + "fjCountryDisplayName", + "fiCountryDisplayName", + "frCountryDisplayName", + "gfCountryDisplayName", + "pfCountryDisplayName", + "gaCountryDisplayName", + "gmCountryDisplayName", + "geCountryDisplayName", + "deCountryDisplayName", + "ghCountryDisplayName", + "giCountryDisplayName", + "grCountryDisplayName", + "glCountryDisplayName", + "gdCountryDisplayName", + "gpCountryDisplayName", + "guCountryDisplayName", + "gtCountryDisplayName", + "ggCountryDisplayName", + "gnCountryDisplayName", + "gwCountryDisplayName", + "gyCountryDisplayName", + "htCountryDisplayName", + "hmCountryDisplayName", + "hnCountryDisplayName", + "hkCountryDisplayName", + "huCountryDisplayName", + "isCountryDisplayName", + "inCountryDisplayName", + "idCountryDisplayName", + "irCountryDisplayName", + "iqCountryDisplayName", + "ieCountryDisplayName", + "imCountryDisplayName", + "ilCountryDisplayName", + "itCountryDisplayName", + "jmCountryDisplayName", + "jpCountryDisplayName", + "jeCountryDisplayName", + "joCountryDisplayName", + "kzCountryDisplayName", + "keCountryDisplayName", + "kiCountryDisplayName", + "xkCountryDisplayName", + "kwCountryDisplayName", + "kgCountryDisplayName", + "laCountryDisplayName", + "lvCountryDisplayName", + "lbCountryDisplayName", + "lsCountryDisplayName", + "lrCountryDisplayName", + "lyCountryDisplayName", + "liCountryDisplayName", + "ltCountryDisplayName", + "luCountryDisplayName", + "moCountryDisplayName", + "mkCountryDisplayName", + "mgCountryDisplayName", + "mwCountryDisplayName", + "myCountryDisplayName", + "mvCountryDisplayName", + "mlCountryDisplayName", + "mtCountryDisplayName", + "mhCountryDisplayName", + "mqCountryDisplayName", + "mrCountryDisplayName", + "muCountryDisplayName", + "ytCountryDisplayName", + "mxCountryDisplayName", + "fmCountryDisplayName", + "mdCountryDisplayName", + "mcCountryDisplayName", + "mnCountryDisplayName", + "meCountryDisplayName", + "msCountryDisplayName", + "maCountryDisplayName", + "mzCountryDisplayName", + "mmCountryDisplayName", + "naCountryDisplayName", + "nrCountryDisplayName", + "npCountryDisplayName", + "nlCountryDisplayName", + "ncCountryDisplayName", + "nzCountryDisplayName", + "niCountryDisplayName", + "neCountryDisplayName", + "ngCountryDisplayName", + "nuCountryDisplayName", + "nfCountryDisplayName", + "kpCountryDisplayName", + "mpCountryDisplayName", + "noCountryDisplayName", + "omCountryDisplayName", + "pkCountryDisplayName", + "pwCountryDisplayName", + "psCountryDisplayName", + "paCountryDisplayName", + "pgCountryDisplayName", + "pyCountryDisplayName", + "peCountryDisplayName", + "phCountryDisplayName", + "plCountryDisplayName", + "ptCountryDisplayName", + "prCountryDisplayName", + "qaCountryDisplayName", + "reCountryDisplayName", + "roCountryDisplayName", + "ruCountryDisplayName", + "rwCountryDisplayName", + "blCountryDisplayName", + "shCountryDisplayName", + "knCountryDisplayName", + "lcCountryDisplayName", + "mfCountryDisplayName", + "pmCountryDisplayName", + "vcCountryDisplayName", + "wsCountryDisplayName", + "smCountryDisplayName", + "stCountryDisplayName", + "saCountryDisplayName", + "snCountryDisplayName", + "rsCountryDisplayName", + "scCountryDisplayName", + "slCountryDisplayName", + "sgCountryDisplayName", + "sxCountryDisplayName", + "skCountryDisplayName", + "siCountryDisplayName", + "sbCountryDisplayName", + "soCountryDisplayName", + "zaCountryDisplayName", + "gsCountryDisplayName", + "krCountryDisplayName", + "ssCountryDisplayName", + "esCountryDisplayName", + "lkCountryDisplayName", + "sdCountryDisplayName", + "srCountryDisplayName", + "sjCountryDisplayName", + "seCountryDisplayName", + "chCountryDisplayName", + "syCountryDisplayName", + "twCountryDisplayName", + "tjCountryDisplayName", + "tzCountryDisplayName", + "thCountryDisplayName", + "tgCountryDisplayName", + "tkCountryDisplayName", + "toCountryDisplayName", + "ttCountryDisplayName", + "tnCountryDisplayName", + "trCountryDisplayName", + "tmCountryDisplayName", + "tcCountryDisplayName", + "tvCountryDisplayName", + "viCountryDisplayName", + "ugCountryDisplayName", + "uaCountryDisplayName", + "aeCountryDisplayName", + "gbCountryDisplayName", + "usCountryDisplayName", + "uyCountryDisplayName", + "uzCountryDisplayName", + "vuCountryDisplayName", + "vaCountryDisplayName", + "veCountryDisplayName", + "vnCountryDisplayName", + "wfCountryDisplayName", + "ehCountryDisplayName", + "yeCountryDisplayName", + "zmCountryDisplayName", + "zwCountryDisplayName", + "pay", + "allPrivateChats", + "unknownPrivateChat", + "copyClassCodeDesc", + "addToClassDesc", + "addToClassOrExchange", + "addToClassOrExchangeDesc", + "invitedToClassOrExchange", + "decline", + "declinedInvitation", + "acceptedInvitation", + "youreInvited", + "studentPermissionsDesc", + "noEligibleSpaces", + "youAddedToSpace", + "youRemovedFromSpace", + "invitedToChat", + "monthlySubscription", + "yearlySubscription", + "defaultSubscription", + "freeTrial", + "grammarAnalytics", + "total", + "noDataFound", + "promoSubscriptionExpirationDesc", + "emptyChatNameWarning", + "emptyClassNameWarning", + "emptyExchangeNameWarning", + "blurMeansTranslateTitle", + "blurMeansTranslateBody", + "someErrorTitle", + "someErrorBody", + "bestCorrectionFeedback", + "distractorFeedback", + "bestAnswerFeedback", + "definitionDefaultPrompt", + "practiceDefaultPrompt", + "correctionDefaultPrompt", + "itStartDefaultPrompt", + "languageLevelWarning", + "lockedChatWarning", + "lockSpace", + "lockChat", + "archiveSpace", + "suggestTo", + "suggestChatDesc", + "suggestExchangeDesc", + "acceptSelection", + "acceptSelectionAnyway", + "makingActivity", + "why", + "definition", + "exampleSentence", + "addToClassTitle", + "reportToTeacher", + "reportMessageTitle", + "reportMessageBody", + "noTeachersFound", + "noAddToSpacePermissions", + "alreadyInSpace", + "yourGlobalUserIdIs", + "noUsersFoundWithQuery", + "searchChatsRooms", + "groupName", + "createGroupAndInviteUsers", + "groupCanBeFoundViaSearch", + "inNoSpaces" + ], + + "ga": [ + "accountInformation", + "addNewFriend", + "alreadyHaveAnAccount", + "classes", + "allCorrect", + "newWayAllGood", + "othersAreBetter", + "holdForInfo", + "greenFeedback", + "yellowFeedback", + "redFeedback", + "customInputFeedbackChoice", + "itInstructionsTitle", + "itInstructionsBody", + "toggleLanguages", + "classWelcomeChat", + "deleteSpace", + "deleteGroup", + "areYouSureDeleteClass", + "areYouSureDeleteGroup", + "cannotBeReversed", + "enterDeletedClassName", + "incorrectClassName", + "oneday", + "oneweek", + "onemonth", + "sixmonth", + "oneyear", + "gaTooltip", + "taTooltip", + "unTooltip", + "interactiveTranslatorSliderHeader", + "interactiveGrammarSliderHeader", + "interactiveTranslatorNotAllowed", + "interactiveTranslatorAllowed", + "interactiveTranslatorRequired", + "interactiveTranslatorNotAllowedDesc", + "interactiveTranslatorAllowedDesc", + "interactiveTranslatorRequiredDesc", + "notYetSet", + "multiLingualClass", + "classAnalytics", + "allClasses", + "myLearning", + "allChatsAndClasses", + "timeOfLastMessage", + "totalMessages", + "waTooltip", + "changeDateRange", + "numberOfStudents", + "classDescription", + "classDescriptionDesc", + "requestToEnroll", + "requestAnExchange", + "findLanguageExchange", + "classAnalyticsDesc", + "addStudents", + "copyClassLink", + "copyClassLinkDesc", + "copyClassCode", + "inviteStudentByUserName", + "classSettings", + "classSettingsDesc", + "selectClassRoomDominantLanguage", + "selectTargetLanguage", + "whatIsYourClassLanguageLevel", + "studentPermissions", + "interactiveTranslator", + "oneToOneChatsWithinClass", + "oneToOneChatsWithinClassDesc", + "createGroupChats", + "createGroupChatsDesc", + "shareVideo", + "shareVideoDesc", + "sharePhotos", + "sharePhotosDesc", + "shareFiles", + "shareFilesDesc", + "shareLocationDesc", + "selectLanguageLevel", + "noIdenticalLanguages", + "iWantALanguagePartnerFrom", + "worldWide", + "noResults", + "searchBy", + "iWantAConversationPartner", + "iWantALanguagePartnerWhoSpeaks", + "iWantALanguagePartnerWhoIsLearning", + "yourBirthdayPlease", + "invalidDob", + "enterYourDob", + "getStarted", + "mustBe13", + "yourBirthdayPleaseShort", + "errorPleaseRefresh", + "joinWithClassCode", + "joinWithClassCodeDesc", + "joinWithClassCodeHint", + "unableToFindClass", + "languageLevelPreA1", + "languageLevelA1", + "languageLevelA2", + "languageLevelB1", + "languageLevelB2", + "languageLevelC1", + "languageLevelC2", + "changeTheNameOfTheClass", + "changeTheNameOfTheChat", + "welcomeToYourNewClass", + "welcomeToClass", + "welcomeToPangea18Plus", + "welcomeToPangeaMinor", + "findALanguagePartner", + "setToPublicSettingsTitle", + "setToPublicSettingsDesc", + "accountSettings", + "unableToFindClassCode", + "askPangeaBot", + "sorryNoResults", + "ignoreInThisText", + "helpMeTranslate", + "needsItShortMessage", + "needsIGCShortMessage", + "needsItMessage", + "needsIgcMessage", + "tokenTranslationTitle", + "spanTranslationDesc", + "spanTranslationTitle", + "l1SpanAndGrammarTitle", + "l1SpanAndGrammarDesc", + "otherTitle", + "otherDesc", + "countryInformation", + "myLanguages", + "targetLanguage", + "sourceLanguage", + "languagesISpeak", + "updateLanguage", + "whatLanguageYouWantToLearn", + "whatIsYourBaseLanguage", + "saveChanges", + "publicProfileTitle", + "publicProfileDesc", + "error502504Title", + "error502504Desc", + "error404Title", + "error404Desc", + "errorDisableIT", + "errorDisableIGC", + "errorDisableLanguageAssistance", + "errorDisableITUserDesc", + "errorDisableIGCUserDesc", + "errorDisableLanguageAssistanceUserDesc", + "errorDisableITClassDesc", + "errorDisableIGCClassDesc", + "errorDisableLanguageAssistanceClassDesc", + "itIsDisabled", + "igcIsDisabled", + "goToLearningSettings", + "error405Title", + "error405Desc", + "loginOrSignup", + "iAgreeToThe", + "termsAndConditions", + "andCertifyIAmAtLeast13YearsOfAge", + "findAClass", + "toggleIT", + "toggleIGC", + "toggleToolSettingsDescription", + "connectedToStaging", + "learningSettings", + "classNameRequired", + "sendVoiceNotes", + "sendVoiceNotesDesc", + "chatTopic", + "chatTopicDesc", + "inviteStudentByUserNameDesc", + "classRoster", + "almostPerfect", + "prettyGood", + "letMeThink", + "clickMessageTitle", + "clickMessageBody", + "understandingMessagesTitle", + "addToClass", + "understandingMessagesBody", + "allDone", + "vocab", + "low", + "medium", + "high", + "unknownProficiency", + "changeView", + "clearAll", + "generateVocabulary", + "generatePrompts", + "subscribe", + "getAccess", + "subscriptionDesc", + "subscriptionManagement", + "currentSubscription", + "changeSubscription", + "cancelSubscription", + "selectYourPlan", + "subsciptionPlatformTooltip", + "subscriptionManagementUnavailable", + "paymentMethod", + "paymentHistory", + "emptyChatDownloadWarning", + "appUpdateAvailable", + "update", + "updateDesc", + "maybeLater", + "mainMenu", + "toggleImmersionMode", + "toggleImmersionModeDesc", + "itToggleDescription", + "igcToggleDescription", + "sendOnEnterDescription", + "alreadyInClass", + "pleaseLoginFirst", + "originalMessage", + "sentMessage", + "useType", + "notAvailable", + "taAndGaTooltip", + "definitionsToolName", + "messageTranslationsToolName", + "definitionsToolDescription", + "translationsToolDescrption", + "welcomeBack", + "classExchanges", + "createNewClass", + "newExchange", + "kickAllStudents", + "kickAllStudentsConfirmation", + "inviteAllStudents", + "inviteAllStudentsConfirmation", + "inviteStudentsFromOtherClasses", + "inviteUsersFromPangea", + "allExchanges", + "redeemPromoCode", + "enterPromoCode", + "downloadTxtFile", + "downloadCSVFile", + "promotionalSubscriptionDesc", + "originalSubscriptionPlatform", + "oneWeekTrial", + "creatingSpacePleaseWait", + "downloadXLSXFile", + "abDisplayName", + "aaDisplayName", + "afDisplayName", + "akDisplayName", + "sqDisplayName", + "amDisplayName", + "arDisplayName", + "anDisplayName", + "hyDisplayName", + "asDisplayName", + "avDisplayName", + "aeDisplayName", + "ayDisplayName", + "azDisplayName", + "bmDisplayName", + "baDisplayName", + "euDisplayName", + "beDisplayName", + "bnDisplayName", + "bhDisplayName", + "biDisplayName", + "bsDisplayName", + "brDisplayName", + "bgDisplayName", + "myDisplayName", + "caDisplayName", + "chDisplayName", + "ceDisplayName", + "nyDisplayName", + "zhDisplayName", + "cvDisplayName", + "kwDisplayName", + "coDisplayName", + "crDisplayName", + "hrDisplayName", + "csDisplayName", + "daDisplayName", + "dvDisplayName", + "nlDisplayName", + "enDisplayName", + "eoDisplayName", + "etDisplayName", + "eeDisplayName", + "foDisplayName", + "fjDisplayName", + "fiDisplayName", + "frDisplayName", + "ffDisplayName", + "glDisplayName", + "kaDisplayName", + "deDisplayName", + "elDisplayName", + "gnDisplayName", + "guDisplayName", + "htDisplayName", + "haDisplayName", + "heDisplayName", + "hzDisplayName", + "hiDisplayName", + "hoDisplayName", + "huDisplayName", + "iaDisplayName", + "idDisplayName", + "ieDisplayName", + "gaDisplayName", + "igDisplayName", + "ikDisplayName", + "ioDisplayName", + "isDisplayName", + "itDisplayName", + "iuDisplayName", + "jaDisplayName", + "jvDisplayName", + "klDisplayName", + "knDisplayName", + "krDisplayName", + "ksDisplayName", + "kkDisplayName", + "kmDisplayName", + "kiDisplayName", + "rwDisplayName", + "kyDisplayName", + "kvDisplayName", + "kgDisplayName", + "koDisplayName", + "kuDisplayName", + "kjDisplayName", + "laDisplayName", + "lbDisplayName", + "lgDisplayName", + "liDisplayName", + "lnDisplayName", + "loDisplayName", + "ltDisplayName", + "luDisplayName", + "lvDisplayName", + "gvDisplayName", + "mkDisplayName", + "mgDisplayName", + "msDisplayName", + "mlDisplayName", + "mtDisplayName", + "miDisplayName", + "mrDisplayName", + "mhDisplayName", + "mnDisplayName", + "naDisplayName", + "nvDisplayName", + "nbDisplayName", + "ndDisplayName", + "neDisplayName", + "ngDisplayName", + "nnDisplayName", + "noDisplayName", + "iiDisplayName", + "nrDisplayName", + "ocDisplayName", + "ojDisplayName", + "cuDisplayName", + "omDisplayName", + "orDisplayName", + "osDisplayName", + "paDisplayName", + "piDisplayName", + "faDisplayName", + "plDisplayName", + "psDisplayName", + "ptDisplayName", + "quDisplayName", + "rmDisplayName", + "rnDisplayName", + "roDisplayName", + "ruDisplayName", + "saDisplayName", + "scDisplayName", + "sdDisplayName", + "seDisplayName", + "smDisplayName", + "sgDisplayName", + "srDisplayName", + "gdDisplayName", + "snDisplayName", + "siDisplayName", + "skDisplayName", + "slDisplayName", + "soDisplayName", + "stDisplayName", + "esDisplayName", + "suDisplayName", + "swDisplayName", + "ssDisplayName", + "svDisplayName", + "taDisplayName", + "teDisplayName", + "tgDisplayName", + "thDisplayName", + "tiDisplayName", + "boDisplayName", + "tkDisplayName", + "tlDisplayName", + "tnDisplayName", + "toDisplayName", + "trDisplayName", + "tsDisplayName", + "ttDisplayName", + "twDisplayName", + "tyDisplayName", + "ugDisplayName", + "ukDisplayName", + "urDisplayName", + "uzDisplayName", + "veDisplayName", + "viDisplayName", + "voDisplayName", + "waDisplayName", + "cyDisplayName", + "woDisplayName", + "fyDisplayName", + "xhDisplayName", + "yiDisplayName", + "yoDisplayName", + "zaDisplayName", + "unkDisplayName", + "zuDisplayName", + "hawDisplayName", + "hmnDisplayName", + "multiDisplayName", + "cebDisplayName", + "dzDisplayName", + "iwDisplayName", + "jwDisplayName", + "moDisplayName", + "shDisplayName", + "wwCountryDisplayName", + "afCountryDisplayName", + "axCountryDisplayName", + "alCountryDisplayName", + "dzCountryDisplayName", + "asCountryDisplayName", + "adCountryDisplayName", + "aoCountryDisplayName", + "aiCountryDisplayName", + "agCountryDisplayName", + "arCountryDisplayName", + "amCountryDisplayName", + "awCountryDisplayName", + "acCountryDisplayName", + "auCountryDisplayName", + "atCountryDisplayName", + "azCountryDisplayName", + "bsCountryDisplayName", + "bhCountryDisplayName", + "bdCountryDisplayName", + "bbCountryDisplayName", + "byCountryDisplayName", + "beCountryDisplayName", + "bzCountryDisplayName", + "bjCountryDisplayName", + "bmCountryDisplayName", + "btCountryDisplayName", + "boCountryDisplayName", + "baCountryDisplayName", + "bwCountryDisplayName", + "brCountryDisplayName", + "ioCountryDisplayName", + "vgCountryDisplayName", + "bnCountryDisplayName", + "bgCountryDisplayName", + "bfCountryDisplayName", + "biCountryDisplayName", + "khCountryDisplayName", + "cmCountryDisplayName", + "caCountryDisplayName", + "cvCountryDisplayName", + "bqCountryDisplayName", + "kyCountryDisplayName", + "cfCountryDisplayName", + "tdCountryDisplayName", + "clCountryDisplayName", + "cnCountryDisplayName", + "cxCountryDisplayName", + "ccCountryDisplayName", + "coCountryDisplayName", + "kmCountryDisplayName", + "cdCountryDisplayName", + "cgCountryDisplayName", + "ckCountryDisplayName", + "crCountryDisplayName", + "ciCountryDisplayName", + "hrCountryDisplayName", + "cuCountryDisplayName", + "cwCountryDisplayName", + "cyCountryDisplayName", + "czCountryDisplayName", + "dkCountryDisplayName", + "djCountryDisplayName", + "dmCountryDisplayName", + "doCountryDisplayName", + "tlCountryDisplayName", + "ecCountryDisplayName", + "egCountryDisplayName", + "svCountryDisplayName", + "gqCountryDisplayName", + "erCountryDisplayName", + "eeCountryDisplayName", + "szCountryDisplayName", + "etCountryDisplayName", + "fkCountryDisplayName", + "foCountryDisplayName", + "fjCountryDisplayName", + "fiCountryDisplayName", + "frCountryDisplayName", + "gfCountryDisplayName", + "pfCountryDisplayName", + "gaCountryDisplayName", + "gmCountryDisplayName", + "geCountryDisplayName", + "deCountryDisplayName", + "ghCountryDisplayName", + "giCountryDisplayName", + "grCountryDisplayName", + "glCountryDisplayName", + "gdCountryDisplayName", + "gpCountryDisplayName", + "guCountryDisplayName", + "gtCountryDisplayName", + "ggCountryDisplayName", + "gnCountryDisplayName", + "gwCountryDisplayName", + "gyCountryDisplayName", + "htCountryDisplayName", + "hmCountryDisplayName", + "hnCountryDisplayName", + "hkCountryDisplayName", + "huCountryDisplayName", + "isCountryDisplayName", + "inCountryDisplayName", + "idCountryDisplayName", + "irCountryDisplayName", + "iqCountryDisplayName", + "ieCountryDisplayName", + "imCountryDisplayName", + "ilCountryDisplayName", + "itCountryDisplayName", + "jmCountryDisplayName", + "jpCountryDisplayName", + "jeCountryDisplayName", + "joCountryDisplayName", + "kzCountryDisplayName", + "keCountryDisplayName", + "kiCountryDisplayName", + "xkCountryDisplayName", + "kwCountryDisplayName", + "kgCountryDisplayName", + "laCountryDisplayName", + "lvCountryDisplayName", + "lbCountryDisplayName", + "lsCountryDisplayName", + "lrCountryDisplayName", + "lyCountryDisplayName", + "liCountryDisplayName", + "ltCountryDisplayName", + "luCountryDisplayName", + "moCountryDisplayName", + "mkCountryDisplayName", + "mgCountryDisplayName", + "mwCountryDisplayName", + "myCountryDisplayName", + "mvCountryDisplayName", + "mlCountryDisplayName", + "mtCountryDisplayName", + "mhCountryDisplayName", + "mqCountryDisplayName", + "mrCountryDisplayName", + "muCountryDisplayName", + "ytCountryDisplayName", + "mxCountryDisplayName", + "fmCountryDisplayName", + "mdCountryDisplayName", + "mcCountryDisplayName", + "mnCountryDisplayName", + "meCountryDisplayName", + "msCountryDisplayName", + "maCountryDisplayName", + "mzCountryDisplayName", + "mmCountryDisplayName", + "naCountryDisplayName", + "nrCountryDisplayName", + "npCountryDisplayName", + "nlCountryDisplayName", + "ncCountryDisplayName", + "nzCountryDisplayName", + "niCountryDisplayName", + "neCountryDisplayName", + "ngCountryDisplayName", + "nuCountryDisplayName", + "nfCountryDisplayName", + "kpCountryDisplayName", + "mpCountryDisplayName", + "noCountryDisplayName", + "omCountryDisplayName", + "pkCountryDisplayName", + "pwCountryDisplayName", + "psCountryDisplayName", + "paCountryDisplayName", + "pgCountryDisplayName", + "pyCountryDisplayName", + "peCountryDisplayName", + "phCountryDisplayName", + "plCountryDisplayName", + "ptCountryDisplayName", + "prCountryDisplayName", + "qaCountryDisplayName", + "reCountryDisplayName", + "roCountryDisplayName", + "ruCountryDisplayName", + "rwCountryDisplayName", + "blCountryDisplayName", + "shCountryDisplayName", + "knCountryDisplayName", + "lcCountryDisplayName", + "mfCountryDisplayName", + "pmCountryDisplayName", + "vcCountryDisplayName", + "wsCountryDisplayName", + "smCountryDisplayName", + "stCountryDisplayName", + "saCountryDisplayName", + "snCountryDisplayName", + "rsCountryDisplayName", + "scCountryDisplayName", + "slCountryDisplayName", + "sgCountryDisplayName", + "sxCountryDisplayName", + "skCountryDisplayName", + "siCountryDisplayName", + "sbCountryDisplayName", + "soCountryDisplayName", + "zaCountryDisplayName", + "gsCountryDisplayName", + "krCountryDisplayName", + "ssCountryDisplayName", + "esCountryDisplayName", + "lkCountryDisplayName", + "sdCountryDisplayName", + "srCountryDisplayName", + "sjCountryDisplayName", + "seCountryDisplayName", + "chCountryDisplayName", + "syCountryDisplayName", + "twCountryDisplayName", + "tjCountryDisplayName", + "tzCountryDisplayName", + "thCountryDisplayName", + "tgCountryDisplayName", + "tkCountryDisplayName", + "toCountryDisplayName", + "ttCountryDisplayName", + "tnCountryDisplayName", + "trCountryDisplayName", + "tmCountryDisplayName", + "tcCountryDisplayName", + "tvCountryDisplayName", + "viCountryDisplayName", + "ugCountryDisplayName", + "uaCountryDisplayName", + "aeCountryDisplayName", + "gbCountryDisplayName", + "usCountryDisplayName", + "uyCountryDisplayName", + "uzCountryDisplayName", + "vuCountryDisplayName", + "vaCountryDisplayName", + "veCountryDisplayName", + "vnCountryDisplayName", + "wfCountryDisplayName", + "ehCountryDisplayName", + "yeCountryDisplayName", + "zmCountryDisplayName", + "zwCountryDisplayName", + "pay", + "allPrivateChats", + "unknownPrivateChat", + "copyClassCodeDesc", + "addToClassDesc", + "addToClassOrExchange", + "addToClassOrExchangeDesc", + "invitedToClassOrExchange", + "decline", + "declinedInvitation", + "acceptedInvitation", + "youreInvited", + "studentPermissionsDesc", + "noEligibleSpaces", + "youAddedToSpace", + "youRemovedFromSpace", + "invitedToChat", + "monthlySubscription", + "yearlySubscription", + "defaultSubscription", + "freeTrial", + "grammarAnalytics", + "total", + "noDataFound", + "promoSubscriptionExpirationDesc", + "emptyChatNameWarning", + "emptyClassNameWarning", + "emptyExchangeNameWarning", + "blurMeansTranslateTitle", + "blurMeansTranslateBody", + "someErrorTitle", + "someErrorBody", + "bestCorrectionFeedback", + "distractorFeedback", + "bestAnswerFeedback", + "definitionDefaultPrompt", + "practiceDefaultPrompt", + "correctionDefaultPrompt", + "itStartDefaultPrompt", + "languageLevelWarning", + "lockedChatWarning", + "lockSpace", + "lockChat", + "archiveSpace", + "suggestTo", + "suggestChatDesc", + "suggestExchangeDesc", + "acceptSelection", + "acceptSelectionAnyway", + "makingActivity", + "why", + "definition", + "exampleSentence", + "addToClassTitle", + "reportToTeacher", + "reportMessageTitle", + "reportMessageBody", + "noTeachersFound", + "noAddToSpacePermissions", + "alreadyInSpace", + "yourGlobalUserIdIs", + "noUsersFoundWithQuery", + "searchChatsRooms", + "groupName", + "createGroupAndInviteUsers", + "groupCanBeFoundViaSearch", + "inNoSpaces" + ], + + "gl": [ + "accountInformation", + "addNewFriend", + "alreadyHaveAnAccount", + "classes", + "allCorrect", + "newWayAllGood", + "othersAreBetter", + "holdForInfo", + "greenFeedback", + "yellowFeedback", + "redFeedback", + "customInputFeedbackChoice", + "itInstructionsTitle", + "itInstructionsBody", + "toggleLanguages", + "classWelcomeChat", + "deleteSpace", + "deleteGroup", + "areYouSureDeleteClass", + "areYouSureDeleteGroup", + "cannotBeReversed", + "enterDeletedClassName", + "incorrectClassName", + "oneday", + "oneweek", + "onemonth", + "sixmonth", + "oneyear", + "gaTooltip", + "taTooltip", + "unTooltip", + "interactiveTranslatorSliderHeader", + "interactiveGrammarSliderHeader", + "interactiveTranslatorNotAllowed", + "interactiveTranslatorAllowed", + "interactiveTranslatorRequired", + "interactiveTranslatorNotAllowedDesc", + "interactiveTranslatorAllowedDesc", + "interactiveTranslatorRequiredDesc", + "notYetSet", + "multiLingualClass", + "classAnalytics", + "allClasses", + "myLearning", + "allChatsAndClasses", + "timeOfLastMessage", + "totalMessages", + "waTooltip", + "changeDateRange", + "numberOfStudents", + "classDescription", + "classDescriptionDesc", + "requestToEnroll", + "requestAnExchange", + "findLanguageExchange", + "classAnalyticsDesc", + "addStudents", + "copyClassLink", + "copyClassLinkDesc", + "copyClassCode", + "inviteStudentByUserName", + "classSettings", + "classSettingsDesc", + "selectClassRoomDominantLanguage", + "selectTargetLanguage", + "whatIsYourClassLanguageLevel", + "studentPermissions", + "interactiveTranslator", + "oneToOneChatsWithinClass", + "oneToOneChatsWithinClassDesc", + "createGroupChats", + "createGroupChatsDesc", + "shareVideo", + "shareVideoDesc", + "sharePhotos", + "sharePhotosDesc", + "shareFiles", + "shareFilesDesc", + "shareLocationDesc", + "selectLanguageLevel", + "noIdenticalLanguages", + "iWantALanguagePartnerFrom", + "worldWide", + "noResults", + "searchBy", + "iWantAConversationPartner", + "iWantALanguagePartnerWhoSpeaks", + "iWantALanguagePartnerWhoIsLearning", + "yourBirthdayPlease", + "invalidDob", + "enterYourDob", + "getStarted", + "mustBe13", + "yourBirthdayPleaseShort", + "errorPleaseRefresh", + "joinWithClassCode", + "joinWithClassCodeDesc", + "joinWithClassCodeHint", + "unableToFindClass", + "languageLevelPreA1", + "languageLevelA1", + "languageLevelA2", + "languageLevelB1", + "languageLevelB2", + "languageLevelC1", + "languageLevelC2", + "changeTheNameOfTheClass", + "changeTheNameOfTheChat", + "welcomeToYourNewClass", + "welcomeToClass", + "welcomeToPangea18Plus", + "welcomeToPangeaMinor", + "findALanguagePartner", + "setToPublicSettingsTitle", + "setToPublicSettingsDesc", + "accountSettings", + "unableToFindClassCode", + "askPangeaBot", + "sorryNoResults", + "ignoreInThisText", + "helpMeTranslate", + "needsItShortMessage", + "needsIGCShortMessage", + "needsItMessage", + "needsIgcMessage", + "tokenTranslationTitle", + "spanTranslationDesc", + "spanTranslationTitle", + "l1SpanAndGrammarTitle", + "l1SpanAndGrammarDesc", + "otherTitle", + "otherDesc", + "countryInformation", + "myLanguages", + "targetLanguage", + "sourceLanguage", + "languagesISpeak", + "updateLanguage", + "whatLanguageYouWantToLearn", + "whatIsYourBaseLanguage", + "saveChanges", + "publicProfileTitle", + "publicProfileDesc", + "error502504Title", + "error502504Desc", + "error404Title", + "error404Desc", + "errorDisableIT", + "errorDisableIGC", + "errorDisableLanguageAssistance", + "errorDisableITUserDesc", + "errorDisableIGCUserDesc", + "errorDisableLanguageAssistanceUserDesc", + "errorDisableITClassDesc", + "errorDisableIGCClassDesc", + "errorDisableLanguageAssistanceClassDesc", + "itIsDisabled", + "igcIsDisabled", + "goToLearningSettings", + "error405Title", + "error405Desc", + "loginOrSignup", + "iAgreeToThe", + "termsAndConditions", + "andCertifyIAmAtLeast13YearsOfAge", + "findAClass", + "toggleIT", + "toggleIGC", + "toggleToolSettingsDescription", + "connectedToStaging", + "learningSettings", + "classNameRequired", + "sendVoiceNotes", + "sendVoiceNotesDesc", + "chatTopic", + "chatTopicDesc", + "inviteStudentByUserNameDesc", + "classRoster", + "almostPerfect", + "prettyGood", + "letMeThink", + "clickMessageTitle", + "clickMessageBody", + "understandingMessagesTitle", + "addToClass", + "understandingMessagesBody", + "allDone", + "vocab", + "low", + "medium", + "high", + "unknownProficiency", + "changeView", + "clearAll", + "generateVocabulary", + "generatePrompts", + "subscribe", + "getAccess", + "subscriptionDesc", + "subscriptionManagement", + "currentSubscription", + "changeSubscription", + "cancelSubscription", + "selectYourPlan", + "subsciptionPlatformTooltip", + "subscriptionManagementUnavailable", + "paymentMethod", + "paymentHistory", + "emptyChatDownloadWarning", + "appUpdateAvailable", + "update", + "updateDesc", + "maybeLater", + "mainMenu", + "toggleImmersionMode", + "toggleImmersionModeDesc", + "itToggleDescription", + "igcToggleDescription", + "sendOnEnterDescription", + "alreadyInClass", + "pleaseLoginFirst", + "originalMessage", + "sentMessage", + "useType", + "notAvailable", + "taAndGaTooltip", + "definitionsToolName", + "messageTranslationsToolName", + "definitionsToolDescription", + "translationsToolDescrption", + "welcomeBack", + "classExchanges", + "createNewClass", + "newExchange", + "kickAllStudents", + "kickAllStudentsConfirmation", + "inviteAllStudents", + "inviteAllStudentsConfirmation", + "inviteStudentsFromOtherClasses", + "inviteUsersFromPangea", + "allExchanges", + "redeemPromoCode", + "enterPromoCode", + "downloadTxtFile", + "downloadCSVFile", + "promotionalSubscriptionDesc", + "originalSubscriptionPlatform", + "oneWeekTrial", + "creatingSpacePleaseWait", + "downloadXLSXFile", + "abDisplayName", + "aaDisplayName", + "afDisplayName", + "akDisplayName", + "sqDisplayName", + "amDisplayName", + "arDisplayName", + "anDisplayName", + "hyDisplayName", + "asDisplayName", + "avDisplayName", + "aeDisplayName", + "ayDisplayName", + "azDisplayName", + "bmDisplayName", + "baDisplayName", + "euDisplayName", + "beDisplayName", + "bnDisplayName", + "bhDisplayName", + "biDisplayName", + "bsDisplayName", + "brDisplayName", + "bgDisplayName", + "myDisplayName", + "caDisplayName", + "chDisplayName", + "ceDisplayName", + "nyDisplayName", + "zhDisplayName", + "cvDisplayName", + "kwDisplayName", + "coDisplayName", + "crDisplayName", + "hrDisplayName", + "csDisplayName", + "daDisplayName", + "dvDisplayName", + "nlDisplayName", + "enDisplayName", + "eoDisplayName", + "etDisplayName", + "eeDisplayName", + "foDisplayName", + "fjDisplayName", + "fiDisplayName", + "frDisplayName", + "ffDisplayName", + "glDisplayName", + "kaDisplayName", + "deDisplayName", + "elDisplayName", + "gnDisplayName", + "guDisplayName", + "htDisplayName", + "haDisplayName", + "heDisplayName", + "hzDisplayName", + "hiDisplayName", + "hoDisplayName", + "huDisplayName", + "iaDisplayName", + "idDisplayName", + "ieDisplayName", + "gaDisplayName", + "igDisplayName", + "ikDisplayName", + "ioDisplayName", + "isDisplayName", + "itDisplayName", + "iuDisplayName", + "jaDisplayName", + "jvDisplayName", + "klDisplayName", + "knDisplayName", + "krDisplayName", + "ksDisplayName", + "kkDisplayName", + "kmDisplayName", + "kiDisplayName", + "rwDisplayName", + "kyDisplayName", + "kvDisplayName", + "kgDisplayName", + "koDisplayName", + "kuDisplayName", + "kjDisplayName", + "laDisplayName", + "lbDisplayName", + "lgDisplayName", + "liDisplayName", + "lnDisplayName", + "loDisplayName", + "ltDisplayName", + "luDisplayName", + "lvDisplayName", + "gvDisplayName", + "mkDisplayName", + "mgDisplayName", + "msDisplayName", + "mlDisplayName", + "mtDisplayName", + "miDisplayName", + "mrDisplayName", + "mhDisplayName", + "mnDisplayName", + "naDisplayName", + "nvDisplayName", + "nbDisplayName", + "ndDisplayName", + "neDisplayName", + "ngDisplayName", + "nnDisplayName", + "noDisplayName", + "iiDisplayName", + "nrDisplayName", + "ocDisplayName", + "ojDisplayName", + "cuDisplayName", + "omDisplayName", + "orDisplayName", + "osDisplayName", + "paDisplayName", + "piDisplayName", + "faDisplayName", + "plDisplayName", + "psDisplayName", + "ptDisplayName", + "quDisplayName", + "rmDisplayName", + "rnDisplayName", + "roDisplayName", + "ruDisplayName", + "saDisplayName", + "scDisplayName", + "sdDisplayName", + "seDisplayName", + "smDisplayName", + "sgDisplayName", + "srDisplayName", + "gdDisplayName", + "snDisplayName", + "siDisplayName", + "skDisplayName", + "slDisplayName", + "soDisplayName", + "stDisplayName", + "esDisplayName", + "suDisplayName", + "swDisplayName", + "ssDisplayName", + "svDisplayName", + "taDisplayName", + "teDisplayName", + "tgDisplayName", + "thDisplayName", + "tiDisplayName", + "boDisplayName", + "tkDisplayName", + "tlDisplayName", + "tnDisplayName", + "toDisplayName", + "trDisplayName", + "tsDisplayName", + "ttDisplayName", + "twDisplayName", + "tyDisplayName", + "ugDisplayName", + "ukDisplayName", + "urDisplayName", + "uzDisplayName", + "veDisplayName", + "viDisplayName", + "voDisplayName", + "waDisplayName", + "cyDisplayName", + "woDisplayName", + "fyDisplayName", + "xhDisplayName", + "yiDisplayName", + "yoDisplayName", + "zaDisplayName", + "unkDisplayName", + "zuDisplayName", + "hawDisplayName", + "hmnDisplayName", + "multiDisplayName", + "cebDisplayName", + "dzDisplayName", + "iwDisplayName", + "jwDisplayName", + "moDisplayName", + "shDisplayName", + "wwCountryDisplayName", + "afCountryDisplayName", + "axCountryDisplayName", + "alCountryDisplayName", + "dzCountryDisplayName", + "asCountryDisplayName", + "adCountryDisplayName", + "aoCountryDisplayName", + "aiCountryDisplayName", + "agCountryDisplayName", + "arCountryDisplayName", + "amCountryDisplayName", + "awCountryDisplayName", + "acCountryDisplayName", + "auCountryDisplayName", + "atCountryDisplayName", + "azCountryDisplayName", + "bsCountryDisplayName", + "bhCountryDisplayName", + "bdCountryDisplayName", + "bbCountryDisplayName", + "byCountryDisplayName", + "beCountryDisplayName", + "bzCountryDisplayName", + "bjCountryDisplayName", + "bmCountryDisplayName", + "btCountryDisplayName", + "boCountryDisplayName", + "baCountryDisplayName", + "bwCountryDisplayName", + "brCountryDisplayName", + "ioCountryDisplayName", + "vgCountryDisplayName", + "bnCountryDisplayName", + "bgCountryDisplayName", + "bfCountryDisplayName", + "biCountryDisplayName", + "khCountryDisplayName", + "cmCountryDisplayName", + "caCountryDisplayName", + "cvCountryDisplayName", + "bqCountryDisplayName", + "kyCountryDisplayName", + "cfCountryDisplayName", + "tdCountryDisplayName", + "clCountryDisplayName", + "cnCountryDisplayName", + "cxCountryDisplayName", + "ccCountryDisplayName", + "coCountryDisplayName", + "kmCountryDisplayName", + "cdCountryDisplayName", + "cgCountryDisplayName", + "ckCountryDisplayName", + "crCountryDisplayName", + "ciCountryDisplayName", + "hrCountryDisplayName", + "cuCountryDisplayName", + "cwCountryDisplayName", + "cyCountryDisplayName", + "czCountryDisplayName", + "dkCountryDisplayName", + "djCountryDisplayName", + "dmCountryDisplayName", + "doCountryDisplayName", + "tlCountryDisplayName", + "ecCountryDisplayName", + "egCountryDisplayName", + "svCountryDisplayName", + "gqCountryDisplayName", + "erCountryDisplayName", + "eeCountryDisplayName", + "szCountryDisplayName", + "etCountryDisplayName", + "fkCountryDisplayName", + "foCountryDisplayName", + "fjCountryDisplayName", + "fiCountryDisplayName", + "frCountryDisplayName", + "gfCountryDisplayName", + "pfCountryDisplayName", + "gaCountryDisplayName", + "gmCountryDisplayName", + "geCountryDisplayName", + "deCountryDisplayName", + "ghCountryDisplayName", + "giCountryDisplayName", + "grCountryDisplayName", + "glCountryDisplayName", + "gdCountryDisplayName", + "gpCountryDisplayName", + "guCountryDisplayName", + "gtCountryDisplayName", + "ggCountryDisplayName", + "gnCountryDisplayName", + "gwCountryDisplayName", + "gyCountryDisplayName", + "htCountryDisplayName", + "hmCountryDisplayName", + "hnCountryDisplayName", + "hkCountryDisplayName", + "huCountryDisplayName", + "isCountryDisplayName", + "inCountryDisplayName", + "idCountryDisplayName", + "irCountryDisplayName", + "iqCountryDisplayName", + "ieCountryDisplayName", + "imCountryDisplayName", + "ilCountryDisplayName", + "itCountryDisplayName", + "jmCountryDisplayName", + "jpCountryDisplayName", + "jeCountryDisplayName", + "joCountryDisplayName", + "kzCountryDisplayName", + "keCountryDisplayName", + "kiCountryDisplayName", + "xkCountryDisplayName", + "kwCountryDisplayName", + "kgCountryDisplayName", + "laCountryDisplayName", + "lvCountryDisplayName", + "lbCountryDisplayName", + "lsCountryDisplayName", + "lrCountryDisplayName", + "lyCountryDisplayName", + "liCountryDisplayName", + "ltCountryDisplayName", + "luCountryDisplayName", + "moCountryDisplayName", + "mkCountryDisplayName", + "mgCountryDisplayName", + "mwCountryDisplayName", + "myCountryDisplayName", + "mvCountryDisplayName", + "mlCountryDisplayName", + "mtCountryDisplayName", + "mhCountryDisplayName", + "mqCountryDisplayName", + "mrCountryDisplayName", + "muCountryDisplayName", + "ytCountryDisplayName", + "mxCountryDisplayName", + "fmCountryDisplayName", + "mdCountryDisplayName", + "mcCountryDisplayName", + "mnCountryDisplayName", + "meCountryDisplayName", + "msCountryDisplayName", + "maCountryDisplayName", + "mzCountryDisplayName", + "mmCountryDisplayName", + "naCountryDisplayName", + "nrCountryDisplayName", + "npCountryDisplayName", + "nlCountryDisplayName", + "ncCountryDisplayName", + "nzCountryDisplayName", + "niCountryDisplayName", + "neCountryDisplayName", + "ngCountryDisplayName", + "nuCountryDisplayName", + "nfCountryDisplayName", + "kpCountryDisplayName", + "mpCountryDisplayName", + "noCountryDisplayName", + "omCountryDisplayName", + "pkCountryDisplayName", + "pwCountryDisplayName", + "psCountryDisplayName", + "paCountryDisplayName", + "pgCountryDisplayName", + "pyCountryDisplayName", + "peCountryDisplayName", + "phCountryDisplayName", + "plCountryDisplayName", + "ptCountryDisplayName", + "prCountryDisplayName", + "qaCountryDisplayName", + "reCountryDisplayName", + "roCountryDisplayName", + "ruCountryDisplayName", + "rwCountryDisplayName", + "blCountryDisplayName", + "shCountryDisplayName", + "knCountryDisplayName", + "lcCountryDisplayName", + "mfCountryDisplayName", + "pmCountryDisplayName", + "vcCountryDisplayName", + "wsCountryDisplayName", + "smCountryDisplayName", + "stCountryDisplayName", + "saCountryDisplayName", + "snCountryDisplayName", + "rsCountryDisplayName", + "scCountryDisplayName", + "slCountryDisplayName", + "sgCountryDisplayName", + "sxCountryDisplayName", + "skCountryDisplayName", + "siCountryDisplayName", + "sbCountryDisplayName", + "soCountryDisplayName", + "zaCountryDisplayName", + "gsCountryDisplayName", + "krCountryDisplayName", + "ssCountryDisplayName", + "esCountryDisplayName", + "lkCountryDisplayName", + "sdCountryDisplayName", + "srCountryDisplayName", + "sjCountryDisplayName", + "seCountryDisplayName", + "chCountryDisplayName", + "syCountryDisplayName", + "twCountryDisplayName", + "tjCountryDisplayName", + "tzCountryDisplayName", + "thCountryDisplayName", + "tgCountryDisplayName", + "tkCountryDisplayName", + "toCountryDisplayName", + "ttCountryDisplayName", + "tnCountryDisplayName", + "trCountryDisplayName", + "tmCountryDisplayName", + "tcCountryDisplayName", + "tvCountryDisplayName", + "viCountryDisplayName", + "ugCountryDisplayName", + "uaCountryDisplayName", + "aeCountryDisplayName", + "gbCountryDisplayName", + "usCountryDisplayName", + "uyCountryDisplayName", + "uzCountryDisplayName", + "vuCountryDisplayName", + "vaCountryDisplayName", + "veCountryDisplayName", + "vnCountryDisplayName", + "wfCountryDisplayName", + "ehCountryDisplayName", + "yeCountryDisplayName", + "zmCountryDisplayName", + "zwCountryDisplayName", + "pay", + "allPrivateChats", + "unknownPrivateChat", + "copyClassCodeDesc", + "addToClassDesc", + "addToClassOrExchange", + "addToClassOrExchangeDesc", + "invitedToClassOrExchange", + "decline", + "declinedInvitation", + "acceptedInvitation", + "youreInvited", + "studentPermissionsDesc", + "noEligibleSpaces", + "youAddedToSpace", + "youRemovedFromSpace", + "invitedToChat", + "monthlySubscription", + "yearlySubscription", + "defaultSubscription", + "freeTrial", + "grammarAnalytics", + "total", + "noDataFound", + "promoSubscriptionExpirationDesc", + "emptyChatNameWarning", + "emptyClassNameWarning", + "emptyExchangeNameWarning", + "blurMeansTranslateTitle", + "blurMeansTranslateBody", + "someErrorTitle", + "someErrorBody", + "bestCorrectionFeedback", + "distractorFeedback", + "bestAnswerFeedback", + "definitionDefaultPrompt", + "practiceDefaultPrompt", + "correctionDefaultPrompt", + "itStartDefaultPrompt", + "languageLevelWarning", + "lockedChatWarning", + "lockSpace", + "lockChat", + "archiveSpace", + "suggestTo", + "suggestChatDesc", + "suggestExchangeDesc", + "acceptSelection", + "acceptSelectionAnyway", + "makingActivity", + "why", + "definition", + "exampleSentence", + "addToClassTitle", + "reportToTeacher", + "reportMessageTitle", + "reportMessageBody", + "noTeachersFound", + "noAddToSpacePermissions", + "alreadyInSpace", + "yourGlobalUserIdIs", + "noUsersFoundWithQuery", + "searchChatsRooms", + "groupName", + "createGroupAndInviteUsers", + "groupCanBeFoundViaSearch", + "inNoSpaces" + ], + + "he": [ + "accountInformation", + "addNewFriend", + "alreadyHaveAnAccount", + "classes", + "allCorrect", + "newWayAllGood", + "othersAreBetter", + "holdForInfo", + "greenFeedback", + "yellowFeedback", + "redFeedback", + "customInputFeedbackChoice", + "itInstructionsTitle", + "itInstructionsBody", + "toggleLanguages", + "classWelcomeChat", + "deleteSpace", + "deleteGroup", + "areYouSureDeleteClass", + "areYouSureDeleteGroup", + "cannotBeReversed", + "enterDeletedClassName", + "incorrectClassName", + "oneday", + "oneweek", + "onemonth", + "sixmonth", + "oneyear", + "gaTooltip", + "taTooltip", + "unTooltip", + "interactiveTranslatorSliderHeader", + "interactiveGrammarSliderHeader", + "interactiveTranslatorNotAllowed", + "interactiveTranslatorAllowed", + "interactiveTranslatorRequired", + "interactiveTranslatorNotAllowedDesc", + "interactiveTranslatorAllowedDesc", + "interactiveTranslatorRequiredDesc", + "notYetSet", + "multiLingualClass", + "classAnalytics", + "allClasses", + "myLearning", + "allChatsAndClasses", + "timeOfLastMessage", + "totalMessages", + "waTooltip", + "changeDateRange", + "numberOfStudents", + "classDescription", + "classDescriptionDesc", + "requestToEnroll", + "requestAnExchange", + "findLanguageExchange", + "classAnalyticsDesc", + "addStudents", + "copyClassLink", + "copyClassLinkDesc", + "copyClassCode", + "inviteStudentByUserName", + "classSettings", + "classSettingsDesc", + "selectClassRoomDominantLanguage", + "selectTargetLanguage", + "whatIsYourClassLanguageLevel", + "studentPermissions", + "interactiveTranslator", + "oneToOneChatsWithinClass", + "oneToOneChatsWithinClassDesc", + "createGroupChats", + "createGroupChatsDesc", + "shareVideo", + "shareVideoDesc", + "sharePhotos", + "sharePhotosDesc", + "shareFiles", + "shareFilesDesc", + "shareLocationDesc", + "selectLanguageLevel", + "noIdenticalLanguages", + "iWantALanguagePartnerFrom", + "worldWide", + "noResults", + "searchBy", + "iWantAConversationPartner", + "iWantALanguagePartnerWhoSpeaks", + "iWantALanguagePartnerWhoIsLearning", + "yourBirthdayPlease", + "invalidDob", + "enterYourDob", + "getStarted", + "mustBe13", + "yourBirthdayPleaseShort", + "errorPleaseRefresh", + "joinWithClassCode", + "joinWithClassCodeDesc", + "joinWithClassCodeHint", + "unableToFindClass", + "languageLevelPreA1", + "languageLevelA1", + "languageLevelA2", + "languageLevelB1", + "languageLevelB2", + "languageLevelC1", + "languageLevelC2", + "changeTheNameOfTheClass", + "changeTheNameOfTheChat", + "welcomeToYourNewClass", + "welcomeToClass", + "welcomeToPangea18Plus", + "welcomeToPangeaMinor", + "findALanguagePartner", + "setToPublicSettingsTitle", + "setToPublicSettingsDesc", + "accountSettings", + "unableToFindClassCode", + "askPangeaBot", + "sorryNoResults", + "ignoreInThisText", + "helpMeTranslate", + "needsItShortMessage", + "needsIGCShortMessage", + "needsItMessage", + "needsIgcMessage", + "tokenTranslationTitle", + "spanTranslationDesc", + "spanTranslationTitle", + "l1SpanAndGrammarTitle", + "l1SpanAndGrammarDesc", + "otherTitle", + "otherDesc", + "countryInformation", + "myLanguages", + "targetLanguage", + "sourceLanguage", + "languagesISpeak", + "updateLanguage", + "whatLanguageYouWantToLearn", + "whatIsYourBaseLanguage", + "saveChanges", + "publicProfileTitle", + "publicProfileDesc", + "error502504Title", + "error502504Desc", + "error404Title", + "error404Desc", + "errorDisableIT", + "errorDisableIGC", + "errorDisableLanguageAssistance", + "errorDisableITUserDesc", + "errorDisableIGCUserDesc", + "errorDisableLanguageAssistanceUserDesc", + "errorDisableITClassDesc", + "errorDisableIGCClassDesc", + "errorDisableLanguageAssistanceClassDesc", + "itIsDisabled", + "igcIsDisabled", + "goToLearningSettings", + "error405Title", + "error405Desc", + "loginOrSignup", + "iAgreeToThe", + "termsAndConditions", + "andCertifyIAmAtLeast13YearsOfAge", + "findAClass", + "toggleIT", + "toggleIGC", + "toggleToolSettingsDescription", + "connectedToStaging", + "learningSettings", + "classNameRequired", + "sendVoiceNotes", + "sendVoiceNotesDesc", + "chatTopic", + "chatTopicDesc", + "inviteStudentByUserNameDesc", + "classRoster", + "almostPerfect", + "prettyGood", + "letMeThink", + "clickMessageTitle", + "clickMessageBody", + "understandingMessagesTitle", + "addToClass", + "understandingMessagesBody", + "allDone", + "vocab", + "low", + "medium", + "high", + "unknownProficiency", + "changeView", + "clearAll", + "generateVocabulary", + "generatePrompts", + "subscribe", + "getAccess", + "subscriptionDesc", + "subscriptionManagement", + "currentSubscription", + "changeSubscription", + "cancelSubscription", + "selectYourPlan", + "subsciptionPlatformTooltip", + "subscriptionManagementUnavailable", + "paymentMethod", + "paymentHistory", + "emptyChatDownloadWarning", + "appUpdateAvailable", + "update", + "updateDesc", + "maybeLater", + "mainMenu", + "toggleImmersionMode", + "toggleImmersionModeDesc", + "itToggleDescription", + "igcToggleDescription", + "sendOnEnterDescription", + "alreadyInClass", + "pleaseLoginFirst", + "originalMessage", + "sentMessage", + "useType", + "notAvailable", + "taAndGaTooltip", + "definitionsToolName", + "messageTranslationsToolName", + "definitionsToolDescription", + "translationsToolDescrption", + "welcomeBack", + "classExchanges", + "createNewClass", + "newExchange", + "kickAllStudents", + "kickAllStudentsConfirmation", + "inviteAllStudents", + "inviteAllStudentsConfirmation", + "inviteStudentsFromOtherClasses", + "inviteUsersFromPangea", + "allExchanges", + "redeemPromoCode", + "enterPromoCode", + "downloadTxtFile", + "downloadCSVFile", + "promotionalSubscriptionDesc", + "originalSubscriptionPlatform", + "oneWeekTrial", + "creatingSpacePleaseWait", + "downloadXLSXFile", + "abDisplayName", + "aaDisplayName", + "afDisplayName", + "akDisplayName", + "sqDisplayName", + "amDisplayName", + "arDisplayName", + "anDisplayName", + "hyDisplayName", + "asDisplayName", + "avDisplayName", + "aeDisplayName", + "ayDisplayName", + "azDisplayName", + "bmDisplayName", + "baDisplayName", + "euDisplayName", + "beDisplayName", + "bnDisplayName", + "bhDisplayName", + "biDisplayName", + "bsDisplayName", + "brDisplayName", + "bgDisplayName", + "myDisplayName", + "caDisplayName", + "chDisplayName", + "ceDisplayName", + "nyDisplayName", + "zhDisplayName", + "cvDisplayName", + "kwDisplayName", + "coDisplayName", + "crDisplayName", + "hrDisplayName", + "csDisplayName", + "daDisplayName", + "dvDisplayName", + "nlDisplayName", + "enDisplayName", + "eoDisplayName", + "etDisplayName", + "eeDisplayName", + "foDisplayName", + "fjDisplayName", + "fiDisplayName", + "frDisplayName", + "ffDisplayName", + "glDisplayName", + "kaDisplayName", + "deDisplayName", + "elDisplayName", + "gnDisplayName", + "guDisplayName", + "htDisplayName", + "haDisplayName", + "heDisplayName", + "hzDisplayName", + "hiDisplayName", + "hoDisplayName", + "huDisplayName", + "iaDisplayName", + "idDisplayName", + "ieDisplayName", + "gaDisplayName", + "igDisplayName", + "ikDisplayName", + "ioDisplayName", + "isDisplayName", + "itDisplayName", + "iuDisplayName", + "jaDisplayName", + "jvDisplayName", + "klDisplayName", + "knDisplayName", + "krDisplayName", + "ksDisplayName", + "kkDisplayName", + "kmDisplayName", + "kiDisplayName", + "rwDisplayName", + "kyDisplayName", + "kvDisplayName", + "kgDisplayName", + "koDisplayName", + "kuDisplayName", + "kjDisplayName", + "laDisplayName", + "lbDisplayName", + "lgDisplayName", + "liDisplayName", + "lnDisplayName", + "loDisplayName", + "ltDisplayName", + "luDisplayName", + "lvDisplayName", + "gvDisplayName", + "mkDisplayName", + "mgDisplayName", + "msDisplayName", + "mlDisplayName", + "mtDisplayName", + "miDisplayName", + "mrDisplayName", + "mhDisplayName", + "mnDisplayName", + "naDisplayName", + "nvDisplayName", + "nbDisplayName", + "ndDisplayName", + "neDisplayName", + "ngDisplayName", + "nnDisplayName", + "noDisplayName", + "iiDisplayName", + "nrDisplayName", + "ocDisplayName", + "ojDisplayName", + "cuDisplayName", + "omDisplayName", + "orDisplayName", + "osDisplayName", + "paDisplayName", + "piDisplayName", + "faDisplayName", + "plDisplayName", + "psDisplayName", + "ptDisplayName", + "quDisplayName", + "rmDisplayName", + "rnDisplayName", + "roDisplayName", + "ruDisplayName", + "saDisplayName", + "scDisplayName", + "sdDisplayName", + "seDisplayName", + "smDisplayName", + "sgDisplayName", + "srDisplayName", + "gdDisplayName", + "snDisplayName", + "siDisplayName", + "skDisplayName", + "slDisplayName", + "soDisplayName", + "stDisplayName", + "esDisplayName", + "suDisplayName", + "swDisplayName", + "ssDisplayName", + "svDisplayName", + "taDisplayName", + "teDisplayName", + "tgDisplayName", + "thDisplayName", + "tiDisplayName", + "boDisplayName", + "tkDisplayName", + "tlDisplayName", + "tnDisplayName", + "toDisplayName", + "trDisplayName", + "tsDisplayName", + "ttDisplayName", + "twDisplayName", + "tyDisplayName", + "ugDisplayName", + "ukDisplayName", + "urDisplayName", + "uzDisplayName", + "veDisplayName", + "viDisplayName", + "voDisplayName", + "waDisplayName", + "cyDisplayName", + "woDisplayName", + "fyDisplayName", + "xhDisplayName", + "yiDisplayName", + "yoDisplayName", + "zaDisplayName", + "unkDisplayName", + "zuDisplayName", + "hawDisplayName", + "hmnDisplayName", + "multiDisplayName", + "cebDisplayName", + "dzDisplayName", + "iwDisplayName", + "jwDisplayName", + "moDisplayName", + "shDisplayName", + "wwCountryDisplayName", + "afCountryDisplayName", + "axCountryDisplayName", + "alCountryDisplayName", + "dzCountryDisplayName", + "asCountryDisplayName", + "adCountryDisplayName", + "aoCountryDisplayName", + "aiCountryDisplayName", + "agCountryDisplayName", + "arCountryDisplayName", + "amCountryDisplayName", + "awCountryDisplayName", + "acCountryDisplayName", + "auCountryDisplayName", + "atCountryDisplayName", + "azCountryDisplayName", + "bsCountryDisplayName", + "bhCountryDisplayName", + "bdCountryDisplayName", + "bbCountryDisplayName", + "byCountryDisplayName", + "beCountryDisplayName", + "bzCountryDisplayName", + "bjCountryDisplayName", + "bmCountryDisplayName", + "btCountryDisplayName", + "boCountryDisplayName", + "baCountryDisplayName", + "bwCountryDisplayName", + "brCountryDisplayName", + "ioCountryDisplayName", + "vgCountryDisplayName", + "bnCountryDisplayName", + "bgCountryDisplayName", + "bfCountryDisplayName", + "biCountryDisplayName", + "khCountryDisplayName", + "cmCountryDisplayName", + "caCountryDisplayName", + "cvCountryDisplayName", + "bqCountryDisplayName", + "kyCountryDisplayName", + "cfCountryDisplayName", + "tdCountryDisplayName", + "clCountryDisplayName", + "cnCountryDisplayName", + "cxCountryDisplayName", + "ccCountryDisplayName", + "coCountryDisplayName", + "kmCountryDisplayName", + "cdCountryDisplayName", + "cgCountryDisplayName", + "ckCountryDisplayName", + "crCountryDisplayName", + "ciCountryDisplayName", + "hrCountryDisplayName", + "cuCountryDisplayName", + "cwCountryDisplayName", + "cyCountryDisplayName", + "czCountryDisplayName", + "dkCountryDisplayName", + "djCountryDisplayName", + "dmCountryDisplayName", + "doCountryDisplayName", + "tlCountryDisplayName", + "ecCountryDisplayName", + "egCountryDisplayName", + "svCountryDisplayName", + "gqCountryDisplayName", + "erCountryDisplayName", + "eeCountryDisplayName", + "szCountryDisplayName", + "etCountryDisplayName", + "fkCountryDisplayName", + "foCountryDisplayName", + "fjCountryDisplayName", + "fiCountryDisplayName", + "frCountryDisplayName", + "gfCountryDisplayName", + "pfCountryDisplayName", + "gaCountryDisplayName", + "gmCountryDisplayName", + "geCountryDisplayName", + "deCountryDisplayName", + "ghCountryDisplayName", + "giCountryDisplayName", + "grCountryDisplayName", + "glCountryDisplayName", + "gdCountryDisplayName", + "gpCountryDisplayName", + "guCountryDisplayName", + "gtCountryDisplayName", + "ggCountryDisplayName", + "gnCountryDisplayName", + "gwCountryDisplayName", + "gyCountryDisplayName", + "htCountryDisplayName", + "hmCountryDisplayName", + "hnCountryDisplayName", + "hkCountryDisplayName", + "huCountryDisplayName", + "isCountryDisplayName", + "inCountryDisplayName", + "idCountryDisplayName", + "irCountryDisplayName", + "iqCountryDisplayName", + "ieCountryDisplayName", + "imCountryDisplayName", + "ilCountryDisplayName", + "itCountryDisplayName", + "jmCountryDisplayName", + "jpCountryDisplayName", + "jeCountryDisplayName", + "joCountryDisplayName", + "kzCountryDisplayName", + "keCountryDisplayName", + "kiCountryDisplayName", + "xkCountryDisplayName", + "kwCountryDisplayName", + "kgCountryDisplayName", + "laCountryDisplayName", + "lvCountryDisplayName", + "lbCountryDisplayName", + "lsCountryDisplayName", + "lrCountryDisplayName", + "lyCountryDisplayName", + "liCountryDisplayName", + "ltCountryDisplayName", + "luCountryDisplayName", + "moCountryDisplayName", + "mkCountryDisplayName", + "mgCountryDisplayName", + "mwCountryDisplayName", + "myCountryDisplayName", + "mvCountryDisplayName", + "mlCountryDisplayName", + "mtCountryDisplayName", + "mhCountryDisplayName", + "mqCountryDisplayName", + "mrCountryDisplayName", + "muCountryDisplayName", + "ytCountryDisplayName", + "mxCountryDisplayName", + "fmCountryDisplayName", + "mdCountryDisplayName", + "mcCountryDisplayName", + "mnCountryDisplayName", + "meCountryDisplayName", + "msCountryDisplayName", + "maCountryDisplayName", + "mzCountryDisplayName", + "mmCountryDisplayName", + "naCountryDisplayName", + "nrCountryDisplayName", + "npCountryDisplayName", + "nlCountryDisplayName", + "ncCountryDisplayName", + "nzCountryDisplayName", + "niCountryDisplayName", + "neCountryDisplayName", + "ngCountryDisplayName", + "nuCountryDisplayName", + "nfCountryDisplayName", + "kpCountryDisplayName", + "mpCountryDisplayName", + "noCountryDisplayName", + "omCountryDisplayName", + "pkCountryDisplayName", + "pwCountryDisplayName", + "psCountryDisplayName", + "paCountryDisplayName", + "pgCountryDisplayName", + "pyCountryDisplayName", + "peCountryDisplayName", + "phCountryDisplayName", + "plCountryDisplayName", + "ptCountryDisplayName", + "prCountryDisplayName", + "qaCountryDisplayName", + "reCountryDisplayName", + "roCountryDisplayName", + "ruCountryDisplayName", + "rwCountryDisplayName", + "blCountryDisplayName", + "shCountryDisplayName", + "knCountryDisplayName", + "lcCountryDisplayName", + "mfCountryDisplayName", + "pmCountryDisplayName", + "vcCountryDisplayName", + "wsCountryDisplayName", + "smCountryDisplayName", + "stCountryDisplayName", + "saCountryDisplayName", + "snCountryDisplayName", + "rsCountryDisplayName", + "scCountryDisplayName", + "slCountryDisplayName", + "sgCountryDisplayName", + "sxCountryDisplayName", + "skCountryDisplayName", + "siCountryDisplayName", + "sbCountryDisplayName", + "soCountryDisplayName", + "zaCountryDisplayName", + "gsCountryDisplayName", + "krCountryDisplayName", + "ssCountryDisplayName", + "esCountryDisplayName", + "lkCountryDisplayName", + "sdCountryDisplayName", + "srCountryDisplayName", + "sjCountryDisplayName", + "seCountryDisplayName", + "chCountryDisplayName", + "syCountryDisplayName", + "twCountryDisplayName", + "tjCountryDisplayName", + "tzCountryDisplayName", + "thCountryDisplayName", + "tgCountryDisplayName", + "tkCountryDisplayName", + "toCountryDisplayName", + "ttCountryDisplayName", + "tnCountryDisplayName", + "trCountryDisplayName", + "tmCountryDisplayName", + "tcCountryDisplayName", + "tvCountryDisplayName", + "viCountryDisplayName", + "ugCountryDisplayName", + "uaCountryDisplayName", + "aeCountryDisplayName", + "gbCountryDisplayName", + "usCountryDisplayName", + "uyCountryDisplayName", + "uzCountryDisplayName", + "vuCountryDisplayName", + "vaCountryDisplayName", + "veCountryDisplayName", + "vnCountryDisplayName", + "wfCountryDisplayName", + "ehCountryDisplayName", + "yeCountryDisplayName", + "zmCountryDisplayName", + "zwCountryDisplayName", + "pay", + "allPrivateChats", + "unknownPrivateChat", + "copyClassCodeDesc", + "addToClassDesc", + "addToClassOrExchange", + "addToClassOrExchangeDesc", + "invitedToClassOrExchange", + "decline", + "declinedInvitation", + "acceptedInvitation", + "youreInvited", + "studentPermissionsDesc", + "noEligibleSpaces", + "youAddedToSpace", + "youRemovedFromSpace", + "invitedToChat", + "monthlySubscription", + "yearlySubscription", + "defaultSubscription", + "freeTrial", + "grammarAnalytics", + "total", + "noDataFound", + "promoSubscriptionExpirationDesc", + "emptyChatNameWarning", + "emptyClassNameWarning", + "emptyExchangeNameWarning", + "blurMeansTranslateTitle", + "blurMeansTranslateBody", + "someErrorTitle", + "someErrorBody", + "bestCorrectionFeedback", + "distractorFeedback", + "bestAnswerFeedback", + "definitionDefaultPrompt", + "practiceDefaultPrompt", + "correctionDefaultPrompt", + "itStartDefaultPrompt", + "languageLevelWarning", + "lockedChatWarning", + "lockSpace", + "lockChat", + "archiveSpace", + "suggestTo", + "suggestChatDesc", + "suggestExchangeDesc", + "acceptSelection", + "acceptSelectionAnyway", + "makingActivity", + "why", + "definition", + "exampleSentence", + "addToClassTitle", + "reportToTeacher", + "reportMessageTitle", + "reportMessageBody", + "noTeachersFound", + "noAddToSpacePermissions", + "alreadyInSpace", + "yourGlobalUserIdIs", + "noUsersFoundWithQuery", + "searchChatsRooms", + "groupName", + "createGroupAndInviteUsers", + "groupCanBeFoundViaSearch", + "inNoSpaces" + ], + + "hi": [ + "accountInformation", + "addGroupDescription", + "addNewFriend", + "alreadyHaveAnAccount", + "classes", + "createNewGroup", + "editChatPermissions", + "groupDescription", + "groupDescriptionHasBeenChanged", + "allCorrect", + "newWayAllGood", + "othersAreBetter", + "holdForInfo", + "greenFeedback", + "yellowFeedback", + "redFeedback", + "customInputFeedbackChoice", + "itInstructionsTitle", + "itInstructionsBody", + "toggleLanguages", + "classWelcomeChat", + "deleteSpace", + "deleteGroup", + "areYouSureDeleteClass", + "areYouSureDeleteGroup", + "cannotBeReversed", + "enterDeletedClassName", + "incorrectClassName", + "oneday", + "oneweek", + "onemonth", + "sixmonth", + "oneyear", + "gaTooltip", + "taTooltip", + "unTooltip", + "interactiveTranslatorSliderHeader", + "interactiveGrammarSliderHeader", + "interactiveTranslatorNotAllowed", + "interactiveTranslatorAllowed", + "interactiveTranslatorRequired", + "interactiveTranslatorNotAllowedDesc", + "interactiveTranslatorAllowedDesc", + "interactiveTranslatorRequiredDesc", + "notYetSet", + "multiLingualClass", + "classAnalytics", + "allClasses", + "myLearning", + "allChatsAndClasses", + "timeOfLastMessage", + "totalMessages", + "waTooltip", + "changeDateRange", + "numberOfStudents", + "classDescription", + "classDescriptionDesc", + "requestToEnroll", + "requestAnExchange", + "findLanguageExchange", + "classAnalyticsDesc", + "addStudents", + "copyClassLink", + "copyClassLinkDesc", + "copyClassCode", + "inviteStudentByUserName", + "classSettings", + "classSettingsDesc", + "selectClassRoomDominantLanguage", + "selectTargetLanguage", + "whatIsYourClassLanguageLevel", + "studentPermissions", + "interactiveTranslator", + "oneToOneChatsWithinClass", + "oneToOneChatsWithinClassDesc", + "createGroupChats", + "createGroupChatsDesc", + "shareVideo", + "shareVideoDesc", + "sharePhotos", + "sharePhotosDesc", + "shareFiles", + "shareFilesDesc", + "shareLocationDesc", + "selectLanguageLevel", + "noIdenticalLanguages", + "iWantALanguagePartnerFrom", + "worldWide", + "noResults", + "searchBy", + "iWantAConversationPartner", + "iWantALanguagePartnerWhoSpeaks", + "iWantALanguagePartnerWhoIsLearning", + "yourBirthdayPlease", + "invalidDob", + "enterYourDob", + "getStarted", + "mustBe13", + "yourBirthdayPleaseShort", + "errorPleaseRefresh", + "joinWithClassCode", + "joinWithClassCodeDesc", + "joinWithClassCodeHint", + "unableToFindClass", + "languageLevelPreA1", + "languageLevelA1", + "languageLevelA2", + "languageLevelB1", + "languageLevelB2", + "languageLevelC1", + "languageLevelC2", + "changeTheNameOfTheClass", + "changeTheNameOfTheChat", + "welcomeToYourNewClass", + "welcomeToClass", + "welcomeToPangea18Plus", + "welcomeToPangeaMinor", + "findALanguagePartner", + "setToPublicSettingsTitle", + "setToPublicSettingsDesc", + "accountSettings", + "unableToFindClassCode", + "askPangeaBot", + "sorryNoResults", + "ignoreInThisText", + "helpMeTranslate", + "needsItShortMessage", + "needsIGCShortMessage", + "needsItMessage", + "needsIgcMessage", + "tokenTranslationTitle", + "spanTranslationDesc", + "spanTranslationTitle", + "l1SpanAndGrammarTitle", + "l1SpanAndGrammarDesc", + "otherTitle", + "otherDesc", + "countryInformation", + "myLanguages", + "targetLanguage", + "sourceLanguage", + "languagesISpeak", + "updateLanguage", + "whatLanguageYouWantToLearn", + "whatIsYourBaseLanguage", + "saveChanges", + "publicProfileTitle", + "publicProfileDesc", + "error502504Title", + "error502504Desc", + "error404Title", + "error404Desc", + "errorDisableIT", + "errorDisableIGC", + "errorDisableLanguageAssistance", + "errorDisableITUserDesc", + "errorDisableIGCUserDesc", + "errorDisableLanguageAssistanceUserDesc", + "errorDisableITClassDesc", + "errorDisableIGCClassDesc", + "errorDisableLanguageAssistanceClassDesc", + "itIsDisabled", + "igcIsDisabled", + "goToLearningSettings", + "error405Title", + "error405Desc", + "loginOrSignup", + "iAgreeToThe", + "termsAndConditions", + "andCertifyIAmAtLeast13YearsOfAge", + "findAClass", + "toggleIT", + "toggleIGC", + "toggleToolSettingsDescription", + "connectedToStaging", + "learningSettings", + "classNameRequired", + "sendVoiceNotes", + "sendVoiceNotesDesc", + "chatTopic", + "chatTopicDesc", + "inviteStudentByUserNameDesc", + "classRoster", + "almostPerfect", + "prettyGood", + "letMeThink", + "clickMessageTitle", + "clickMessageBody", + "understandingMessagesTitle", + "addToClass", + "understandingMessagesBody", + "allDone", + "vocab", + "low", + "medium", + "high", + "unknownProficiency", + "changeView", + "clearAll", + "generateVocabulary", + "generatePrompts", + "subscribe", + "getAccess", + "subscriptionDesc", + "subscriptionManagement", + "currentSubscription", + "changeSubscription", + "cancelSubscription", + "selectYourPlan", + "subsciptionPlatformTooltip", + "subscriptionManagementUnavailable", + "paymentMethod", + "paymentHistory", + "emptyChatDownloadWarning", + "appUpdateAvailable", + "update", + "updateDesc", + "maybeLater", + "mainMenu", + "toggleImmersionMode", + "toggleImmersionModeDesc", + "itToggleDescription", + "igcToggleDescription", + "sendOnEnterDescription", + "alreadyInClass", + "pleaseLoginFirst", + "originalMessage", + "sentMessage", + "useType", + "notAvailable", + "taAndGaTooltip", + "definitionsToolName", + "messageTranslationsToolName", + "definitionsToolDescription", + "translationsToolDescrption", + "welcomeBack", + "classExchanges", + "createNewClass", + "newExchange", + "kickAllStudents", + "kickAllStudentsConfirmation", + "inviteAllStudents", + "inviteAllStudentsConfirmation", + "inviteStudentsFromOtherClasses", + "inviteUsersFromPangea", + "allExchanges", + "redeemPromoCode", + "enterPromoCode", + "downloadTxtFile", + "downloadCSVFile", + "promotionalSubscriptionDesc", + "originalSubscriptionPlatform", + "oneWeekTrial", + "creatingSpacePleaseWait", + "downloadXLSXFile", + "abDisplayName", + "aaDisplayName", + "afDisplayName", + "akDisplayName", + "sqDisplayName", + "amDisplayName", + "arDisplayName", + "anDisplayName", + "hyDisplayName", + "asDisplayName", + "avDisplayName", + "aeDisplayName", + "ayDisplayName", + "azDisplayName", + "bmDisplayName", + "baDisplayName", + "euDisplayName", + "beDisplayName", + "bnDisplayName", + "bhDisplayName", + "biDisplayName", + "bsDisplayName", + "brDisplayName", + "bgDisplayName", + "myDisplayName", + "caDisplayName", + "chDisplayName", + "ceDisplayName", + "nyDisplayName", + "zhDisplayName", + "cvDisplayName", + "kwDisplayName", + "coDisplayName", + "crDisplayName", + "hrDisplayName", + "csDisplayName", + "daDisplayName", + "dvDisplayName", + "nlDisplayName", + "enDisplayName", + "eoDisplayName", + "etDisplayName", + "eeDisplayName", + "foDisplayName", + "fjDisplayName", + "fiDisplayName", + "frDisplayName", + "ffDisplayName", + "glDisplayName", + "kaDisplayName", + "deDisplayName", + "elDisplayName", + "gnDisplayName", + "guDisplayName", + "htDisplayName", + "haDisplayName", + "heDisplayName", + "hzDisplayName", + "hiDisplayName", + "hoDisplayName", + "huDisplayName", + "iaDisplayName", + "idDisplayName", + "ieDisplayName", + "gaDisplayName", + "igDisplayName", + "ikDisplayName", + "ioDisplayName", + "isDisplayName", + "itDisplayName", + "iuDisplayName", + "jaDisplayName", + "jvDisplayName", + "klDisplayName", + "knDisplayName", + "krDisplayName", + "ksDisplayName", + "kkDisplayName", + "kmDisplayName", + "kiDisplayName", + "rwDisplayName", + "kyDisplayName", + "kvDisplayName", + "kgDisplayName", + "koDisplayName", + "kuDisplayName", + "kjDisplayName", + "laDisplayName", + "lbDisplayName", + "lgDisplayName", + "liDisplayName", + "lnDisplayName", + "loDisplayName", + "ltDisplayName", + "luDisplayName", + "lvDisplayName", + "gvDisplayName", + "mkDisplayName", + "mgDisplayName", + "msDisplayName", + "mlDisplayName", + "mtDisplayName", + "miDisplayName", + "mrDisplayName", + "mhDisplayName", + "mnDisplayName", + "naDisplayName", + "nvDisplayName", + "nbDisplayName", + "ndDisplayName", + "neDisplayName", + "ngDisplayName", + "nnDisplayName", + "noDisplayName", + "iiDisplayName", + "nrDisplayName", + "ocDisplayName", + "ojDisplayName", + "cuDisplayName", + "omDisplayName", + "orDisplayName", + "osDisplayName", + "paDisplayName", + "piDisplayName", + "faDisplayName", + "plDisplayName", + "psDisplayName", + "ptDisplayName", + "quDisplayName", + "rmDisplayName", + "rnDisplayName", + "roDisplayName", + "ruDisplayName", + "saDisplayName", + "scDisplayName", + "sdDisplayName", + "seDisplayName", + "smDisplayName", + "sgDisplayName", + "srDisplayName", + "gdDisplayName", + "snDisplayName", + "siDisplayName", + "skDisplayName", + "slDisplayName", + "soDisplayName", + "stDisplayName", + "esDisplayName", + "suDisplayName", + "swDisplayName", + "ssDisplayName", + "svDisplayName", + "taDisplayName", + "teDisplayName", + "tgDisplayName", + "thDisplayName", + "tiDisplayName", + "boDisplayName", + "tkDisplayName", + "tlDisplayName", + "tnDisplayName", + "toDisplayName", + "trDisplayName", + "tsDisplayName", + "ttDisplayName", + "twDisplayName", + "tyDisplayName", + "ugDisplayName", + "ukDisplayName", + "urDisplayName", + "uzDisplayName", + "veDisplayName", + "viDisplayName", + "voDisplayName", + "waDisplayName", + "cyDisplayName", + "woDisplayName", + "fyDisplayName", + "xhDisplayName", + "yiDisplayName", + "yoDisplayName", + "zaDisplayName", + "unkDisplayName", + "zuDisplayName", + "hawDisplayName", + "hmnDisplayName", + "multiDisplayName", + "cebDisplayName", + "dzDisplayName", + "iwDisplayName", + "jwDisplayName", + "moDisplayName", + "shDisplayName", + "wwCountryDisplayName", + "afCountryDisplayName", + "axCountryDisplayName", + "alCountryDisplayName", + "dzCountryDisplayName", + "asCountryDisplayName", + "adCountryDisplayName", + "aoCountryDisplayName", + "aiCountryDisplayName", + "agCountryDisplayName", + "arCountryDisplayName", + "amCountryDisplayName", + "awCountryDisplayName", + "acCountryDisplayName", + "auCountryDisplayName", + "atCountryDisplayName", + "azCountryDisplayName", + "bsCountryDisplayName", + "bhCountryDisplayName", + "bdCountryDisplayName", + "bbCountryDisplayName", + "byCountryDisplayName", + "beCountryDisplayName", + "bzCountryDisplayName", + "bjCountryDisplayName", + "bmCountryDisplayName", + "btCountryDisplayName", + "boCountryDisplayName", + "baCountryDisplayName", + "bwCountryDisplayName", + "brCountryDisplayName", + "ioCountryDisplayName", + "vgCountryDisplayName", + "bnCountryDisplayName", + "bgCountryDisplayName", + "bfCountryDisplayName", + "biCountryDisplayName", + "khCountryDisplayName", + "cmCountryDisplayName", + "caCountryDisplayName", + "cvCountryDisplayName", + "bqCountryDisplayName", + "kyCountryDisplayName", + "cfCountryDisplayName", + "tdCountryDisplayName", + "clCountryDisplayName", + "cnCountryDisplayName", + "cxCountryDisplayName", + "ccCountryDisplayName", + "coCountryDisplayName", + "kmCountryDisplayName", + "cdCountryDisplayName", + "cgCountryDisplayName", + "ckCountryDisplayName", + "crCountryDisplayName", + "ciCountryDisplayName", + "hrCountryDisplayName", + "cuCountryDisplayName", + "cwCountryDisplayName", + "cyCountryDisplayName", + "czCountryDisplayName", + "dkCountryDisplayName", + "djCountryDisplayName", + "dmCountryDisplayName", + "doCountryDisplayName", + "tlCountryDisplayName", + "ecCountryDisplayName", + "egCountryDisplayName", + "svCountryDisplayName", + "gqCountryDisplayName", + "erCountryDisplayName", + "eeCountryDisplayName", + "szCountryDisplayName", + "etCountryDisplayName", + "fkCountryDisplayName", + "foCountryDisplayName", + "fjCountryDisplayName", + "fiCountryDisplayName", + "frCountryDisplayName", + "gfCountryDisplayName", + "pfCountryDisplayName", + "gaCountryDisplayName", + "gmCountryDisplayName", + "geCountryDisplayName", + "deCountryDisplayName", + "ghCountryDisplayName", + "giCountryDisplayName", + "grCountryDisplayName", + "glCountryDisplayName", + "gdCountryDisplayName", + "gpCountryDisplayName", + "guCountryDisplayName", + "gtCountryDisplayName", + "ggCountryDisplayName", + "gnCountryDisplayName", + "gwCountryDisplayName", + "gyCountryDisplayName", + "htCountryDisplayName", + "hmCountryDisplayName", + "hnCountryDisplayName", + "hkCountryDisplayName", + "huCountryDisplayName", + "isCountryDisplayName", + "inCountryDisplayName", + "idCountryDisplayName", + "irCountryDisplayName", + "iqCountryDisplayName", + "ieCountryDisplayName", + "imCountryDisplayName", + "ilCountryDisplayName", + "itCountryDisplayName", + "jmCountryDisplayName", + "jpCountryDisplayName", + "jeCountryDisplayName", + "joCountryDisplayName", + "kzCountryDisplayName", + "keCountryDisplayName", + "kiCountryDisplayName", + "xkCountryDisplayName", + "kwCountryDisplayName", + "kgCountryDisplayName", + "laCountryDisplayName", + "lvCountryDisplayName", + "lbCountryDisplayName", + "lsCountryDisplayName", + "lrCountryDisplayName", + "lyCountryDisplayName", + "liCountryDisplayName", + "ltCountryDisplayName", + "luCountryDisplayName", + "moCountryDisplayName", + "mkCountryDisplayName", + "mgCountryDisplayName", + "mwCountryDisplayName", + "myCountryDisplayName", + "mvCountryDisplayName", + "mlCountryDisplayName", + "mtCountryDisplayName", + "mhCountryDisplayName", + "mqCountryDisplayName", + "mrCountryDisplayName", + "muCountryDisplayName", + "ytCountryDisplayName", + "mxCountryDisplayName", + "fmCountryDisplayName", + "mdCountryDisplayName", + "mcCountryDisplayName", + "mnCountryDisplayName", + "meCountryDisplayName", + "msCountryDisplayName", + "maCountryDisplayName", + "mzCountryDisplayName", + "mmCountryDisplayName", + "naCountryDisplayName", + "nrCountryDisplayName", + "npCountryDisplayName", + "nlCountryDisplayName", + "ncCountryDisplayName", + "nzCountryDisplayName", + "niCountryDisplayName", + "neCountryDisplayName", + "ngCountryDisplayName", + "nuCountryDisplayName", + "nfCountryDisplayName", + "kpCountryDisplayName", + "mpCountryDisplayName", + "noCountryDisplayName", + "omCountryDisplayName", + "pkCountryDisplayName", + "pwCountryDisplayName", + "psCountryDisplayName", + "paCountryDisplayName", + "pgCountryDisplayName", + "pyCountryDisplayName", + "peCountryDisplayName", + "phCountryDisplayName", + "plCountryDisplayName", + "ptCountryDisplayName", + "prCountryDisplayName", + "qaCountryDisplayName", + "reCountryDisplayName", + "roCountryDisplayName", + "ruCountryDisplayName", + "rwCountryDisplayName", + "blCountryDisplayName", + "shCountryDisplayName", + "knCountryDisplayName", + "lcCountryDisplayName", + "mfCountryDisplayName", + "pmCountryDisplayName", + "vcCountryDisplayName", + "wsCountryDisplayName", + "smCountryDisplayName", + "stCountryDisplayName", + "saCountryDisplayName", + "snCountryDisplayName", + "rsCountryDisplayName", + "scCountryDisplayName", + "slCountryDisplayName", + "sgCountryDisplayName", + "sxCountryDisplayName", + "skCountryDisplayName", + "siCountryDisplayName", + "sbCountryDisplayName", + "soCountryDisplayName", + "zaCountryDisplayName", + "gsCountryDisplayName", + "krCountryDisplayName", + "ssCountryDisplayName", + "esCountryDisplayName", + "lkCountryDisplayName", + "sdCountryDisplayName", + "srCountryDisplayName", + "sjCountryDisplayName", + "seCountryDisplayName", + "chCountryDisplayName", + "syCountryDisplayName", + "twCountryDisplayName", + "tjCountryDisplayName", + "tzCountryDisplayName", + "thCountryDisplayName", + "tgCountryDisplayName", + "tkCountryDisplayName", + "toCountryDisplayName", + "ttCountryDisplayName", + "tnCountryDisplayName", + "trCountryDisplayName", + "tmCountryDisplayName", + "tcCountryDisplayName", + "tvCountryDisplayName", + "viCountryDisplayName", + "ugCountryDisplayName", + "uaCountryDisplayName", + "aeCountryDisplayName", + "gbCountryDisplayName", + "usCountryDisplayName", + "uyCountryDisplayName", + "uzCountryDisplayName", + "vuCountryDisplayName", + "vaCountryDisplayName", + "veCountryDisplayName", + "vnCountryDisplayName", + "wfCountryDisplayName", + "ehCountryDisplayName", + "yeCountryDisplayName", + "zmCountryDisplayName", + "zwCountryDisplayName", + "pay", + "allPrivateChats", + "unknownPrivateChat", + "copyClassCodeDesc", + "addToClassDesc", + "addToClassOrExchange", + "addToClassOrExchangeDesc", + "invitedToClassOrExchange", + "decline", + "declinedInvitation", + "acceptedInvitation", + "youreInvited", + "studentPermissionsDesc", + "noEligibleSpaces", + "youAddedToSpace", + "youRemovedFromSpace", + "invitedToChat", + "monthlySubscription", + "yearlySubscription", + "defaultSubscription", + "freeTrial", + "grammarAnalytics", + "total", + "noDataFound", + "promoSubscriptionExpirationDesc", + "emptyChatNameWarning", + "emptyClassNameWarning", + "emptyExchangeNameWarning", + "blurMeansTranslateTitle", + "blurMeansTranslateBody", + "someErrorTitle", + "someErrorBody", + "bestCorrectionFeedback", + "distractorFeedback", + "bestAnswerFeedback", + "definitionDefaultPrompt", + "practiceDefaultPrompt", + "correctionDefaultPrompt", + "itStartDefaultPrompt", + "languageLevelWarning", + "lockedChatWarning", + "lockSpace", + "lockChat", + "archiveSpace", + "suggestTo", + "suggestChatDesc", + "suggestExchangeDesc", + "acceptSelection", + "acceptSelectionAnyway", + "makingActivity", + "why", + "definition", + "exampleSentence", + "addToClassTitle", + "reportToTeacher", + "reportMessageTitle", + "reportMessageBody", + "noTeachersFound", + "noAddToSpacePermissions", + "alreadyInSpace", + "yourGlobalUserIdIs", + "noUsersFoundWithQuery", + "searchChatsRooms", + "groupName", + "createGroupAndInviteUsers", + "groupCanBeFoundViaSearch", + "inNoSpaces" + ], + + "hr": [ + "accountInformation", + "addNewFriend", + "alreadyHaveAnAccount", + "classes", + "allCorrect", + "newWayAllGood", + "othersAreBetter", + "holdForInfo", + "greenFeedback", + "yellowFeedback", + "redFeedback", + "customInputFeedbackChoice", + "itInstructionsTitle", + "itInstructionsBody", + "toggleLanguages", + "classWelcomeChat", + "deleteSpace", + "deleteGroup", + "areYouSureDeleteClass", + "areYouSureDeleteGroup", + "cannotBeReversed", + "enterDeletedClassName", + "incorrectClassName", + "oneday", + "oneweek", + "onemonth", + "sixmonth", + "oneyear", + "gaTooltip", + "taTooltip", + "unTooltip", + "interactiveTranslatorSliderHeader", + "interactiveGrammarSliderHeader", + "interactiveTranslatorNotAllowed", + "interactiveTranslatorAllowed", + "interactiveTranslatorRequired", + "interactiveTranslatorNotAllowedDesc", + "interactiveTranslatorAllowedDesc", + "interactiveTranslatorRequiredDesc", + "notYetSet", + "multiLingualClass", + "classAnalytics", + "allClasses", + "myLearning", + "allChatsAndClasses", + "timeOfLastMessage", + "totalMessages", + "waTooltip", + "changeDateRange", + "numberOfStudents", + "classDescription", + "classDescriptionDesc", + "requestToEnroll", + "requestAnExchange", + "findLanguageExchange", + "classAnalyticsDesc", + "addStudents", + "copyClassLink", + "copyClassLinkDesc", + "copyClassCode", + "inviteStudentByUserName", + "classSettings", + "classSettingsDesc", + "selectClassRoomDominantLanguage", + "selectTargetLanguage", + "whatIsYourClassLanguageLevel", + "studentPermissions", + "interactiveTranslator", + "oneToOneChatsWithinClass", + "oneToOneChatsWithinClassDesc", + "createGroupChats", + "createGroupChatsDesc", + "shareVideo", + "shareVideoDesc", + "sharePhotos", + "sharePhotosDesc", + "shareFiles", + "shareFilesDesc", + "shareLocationDesc", + "selectLanguageLevel", + "noIdenticalLanguages", + "iWantALanguagePartnerFrom", + "worldWide", + "noResults", + "searchBy", + "iWantAConversationPartner", + "iWantALanguagePartnerWhoSpeaks", + "iWantALanguagePartnerWhoIsLearning", + "yourBirthdayPlease", + "invalidDob", + "enterYourDob", + "getStarted", + "mustBe13", + "yourBirthdayPleaseShort", + "errorPleaseRefresh", + "joinWithClassCode", + "joinWithClassCodeDesc", + "joinWithClassCodeHint", + "unableToFindClass", + "languageLevelPreA1", + "languageLevelA1", + "languageLevelA2", + "languageLevelB1", + "languageLevelB2", + "languageLevelC1", + "languageLevelC2", + "changeTheNameOfTheClass", + "changeTheNameOfTheChat", + "welcomeToYourNewClass", + "welcomeToClass", + "welcomeToPangea18Plus", + "welcomeToPangeaMinor", + "findALanguagePartner", + "setToPublicSettingsTitle", + "setToPublicSettingsDesc", + "accountSettings", + "unableToFindClassCode", + "askPangeaBot", + "sorryNoResults", + "ignoreInThisText", + "helpMeTranslate", + "needsItShortMessage", + "needsIGCShortMessage", + "needsItMessage", + "needsIgcMessage", + "tokenTranslationTitle", + "spanTranslationDesc", + "spanTranslationTitle", + "l1SpanAndGrammarTitle", + "l1SpanAndGrammarDesc", + "otherTitle", + "otherDesc", + "countryInformation", + "myLanguages", + "targetLanguage", + "sourceLanguage", + "languagesISpeak", + "updateLanguage", + "whatLanguageYouWantToLearn", + "whatIsYourBaseLanguage", + "saveChanges", + "publicProfileTitle", + "publicProfileDesc", + "error502504Title", + "error502504Desc", + "error404Title", + "error404Desc", + "errorDisableIT", + "errorDisableIGC", + "errorDisableLanguageAssistance", + "errorDisableITUserDesc", + "errorDisableIGCUserDesc", + "errorDisableLanguageAssistanceUserDesc", + "errorDisableITClassDesc", + "errorDisableIGCClassDesc", + "errorDisableLanguageAssistanceClassDesc", + "itIsDisabled", + "igcIsDisabled", + "goToLearningSettings", + "error405Title", + "error405Desc", + "loginOrSignup", + "iAgreeToThe", + "termsAndConditions", + "andCertifyIAmAtLeast13YearsOfAge", + "findAClass", + "toggleIT", + "toggleIGC", + "toggleToolSettingsDescription", + "connectedToStaging", + "learningSettings", + "classNameRequired", + "sendVoiceNotes", + "sendVoiceNotesDesc", + "chatTopic", + "chatTopicDesc", + "inviteStudentByUserNameDesc", + "classRoster", + "almostPerfect", + "prettyGood", + "letMeThink", + "clickMessageTitle", + "clickMessageBody", + "understandingMessagesTitle", + "addToClass", + "understandingMessagesBody", + "allDone", + "vocab", + "low", + "medium", + "high", + "unknownProficiency", + "changeView", + "clearAll", + "generateVocabulary", + "generatePrompts", + "subscribe", + "getAccess", + "subscriptionDesc", + "subscriptionManagement", + "currentSubscription", + "changeSubscription", + "cancelSubscription", + "selectYourPlan", + "subsciptionPlatformTooltip", + "subscriptionManagementUnavailable", + "paymentMethod", + "paymentHistory", + "emptyChatDownloadWarning", + "appUpdateAvailable", + "update", + "updateDesc", + "maybeLater", + "mainMenu", + "toggleImmersionMode", + "toggleImmersionModeDesc", + "itToggleDescription", + "igcToggleDescription", + "sendOnEnterDescription", + "alreadyInClass", + "pleaseLoginFirst", + "originalMessage", + "sentMessage", + "useType", + "notAvailable", + "taAndGaTooltip", + "definitionsToolName", + "messageTranslationsToolName", + "definitionsToolDescription", + "translationsToolDescrption", + "welcomeBack", + "classExchanges", + "createNewClass", + "newExchange", + "kickAllStudents", + "kickAllStudentsConfirmation", + "inviteAllStudents", + "inviteAllStudentsConfirmation", + "inviteStudentsFromOtherClasses", + "inviteUsersFromPangea", + "allExchanges", + "redeemPromoCode", + "enterPromoCode", + "downloadTxtFile", + "downloadCSVFile", + "promotionalSubscriptionDesc", + "originalSubscriptionPlatform", + "oneWeekTrial", + "creatingSpacePleaseWait", + "downloadXLSXFile", + "abDisplayName", + "aaDisplayName", + "afDisplayName", + "akDisplayName", + "sqDisplayName", + "amDisplayName", + "arDisplayName", + "anDisplayName", + "hyDisplayName", + "asDisplayName", + "avDisplayName", + "aeDisplayName", + "ayDisplayName", + "azDisplayName", + "bmDisplayName", + "baDisplayName", + "euDisplayName", + "beDisplayName", + "bnDisplayName", + "bhDisplayName", + "biDisplayName", + "bsDisplayName", + "brDisplayName", + "bgDisplayName", + "myDisplayName", + "caDisplayName", + "chDisplayName", + "ceDisplayName", + "nyDisplayName", + "zhDisplayName", + "cvDisplayName", + "kwDisplayName", + "coDisplayName", + "crDisplayName", + "hrDisplayName", + "csDisplayName", + "daDisplayName", + "dvDisplayName", + "nlDisplayName", + "enDisplayName", + "eoDisplayName", + "etDisplayName", + "eeDisplayName", + "foDisplayName", + "fjDisplayName", + "fiDisplayName", + "frDisplayName", + "ffDisplayName", + "glDisplayName", + "kaDisplayName", + "deDisplayName", + "elDisplayName", + "gnDisplayName", + "guDisplayName", + "htDisplayName", + "haDisplayName", + "heDisplayName", + "hzDisplayName", + "hiDisplayName", + "hoDisplayName", + "huDisplayName", + "iaDisplayName", + "idDisplayName", + "ieDisplayName", + "gaDisplayName", + "igDisplayName", + "ikDisplayName", + "ioDisplayName", + "isDisplayName", + "itDisplayName", + "iuDisplayName", + "jaDisplayName", + "jvDisplayName", + "klDisplayName", + "knDisplayName", + "krDisplayName", + "ksDisplayName", + "kkDisplayName", + "kmDisplayName", + "kiDisplayName", + "rwDisplayName", + "kyDisplayName", + "kvDisplayName", + "kgDisplayName", + "koDisplayName", + "kuDisplayName", + "kjDisplayName", + "laDisplayName", + "lbDisplayName", + "lgDisplayName", + "liDisplayName", + "lnDisplayName", + "loDisplayName", + "ltDisplayName", + "luDisplayName", + "lvDisplayName", + "gvDisplayName", + "mkDisplayName", + "mgDisplayName", + "msDisplayName", + "mlDisplayName", + "mtDisplayName", + "miDisplayName", + "mrDisplayName", + "mhDisplayName", + "mnDisplayName", + "naDisplayName", + "nvDisplayName", + "nbDisplayName", + "ndDisplayName", + "neDisplayName", + "ngDisplayName", + "nnDisplayName", + "noDisplayName", + "iiDisplayName", + "nrDisplayName", + "ocDisplayName", + "ojDisplayName", + "cuDisplayName", + "omDisplayName", + "orDisplayName", + "osDisplayName", + "paDisplayName", + "piDisplayName", + "faDisplayName", + "plDisplayName", + "psDisplayName", + "ptDisplayName", + "quDisplayName", + "rmDisplayName", + "rnDisplayName", + "roDisplayName", + "ruDisplayName", + "saDisplayName", + "scDisplayName", + "sdDisplayName", + "seDisplayName", + "smDisplayName", + "sgDisplayName", + "srDisplayName", + "gdDisplayName", + "snDisplayName", + "siDisplayName", + "skDisplayName", + "slDisplayName", + "soDisplayName", + "stDisplayName", + "esDisplayName", + "suDisplayName", + "swDisplayName", + "ssDisplayName", + "svDisplayName", + "taDisplayName", + "teDisplayName", + "tgDisplayName", + "thDisplayName", + "tiDisplayName", + "boDisplayName", + "tkDisplayName", + "tlDisplayName", + "tnDisplayName", + "toDisplayName", + "trDisplayName", + "tsDisplayName", + "ttDisplayName", + "twDisplayName", + "tyDisplayName", + "ugDisplayName", + "ukDisplayName", + "urDisplayName", + "uzDisplayName", + "veDisplayName", + "viDisplayName", + "voDisplayName", + "waDisplayName", + "cyDisplayName", + "woDisplayName", + "fyDisplayName", + "xhDisplayName", + "yiDisplayName", + "yoDisplayName", + "zaDisplayName", + "unkDisplayName", + "zuDisplayName", + "hawDisplayName", + "hmnDisplayName", + "multiDisplayName", + "cebDisplayName", + "dzDisplayName", + "iwDisplayName", + "jwDisplayName", + "moDisplayName", + "shDisplayName", + "wwCountryDisplayName", + "afCountryDisplayName", + "axCountryDisplayName", + "alCountryDisplayName", + "dzCountryDisplayName", + "asCountryDisplayName", + "adCountryDisplayName", + "aoCountryDisplayName", + "aiCountryDisplayName", + "agCountryDisplayName", + "arCountryDisplayName", + "amCountryDisplayName", + "awCountryDisplayName", + "acCountryDisplayName", + "auCountryDisplayName", + "atCountryDisplayName", + "azCountryDisplayName", + "bsCountryDisplayName", + "bhCountryDisplayName", + "bdCountryDisplayName", + "bbCountryDisplayName", + "byCountryDisplayName", + "beCountryDisplayName", + "bzCountryDisplayName", + "bjCountryDisplayName", + "bmCountryDisplayName", + "btCountryDisplayName", + "boCountryDisplayName", + "baCountryDisplayName", + "bwCountryDisplayName", + "brCountryDisplayName", + "ioCountryDisplayName", + "vgCountryDisplayName", + "bnCountryDisplayName", + "bgCountryDisplayName", + "bfCountryDisplayName", + "biCountryDisplayName", + "khCountryDisplayName", + "cmCountryDisplayName", + "caCountryDisplayName", + "cvCountryDisplayName", + "bqCountryDisplayName", + "kyCountryDisplayName", + "cfCountryDisplayName", + "tdCountryDisplayName", + "clCountryDisplayName", + "cnCountryDisplayName", + "cxCountryDisplayName", + "ccCountryDisplayName", + "coCountryDisplayName", + "kmCountryDisplayName", + "cdCountryDisplayName", + "cgCountryDisplayName", + "ckCountryDisplayName", + "crCountryDisplayName", + "ciCountryDisplayName", + "hrCountryDisplayName", + "cuCountryDisplayName", + "cwCountryDisplayName", + "cyCountryDisplayName", + "czCountryDisplayName", + "dkCountryDisplayName", + "djCountryDisplayName", + "dmCountryDisplayName", + "doCountryDisplayName", + "tlCountryDisplayName", + "ecCountryDisplayName", + "egCountryDisplayName", + "svCountryDisplayName", + "gqCountryDisplayName", + "erCountryDisplayName", + "eeCountryDisplayName", + "szCountryDisplayName", + "etCountryDisplayName", + "fkCountryDisplayName", + "foCountryDisplayName", + "fjCountryDisplayName", + "fiCountryDisplayName", + "frCountryDisplayName", + "gfCountryDisplayName", + "pfCountryDisplayName", + "gaCountryDisplayName", + "gmCountryDisplayName", + "geCountryDisplayName", + "deCountryDisplayName", + "ghCountryDisplayName", + "giCountryDisplayName", + "grCountryDisplayName", + "glCountryDisplayName", + "gdCountryDisplayName", + "gpCountryDisplayName", + "guCountryDisplayName", + "gtCountryDisplayName", + "ggCountryDisplayName", + "gnCountryDisplayName", + "gwCountryDisplayName", + "gyCountryDisplayName", + "htCountryDisplayName", + "hmCountryDisplayName", + "hnCountryDisplayName", + "hkCountryDisplayName", + "huCountryDisplayName", + "isCountryDisplayName", + "inCountryDisplayName", + "idCountryDisplayName", + "irCountryDisplayName", + "iqCountryDisplayName", + "ieCountryDisplayName", + "imCountryDisplayName", + "ilCountryDisplayName", + "itCountryDisplayName", + "jmCountryDisplayName", + "jpCountryDisplayName", + "jeCountryDisplayName", + "joCountryDisplayName", + "kzCountryDisplayName", + "keCountryDisplayName", + "kiCountryDisplayName", + "xkCountryDisplayName", + "kwCountryDisplayName", + "kgCountryDisplayName", + "laCountryDisplayName", + "lvCountryDisplayName", + "lbCountryDisplayName", + "lsCountryDisplayName", + "lrCountryDisplayName", + "lyCountryDisplayName", + "liCountryDisplayName", + "ltCountryDisplayName", + "luCountryDisplayName", + "moCountryDisplayName", + "mkCountryDisplayName", + "mgCountryDisplayName", + "mwCountryDisplayName", + "myCountryDisplayName", + "mvCountryDisplayName", + "mlCountryDisplayName", + "mtCountryDisplayName", + "mhCountryDisplayName", + "mqCountryDisplayName", + "mrCountryDisplayName", + "muCountryDisplayName", + "ytCountryDisplayName", + "mxCountryDisplayName", + "fmCountryDisplayName", + "mdCountryDisplayName", + "mcCountryDisplayName", + "mnCountryDisplayName", + "meCountryDisplayName", + "msCountryDisplayName", + "maCountryDisplayName", + "mzCountryDisplayName", + "mmCountryDisplayName", + "naCountryDisplayName", + "nrCountryDisplayName", + "npCountryDisplayName", + "nlCountryDisplayName", + "ncCountryDisplayName", + "nzCountryDisplayName", + "niCountryDisplayName", + "neCountryDisplayName", + "ngCountryDisplayName", + "nuCountryDisplayName", + "nfCountryDisplayName", + "kpCountryDisplayName", + "mpCountryDisplayName", + "noCountryDisplayName", + "omCountryDisplayName", + "pkCountryDisplayName", + "pwCountryDisplayName", + "psCountryDisplayName", + "paCountryDisplayName", + "pgCountryDisplayName", + "pyCountryDisplayName", + "peCountryDisplayName", + "phCountryDisplayName", + "plCountryDisplayName", + "ptCountryDisplayName", + "prCountryDisplayName", + "qaCountryDisplayName", + "reCountryDisplayName", + "roCountryDisplayName", + "ruCountryDisplayName", + "rwCountryDisplayName", + "blCountryDisplayName", + "shCountryDisplayName", + "knCountryDisplayName", + "lcCountryDisplayName", + "mfCountryDisplayName", + "pmCountryDisplayName", + "vcCountryDisplayName", + "wsCountryDisplayName", + "smCountryDisplayName", + "stCountryDisplayName", + "saCountryDisplayName", + "snCountryDisplayName", + "rsCountryDisplayName", + "scCountryDisplayName", + "slCountryDisplayName", + "sgCountryDisplayName", + "sxCountryDisplayName", + "skCountryDisplayName", + "siCountryDisplayName", + "sbCountryDisplayName", + "soCountryDisplayName", + "zaCountryDisplayName", + "gsCountryDisplayName", + "krCountryDisplayName", + "ssCountryDisplayName", + "esCountryDisplayName", + "lkCountryDisplayName", + "sdCountryDisplayName", + "srCountryDisplayName", + "sjCountryDisplayName", + "seCountryDisplayName", + "chCountryDisplayName", + "syCountryDisplayName", + "twCountryDisplayName", + "tjCountryDisplayName", + "tzCountryDisplayName", + "thCountryDisplayName", + "tgCountryDisplayName", + "tkCountryDisplayName", + "toCountryDisplayName", + "ttCountryDisplayName", + "tnCountryDisplayName", + "trCountryDisplayName", + "tmCountryDisplayName", + "tcCountryDisplayName", + "tvCountryDisplayName", + "viCountryDisplayName", + "ugCountryDisplayName", + "uaCountryDisplayName", + "aeCountryDisplayName", + "gbCountryDisplayName", + "usCountryDisplayName", + "uyCountryDisplayName", + "uzCountryDisplayName", + "vuCountryDisplayName", + "vaCountryDisplayName", + "veCountryDisplayName", + "vnCountryDisplayName", + "wfCountryDisplayName", + "ehCountryDisplayName", + "yeCountryDisplayName", + "zmCountryDisplayName", + "zwCountryDisplayName", + "pay", + "allPrivateChats", + "unknownPrivateChat", + "copyClassCodeDesc", + "addToClassDesc", + "addToClassOrExchange", + "addToClassOrExchangeDesc", + "invitedToClassOrExchange", + "decline", + "declinedInvitation", + "acceptedInvitation", + "youreInvited", + "studentPermissionsDesc", + "noEligibleSpaces", + "youAddedToSpace", + "youRemovedFromSpace", + "invitedToChat", + "monthlySubscription", + "yearlySubscription", + "defaultSubscription", + "freeTrial", + "grammarAnalytics", + "total", + "noDataFound", + "promoSubscriptionExpirationDesc", + "emptyChatNameWarning", + "emptyClassNameWarning", + "emptyExchangeNameWarning", + "blurMeansTranslateTitle", + "blurMeansTranslateBody", + "someErrorTitle", + "someErrorBody", + "bestCorrectionFeedback", + "distractorFeedback", + "bestAnswerFeedback", + "definitionDefaultPrompt", + "practiceDefaultPrompt", + "correctionDefaultPrompt", + "itStartDefaultPrompt", + "languageLevelWarning", + "lockedChatWarning", + "lockSpace", + "lockChat", + "archiveSpace", + "suggestTo", + "suggestChatDesc", + "suggestExchangeDesc", + "acceptSelection", + "acceptSelectionAnyway", + "makingActivity", + "why", + "definition", + "exampleSentence", + "addToClassTitle", + "reportToTeacher", + "reportMessageTitle", + "reportMessageBody", + "noTeachersFound", + "noAddToSpacePermissions", + "alreadyInSpace", + "yourGlobalUserIdIs", + "noUsersFoundWithQuery", + "searchChatsRooms", + "groupName", + "createGroupAndInviteUsers", + "groupCanBeFoundViaSearch", + "inNoSpaces" + ], + + "hu": [ + "accountInformation", + "addNewFriend", + "alreadyHaveAnAccount", + "classes", + "allCorrect", + "newWayAllGood", + "othersAreBetter", + "holdForInfo", + "greenFeedback", + "yellowFeedback", + "redFeedback", + "customInputFeedbackChoice", + "itInstructionsTitle", + "itInstructionsBody", + "toggleLanguages", + "classWelcomeChat", + "deleteSpace", + "deleteGroup", + "areYouSureDeleteClass", + "areYouSureDeleteGroup", + "cannotBeReversed", + "enterDeletedClassName", + "incorrectClassName", + "oneday", + "oneweek", + "onemonth", + "sixmonth", + "oneyear", + "gaTooltip", + "taTooltip", + "unTooltip", + "interactiveTranslatorSliderHeader", + "interactiveGrammarSliderHeader", + "interactiveTranslatorNotAllowed", + "interactiveTranslatorAllowed", + "interactiveTranslatorRequired", + "interactiveTranslatorNotAllowedDesc", + "interactiveTranslatorAllowedDesc", + "interactiveTranslatorRequiredDesc", + "notYetSet", + "multiLingualClass", + "classAnalytics", + "allClasses", + "myLearning", + "allChatsAndClasses", + "timeOfLastMessage", + "totalMessages", + "waTooltip", + "changeDateRange", + "numberOfStudents", + "classDescription", + "classDescriptionDesc", + "requestToEnroll", + "requestAnExchange", + "findLanguageExchange", + "classAnalyticsDesc", + "addStudents", + "copyClassLink", + "copyClassLinkDesc", + "copyClassCode", + "inviteStudentByUserName", + "classSettings", + "classSettingsDesc", + "selectClassRoomDominantLanguage", + "selectTargetLanguage", + "whatIsYourClassLanguageLevel", + "studentPermissions", + "interactiveTranslator", + "oneToOneChatsWithinClass", + "oneToOneChatsWithinClassDesc", + "createGroupChats", + "createGroupChatsDesc", + "shareVideo", + "shareVideoDesc", + "sharePhotos", + "sharePhotosDesc", + "shareFiles", + "shareFilesDesc", + "shareLocationDesc", + "selectLanguageLevel", + "noIdenticalLanguages", + "iWantALanguagePartnerFrom", + "worldWide", + "noResults", + "searchBy", + "iWantAConversationPartner", + "iWantALanguagePartnerWhoSpeaks", + "iWantALanguagePartnerWhoIsLearning", + "yourBirthdayPlease", + "invalidDob", + "enterYourDob", + "getStarted", + "mustBe13", + "yourBirthdayPleaseShort", + "errorPleaseRefresh", + "joinWithClassCode", + "joinWithClassCodeDesc", + "joinWithClassCodeHint", + "unableToFindClass", + "languageLevelPreA1", + "languageLevelA1", + "languageLevelA2", + "languageLevelB1", + "languageLevelB2", + "languageLevelC1", + "languageLevelC2", + "changeTheNameOfTheClass", + "changeTheNameOfTheChat", + "welcomeToYourNewClass", + "welcomeToClass", + "welcomeToPangea18Plus", + "welcomeToPangeaMinor", + "findALanguagePartner", + "setToPublicSettingsTitle", + "setToPublicSettingsDesc", + "accountSettings", + "unableToFindClassCode", + "askPangeaBot", + "sorryNoResults", + "ignoreInThisText", + "helpMeTranslate", + "needsItShortMessage", + "needsIGCShortMessage", + "needsItMessage", + "needsIgcMessage", + "tokenTranslationTitle", + "spanTranslationDesc", + "spanTranslationTitle", + "l1SpanAndGrammarTitle", + "l1SpanAndGrammarDesc", + "otherTitle", + "otherDesc", + "countryInformation", + "myLanguages", + "targetLanguage", + "sourceLanguage", + "languagesISpeak", + "updateLanguage", + "whatLanguageYouWantToLearn", + "whatIsYourBaseLanguage", + "saveChanges", + "publicProfileTitle", + "publicProfileDesc", + "error502504Title", + "error502504Desc", + "error404Title", + "error404Desc", + "errorDisableIT", + "errorDisableIGC", + "errorDisableLanguageAssistance", + "errorDisableITUserDesc", + "errorDisableIGCUserDesc", + "errorDisableLanguageAssistanceUserDesc", + "errorDisableITClassDesc", + "errorDisableIGCClassDesc", + "errorDisableLanguageAssistanceClassDesc", + "itIsDisabled", + "igcIsDisabled", + "goToLearningSettings", + "error405Title", + "error405Desc", + "loginOrSignup", + "iAgreeToThe", + "termsAndConditions", + "andCertifyIAmAtLeast13YearsOfAge", + "findAClass", + "toggleIT", + "toggleIGC", + "toggleToolSettingsDescription", + "connectedToStaging", + "learningSettings", + "classNameRequired", + "sendVoiceNotes", + "sendVoiceNotesDesc", + "chatTopic", + "chatTopicDesc", + "inviteStudentByUserNameDesc", + "classRoster", + "almostPerfect", + "prettyGood", + "letMeThink", + "clickMessageTitle", + "clickMessageBody", + "understandingMessagesTitle", + "addToClass", + "understandingMessagesBody", + "allDone", + "vocab", + "low", + "medium", + "high", + "unknownProficiency", + "changeView", + "clearAll", + "generateVocabulary", + "generatePrompts", + "subscribe", + "getAccess", + "subscriptionDesc", + "subscriptionManagement", + "currentSubscription", + "changeSubscription", + "cancelSubscription", + "selectYourPlan", + "subsciptionPlatformTooltip", + "subscriptionManagementUnavailable", + "paymentMethod", + "paymentHistory", + "emptyChatDownloadWarning", + "appUpdateAvailable", + "update", + "updateDesc", + "maybeLater", + "mainMenu", + "toggleImmersionMode", + "toggleImmersionModeDesc", + "itToggleDescription", + "igcToggleDescription", + "sendOnEnterDescription", + "alreadyInClass", + "pleaseLoginFirst", + "originalMessage", + "sentMessage", + "useType", + "notAvailable", + "taAndGaTooltip", + "definitionsToolName", + "messageTranslationsToolName", + "definitionsToolDescription", + "translationsToolDescrption", + "welcomeBack", + "classExchanges", + "createNewClass", + "newExchange", + "kickAllStudents", + "kickAllStudentsConfirmation", + "inviteAllStudents", + "inviteAllStudentsConfirmation", + "inviteStudentsFromOtherClasses", + "inviteUsersFromPangea", + "allExchanges", + "redeemPromoCode", + "enterPromoCode", + "downloadTxtFile", + "downloadCSVFile", + "promotionalSubscriptionDesc", + "originalSubscriptionPlatform", + "oneWeekTrial", + "creatingSpacePleaseWait", + "downloadXLSXFile", + "abDisplayName", + "aaDisplayName", + "afDisplayName", + "akDisplayName", + "sqDisplayName", + "amDisplayName", + "arDisplayName", + "anDisplayName", + "hyDisplayName", + "asDisplayName", + "avDisplayName", + "aeDisplayName", + "ayDisplayName", + "azDisplayName", + "bmDisplayName", + "baDisplayName", + "euDisplayName", + "beDisplayName", + "bnDisplayName", + "bhDisplayName", + "biDisplayName", + "bsDisplayName", + "brDisplayName", + "bgDisplayName", + "myDisplayName", + "caDisplayName", + "chDisplayName", + "ceDisplayName", + "nyDisplayName", + "zhDisplayName", + "cvDisplayName", + "kwDisplayName", + "coDisplayName", + "crDisplayName", + "hrDisplayName", + "csDisplayName", + "daDisplayName", + "dvDisplayName", + "nlDisplayName", + "enDisplayName", + "eoDisplayName", + "etDisplayName", + "eeDisplayName", + "foDisplayName", + "fjDisplayName", + "fiDisplayName", + "frDisplayName", + "ffDisplayName", + "glDisplayName", + "kaDisplayName", + "deDisplayName", + "elDisplayName", + "gnDisplayName", + "guDisplayName", + "htDisplayName", + "haDisplayName", + "heDisplayName", + "hzDisplayName", + "hiDisplayName", + "hoDisplayName", + "huDisplayName", + "iaDisplayName", + "idDisplayName", + "ieDisplayName", + "gaDisplayName", + "igDisplayName", + "ikDisplayName", + "ioDisplayName", + "isDisplayName", + "itDisplayName", + "iuDisplayName", + "jaDisplayName", + "jvDisplayName", + "klDisplayName", + "knDisplayName", + "krDisplayName", + "ksDisplayName", + "kkDisplayName", + "kmDisplayName", + "kiDisplayName", + "rwDisplayName", + "kyDisplayName", + "kvDisplayName", + "kgDisplayName", + "koDisplayName", + "kuDisplayName", + "kjDisplayName", + "laDisplayName", + "lbDisplayName", + "lgDisplayName", + "liDisplayName", + "lnDisplayName", + "loDisplayName", + "ltDisplayName", + "luDisplayName", + "lvDisplayName", + "gvDisplayName", + "mkDisplayName", + "mgDisplayName", + "msDisplayName", + "mlDisplayName", + "mtDisplayName", + "miDisplayName", + "mrDisplayName", + "mhDisplayName", + "mnDisplayName", + "naDisplayName", + "nvDisplayName", + "nbDisplayName", + "ndDisplayName", + "neDisplayName", + "ngDisplayName", + "nnDisplayName", + "noDisplayName", + "iiDisplayName", + "nrDisplayName", + "ocDisplayName", + "ojDisplayName", + "cuDisplayName", + "omDisplayName", + "orDisplayName", + "osDisplayName", + "paDisplayName", + "piDisplayName", + "faDisplayName", + "plDisplayName", + "psDisplayName", + "ptDisplayName", + "quDisplayName", + "rmDisplayName", + "rnDisplayName", + "roDisplayName", + "ruDisplayName", + "saDisplayName", + "scDisplayName", + "sdDisplayName", + "seDisplayName", + "smDisplayName", + "sgDisplayName", + "srDisplayName", + "gdDisplayName", + "snDisplayName", + "siDisplayName", + "skDisplayName", + "slDisplayName", + "soDisplayName", + "stDisplayName", + "esDisplayName", + "suDisplayName", + "swDisplayName", + "ssDisplayName", + "svDisplayName", + "taDisplayName", + "teDisplayName", + "tgDisplayName", + "thDisplayName", + "tiDisplayName", + "boDisplayName", + "tkDisplayName", + "tlDisplayName", + "tnDisplayName", + "toDisplayName", + "trDisplayName", + "tsDisplayName", + "ttDisplayName", + "twDisplayName", + "tyDisplayName", + "ugDisplayName", + "ukDisplayName", + "urDisplayName", + "uzDisplayName", + "veDisplayName", + "viDisplayName", + "voDisplayName", + "waDisplayName", + "cyDisplayName", + "woDisplayName", + "fyDisplayName", + "xhDisplayName", + "yiDisplayName", + "yoDisplayName", + "zaDisplayName", + "unkDisplayName", + "zuDisplayName", + "hawDisplayName", + "hmnDisplayName", + "multiDisplayName", + "cebDisplayName", + "dzDisplayName", + "iwDisplayName", + "jwDisplayName", + "moDisplayName", + "shDisplayName", + "wwCountryDisplayName", + "afCountryDisplayName", + "axCountryDisplayName", + "alCountryDisplayName", + "dzCountryDisplayName", + "asCountryDisplayName", + "adCountryDisplayName", + "aoCountryDisplayName", + "aiCountryDisplayName", + "agCountryDisplayName", + "arCountryDisplayName", + "amCountryDisplayName", + "awCountryDisplayName", + "acCountryDisplayName", + "auCountryDisplayName", + "atCountryDisplayName", + "azCountryDisplayName", + "bsCountryDisplayName", + "bhCountryDisplayName", + "bdCountryDisplayName", + "bbCountryDisplayName", + "byCountryDisplayName", + "beCountryDisplayName", + "bzCountryDisplayName", + "bjCountryDisplayName", + "bmCountryDisplayName", + "btCountryDisplayName", + "boCountryDisplayName", + "baCountryDisplayName", + "bwCountryDisplayName", + "brCountryDisplayName", + "ioCountryDisplayName", + "vgCountryDisplayName", + "bnCountryDisplayName", + "bgCountryDisplayName", + "bfCountryDisplayName", + "biCountryDisplayName", + "khCountryDisplayName", + "cmCountryDisplayName", + "caCountryDisplayName", + "cvCountryDisplayName", + "bqCountryDisplayName", + "kyCountryDisplayName", + "cfCountryDisplayName", + "tdCountryDisplayName", + "clCountryDisplayName", + "cnCountryDisplayName", + "cxCountryDisplayName", + "ccCountryDisplayName", + "coCountryDisplayName", + "kmCountryDisplayName", + "cdCountryDisplayName", + "cgCountryDisplayName", + "ckCountryDisplayName", + "crCountryDisplayName", + "ciCountryDisplayName", + "hrCountryDisplayName", + "cuCountryDisplayName", + "cwCountryDisplayName", + "cyCountryDisplayName", + "czCountryDisplayName", + "dkCountryDisplayName", + "djCountryDisplayName", + "dmCountryDisplayName", + "doCountryDisplayName", + "tlCountryDisplayName", + "ecCountryDisplayName", + "egCountryDisplayName", + "svCountryDisplayName", + "gqCountryDisplayName", + "erCountryDisplayName", + "eeCountryDisplayName", + "szCountryDisplayName", + "etCountryDisplayName", + "fkCountryDisplayName", + "foCountryDisplayName", + "fjCountryDisplayName", + "fiCountryDisplayName", + "frCountryDisplayName", + "gfCountryDisplayName", + "pfCountryDisplayName", + "gaCountryDisplayName", + "gmCountryDisplayName", + "geCountryDisplayName", + "deCountryDisplayName", + "ghCountryDisplayName", + "giCountryDisplayName", + "grCountryDisplayName", + "glCountryDisplayName", + "gdCountryDisplayName", + "gpCountryDisplayName", + "guCountryDisplayName", + "gtCountryDisplayName", + "ggCountryDisplayName", + "gnCountryDisplayName", + "gwCountryDisplayName", + "gyCountryDisplayName", + "htCountryDisplayName", + "hmCountryDisplayName", + "hnCountryDisplayName", + "hkCountryDisplayName", + "huCountryDisplayName", + "isCountryDisplayName", + "inCountryDisplayName", + "idCountryDisplayName", + "irCountryDisplayName", + "iqCountryDisplayName", + "ieCountryDisplayName", + "imCountryDisplayName", + "ilCountryDisplayName", + "itCountryDisplayName", + "jmCountryDisplayName", + "jpCountryDisplayName", + "jeCountryDisplayName", + "joCountryDisplayName", + "kzCountryDisplayName", + "keCountryDisplayName", + "kiCountryDisplayName", + "xkCountryDisplayName", + "kwCountryDisplayName", + "kgCountryDisplayName", + "laCountryDisplayName", + "lvCountryDisplayName", + "lbCountryDisplayName", + "lsCountryDisplayName", + "lrCountryDisplayName", + "lyCountryDisplayName", + "liCountryDisplayName", + "ltCountryDisplayName", + "luCountryDisplayName", + "moCountryDisplayName", + "mkCountryDisplayName", + "mgCountryDisplayName", + "mwCountryDisplayName", + "myCountryDisplayName", + "mvCountryDisplayName", + "mlCountryDisplayName", + "mtCountryDisplayName", + "mhCountryDisplayName", + "mqCountryDisplayName", + "mrCountryDisplayName", + "muCountryDisplayName", + "ytCountryDisplayName", + "mxCountryDisplayName", + "fmCountryDisplayName", + "mdCountryDisplayName", + "mcCountryDisplayName", + "mnCountryDisplayName", + "meCountryDisplayName", + "msCountryDisplayName", + "maCountryDisplayName", + "mzCountryDisplayName", + "mmCountryDisplayName", + "naCountryDisplayName", + "nrCountryDisplayName", + "npCountryDisplayName", + "nlCountryDisplayName", + "ncCountryDisplayName", + "nzCountryDisplayName", + "niCountryDisplayName", + "neCountryDisplayName", + "ngCountryDisplayName", + "nuCountryDisplayName", + "nfCountryDisplayName", + "kpCountryDisplayName", + "mpCountryDisplayName", + "noCountryDisplayName", + "omCountryDisplayName", + "pkCountryDisplayName", + "pwCountryDisplayName", + "psCountryDisplayName", + "paCountryDisplayName", + "pgCountryDisplayName", + "pyCountryDisplayName", + "peCountryDisplayName", + "phCountryDisplayName", + "plCountryDisplayName", + "ptCountryDisplayName", + "prCountryDisplayName", + "qaCountryDisplayName", + "reCountryDisplayName", + "roCountryDisplayName", + "ruCountryDisplayName", + "rwCountryDisplayName", + "blCountryDisplayName", + "shCountryDisplayName", + "knCountryDisplayName", + "lcCountryDisplayName", + "mfCountryDisplayName", + "pmCountryDisplayName", + "vcCountryDisplayName", + "wsCountryDisplayName", + "smCountryDisplayName", + "stCountryDisplayName", + "saCountryDisplayName", + "snCountryDisplayName", + "rsCountryDisplayName", + "scCountryDisplayName", + "slCountryDisplayName", + "sgCountryDisplayName", + "sxCountryDisplayName", + "skCountryDisplayName", + "siCountryDisplayName", + "sbCountryDisplayName", + "soCountryDisplayName", + "zaCountryDisplayName", + "gsCountryDisplayName", + "krCountryDisplayName", + "ssCountryDisplayName", + "esCountryDisplayName", + "lkCountryDisplayName", + "sdCountryDisplayName", + "srCountryDisplayName", + "sjCountryDisplayName", + "seCountryDisplayName", + "chCountryDisplayName", + "syCountryDisplayName", + "twCountryDisplayName", + "tjCountryDisplayName", + "tzCountryDisplayName", + "thCountryDisplayName", + "tgCountryDisplayName", + "tkCountryDisplayName", + "toCountryDisplayName", + "ttCountryDisplayName", + "tnCountryDisplayName", + "trCountryDisplayName", + "tmCountryDisplayName", + "tcCountryDisplayName", + "tvCountryDisplayName", + "viCountryDisplayName", + "ugCountryDisplayName", + "uaCountryDisplayName", + "aeCountryDisplayName", + "gbCountryDisplayName", + "usCountryDisplayName", + "uyCountryDisplayName", + "uzCountryDisplayName", + "vuCountryDisplayName", + "vaCountryDisplayName", + "veCountryDisplayName", + "vnCountryDisplayName", + "wfCountryDisplayName", + "ehCountryDisplayName", + "yeCountryDisplayName", + "zmCountryDisplayName", + "zwCountryDisplayName", + "pay", + "allPrivateChats", + "unknownPrivateChat", + "copyClassCodeDesc", + "addToClassDesc", + "addToClassOrExchange", + "addToClassOrExchangeDesc", + "invitedToClassOrExchange", + "decline", + "declinedInvitation", + "acceptedInvitation", + "youreInvited", + "studentPermissionsDesc", + "noEligibleSpaces", + "youAddedToSpace", + "youRemovedFromSpace", + "invitedToChat", + "monthlySubscription", + "yearlySubscription", + "defaultSubscription", + "freeTrial", + "grammarAnalytics", + "total", + "noDataFound", + "promoSubscriptionExpirationDesc", + "emptyChatNameWarning", + "emptyClassNameWarning", + "emptyExchangeNameWarning", + "blurMeansTranslateTitle", + "blurMeansTranslateBody", + "someErrorTitle", + "someErrorBody", + "bestCorrectionFeedback", + "distractorFeedback", + "bestAnswerFeedback", + "definitionDefaultPrompt", + "practiceDefaultPrompt", + "correctionDefaultPrompt", + "itStartDefaultPrompt", + "languageLevelWarning", + "lockedChatWarning", + "lockSpace", + "lockChat", + "archiveSpace", + "suggestTo", + "suggestChatDesc", + "suggestExchangeDesc", + "acceptSelection", + "acceptSelectionAnyway", + "makingActivity", + "why", + "definition", + "exampleSentence", + "addToClassTitle", + "reportToTeacher", + "reportMessageTitle", + "reportMessageBody", + "noTeachersFound", + "noAddToSpacePermissions", + "alreadyInSpace", + "yourGlobalUserIdIs", + "noUsersFoundWithQuery", + "searchChatsRooms", + "groupName", + "createGroupAndInviteUsers", + "groupCanBeFoundViaSearch", + "inNoSpaces" + ], + + "id": [ + "accountInformation", + "addNewFriend", + "alreadyHaveAnAccount", + "classes", + "allCorrect", + "newWayAllGood", + "othersAreBetter", + "holdForInfo", + "greenFeedback", + "yellowFeedback", + "redFeedback", + "customInputFeedbackChoice", + "itInstructionsTitle", + "itInstructionsBody", + "toggleLanguages", + "classWelcomeChat", + "deleteSpace", + "deleteGroup", + "areYouSureDeleteClass", + "areYouSureDeleteGroup", + "cannotBeReversed", + "enterDeletedClassName", + "incorrectClassName", + "oneday", + "oneweek", + "onemonth", + "sixmonth", + "oneyear", + "gaTooltip", + "taTooltip", + "unTooltip", + "interactiveTranslatorSliderHeader", + "interactiveGrammarSliderHeader", + "interactiveTranslatorNotAllowed", + "interactiveTranslatorAllowed", + "interactiveTranslatorRequired", + "interactiveTranslatorNotAllowedDesc", + "interactiveTranslatorAllowedDesc", + "interactiveTranslatorRequiredDesc", + "notYetSet", + "multiLingualClass", + "classAnalytics", + "allClasses", + "myLearning", + "allChatsAndClasses", + "timeOfLastMessage", + "totalMessages", + "waTooltip", + "changeDateRange", + "numberOfStudents", + "classDescription", + "classDescriptionDesc", + "requestToEnroll", + "requestAnExchange", + "findLanguageExchange", + "classAnalyticsDesc", + "addStudents", + "copyClassLink", + "copyClassLinkDesc", + "copyClassCode", + "inviteStudentByUserName", + "classSettings", + "classSettingsDesc", + "selectClassRoomDominantLanguage", + "selectTargetLanguage", + "whatIsYourClassLanguageLevel", + "studentPermissions", + "interactiveTranslator", + "oneToOneChatsWithinClass", + "oneToOneChatsWithinClassDesc", + "createGroupChats", + "createGroupChatsDesc", + "shareVideo", + "shareVideoDesc", + "sharePhotos", + "sharePhotosDesc", + "shareFiles", + "shareFilesDesc", + "shareLocationDesc", + "selectLanguageLevel", + "noIdenticalLanguages", + "iWantALanguagePartnerFrom", + "worldWide", + "noResults", + "searchBy", + "iWantAConversationPartner", + "iWantALanguagePartnerWhoSpeaks", + "iWantALanguagePartnerWhoIsLearning", + "yourBirthdayPlease", + "invalidDob", + "enterYourDob", + "getStarted", + "mustBe13", + "yourBirthdayPleaseShort", + "errorPleaseRefresh", + "joinWithClassCode", + "joinWithClassCodeDesc", + "joinWithClassCodeHint", + "unableToFindClass", + "languageLevelPreA1", + "languageLevelA1", + "languageLevelA2", + "languageLevelB1", + "languageLevelB2", + "languageLevelC1", + "languageLevelC2", + "changeTheNameOfTheClass", + "changeTheNameOfTheChat", + "welcomeToYourNewClass", + "welcomeToClass", + "welcomeToPangea18Plus", + "welcomeToPangeaMinor", + "findALanguagePartner", + "setToPublicSettingsTitle", + "setToPublicSettingsDesc", + "accountSettings", + "unableToFindClassCode", + "askPangeaBot", + "sorryNoResults", + "ignoreInThisText", + "helpMeTranslate", + "needsItShortMessage", + "needsIGCShortMessage", + "needsItMessage", + "needsIgcMessage", + "tokenTranslationTitle", + "spanTranslationDesc", + "spanTranslationTitle", + "l1SpanAndGrammarTitle", + "l1SpanAndGrammarDesc", + "otherTitle", + "otherDesc", + "countryInformation", + "myLanguages", + "targetLanguage", + "sourceLanguage", + "languagesISpeak", + "updateLanguage", + "whatLanguageYouWantToLearn", + "whatIsYourBaseLanguage", + "saveChanges", + "publicProfileTitle", + "publicProfileDesc", + "error502504Title", + "error502504Desc", + "error404Title", + "error404Desc", + "errorDisableIT", + "errorDisableIGC", + "errorDisableLanguageAssistance", + "errorDisableITUserDesc", + "errorDisableIGCUserDesc", + "errorDisableLanguageAssistanceUserDesc", + "errorDisableITClassDesc", + "errorDisableIGCClassDesc", + "errorDisableLanguageAssistanceClassDesc", + "itIsDisabled", + "igcIsDisabled", + "goToLearningSettings", + "error405Title", + "error405Desc", + "loginOrSignup", + "iAgreeToThe", + "termsAndConditions", + "andCertifyIAmAtLeast13YearsOfAge", + "findAClass", + "toggleIT", + "toggleIGC", + "toggleToolSettingsDescription", + "connectedToStaging", + "learningSettings", + "classNameRequired", + "sendVoiceNotes", + "sendVoiceNotesDesc", + "chatTopic", + "chatTopicDesc", + "inviteStudentByUserNameDesc", + "classRoster", + "almostPerfect", + "prettyGood", + "letMeThink", + "clickMessageTitle", + "clickMessageBody", + "understandingMessagesTitle", + "addToClass", + "understandingMessagesBody", + "allDone", + "vocab", + "low", + "medium", + "high", + "unknownProficiency", + "changeView", + "clearAll", + "generateVocabulary", + "generatePrompts", + "subscribe", + "getAccess", + "subscriptionDesc", + "subscriptionManagement", + "currentSubscription", + "changeSubscription", + "cancelSubscription", + "selectYourPlan", + "subsciptionPlatformTooltip", + "subscriptionManagementUnavailable", + "paymentMethod", + "paymentHistory", + "emptyChatDownloadWarning", + "appUpdateAvailable", + "update", + "updateDesc", + "maybeLater", + "mainMenu", + "toggleImmersionMode", + "toggleImmersionModeDesc", + "itToggleDescription", + "igcToggleDescription", + "sendOnEnterDescription", + "alreadyInClass", + "pleaseLoginFirst", + "originalMessage", + "sentMessage", + "useType", + "notAvailable", + "taAndGaTooltip", + "definitionsToolName", + "messageTranslationsToolName", + "definitionsToolDescription", + "translationsToolDescrption", + "welcomeBack", + "classExchanges", + "createNewClass", + "newExchange", + "kickAllStudents", + "kickAllStudentsConfirmation", + "inviteAllStudents", + "inviteAllStudentsConfirmation", + "inviteStudentsFromOtherClasses", + "inviteUsersFromPangea", + "allExchanges", + "redeemPromoCode", + "enterPromoCode", + "downloadTxtFile", + "downloadCSVFile", + "promotionalSubscriptionDesc", + "originalSubscriptionPlatform", + "oneWeekTrial", + "creatingSpacePleaseWait", + "downloadXLSXFile", + "abDisplayName", + "aaDisplayName", + "afDisplayName", + "akDisplayName", + "sqDisplayName", + "amDisplayName", + "arDisplayName", + "anDisplayName", + "hyDisplayName", + "asDisplayName", + "avDisplayName", + "aeDisplayName", + "ayDisplayName", + "azDisplayName", + "bmDisplayName", + "baDisplayName", + "euDisplayName", + "beDisplayName", + "bnDisplayName", + "bhDisplayName", + "biDisplayName", + "bsDisplayName", + "brDisplayName", + "bgDisplayName", + "myDisplayName", + "caDisplayName", + "chDisplayName", + "ceDisplayName", + "nyDisplayName", + "zhDisplayName", + "cvDisplayName", + "kwDisplayName", + "coDisplayName", + "crDisplayName", + "hrDisplayName", + "csDisplayName", + "daDisplayName", + "dvDisplayName", + "nlDisplayName", + "enDisplayName", + "eoDisplayName", + "etDisplayName", + "eeDisplayName", + "foDisplayName", + "fjDisplayName", + "fiDisplayName", + "frDisplayName", + "ffDisplayName", + "glDisplayName", + "kaDisplayName", + "deDisplayName", + "elDisplayName", + "gnDisplayName", + "guDisplayName", + "htDisplayName", + "haDisplayName", + "heDisplayName", + "hzDisplayName", + "hiDisplayName", + "hoDisplayName", + "huDisplayName", + "iaDisplayName", + "idDisplayName", + "ieDisplayName", + "gaDisplayName", + "igDisplayName", + "ikDisplayName", + "ioDisplayName", + "isDisplayName", + "itDisplayName", + "iuDisplayName", + "jaDisplayName", + "jvDisplayName", + "klDisplayName", + "knDisplayName", + "krDisplayName", + "ksDisplayName", + "kkDisplayName", + "kmDisplayName", + "kiDisplayName", + "rwDisplayName", + "kyDisplayName", + "kvDisplayName", + "kgDisplayName", + "koDisplayName", + "kuDisplayName", + "kjDisplayName", + "laDisplayName", + "lbDisplayName", + "lgDisplayName", + "liDisplayName", + "lnDisplayName", + "loDisplayName", + "ltDisplayName", + "luDisplayName", + "lvDisplayName", + "gvDisplayName", + "mkDisplayName", + "mgDisplayName", + "msDisplayName", + "mlDisplayName", + "mtDisplayName", + "miDisplayName", + "mrDisplayName", + "mhDisplayName", + "mnDisplayName", + "naDisplayName", + "nvDisplayName", + "nbDisplayName", + "ndDisplayName", + "neDisplayName", + "ngDisplayName", + "nnDisplayName", + "noDisplayName", + "iiDisplayName", + "nrDisplayName", + "ocDisplayName", + "ojDisplayName", + "cuDisplayName", + "omDisplayName", + "orDisplayName", + "osDisplayName", + "paDisplayName", + "piDisplayName", + "faDisplayName", + "plDisplayName", + "psDisplayName", + "ptDisplayName", + "quDisplayName", + "rmDisplayName", + "rnDisplayName", + "roDisplayName", + "ruDisplayName", + "saDisplayName", + "scDisplayName", + "sdDisplayName", + "seDisplayName", + "smDisplayName", + "sgDisplayName", + "srDisplayName", + "gdDisplayName", + "snDisplayName", + "siDisplayName", + "skDisplayName", + "slDisplayName", + "soDisplayName", + "stDisplayName", + "esDisplayName", + "suDisplayName", + "swDisplayName", + "ssDisplayName", + "svDisplayName", + "taDisplayName", + "teDisplayName", + "tgDisplayName", + "thDisplayName", + "tiDisplayName", + "boDisplayName", + "tkDisplayName", + "tlDisplayName", + "tnDisplayName", + "toDisplayName", + "trDisplayName", + "tsDisplayName", + "ttDisplayName", + "twDisplayName", + "tyDisplayName", + "ugDisplayName", + "ukDisplayName", + "urDisplayName", + "uzDisplayName", + "veDisplayName", + "viDisplayName", + "voDisplayName", + "waDisplayName", + "cyDisplayName", + "woDisplayName", + "fyDisplayName", + "xhDisplayName", + "yiDisplayName", + "yoDisplayName", + "zaDisplayName", + "unkDisplayName", + "zuDisplayName", + "hawDisplayName", + "hmnDisplayName", + "multiDisplayName", + "cebDisplayName", + "dzDisplayName", + "iwDisplayName", + "jwDisplayName", + "moDisplayName", + "shDisplayName", + "wwCountryDisplayName", + "afCountryDisplayName", + "axCountryDisplayName", + "alCountryDisplayName", + "dzCountryDisplayName", + "asCountryDisplayName", + "adCountryDisplayName", + "aoCountryDisplayName", + "aiCountryDisplayName", + "agCountryDisplayName", + "arCountryDisplayName", + "amCountryDisplayName", + "awCountryDisplayName", + "acCountryDisplayName", + "auCountryDisplayName", + "atCountryDisplayName", + "azCountryDisplayName", + "bsCountryDisplayName", + "bhCountryDisplayName", + "bdCountryDisplayName", + "bbCountryDisplayName", + "byCountryDisplayName", + "beCountryDisplayName", + "bzCountryDisplayName", + "bjCountryDisplayName", + "bmCountryDisplayName", + "btCountryDisplayName", + "boCountryDisplayName", + "baCountryDisplayName", + "bwCountryDisplayName", + "brCountryDisplayName", + "ioCountryDisplayName", + "vgCountryDisplayName", + "bnCountryDisplayName", + "bgCountryDisplayName", + "bfCountryDisplayName", + "biCountryDisplayName", + "khCountryDisplayName", + "cmCountryDisplayName", + "caCountryDisplayName", + "cvCountryDisplayName", + "bqCountryDisplayName", + "kyCountryDisplayName", + "cfCountryDisplayName", + "tdCountryDisplayName", + "clCountryDisplayName", + "cnCountryDisplayName", + "cxCountryDisplayName", + "ccCountryDisplayName", + "coCountryDisplayName", + "kmCountryDisplayName", + "cdCountryDisplayName", + "cgCountryDisplayName", + "ckCountryDisplayName", + "crCountryDisplayName", + "ciCountryDisplayName", + "hrCountryDisplayName", + "cuCountryDisplayName", + "cwCountryDisplayName", + "cyCountryDisplayName", + "czCountryDisplayName", + "dkCountryDisplayName", + "djCountryDisplayName", + "dmCountryDisplayName", + "doCountryDisplayName", + "tlCountryDisplayName", + "ecCountryDisplayName", + "egCountryDisplayName", + "svCountryDisplayName", + "gqCountryDisplayName", + "erCountryDisplayName", + "eeCountryDisplayName", + "szCountryDisplayName", + "etCountryDisplayName", + "fkCountryDisplayName", + "foCountryDisplayName", + "fjCountryDisplayName", + "fiCountryDisplayName", + "frCountryDisplayName", + "gfCountryDisplayName", + "pfCountryDisplayName", + "gaCountryDisplayName", + "gmCountryDisplayName", + "geCountryDisplayName", + "deCountryDisplayName", + "ghCountryDisplayName", + "giCountryDisplayName", + "grCountryDisplayName", + "glCountryDisplayName", + "gdCountryDisplayName", + "gpCountryDisplayName", + "guCountryDisplayName", + "gtCountryDisplayName", + "ggCountryDisplayName", + "gnCountryDisplayName", + "gwCountryDisplayName", + "gyCountryDisplayName", + "htCountryDisplayName", + "hmCountryDisplayName", + "hnCountryDisplayName", + "hkCountryDisplayName", + "huCountryDisplayName", + "isCountryDisplayName", + "inCountryDisplayName", + "idCountryDisplayName", + "irCountryDisplayName", + "iqCountryDisplayName", + "ieCountryDisplayName", + "imCountryDisplayName", + "ilCountryDisplayName", + "itCountryDisplayName", + "jmCountryDisplayName", + "jpCountryDisplayName", + "jeCountryDisplayName", + "joCountryDisplayName", + "kzCountryDisplayName", + "keCountryDisplayName", + "kiCountryDisplayName", + "xkCountryDisplayName", + "kwCountryDisplayName", + "kgCountryDisplayName", + "laCountryDisplayName", + "lvCountryDisplayName", + "lbCountryDisplayName", + "lsCountryDisplayName", + "lrCountryDisplayName", + "lyCountryDisplayName", + "liCountryDisplayName", + "ltCountryDisplayName", + "luCountryDisplayName", + "moCountryDisplayName", + "mkCountryDisplayName", + "mgCountryDisplayName", + "mwCountryDisplayName", + "myCountryDisplayName", + "mvCountryDisplayName", + "mlCountryDisplayName", + "mtCountryDisplayName", + "mhCountryDisplayName", + "mqCountryDisplayName", + "mrCountryDisplayName", + "muCountryDisplayName", + "ytCountryDisplayName", + "mxCountryDisplayName", + "fmCountryDisplayName", + "mdCountryDisplayName", + "mcCountryDisplayName", + "mnCountryDisplayName", + "meCountryDisplayName", + "msCountryDisplayName", + "maCountryDisplayName", + "mzCountryDisplayName", + "mmCountryDisplayName", + "naCountryDisplayName", + "nrCountryDisplayName", + "npCountryDisplayName", + "nlCountryDisplayName", + "ncCountryDisplayName", + "nzCountryDisplayName", + "niCountryDisplayName", + "neCountryDisplayName", + "ngCountryDisplayName", + "nuCountryDisplayName", + "nfCountryDisplayName", + "kpCountryDisplayName", + "mpCountryDisplayName", + "noCountryDisplayName", + "omCountryDisplayName", + "pkCountryDisplayName", + "pwCountryDisplayName", + "psCountryDisplayName", + "paCountryDisplayName", + "pgCountryDisplayName", + "pyCountryDisplayName", + "peCountryDisplayName", + "phCountryDisplayName", + "plCountryDisplayName", + "ptCountryDisplayName", + "prCountryDisplayName", + "qaCountryDisplayName", + "reCountryDisplayName", + "roCountryDisplayName", + "ruCountryDisplayName", + "rwCountryDisplayName", + "blCountryDisplayName", + "shCountryDisplayName", + "knCountryDisplayName", + "lcCountryDisplayName", + "mfCountryDisplayName", + "pmCountryDisplayName", + "vcCountryDisplayName", + "wsCountryDisplayName", + "smCountryDisplayName", + "stCountryDisplayName", + "saCountryDisplayName", + "snCountryDisplayName", + "rsCountryDisplayName", + "scCountryDisplayName", + "slCountryDisplayName", + "sgCountryDisplayName", + "sxCountryDisplayName", + "skCountryDisplayName", + "siCountryDisplayName", + "sbCountryDisplayName", + "soCountryDisplayName", + "zaCountryDisplayName", + "gsCountryDisplayName", + "krCountryDisplayName", + "ssCountryDisplayName", + "esCountryDisplayName", + "lkCountryDisplayName", + "sdCountryDisplayName", + "srCountryDisplayName", + "sjCountryDisplayName", + "seCountryDisplayName", + "chCountryDisplayName", + "syCountryDisplayName", + "twCountryDisplayName", + "tjCountryDisplayName", + "tzCountryDisplayName", + "thCountryDisplayName", + "tgCountryDisplayName", + "tkCountryDisplayName", + "toCountryDisplayName", + "ttCountryDisplayName", + "tnCountryDisplayName", + "trCountryDisplayName", + "tmCountryDisplayName", + "tcCountryDisplayName", + "tvCountryDisplayName", + "viCountryDisplayName", + "ugCountryDisplayName", + "uaCountryDisplayName", + "aeCountryDisplayName", + "gbCountryDisplayName", + "usCountryDisplayName", + "uyCountryDisplayName", + "uzCountryDisplayName", + "vuCountryDisplayName", + "vaCountryDisplayName", + "veCountryDisplayName", + "vnCountryDisplayName", + "wfCountryDisplayName", + "ehCountryDisplayName", + "yeCountryDisplayName", + "zmCountryDisplayName", + "zwCountryDisplayName", + "pay", + "allPrivateChats", + "unknownPrivateChat", + "copyClassCodeDesc", + "addToClassDesc", + "addToClassOrExchange", + "addToClassOrExchangeDesc", + "invitedToClassOrExchange", + "decline", + "declinedInvitation", + "acceptedInvitation", + "youreInvited", + "studentPermissionsDesc", + "noEligibleSpaces", + "youAddedToSpace", + "youRemovedFromSpace", + "invitedToChat", + "monthlySubscription", + "yearlySubscription", + "defaultSubscription", + "freeTrial", + "grammarAnalytics", + "total", + "noDataFound", + "promoSubscriptionExpirationDesc", + "emptyChatNameWarning", + "emptyClassNameWarning", + "emptyExchangeNameWarning", + "blurMeansTranslateTitle", + "blurMeansTranslateBody", + "someErrorTitle", + "someErrorBody", + "bestCorrectionFeedback", + "distractorFeedback", + "bestAnswerFeedback", + "definitionDefaultPrompt", + "practiceDefaultPrompt", + "correctionDefaultPrompt", + "itStartDefaultPrompt", + "languageLevelWarning", + "lockedChatWarning", + "lockSpace", + "lockChat", + "archiveSpace", + "suggestTo", + "suggestChatDesc", + "suggestExchangeDesc", + "acceptSelection", + "acceptSelectionAnyway", + "makingActivity", + "why", + "definition", + "exampleSentence", + "addToClassTitle", + "reportToTeacher", + "reportMessageTitle", + "reportMessageBody", + "noTeachersFound", + "noAddToSpacePermissions", + "alreadyInSpace", + "yourGlobalUserIdIs", + "noUsersFoundWithQuery", + "searchChatsRooms", + "groupName", + "createGroupAndInviteUsers", + "groupCanBeFoundViaSearch", + "inNoSpaces" + ], + + "ie": [ + "accountInformation", + "addNewFriend", + "alreadyHaveAnAccount", + "classes", + "editChatPermissions", + "groupDescriptionHasBeenChanged", + "allCorrect", + "newWayAllGood", + "othersAreBetter", + "holdForInfo", + "greenFeedback", + "yellowFeedback", + "redFeedback", + "customInputFeedbackChoice", + "itInstructionsTitle", + "itInstructionsBody", + "toggleLanguages", + "classWelcomeChat", + "deleteSpace", + "deleteGroup", + "areYouSureDeleteClass", + "areYouSureDeleteGroup", + "cannotBeReversed", + "enterDeletedClassName", + "incorrectClassName", + "oneday", + "oneweek", + "onemonth", + "sixmonth", + "oneyear", + "gaTooltip", + "taTooltip", + "unTooltip", + "interactiveTranslatorSliderHeader", + "interactiveGrammarSliderHeader", + "interactiveTranslatorNotAllowed", + "interactiveTranslatorAllowed", + "interactiveTranslatorRequired", + "interactiveTranslatorNotAllowedDesc", + "interactiveTranslatorAllowedDesc", + "interactiveTranslatorRequiredDesc", + "notYetSet", + "multiLingualClass", + "classAnalytics", + "allClasses", + "myLearning", + "allChatsAndClasses", + "timeOfLastMessage", + "totalMessages", + "waTooltip", + "changeDateRange", + "numberOfStudents", + "classDescription", + "classDescriptionDesc", + "requestToEnroll", + "requestAnExchange", + "findLanguageExchange", + "classAnalyticsDesc", + "addStudents", + "copyClassLink", + "copyClassLinkDesc", + "copyClassCode", + "inviteStudentByUserName", + "classSettings", + "classSettingsDesc", + "selectClassRoomDominantLanguage", + "selectTargetLanguage", + "whatIsYourClassLanguageLevel", + "studentPermissions", + "interactiveTranslator", + "oneToOneChatsWithinClass", + "oneToOneChatsWithinClassDesc", + "createGroupChats", + "createGroupChatsDesc", + "shareVideo", + "shareVideoDesc", + "sharePhotos", + "sharePhotosDesc", + "shareFiles", + "shareFilesDesc", + "shareLocationDesc", + "selectLanguageLevel", + "noIdenticalLanguages", + "iWantALanguagePartnerFrom", + "worldWide", + "noResults", + "searchBy", + "iWantAConversationPartner", + "iWantALanguagePartnerWhoSpeaks", + "iWantALanguagePartnerWhoIsLearning", + "yourBirthdayPlease", + "invalidDob", + "enterYourDob", + "getStarted", + "mustBe13", + "yourBirthdayPleaseShort", + "errorPleaseRefresh", + "joinWithClassCode", + "joinWithClassCodeDesc", + "joinWithClassCodeHint", + "unableToFindClass", + "languageLevelPreA1", + "languageLevelA1", + "languageLevelA2", + "languageLevelB1", + "languageLevelB2", + "languageLevelC1", + "languageLevelC2", + "changeTheNameOfTheClass", + "changeTheNameOfTheChat", + "welcomeToYourNewClass", + "welcomeToClass", + "welcomeToPangea18Plus", + "welcomeToPangeaMinor", + "findALanguagePartner", + "setToPublicSettingsTitle", + "setToPublicSettingsDesc", + "accountSettings", + "unableToFindClassCode", + "askPangeaBot", + "sorryNoResults", + "ignoreInThisText", + "helpMeTranslate", + "needsItShortMessage", + "needsIGCShortMessage", + "needsItMessage", + "needsIgcMessage", + "tokenTranslationTitle", + "spanTranslationDesc", + "spanTranslationTitle", + "l1SpanAndGrammarTitle", + "l1SpanAndGrammarDesc", + "otherTitle", + "otherDesc", + "countryInformation", + "myLanguages", + "targetLanguage", + "sourceLanguage", + "languagesISpeak", + "updateLanguage", + "whatLanguageYouWantToLearn", + "whatIsYourBaseLanguage", + "saveChanges", + "publicProfileTitle", + "publicProfileDesc", + "error502504Title", + "error502504Desc", + "error404Title", + "error404Desc", + "errorDisableIT", + "errorDisableIGC", + "errorDisableLanguageAssistance", + "errorDisableITUserDesc", + "errorDisableIGCUserDesc", + "errorDisableLanguageAssistanceUserDesc", + "errorDisableITClassDesc", + "errorDisableIGCClassDesc", + "errorDisableLanguageAssistanceClassDesc", + "itIsDisabled", + "igcIsDisabled", + "goToLearningSettings", + "error405Title", + "error405Desc", + "loginOrSignup", + "iAgreeToThe", + "termsAndConditions", + "andCertifyIAmAtLeast13YearsOfAge", + "findAClass", + "toggleIT", + "toggleIGC", + "toggleToolSettingsDescription", + "connectedToStaging", + "learningSettings", + "classNameRequired", + "sendVoiceNotes", + "sendVoiceNotesDesc", + "chatTopic", + "chatTopicDesc", + "inviteStudentByUserNameDesc", + "classRoster", + "almostPerfect", + "prettyGood", + "letMeThink", + "clickMessageTitle", + "clickMessageBody", + "understandingMessagesTitle", + "addToClass", + "understandingMessagesBody", + "allDone", + "vocab", + "low", + "medium", + "high", + "unknownProficiency", + "changeView", + "clearAll", + "generateVocabulary", + "generatePrompts", + "subscribe", + "getAccess", + "subscriptionDesc", + "subscriptionManagement", + "currentSubscription", + "changeSubscription", + "cancelSubscription", + "selectYourPlan", + "subsciptionPlatformTooltip", + "subscriptionManagementUnavailable", + "paymentMethod", + "paymentHistory", + "emptyChatDownloadWarning", + "appUpdateAvailable", + "update", + "updateDesc", + "maybeLater", + "mainMenu", + "toggleImmersionMode", + "toggleImmersionModeDesc", + "itToggleDescription", + "igcToggleDescription", + "sendOnEnterDescription", + "alreadyInClass", + "pleaseLoginFirst", + "originalMessage", + "sentMessage", + "useType", + "notAvailable", + "taAndGaTooltip", + "definitionsToolName", + "messageTranslationsToolName", + "definitionsToolDescription", + "translationsToolDescrption", + "welcomeBack", + "classExchanges", + "createNewClass", + "newExchange", + "kickAllStudents", + "kickAllStudentsConfirmation", + "inviteAllStudents", + "inviteAllStudentsConfirmation", + "inviteStudentsFromOtherClasses", + "inviteUsersFromPangea", + "allExchanges", + "redeemPromoCode", + "enterPromoCode", + "downloadTxtFile", + "downloadCSVFile", + "promotionalSubscriptionDesc", + "originalSubscriptionPlatform", + "oneWeekTrial", + "creatingSpacePleaseWait", + "downloadXLSXFile", + "abDisplayName", + "aaDisplayName", + "afDisplayName", + "akDisplayName", + "sqDisplayName", + "amDisplayName", + "arDisplayName", + "anDisplayName", + "hyDisplayName", + "asDisplayName", + "avDisplayName", + "aeDisplayName", + "ayDisplayName", + "azDisplayName", + "bmDisplayName", + "baDisplayName", + "euDisplayName", + "beDisplayName", + "bnDisplayName", + "bhDisplayName", + "biDisplayName", + "bsDisplayName", + "brDisplayName", + "bgDisplayName", + "myDisplayName", + "caDisplayName", + "chDisplayName", + "ceDisplayName", + "nyDisplayName", + "zhDisplayName", + "cvDisplayName", + "kwDisplayName", + "coDisplayName", + "crDisplayName", + "hrDisplayName", + "csDisplayName", + "daDisplayName", + "dvDisplayName", + "nlDisplayName", + "enDisplayName", + "eoDisplayName", + "etDisplayName", + "eeDisplayName", + "foDisplayName", + "fjDisplayName", + "fiDisplayName", + "frDisplayName", + "ffDisplayName", + "glDisplayName", + "kaDisplayName", + "deDisplayName", + "elDisplayName", + "gnDisplayName", + "guDisplayName", + "htDisplayName", + "haDisplayName", + "heDisplayName", + "hzDisplayName", + "hiDisplayName", + "hoDisplayName", + "huDisplayName", + "iaDisplayName", + "idDisplayName", + "ieDisplayName", + "gaDisplayName", + "igDisplayName", + "ikDisplayName", + "ioDisplayName", + "isDisplayName", + "itDisplayName", + "iuDisplayName", + "jaDisplayName", + "jvDisplayName", + "klDisplayName", + "knDisplayName", + "krDisplayName", + "ksDisplayName", + "kkDisplayName", + "kmDisplayName", + "kiDisplayName", + "rwDisplayName", + "kyDisplayName", + "kvDisplayName", + "kgDisplayName", + "koDisplayName", + "kuDisplayName", + "kjDisplayName", + "laDisplayName", + "lbDisplayName", + "lgDisplayName", + "liDisplayName", + "lnDisplayName", + "loDisplayName", + "ltDisplayName", + "luDisplayName", + "lvDisplayName", + "gvDisplayName", + "mkDisplayName", + "mgDisplayName", + "msDisplayName", + "mlDisplayName", + "mtDisplayName", + "miDisplayName", + "mrDisplayName", + "mhDisplayName", + "mnDisplayName", + "naDisplayName", + "nvDisplayName", + "nbDisplayName", + "ndDisplayName", + "neDisplayName", + "ngDisplayName", + "nnDisplayName", + "noDisplayName", + "iiDisplayName", + "nrDisplayName", + "ocDisplayName", + "ojDisplayName", + "cuDisplayName", + "omDisplayName", + "orDisplayName", + "osDisplayName", + "paDisplayName", + "piDisplayName", + "faDisplayName", + "plDisplayName", + "psDisplayName", + "ptDisplayName", + "quDisplayName", + "rmDisplayName", + "rnDisplayName", + "roDisplayName", + "ruDisplayName", + "saDisplayName", + "scDisplayName", + "sdDisplayName", + "seDisplayName", + "smDisplayName", + "sgDisplayName", + "srDisplayName", + "gdDisplayName", + "snDisplayName", + "siDisplayName", + "skDisplayName", + "slDisplayName", + "soDisplayName", + "stDisplayName", + "esDisplayName", + "suDisplayName", + "swDisplayName", + "ssDisplayName", + "svDisplayName", + "taDisplayName", + "teDisplayName", + "tgDisplayName", + "thDisplayName", + "tiDisplayName", + "boDisplayName", + "tkDisplayName", + "tlDisplayName", + "tnDisplayName", + "toDisplayName", + "trDisplayName", + "tsDisplayName", + "ttDisplayName", + "twDisplayName", + "tyDisplayName", + "ugDisplayName", + "ukDisplayName", + "urDisplayName", + "uzDisplayName", + "veDisplayName", + "viDisplayName", + "voDisplayName", + "waDisplayName", + "cyDisplayName", + "woDisplayName", + "fyDisplayName", + "xhDisplayName", + "yiDisplayName", + "yoDisplayName", + "zaDisplayName", + "unkDisplayName", + "zuDisplayName", + "hawDisplayName", + "hmnDisplayName", + "multiDisplayName", + "cebDisplayName", + "dzDisplayName", + "iwDisplayName", + "jwDisplayName", + "moDisplayName", + "shDisplayName", + "wwCountryDisplayName", + "afCountryDisplayName", + "axCountryDisplayName", + "alCountryDisplayName", + "dzCountryDisplayName", + "asCountryDisplayName", + "adCountryDisplayName", + "aoCountryDisplayName", + "aiCountryDisplayName", + "agCountryDisplayName", + "arCountryDisplayName", + "amCountryDisplayName", + "awCountryDisplayName", + "acCountryDisplayName", + "auCountryDisplayName", + "atCountryDisplayName", + "azCountryDisplayName", + "bsCountryDisplayName", + "bhCountryDisplayName", + "bdCountryDisplayName", + "bbCountryDisplayName", + "byCountryDisplayName", + "beCountryDisplayName", + "bzCountryDisplayName", + "bjCountryDisplayName", + "bmCountryDisplayName", + "btCountryDisplayName", + "boCountryDisplayName", + "baCountryDisplayName", + "bwCountryDisplayName", + "brCountryDisplayName", + "ioCountryDisplayName", + "vgCountryDisplayName", + "bnCountryDisplayName", + "bgCountryDisplayName", + "bfCountryDisplayName", + "biCountryDisplayName", + "khCountryDisplayName", + "cmCountryDisplayName", + "caCountryDisplayName", + "cvCountryDisplayName", + "bqCountryDisplayName", + "kyCountryDisplayName", + "cfCountryDisplayName", + "tdCountryDisplayName", + "clCountryDisplayName", + "cnCountryDisplayName", + "cxCountryDisplayName", + "ccCountryDisplayName", + "coCountryDisplayName", + "kmCountryDisplayName", + "cdCountryDisplayName", + "cgCountryDisplayName", + "ckCountryDisplayName", + "crCountryDisplayName", + "ciCountryDisplayName", + "hrCountryDisplayName", + "cuCountryDisplayName", + "cwCountryDisplayName", + "cyCountryDisplayName", + "czCountryDisplayName", + "dkCountryDisplayName", + "djCountryDisplayName", + "dmCountryDisplayName", + "doCountryDisplayName", + "tlCountryDisplayName", + "ecCountryDisplayName", + "egCountryDisplayName", + "svCountryDisplayName", + "gqCountryDisplayName", + "erCountryDisplayName", + "eeCountryDisplayName", + "szCountryDisplayName", + "etCountryDisplayName", + "fkCountryDisplayName", + "foCountryDisplayName", + "fjCountryDisplayName", + "fiCountryDisplayName", + "frCountryDisplayName", + "gfCountryDisplayName", + "pfCountryDisplayName", + "gaCountryDisplayName", + "gmCountryDisplayName", + "geCountryDisplayName", + "deCountryDisplayName", + "ghCountryDisplayName", + "giCountryDisplayName", + "grCountryDisplayName", + "glCountryDisplayName", + "gdCountryDisplayName", + "gpCountryDisplayName", + "guCountryDisplayName", + "gtCountryDisplayName", + "ggCountryDisplayName", + "gnCountryDisplayName", + "gwCountryDisplayName", + "gyCountryDisplayName", + "htCountryDisplayName", + "hmCountryDisplayName", + "hnCountryDisplayName", + "hkCountryDisplayName", + "huCountryDisplayName", + "isCountryDisplayName", + "inCountryDisplayName", + "idCountryDisplayName", + "irCountryDisplayName", + "iqCountryDisplayName", + "ieCountryDisplayName", + "imCountryDisplayName", + "ilCountryDisplayName", + "itCountryDisplayName", + "jmCountryDisplayName", + "jpCountryDisplayName", + "jeCountryDisplayName", + "joCountryDisplayName", + "kzCountryDisplayName", + "keCountryDisplayName", + "kiCountryDisplayName", + "xkCountryDisplayName", + "kwCountryDisplayName", + "kgCountryDisplayName", + "laCountryDisplayName", + "lvCountryDisplayName", + "lbCountryDisplayName", + "lsCountryDisplayName", + "lrCountryDisplayName", + "lyCountryDisplayName", + "liCountryDisplayName", + "ltCountryDisplayName", + "luCountryDisplayName", + "moCountryDisplayName", + "mkCountryDisplayName", + "mgCountryDisplayName", + "mwCountryDisplayName", + "myCountryDisplayName", + "mvCountryDisplayName", + "mlCountryDisplayName", + "mtCountryDisplayName", + "mhCountryDisplayName", + "mqCountryDisplayName", + "mrCountryDisplayName", + "muCountryDisplayName", + "ytCountryDisplayName", + "mxCountryDisplayName", + "fmCountryDisplayName", + "mdCountryDisplayName", + "mcCountryDisplayName", + "mnCountryDisplayName", + "meCountryDisplayName", + "msCountryDisplayName", + "maCountryDisplayName", + "mzCountryDisplayName", + "mmCountryDisplayName", + "naCountryDisplayName", + "nrCountryDisplayName", + "npCountryDisplayName", + "nlCountryDisplayName", + "ncCountryDisplayName", + "nzCountryDisplayName", + "niCountryDisplayName", + "neCountryDisplayName", + "ngCountryDisplayName", + "nuCountryDisplayName", + "nfCountryDisplayName", + "kpCountryDisplayName", + "mpCountryDisplayName", + "noCountryDisplayName", + "omCountryDisplayName", + "pkCountryDisplayName", + "pwCountryDisplayName", + "psCountryDisplayName", + "paCountryDisplayName", + "pgCountryDisplayName", + "pyCountryDisplayName", + "peCountryDisplayName", + "phCountryDisplayName", + "plCountryDisplayName", + "ptCountryDisplayName", + "prCountryDisplayName", + "qaCountryDisplayName", + "reCountryDisplayName", + "roCountryDisplayName", + "ruCountryDisplayName", + "rwCountryDisplayName", + "blCountryDisplayName", + "shCountryDisplayName", + "knCountryDisplayName", + "lcCountryDisplayName", + "mfCountryDisplayName", + "pmCountryDisplayName", + "vcCountryDisplayName", + "wsCountryDisplayName", + "smCountryDisplayName", + "stCountryDisplayName", + "saCountryDisplayName", + "snCountryDisplayName", + "rsCountryDisplayName", + "scCountryDisplayName", + "slCountryDisplayName", + "sgCountryDisplayName", + "sxCountryDisplayName", + "skCountryDisplayName", + "siCountryDisplayName", + "sbCountryDisplayName", + "soCountryDisplayName", + "zaCountryDisplayName", + "gsCountryDisplayName", + "krCountryDisplayName", + "ssCountryDisplayName", + "esCountryDisplayName", + "lkCountryDisplayName", + "sdCountryDisplayName", + "srCountryDisplayName", + "sjCountryDisplayName", + "seCountryDisplayName", + "chCountryDisplayName", + "syCountryDisplayName", + "twCountryDisplayName", + "tjCountryDisplayName", + "tzCountryDisplayName", + "thCountryDisplayName", + "tgCountryDisplayName", + "tkCountryDisplayName", + "toCountryDisplayName", + "ttCountryDisplayName", + "tnCountryDisplayName", + "trCountryDisplayName", + "tmCountryDisplayName", + "tcCountryDisplayName", + "tvCountryDisplayName", + "viCountryDisplayName", + "ugCountryDisplayName", + "uaCountryDisplayName", + "aeCountryDisplayName", + "gbCountryDisplayName", + "usCountryDisplayName", + "uyCountryDisplayName", + "uzCountryDisplayName", + "vuCountryDisplayName", + "vaCountryDisplayName", + "veCountryDisplayName", + "vnCountryDisplayName", + "wfCountryDisplayName", + "ehCountryDisplayName", + "yeCountryDisplayName", + "zmCountryDisplayName", + "zwCountryDisplayName", + "pay", + "allPrivateChats", + "unknownPrivateChat", + "copyClassCodeDesc", + "addToClassDesc", + "addToClassOrExchange", + "addToClassOrExchangeDesc", + "invitedToClassOrExchange", + "decline", + "declinedInvitation", + "acceptedInvitation", + "youreInvited", + "studentPermissionsDesc", + "noEligibleSpaces", + "youAddedToSpace", + "youRemovedFromSpace", + "invitedToChat", + "monthlySubscription", + "yearlySubscription", + "defaultSubscription", + "freeTrial", + "grammarAnalytics", + "total", + "noDataFound", + "promoSubscriptionExpirationDesc", + "emptyChatNameWarning", + "emptyClassNameWarning", + "emptyExchangeNameWarning", + "blurMeansTranslateTitle", + "blurMeansTranslateBody", + "someErrorTitle", + "someErrorBody", + "bestCorrectionFeedback", + "distractorFeedback", + "bestAnswerFeedback", + "definitionDefaultPrompt", + "practiceDefaultPrompt", + "correctionDefaultPrompt", + "itStartDefaultPrompt", + "languageLevelWarning", + "lockedChatWarning", + "lockSpace", + "lockChat", + "archiveSpace", + "suggestTo", + "suggestChatDesc", + "suggestExchangeDesc", + "acceptSelection", + "acceptSelectionAnyway", + "makingActivity", + "why", + "definition", + "exampleSentence", + "addToClassTitle", + "reportToTeacher", + "reportMessageTitle", + "reportMessageBody", + "noTeachersFound", + "noAddToSpacePermissions", + "alreadyInSpace", + "yourGlobalUserIdIs", + "noUsersFoundWithQuery", + "searchChatsRooms", + "groupName", + "createGroupAndInviteUsers", + "groupCanBeFoundViaSearch", + "inNoSpaces" + ], + + "it": [ + "accountInformation", + "addNewFriend", + "alreadyHaveAnAccount", + "classes", + "allCorrect", + "newWayAllGood", + "othersAreBetter", + "holdForInfo", + "greenFeedback", + "yellowFeedback", + "redFeedback", + "customInputFeedbackChoice", + "itInstructionsTitle", + "itInstructionsBody", + "toggleLanguages", + "classWelcomeChat", + "deleteSpace", + "deleteGroup", + "areYouSureDeleteClass", + "areYouSureDeleteGroup", + "cannotBeReversed", + "enterDeletedClassName", + "incorrectClassName", + "oneday", + "oneweek", + "onemonth", + "sixmonth", + "oneyear", + "gaTooltip", + "taTooltip", + "unTooltip", + "interactiveTranslatorSliderHeader", + "interactiveGrammarSliderHeader", + "interactiveTranslatorNotAllowed", + "interactiveTranslatorAllowed", + "interactiveTranslatorRequired", + "interactiveTranslatorNotAllowedDesc", + "interactiveTranslatorAllowedDesc", + "interactiveTranslatorRequiredDesc", + "notYetSet", + "multiLingualClass", + "classAnalytics", + "allClasses", + "myLearning", + "allChatsAndClasses", + "timeOfLastMessage", + "totalMessages", + "waTooltip", + "changeDateRange", + "numberOfStudents", + "classDescription", + "classDescriptionDesc", + "requestToEnroll", + "requestAnExchange", + "findLanguageExchange", + "classAnalyticsDesc", + "addStudents", + "copyClassLink", + "copyClassLinkDesc", + "copyClassCode", + "inviteStudentByUserName", + "classSettings", + "classSettingsDesc", + "selectClassRoomDominantLanguage", + "selectTargetLanguage", + "whatIsYourClassLanguageLevel", + "studentPermissions", + "interactiveTranslator", + "oneToOneChatsWithinClass", + "oneToOneChatsWithinClassDesc", + "createGroupChats", + "createGroupChatsDesc", + "shareVideo", + "shareVideoDesc", + "sharePhotos", + "sharePhotosDesc", + "shareFiles", + "shareFilesDesc", + "shareLocationDesc", + "selectLanguageLevel", + "noIdenticalLanguages", + "iWantALanguagePartnerFrom", + "worldWide", + "noResults", + "searchBy", + "iWantAConversationPartner", + "iWantALanguagePartnerWhoSpeaks", + "iWantALanguagePartnerWhoIsLearning", + "yourBirthdayPlease", + "invalidDob", + "enterYourDob", + "getStarted", + "mustBe13", + "yourBirthdayPleaseShort", + "errorPleaseRefresh", + "joinWithClassCode", + "joinWithClassCodeDesc", + "joinWithClassCodeHint", + "unableToFindClass", + "languageLevelPreA1", + "languageLevelA1", + "languageLevelA2", + "languageLevelB1", + "languageLevelB2", + "languageLevelC1", + "languageLevelC2", + "changeTheNameOfTheClass", + "changeTheNameOfTheChat", + "welcomeToYourNewClass", + "welcomeToClass", + "welcomeToPangea18Plus", + "welcomeToPangeaMinor", + "findALanguagePartner", + "setToPublicSettingsTitle", + "setToPublicSettingsDesc", + "accountSettings", + "unableToFindClassCode", + "askPangeaBot", + "sorryNoResults", + "ignoreInThisText", + "helpMeTranslate", + "needsItShortMessage", + "needsIGCShortMessage", + "needsItMessage", + "needsIgcMessage", + "tokenTranslationTitle", + "spanTranslationDesc", + "spanTranslationTitle", + "l1SpanAndGrammarTitle", + "l1SpanAndGrammarDesc", + "otherTitle", + "otherDesc", + "countryInformation", + "myLanguages", + "targetLanguage", + "sourceLanguage", + "languagesISpeak", + "updateLanguage", + "whatLanguageYouWantToLearn", + "whatIsYourBaseLanguage", + "saveChanges", + "publicProfileTitle", + "publicProfileDesc", + "error502504Title", + "error502504Desc", + "error404Title", + "error404Desc", + "errorDisableIT", + "errorDisableIGC", + "errorDisableLanguageAssistance", + "errorDisableITUserDesc", + "errorDisableIGCUserDesc", + "errorDisableLanguageAssistanceUserDesc", + "errorDisableITClassDesc", + "errorDisableIGCClassDesc", + "errorDisableLanguageAssistanceClassDesc", + "itIsDisabled", + "igcIsDisabled", + "goToLearningSettings", + "error405Title", + "error405Desc", + "loginOrSignup", + "iAgreeToThe", + "termsAndConditions", + "andCertifyIAmAtLeast13YearsOfAge", + "findAClass", + "toggleIT", + "toggleIGC", + "toggleToolSettingsDescription", + "connectedToStaging", + "learningSettings", + "classNameRequired", + "sendVoiceNotes", + "sendVoiceNotesDesc", + "chatTopic", + "chatTopicDesc", + "inviteStudentByUserNameDesc", + "classRoster", + "almostPerfect", + "prettyGood", + "letMeThink", + "clickMessageTitle", + "clickMessageBody", + "understandingMessagesTitle", + "addToClass", + "understandingMessagesBody", + "allDone", + "vocab", + "low", + "medium", + "high", + "unknownProficiency", + "changeView", + "clearAll", + "generateVocabulary", + "generatePrompts", + "subscribe", + "getAccess", + "subscriptionDesc", + "subscriptionManagement", + "currentSubscription", + "changeSubscription", + "cancelSubscription", + "selectYourPlan", + "subsciptionPlatformTooltip", + "subscriptionManagementUnavailable", + "paymentMethod", + "paymentHistory", + "emptyChatDownloadWarning", + "appUpdateAvailable", + "update", + "updateDesc", + "maybeLater", + "mainMenu", + "toggleImmersionMode", + "toggleImmersionModeDesc", + "itToggleDescription", + "igcToggleDescription", + "sendOnEnterDescription", + "alreadyInClass", + "pleaseLoginFirst", + "originalMessage", + "sentMessage", + "useType", + "notAvailable", + "taAndGaTooltip", + "definitionsToolName", + "messageTranslationsToolName", + "definitionsToolDescription", + "translationsToolDescrption", + "welcomeBack", + "classExchanges", + "createNewClass", + "newExchange", + "kickAllStudents", + "kickAllStudentsConfirmation", + "inviteAllStudents", + "inviteAllStudentsConfirmation", + "inviteStudentsFromOtherClasses", + "inviteUsersFromPangea", + "allExchanges", + "redeemPromoCode", + "enterPromoCode", + "downloadTxtFile", + "downloadCSVFile", + "promotionalSubscriptionDesc", + "originalSubscriptionPlatform", + "oneWeekTrial", + "creatingSpacePleaseWait", + "downloadXLSXFile", + "abDisplayName", + "aaDisplayName", + "afDisplayName", + "akDisplayName", + "sqDisplayName", + "amDisplayName", + "arDisplayName", + "anDisplayName", + "hyDisplayName", + "asDisplayName", + "avDisplayName", + "aeDisplayName", + "ayDisplayName", + "azDisplayName", + "bmDisplayName", + "baDisplayName", + "euDisplayName", + "beDisplayName", + "bnDisplayName", + "bhDisplayName", + "biDisplayName", + "bsDisplayName", + "brDisplayName", + "bgDisplayName", + "myDisplayName", + "caDisplayName", + "chDisplayName", + "ceDisplayName", + "nyDisplayName", + "zhDisplayName", + "cvDisplayName", + "kwDisplayName", + "coDisplayName", + "crDisplayName", + "hrDisplayName", + "csDisplayName", + "daDisplayName", + "dvDisplayName", + "nlDisplayName", + "enDisplayName", + "eoDisplayName", + "etDisplayName", + "eeDisplayName", + "foDisplayName", + "fjDisplayName", + "fiDisplayName", + "frDisplayName", + "ffDisplayName", + "glDisplayName", + "kaDisplayName", + "deDisplayName", + "elDisplayName", + "gnDisplayName", + "guDisplayName", + "htDisplayName", + "haDisplayName", + "heDisplayName", + "hzDisplayName", + "hiDisplayName", + "hoDisplayName", + "huDisplayName", + "iaDisplayName", + "idDisplayName", + "ieDisplayName", + "gaDisplayName", + "igDisplayName", + "ikDisplayName", + "ioDisplayName", + "isDisplayName", + "itDisplayName", + "iuDisplayName", + "jaDisplayName", + "jvDisplayName", + "klDisplayName", + "knDisplayName", + "krDisplayName", + "ksDisplayName", + "kkDisplayName", + "kmDisplayName", + "kiDisplayName", + "rwDisplayName", + "kyDisplayName", + "kvDisplayName", + "kgDisplayName", + "koDisplayName", + "kuDisplayName", + "kjDisplayName", + "laDisplayName", + "lbDisplayName", + "lgDisplayName", + "liDisplayName", + "lnDisplayName", + "loDisplayName", + "ltDisplayName", + "luDisplayName", + "lvDisplayName", + "gvDisplayName", + "mkDisplayName", + "mgDisplayName", + "msDisplayName", + "mlDisplayName", + "mtDisplayName", + "miDisplayName", + "mrDisplayName", + "mhDisplayName", + "mnDisplayName", + "naDisplayName", + "nvDisplayName", + "nbDisplayName", + "ndDisplayName", + "neDisplayName", + "ngDisplayName", + "nnDisplayName", + "noDisplayName", + "iiDisplayName", + "nrDisplayName", + "ocDisplayName", + "ojDisplayName", + "cuDisplayName", + "omDisplayName", + "orDisplayName", + "osDisplayName", + "paDisplayName", + "piDisplayName", + "faDisplayName", + "plDisplayName", + "psDisplayName", + "ptDisplayName", + "quDisplayName", + "rmDisplayName", + "rnDisplayName", + "roDisplayName", + "ruDisplayName", + "saDisplayName", + "scDisplayName", + "sdDisplayName", + "seDisplayName", + "smDisplayName", + "sgDisplayName", + "srDisplayName", + "gdDisplayName", + "snDisplayName", + "siDisplayName", + "skDisplayName", + "slDisplayName", + "soDisplayName", + "stDisplayName", + "esDisplayName", + "suDisplayName", + "swDisplayName", + "ssDisplayName", + "svDisplayName", + "taDisplayName", + "teDisplayName", + "tgDisplayName", + "thDisplayName", + "tiDisplayName", + "boDisplayName", + "tkDisplayName", + "tlDisplayName", + "tnDisplayName", + "toDisplayName", + "trDisplayName", + "tsDisplayName", + "ttDisplayName", + "twDisplayName", + "tyDisplayName", + "ugDisplayName", + "ukDisplayName", + "urDisplayName", + "uzDisplayName", + "veDisplayName", + "viDisplayName", + "voDisplayName", + "waDisplayName", + "cyDisplayName", + "woDisplayName", + "fyDisplayName", + "xhDisplayName", + "yiDisplayName", + "yoDisplayName", + "zaDisplayName", + "unkDisplayName", + "zuDisplayName", + "hawDisplayName", + "hmnDisplayName", + "multiDisplayName", + "cebDisplayName", + "dzDisplayName", + "iwDisplayName", + "jwDisplayName", + "moDisplayName", + "shDisplayName", + "wwCountryDisplayName", + "afCountryDisplayName", + "axCountryDisplayName", + "alCountryDisplayName", + "dzCountryDisplayName", + "asCountryDisplayName", + "adCountryDisplayName", + "aoCountryDisplayName", + "aiCountryDisplayName", + "agCountryDisplayName", + "arCountryDisplayName", + "amCountryDisplayName", + "awCountryDisplayName", + "acCountryDisplayName", + "auCountryDisplayName", + "atCountryDisplayName", + "azCountryDisplayName", + "bsCountryDisplayName", + "bhCountryDisplayName", + "bdCountryDisplayName", + "bbCountryDisplayName", + "byCountryDisplayName", + "beCountryDisplayName", + "bzCountryDisplayName", + "bjCountryDisplayName", + "bmCountryDisplayName", + "btCountryDisplayName", + "boCountryDisplayName", + "baCountryDisplayName", + "bwCountryDisplayName", + "brCountryDisplayName", + "ioCountryDisplayName", + "vgCountryDisplayName", + "bnCountryDisplayName", + "bgCountryDisplayName", + "bfCountryDisplayName", + "biCountryDisplayName", + "khCountryDisplayName", + "cmCountryDisplayName", + "caCountryDisplayName", + "cvCountryDisplayName", + "bqCountryDisplayName", + "kyCountryDisplayName", + "cfCountryDisplayName", + "tdCountryDisplayName", + "clCountryDisplayName", + "cnCountryDisplayName", + "cxCountryDisplayName", + "ccCountryDisplayName", + "coCountryDisplayName", + "kmCountryDisplayName", + "cdCountryDisplayName", + "cgCountryDisplayName", + "ckCountryDisplayName", + "crCountryDisplayName", + "ciCountryDisplayName", + "hrCountryDisplayName", + "cuCountryDisplayName", + "cwCountryDisplayName", + "cyCountryDisplayName", + "czCountryDisplayName", + "dkCountryDisplayName", + "djCountryDisplayName", + "dmCountryDisplayName", + "doCountryDisplayName", + "tlCountryDisplayName", + "ecCountryDisplayName", + "egCountryDisplayName", + "svCountryDisplayName", + "gqCountryDisplayName", + "erCountryDisplayName", + "eeCountryDisplayName", + "szCountryDisplayName", + "etCountryDisplayName", + "fkCountryDisplayName", + "foCountryDisplayName", + "fjCountryDisplayName", + "fiCountryDisplayName", + "frCountryDisplayName", + "gfCountryDisplayName", + "pfCountryDisplayName", + "gaCountryDisplayName", + "gmCountryDisplayName", + "geCountryDisplayName", + "deCountryDisplayName", + "ghCountryDisplayName", + "giCountryDisplayName", + "grCountryDisplayName", + "glCountryDisplayName", + "gdCountryDisplayName", + "gpCountryDisplayName", + "guCountryDisplayName", + "gtCountryDisplayName", + "ggCountryDisplayName", + "gnCountryDisplayName", + "gwCountryDisplayName", + "gyCountryDisplayName", + "htCountryDisplayName", + "hmCountryDisplayName", + "hnCountryDisplayName", + "hkCountryDisplayName", + "huCountryDisplayName", + "isCountryDisplayName", + "inCountryDisplayName", + "idCountryDisplayName", + "irCountryDisplayName", + "iqCountryDisplayName", + "ieCountryDisplayName", + "imCountryDisplayName", + "ilCountryDisplayName", + "itCountryDisplayName", + "jmCountryDisplayName", + "jpCountryDisplayName", + "jeCountryDisplayName", + "joCountryDisplayName", + "kzCountryDisplayName", + "keCountryDisplayName", + "kiCountryDisplayName", + "xkCountryDisplayName", + "kwCountryDisplayName", + "kgCountryDisplayName", + "laCountryDisplayName", + "lvCountryDisplayName", + "lbCountryDisplayName", + "lsCountryDisplayName", + "lrCountryDisplayName", + "lyCountryDisplayName", + "liCountryDisplayName", + "ltCountryDisplayName", + "luCountryDisplayName", + "moCountryDisplayName", + "mkCountryDisplayName", + "mgCountryDisplayName", + "mwCountryDisplayName", + "myCountryDisplayName", + "mvCountryDisplayName", + "mlCountryDisplayName", + "mtCountryDisplayName", + "mhCountryDisplayName", + "mqCountryDisplayName", + "mrCountryDisplayName", + "muCountryDisplayName", + "ytCountryDisplayName", + "mxCountryDisplayName", + "fmCountryDisplayName", + "mdCountryDisplayName", + "mcCountryDisplayName", + "mnCountryDisplayName", + "meCountryDisplayName", + "msCountryDisplayName", + "maCountryDisplayName", + "mzCountryDisplayName", + "mmCountryDisplayName", + "naCountryDisplayName", + "nrCountryDisplayName", + "npCountryDisplayName", + "nlCountryDisplayName", + "ncCountryDisplayName", + "nzCountryDisplayName", + "niCountryDisplayName", + "neCountryDisplayName", + "ngCountryDisplayName", + "nuCountryDisplayName", + "nfCountryDisplayName", + "kpCountryDisplayName", + "mpCountryDisplayName", + "noCountryDisplayName", + "omCountryDisplayName", + "pkCountryDisplayName", + "pwCountryDisplayName", + "psCountryDisplayName", + "paCountryDisplayName", + "pgCountryDisplayName", + "pyCountryDisplayName", + "peCountryDisplayName", + "phCountryDisplayName", + "plCountryDisplayName", + "ptCountryDisplayName", + "prCountryDisplayName", + "qaCountryDisplayName", + "reCountryDisplayName", + "roCountryDisplayName", + "ruCountryDisplayName", + "rwCountryDisplayName", + "blCountryDisplayName", + "shCountryDisplayName", + "knCountryDisplayName", + "lcCountryDisplayName", + "mfCountryDisplayName", + "pmCountryDisplayName", + "vcCountryDisplayName", + "wsCountryDisplayName", + "smCountryDisplayName", + "stCountryDisplayName", + "saCountryDisplayName", + "snCountryDisplayName", + "rsCountryDisplayName", + "scCountryDisplayName", + "slCountryDisplayName", + "sgCountryDisplayName", + "sxCountryDisplayName", + "skCountryDisplayName", + "siCountryDisplayName", + "sbCountryDisplayName", + "soCountryDisplayName", + "zaCountryDisplayName", + "gsCountryDisplayName", + "krCountryDisplayName", + "ssCountryDisplayName", + "esCountryDisplayName", + "lkCountryDisplayName", + "sdCountryDisplayName", + "srCountryDisplayName", + "sjCountryDisplayName", + "seCountryDisplayName", + "chCountryDisplayName", + "syCountryDisplayName", + "twCountryDisplayName", + "tjCountryDisplayName", + "tzCountryDisplayName", + "thCountryDisplayName", + "tgCountryDisplayName", + "tkCountryDisplayName", + "toCountryDisplayName", + "ttCountryDisplayName", + "tnCountryDisplayName", + "trCountryDisplayName", + "tmCountryDisplayName", + "tcCountryDisplayName", + "tvCountryDisplayName", + "viCountryDisplayName", + "ugCountryDisplayName", + "uaCountryDisplayName", + "aeCountryDisplayName", + "gbCountryDisplayName", + "usCountryDisplayName", + "uyCountryDisplayName", + "uzCountryDisplayName", + "vuCountryDisplayName", + "vaCountryDisplayName", + "veCountryDisplayName", + "vnCountryDisplayName", + "wfCountryDisplayName", + "ehCountryDisplayName", + "yeCountryDisplayName", + "zmCountryDisplayName", + "zwCountryDisplayName", + "pay", + "allPrivateChats", + "unknownPrivateChat", + "copyClassCodeDesc", + "addToClassDesc", + "addToClassOrExchange", + "addToClassOrExchangeDesc", + "invitedToClassOrExchange", + "decline", + "declinedInvitation", + "acceptedInvitation", + "youreInvited", + "studentPermissionsDesc", + "noEligibleSpaces", + "youAddedToSpace", + "youRemovedFromSpace", + "invitedToChat", + "monthlySubscription", + "yearlySubscription", + "defaultSubscription", + "freeTrial", + "grammarAnalytics", + "total", + "noDataFound", + "promoSubscriptionExpirationDesc", + "emptyChatNameWarning", + "emptyClassNameWarning", + "emptyExchangeNameWarning", + "blurMeansTranslateTitle", + "blurMeansTranslateBody", + "someErrorTitle", + "someErrorBody", + "bestCorrectionFeedback", + "distractorFeedback", + "bestAnswerFeedback", + "definitionDefaultPrompt", + "practiceDefaultPrompt", + "correctionDefaultPrompt", + "itStartDefaultPrompt", + "languageLevelWarning", + "lockedChatWarning", + "lockSpace", + "lockChat", + "archiveSpace", + "suggestTo", + "suggestChatDesc", + "suggestExchangeDesc", + "acceptSelection", + "acceptSelectionAnyway", + "makingActivity", + "why", + "definition", + "exampleSentence", + "addToClassTitle", + "reportToTeacher", + "reportMessageTitle", + "reportMessageBody", + "noTeachersFound", + "noAddToSpacePermissions", + "alreadyInSpace", + "yourGlobalUserIdIs", + "noUsersFoundWithQuery", + "searchChatsRooms", + "groupName", + "createGroupAndInviteUsers", + "groupCanBeFoundViaSearch", + "inNoSpaces" + ], + + "ja": [ + "accountInformation", + "addNewFriend", + "alreadyHaveAnAccount", + "classes", + "allCorrect", + "newWayAllGood", + "othersAreBetter", + "holdForInfo", + "greenFeedback", + "yellowFeedback", + "redFeedback", + "customInputFeedbackChoice", + "itInstructionsTitle", + "itInstructionsBody", + "toggleLanguages", + "classWelcomeChat", + "deleteSpace", + "deleteGroup", + "areYouSureDeleteClass", + "areYouSureDeleteGroup", + "cannotBeReversed", + "enterDeletedClassName", + "incorrectClassName", + "oneday", + "oneweek", + "onemonth", + "sixmonth", + "oneyear", + "gaTooltip", + "taTooltip", + "unTooltip", + "interactiveTranslatorSliderHeader", + "interactiveGrammarSliderHeader", + "interactiveTranslatorNotAllowed", + "interactiveTranslatorAllowed", + "interactiveTranslatorRequired", + "interactiveTranslatorNotAllowedDesc", + "interactiveTranslatorAllowedDesc", + "interactiveTranslatorRequiredDesc", + "notYetSet", + "multiLingualClass", + "classAnalytics", + "allClasses", + "myLearning", + "allChatsAndClasses", + "timeOfLastMessage", + "totalMessages", + "waTooltip", + "changeDateRange", + "numberOfStudents", + "classDescription", + "classDescriptionDesc", + "requestToEnroll", + "requestAnExchange", + "findLanguageExchange", + "classAnalyticsDesc", + "addStudents", + "copyClassLink", + "copyClassLinkDesc", + "copyClassCode", + "inviteStudentByUserName", + "classSettings", + "classSettingsDesc", + "selectClassRoomDominantLanguage", + "selectTargetLanguage", + "whatIsYourClassLanguageLevel", + "studentPermissions", + "interactiveTranslator", + "oneToOneChatsWithinClass", + "oneToOneChatsWithinClassDesc", + "createGroupChats", + "createGroupChatsDesc", + "shareVideo", + "shareVideoDesc", + "sharePhotos", + "sharePhotosDesc", + "shareFiles", + "shareFilesDesc", + "shareLocationDesc", + "selectLanguageLevel", + "noIdenticalLanguages", + "iWantALanguagePartnerFrom", + "worldWide", + "noResults", + "searchBy", + "iWantAConversationPartner", + "iWantALanguagePartnerWhoSpeaks", + "iWantALanguagePartnerWhoIsLearning", + "yourBirthdayPlease", + "invalidDob", + "enterYourDob", + "getStarted", + "mustBe13", + "yourBirthdayPleaseShort", + "errorPleaseRefresh", + "joinWithClassCode", + "joinWithClassCodeDesc", + "joinWithClassCodeHint", + "unableToFindClass", + "languageLevelPreA1", + "languageLevelA1", + "languageLevelA2", + "languageLevelB1", + "languageLevelB2", + "languageLevelC1", + "languageLevelC2", + "changeTheNameOfTheClass", + "changeTheNameOfTheChat", + "welcomeToYourNewClass", + "welcomeToClass", + "welcomeToPangea18Plus", + "welcomeToPangeaMinor", + "findALanguagePartner", + "setToPublicSettingsTitle", + "setToPublicSettingsDesc", + "accountSettings", + "unableToFindClassCode", + "askPangeaBot", + "sorryNoResults", + "ignoreInThisText", + "helpMeTranslate", + "needsItShortMessage", + "needsIGCShortMessage", + "needsItMessage", + "needsIgcMessage", + "tokenTranslationTitle", + "spanTranslationDesc", + "spanTranslationTitle", + "l1SpanAndGrammarTitle", + "l1SpanAndGrammarDesc", + "otherTitle", + "otherDesc", + "countryInformation", + "myLanguages", + "targetLanguage", + "sourceLanguage", + "languagesISpeak", + "updateLanguage", + "whatLanguageYouWantToLearn", + "whatIsYourBaseLanguage", + "saveChanges", + "publicProfileTitle", + "publicProfileDesc", + "error502504Title", + "error502504Desc", + "error404Title", + "error404Desc", + "errorDisableIT", + "errorDisableIGC", + "errorDisableLanguageAssistance", + "errorDisableITUserDesc", + "errorDisableIGCUserDesc", + "errorDisableLanguageAssistanceUserDesc", + "errorDisableITClassDesc", + "errorDisableIGCClassDesc", + "errorDisableLanguageAssistanceClassDesc", + "itIsDisabled", + "igcIsDisabled", + "goToLearningSettings", + "error405Title", + "error405Desc", + "loginOrSignup", + "iAgreeToThe", + "termsAndConditions", + "andCertifyIAmAtLeast13YearsOfAge", + "findAClass", + "toggleIT", + "toggleIGC", + "toggleToolSettingsDescription", + "connectedToStaging", + "learningSettings", + "classNameRequired", + "sendVoiceNotes", + "sendVoiceNotesDesc", + "chatTopic", + "chatTopicDesc", + "inviteStudentByUserNameDesc", + "classRoster", + "almostPerfect", + "prettyGood", + "letMeThink", + "clickMessageTitle", + "clickMessageBody", + "understandingMessagesTitle", + "addToClass", + "understandingMessagesBody", + "allDone", + "vocab", + "low", + "medium", + "high", + "unknownProficiency", + "changeView", + "clearAll", + "generateVocabulary", + "generatePrompts", + "subscribe", + "getAccess", + "subscriptionDesc", + "subscriptionManagement", + "currentSubscription", + "changeSubscription", + "cancelSubscription", + "selectYourPlan", + "subsciptionPlatformTooltip", + "subscriptionManagementUnavailable", + "paymentMethod", + "paymentHistory", + "emptyChatDownloadWarning", + "appUpdateAvailable", + "update", + "updateDesc", + "maybeLater", + "mainMenu", + "toggleImmersionMode", + "toggleImmersionModeDesc", + "itToggleDescription", + "igcToggleDescription", + "sendOnEnterDescription", + "alreadyInClass", + "pleaseLoginFirst", + "originalMessage", + "sentMessage", + "useType", + "notAvailable", + "taAndGaTooltip", + "definitionsToolName", + "messageTranslationsToolName", + "definitionsToolDescription", + "translationsToolDescrption", + "welcomeBack", + "classExchanges", + "createNewClass", + "newExchange", + "kickAllStudents", + "kickAllStudentsConfirmation", + "inviteAllStudents", + "inviteAllStudentsConfirmation", + "inviteStudentsFromOtherClasses", + "inviteUsersFromPangea", + "allExchanges", + "redeemPromoCode", + "enterPromoCode", + "downloadTxtFile", + "downloadCSVFile", + "promotionalSubscriptionDesc", + "originalSubscriptionPlatform", + "oneWeekTrial", + "creatingSpacePleaseWait", + "downloadXLSXFile", + "abDisplayName", + "aaDisplayName", + "afDisplayName", + "akDisplayName", + "sqDisplayName", + "amDisplayName", + "arDisplayName", + "anDisplayName", + "hyDisplayName", + "asDisplayName", + "avDisplayName", + "aeDisplayName", + "ayDisplayName", + "azDisplayName", + "bmDisplayName", + "baDisplayName", + "euDisplayName", + "beDisplayName", + "bnDisplayName", + "bhDisplayName", + "biDisplayName", + "bsDisplayName", + "brDisplayName", + "bgDisplayName", + "myDisplayName", + "caDisplayName", + "chDisplayName", + "ceDisplayName", + "nyDisplayName", + "zhDisplayName", + "cvDisplayName", + "kwDisplayName", + "coDisplayName", + "crDisplayName", + "hrDisplayName", + "csDisplayName", + "daDisplayName", + "dvDisplayName", + "nlDisplayName", + "enDisplayName", + "eoDisplayName", + "etDisplayName", + "eeDisplayName", + "foDisplayName", + "fjDisplayName", + "fiDisplayName", + "frDisplayName", + "ffDisplayName", + "glDisplayName", + "kaDisplayName", + "deDisplayName", + "elDisplayName", + "gnDisplayName", + "guDisplayName", + "htDisplayName", + "haDisplayName", + "heDisplayName", + "hzDisplayName", + "hiDisplayName", + "hoDisplayName", + "huDisplayName", + "iaDisplayName", + "idDisplayName", + "ieDisplayName", + "gaDisplayName", + "igDisplayName", + "ikDisplayName", + "ioDisplayName", + "isDisplayName", + "itDisplayName", + "iuDisplayName", + "jaDisplayName", + "jvDisplayName", + "klDisplayName", + "knDisplayName", + "krDisplayName", + "ksDisplayName", + "kkDisplayName", + "kmDisplayName", + "kiDisplayName", + "rwDisplayName", + "kyDisplayName", + "kvDisplayName", + "kgDisplayName", + "koDisplayName", + "kuDisplayName", + "kjDisplayName", + "laDisplayName", + "lbDisplayName", + "lgDisplayName", + "liDisplayName", + "lnDisplayName", + "loDisplayName", + "ltDisplayName", + "luDisplayName", + "lvDisplayName", + "gvDisplayName", + "mkDisplayName", + "mgDisplayName", + "msDisplayName", + "mlDisplayName", + "mtDisplayName", + "miDisplayName", + "mrDisplayName", + "mhDisplayName", + "mnDisplayName", + "naDisplayName", + "nvDisplayName", + "nbDisplayName", + "ndDisplayName", + "neDisplayName", + "ngDisplayName", + "nnDisplayName", + "noDisplayName", + "iiDisplayName", + "nrDisplayName", + "ocDisplayName", + "ojDisplayName", + "cuDisplayName", + "omDisplayName", + "orDisplayName", + "osDisplayName", + "paDisplayName", + "piDisplayName", + "faDisplayName", + "plDisplayName", + "psDisplayName", + "ptDisplayName", + "quDisplayName", + "rmDisplayName", + "rnDisplayName", + "roDisplayName", + "ruDisplayName", + "saDisplayName", + "scDisplayName", + "sdDisplayName", + "seDisplayName", + "smDisplayName", + "sgDisplayName", + "srDisplayName", + "gdDisplayName", + "snDisplayName", + "siDisplayName", + "skDisplayName", + "slDisplayName", + "soDisplayName", + "stDisplayName", + "esDisplayName", + "suDisplayName", + "swDisplayName", + "ssDisplayName", + "svDisplayName", + "taDisplayName", + "teDisplayName", + "tgDisplayName", + "thDisplayName", + "tiDisplayName", + "boDisplayName", + "tkDisplayName", + "tlDisplayName", + "tnDisplayName", + "toDisplayName", + "trDisplayName", + "tsDisplayName", + "ttDisplayName", + "twDisplayName", + "tyDisplayName", + "ugDisplayName", + "ukDisplayName", + "urDisplayName", + "uzDisplayName", + "veDisplayName", + "viDisplayName", + "voDisplayName", + "waDisplayName", + "cyDisplayName", + "woDisplayName", + "fyDisplayName", + "xhDisplayName", + "yiDisplayName", + "yoDisplayName", + "zaDisplayName", + "unkDisplayName", + "zuDisplayName", + "hawDisplayName", + "hmnDisplayName", + "multiDisplayName", + "cebDisplayName", + "dzDisplayName", + "iwDisplayName", + "jwDisplayName", + "moDisplayName", + "shDisplayName", + "wwCountryDisplayName", + "afCountryDisplayName", + "axCountryDisplayName", + "alCountryDisplayName", + "dzCountryDisplayName", + "asCountryDisplayName", + "adCountryDisplayName", + "aoCountryDisplayName", + "aiCountryDisplayName", + "agCountryDisplayName", + "arCountryDisplayName", + "amCountryDisplayName", + "awCountryDisplayName", + "acCountryDisplayName", + "auCountryDisplayName", + "atCountryDisplayName", + "azCountryDisplayName", + "bsCountryDisplayName", + "bhCountryDisplayName", + "bdCountryDisplayName", + "bbCountryDisplayName", + "byCountryDisplayName", + "beCountryDisplayName", + "bzCountryDisplayName", + "bjCountryDisplayName", + "bmCountryDisplayName", + "btCountryDisplayName", + "boCountryDisplayName", + "baCountryDisplayName", + "bwCountryDisplayName", + "brCountryDisplayName", + "ioCountryDisplayName", + "vgCountryDisplayName", + "bnCountryDisplayName", + "bgCountryDisplayName", + "bfCountryDisplayName", + "biCountryDisplayName", + "khCountryDisplayName", + "cmCountryDisplayName", + "caCountryDisplayName", + "cvCountryDisplayName", + "bqCountryDisplayName", + "kyCountryDisplayName", + "cfCountryDisplayName", + "tdCountryDisplayName", + "clCountryDisplayName", + "cnCountryDisplayName", + "cxCountryDisplayName", + "ccCountryDisplayName", + "coCountryDisplayName", + "kmCountryDisplayName", + "cdCountryDisplayName", + "cgCountryDisplayName", + "ckCountryDisplayName", + "crCountryDisplayName", + "ciCountryDisplayName", + "hrCountryDisplayName", + "cuCountryDisplayName", + "cwCountryDisplayName", + "cyCountryDisplayName", + "czCountryDisplayName", + "dkCountryDisplayName", + "djCountryDisplayName", + "dmCountryDisplayName", + "doCountryDisplayName", + "tlCountryDisplayName", + "ecCountryDisplayName", + "egCountryDisplayName", + "svCountryDisplayName", + "gqCountryDisplayName", + "erCountryDisplayName", + "eeCountryDisplayName", + "szCountryDisplayName", + "etCountryDisplayName", + "fkCountryDisplayName", + "foCountryDisplayName", + "fjCountryDisplayName", + "fiCountryDisplayName", + "frCountryDisplayName", + "gfCountryDisplayName", + "pfCountryDisplayName", + "gaCountryDisplayName", + "gmCountryDisplayName", + "geCountryDisplayName", + "deCountryDisplayName", + "ghCountryDisplayName", + "giCountryDisplayName", + "grCountryDisplayName", + "glCountryDisplayName", + "gdCountryDisplayName", + "gpCountryDisplayName", + "guCountryDisplayName", + "gtCountryDisplayName", + "ggCountryDisplayName", + "gnCountryDisplayName", + "gwCountryDisplayName", + "gyCountryDisplayName", + "htCountryDisplayName", + "hmCountryDisplayName", + "hnCountryDisplayName", + "hkCountryDisplayName", + "huCountryDisplayName", + "isCountryDisplayName", + "inCountryDisplayName", + "idCountryDisplayName", + "irCountryDisplayName", + "iqCountryDisplayName", + "ieCountryDisplayName", + "imCountryDisplayName", + "ilCountryDisplayName", + "itCountryDisplayName", + "jmCountryDisplayName", + "jpCountryDisplayName", + "jeCountryDisplayName", + "joCountryDisplayName", + "kzCountryDisplayName", + "keCountryDisplayName", + "kiCountryDisplayName", + "xkCountryDisplayName", + "kwCountryDisplayName", + "kgCountryDisplayName", + "laCountryDisplayName", + "lvCountryDisplayName", + "lbCountryDisplayName", + "lsCountryDisplayName", + "lrCountryDisplayName", + "lyCountryDisplayName", + "liCountryDisplayName", + "ltCountryDisplayName", + "luCountryDisplayName", + "moCountryDisplayName", + "mkCountryDisplayName", + "mgCountryDisplayName", + "mwCountryDisplayName", + "myCountryDisplayName", + "mvCountryDisplayName", + "mlCountryDisplayName", + "mtCountryDisplayName", + "mhCountryDisplayName", + "mqCountryDisplayName", + "mrCountryDisplayName", + "muCountryDisplayName", + "ytCountryDisplayName", + "mxCountryDisplayName", + "fmCountryDisplayName", + "mdCountryDisplayName", + "mcCountryDisplayName", + "mnCountryDisplayName", + "meCountryDisplayName", + "msCountryDisplayName", + "maCountryDisplayName", + "mzCountryDisplayName", + "mmCountryDisplayName", + "naCountryDisplayName", + "nrCountryDisplayName", + "npCountryDisplayName", + "nlCountryDisplayName", + "ncCountryDisplayName", + "nzCountryDisplayName", + "niCountryDisplayName", + "neCountryDisplayName", + "ngCountryDisplayName", + "nuCountryDisplayName", + "nfCountryDisplayName", + "kpCountryDisplayName", + "mpCountryDisplayName", + "noCountryDisplayName", + "omCountryDisplayName", + "pkCountryDisplayName", + "pwCountryDisplayName", + "psCountryDisplayName", + "paCountryDisplayName", + "pgCountryDisplayName", + "pyCountryDisplayName", + "peCountryDisplayName", + "phCountryDisplayName", + "plCountryDisplayName", + "ptCountryDisplayName", + "prCountryDisplayName", + "qaCountryDisplayName", + "reCountryDisplayName", + "roCountryDisplayName", + "ruCountryDisplayName", + "rwCountryDisplayName", + "blCountryDisplayName", + "shCountryDisplayName", + "knCountryDisplayName", + "lcCountryDisplayName", + "mfCountryDisplayName", + "pmCountryDisplayName", + "vcCountryDisplayName", + "wsCountryDisplayName", + "smCountryDisplayName", + "stCountryDisplayName", + "saCountryDisplayName", + "snCountryDisplayName", + "rsCountryDisplayName", + "scCountryDisplayName", + "slCountryDisplayName", + "sgCountryDisplayName", + "sxCountryDisplayName", + "skCountryDisplayName", + "siCountryDisplayName", + "sbCountryDisplayName", + "soCountryDisplayName", + "zaCountryDisplayName", + "gsCountryDisplayName", + "krCountryDisplayName", + "ssCountryDisplayName", + "esCountryDisplayName", + "lkCountryDisplayName", + "sdCountryDisplayName", + "srCountryDisplayName", + "sjCountryDisplayName", + "seCountryDisplayName", + "chCountryDisplayName", + "syCountryDisplayName", + "twCountryDisplayName", + "tjCountryDisplayName", + "tzCountryDisplayName", + "thCountryDisplayName", + "tgCountryDisplayName", + "tkCountryDisplayName", + "toCountryDisplayName", + "ttCountryDisplayName", + "tnCountryDisplayName", + "trCountryDisplayName", + "tmCountryDisplayName", + "tcCountryDisplayName", + "tvCountryDisplayName", + "viCountryDisplayName", + "ugCountryDisplayName", + "uaCountryDisplayName", + "aeCountryDisplayName", + "gbCountryDisplayName", + "usCountryDisplayName", + "uyCountryDisplayName", + "uzCountryDisplayName", + "vuCountryDisplayName", + "vaCountryDisplayName", + "veCountryDisplayName", + "vnCountryDisplayName", + "wfCountryDisplayName", + "ehCountryDisplayName", + "yeCountryDisplayName", + "zmCountryDisplayName", + "zwCountryDisplayName", + "pay", + "allPrivateChats", + "unknownPrivateChat", + "copyClassCodeDesc", + "addToClassDesc", + "addToClassOrExchange", + "addToClassOrExchangeDesc", + "invitedToClassOrExchange", + "decline", + "declinedInvitation", + "acceptedInvitation", + "youreInvited", + "studentPermissionsDesc", + "noEligibleSpaces", + "youAddedToSpace", + "youRemovedFromSpace", + "invitedToChat", + "monthlySubscription", + "yearlySubscription", + "defaultSubscription", + "freeTrial", + "grammarAnalytics", + "total", + "noDataFound", + "promoSubscriptionExpirationDesc", + "emptyChatNameWarning", + "emptyClassNameWarning", + "emptyExchangeNameWarning", + "blurMeansTranslateTitle", + "blurMeansTranslateBody", + "someErrorTitle", + "someErrorBody", + "bestCorrectionFeedback", + "distractorFeedback", + "bestAnswerFeedback", + "definitionDefaultPrompt", + "practiceDefaultPrompt", + "correctionDefaultPrompt", + "itStartDefaultPrompt", + "languageLevelWarning", + "lockedChatWarning", + "lockSpace", + "lockChat", + "archiveSpace", + "suggestTo", + "suggestChatDesc", + "suggestExchangeDesc", + "acceptSelection", + "acceptSelectionAnyway", + "makingActivity", + "why", + "definition", + "exampleSentence", + "addToClassTitle", + "reportToTeacher", + "reportMessageTitle", + "reportMessageBody", + "noTeachersFound", + "noAddToSpacePermissions", + "alreadyInSpace", + "yourGlobalUserIdIs", + "noUsersFoundWithQuery", + "searchChatsRooms", + "groupName", + "createGroupAndInviteUsers", + "groupCanBeFoundViaSearch", + "inNoSpaces" + ], + + "ko": [ + "accountInformation", + "addNewFriend", + "alreadyHaveAnAccount", + "classes", + "allCorrect", + "newWayAllGood", + "othersAreBetter", + "holdForInfo", + "greenFeedback", + "yellowFeedback", + "redFeedback", + "customInputFeedbackChoice", + "itInstructionsTitle", + "itInstructionsBody", + "toggleLanguages", + "classWelcomeChat", + "deleteSpace", + "deleteGroup", + "areYouSureDeleteClass", + "areYouSureDeleteGroup", + "cannotBeReversed", + "enterDeletedClassName", + "incorrectClassName", + "oneday", + "oneweek", + "onemonth", + "sixmonth", + "oneyear", + "gaTooltip", + "taTooltip", + "unTooltip", + "interactiveTranslatorSliderHeader", + "interactiveGrammarSliderHeader", + "interactiveTranslatorNotAllowed", + "interactiveTranslatorAllowed", + "interactiveTranslatorRequired", + "interactiveTranslatorNotAllowedDesc", + "interactiveTranslatorAllowedDesc", + "interactiveTranslatorRequiredDesc", + "notYetSet", + "multiLingualClass", + "classAnalytics", + "allClasses", + "myLearning", + "allChatsAndClasses", + "timeOfLastMessage", + "totalMessages", + "waTooltip", + "changeDateRange", + "numberOfStudents", + "classDescription", + "classDescriptionDesc", + "requestToEnroll", + "requestAnExchange", + "findLanguageExchange", + "classAnalyticsDesc", + "addStudents", + "copyClassLink", + "copyClassLinkDesc", + "copyClassCode", + "inviteStudentByUserName", + "classSettings", + "classSettingsDesc", + "selectClassRoomDominantLanguage", + "selectTargetLanguage", + "whatIsYourClassLanguageLevel", + "studentPermissions", + "interactiveTranslator", + "oneToOneChatsWithinClass", + "oneToOneChatsWithinClassDesc", + "createGroupChats", + "createGroupChatsDesc", + "shareVideo", + "shareVideoDesc", + "sharePhotos", + "sharePhotosDesc", + "shareFiles", + "shareFilesDesc", + "shareLocationDesc", + "selectLanguageLevel", + "noIdenticalLanguages", + "iWantALanguagePartnerFrom", + "worldWide", + "noResults", + "searchBy", + "iWantAConversationPartner", + "iWantALanguagePartnerWhoSpeaks", + "iWantALanguagePartnerWhoIsLearning", + "yourBirthdayPlease", + "invalidDob", + "enterYourDob", + "getStarted", + "mustBe13", + "yourBirthdayPleaseShort", + "errorPleaseRefresh", + "joinWithClassCode", + "joinWithClassCodeDesc", + "joinWithClassCodeHint", + "unableToFindClass", + "languageLevelPreA1", + "languageLevelA1", + "languageLevelA2", + "languageLevelB1", + "languageLevelB2", + "languageLevelC1", + "languageLevelC2", + "changeTheNameOfTheClass", + "changeTheNameOfTheChat", + "welcomeToYourNewClass", + "welcomeToClass", + "welcomeToPangea18Plus", + "welcomeToPangeaMinor", + "findALanguagePartner", + "setToPublicSettingsTitle", + "setToPublicSettingsDesc", + "accountSettings", + "unableToFindClassCode", + "askPangeaBot", + "sorryNoResults", + "ignoreInThisText", + "helpMeTranslate", + "needsItShortMessage", + "needsIGCShortMessage", + "needsItMessage", + "needsIgcMessage", + "tokenTranslationTitle", + "spanTranslationDesc", + "spanTranslationTitle", + "l1SpanAndGrammarTitle", + "l1SpanAndGrammarDesc", + "otherTitle", + "otherDesc", + "countryInformation", + "myLanguages", + "targetLanguage", + "sourceLanguage", + "languagesISpeak", + "updateLanguage", + "whatLanguageYouWantToLearn", + "whatIsYourBaseLanguage", + "saveChanges", + "publicProfileTitle", + "publicProfileDesc", + "error502504Title", + "error502504Desc", + "error404Title", + "error404Desc", + "errorDisableIT", + "errorDisableIGC", + "errorDisableLanguageAssistance", + "errorDisableITUserDesc", + "errorDisableIGCUserDesc", + "errorDisableLanguageAssistanceUserDesc", + "errorDisableITClassDesc", + "errorDisableIGCClassDesc", + "errorDisableLanguageAssistanceClassDesc", + "itIsDisabled", + "igcIsDisabled", + "goToLearningSettings", + "error405Title", + "error405Desc", + "loginOrSignup", + "iAgreeToThe", + "termsAndConditions", + "andCertifyIAmAtLeast13YearsOfAge", + "findAClass", + "toggleIT", + "toggleIGC", + "toggleToolSettingsDescription", + "connectedToStaging", + "learningSettings", + "classNameRequired", + "sendVoiceNotes", + "sendVoiceNotesDesc", + "chatTopic", + "chatTopicDesc", + "inviteStudentByUserNameDesc", + "classRoster", + "almostPerfect", + "prettyGood", + "letMeThink", + "clickMessageTitle", + "clickMessageBody", + "understandingMessagesTitle", + "addToClass", + "understandingMessagesBody", + "allDone", + "vocab", + "low", + "medium", + "high", + "unknownProficiency", + "changeView", + "clearAll", + "generateVocabulary", + "generatePrompts", + "subscribe", + "getAccess", + "subscriptionDesc", + "subscriptionManagement", + "currentSubscription", + "changeSubscription", + "cancelSubscription", + "selectYourPlan", + "subsciptionPlatformTooltip", + "subscriptionManagementUnavailable", + "paymentMethod", + "paymentHistory", + "emptyChatDownloadWarning", + "appUpdateAvailable", + "update", + "updateDesc", + "maybeLater", + "mainMenu", + "toggleImmersionMode", + "toggleImmersionModeDesc", + "itToggleDescription", + "igcToggleDescription", + "sendOnEnterDescription", + "alreadyInClass", + "pleaseLoginFirst", + "originalMessage", + "sentMessage", + "useType", + "notAvailable", + "taAndGaTooltip", + "definitionsToolName", + "messageTranslationsToolName", + "definitionsToolDescription", + "translationsToolDescrption", + "welcomeBack", + "classExchanges", + "createNewClass", + "newExchange", + "kickAllStudents", + "kickAllStudentsConfirmation", + "inviteAllStudents", + "inviteAllStudentsConfirmation", + "inviteStudentsFromOtherClasses", + "inviteUsersFromPangea", + "allExchanges", + "redeemPromoCode", + "enterPromoCode", + "downloadTxtFile", + "downloadCSVFile", + "promotionalSubscriptionDesc", + "originalSubscriptionPlatform", + "oneWeekTrial", + "creatingSpacePleaseWait", + "downloadXLSXFile", + "abDisplayName", + "aaDisplayName", + "afDisplayName", + "akDisplayName", + "sqDisplayName", + "amDisplayName", + "arDisplayName", + "anDisplayName", + "hyDisplayName", + "asDisplayName", + "avDisplayName", + "aeDisplayName", + "ayDisplayName", + "azDisplayName", + "bmDisplayName", + "baDisplayName", + "euDisplayName", + "beDisplayName", + "bnDisplayName", + "bhDisplayName", + "biDisplayName", + "bsDisplayName", + "brDisplayName", + "bgDisplayName", + "myDisplayName", + "caDisplayName", + "chDisplayName", + "ceDisplayName", + "nyDisplayName", + "zhDisplayName", + "cvDisplayName", + "kwDisplayName", + "coDisplayName", + "crDisplayName", + "hrDisplayName", + "csDisplayName", + "daDisplayName", + "dvDisplayName", + "nlDisplayName", + "enDisplayName", + "eoDisplayName", + "etDisplayName", + "eeDisplayName", + "foDisplayName", + "fjDisplayName", + "fiDisplayName", + "frDisplayName", + "ffDisplayName", + "glDisplayName", + "kaDisplayName", + "deDisplayName", + "elDisplayName", + "gnDisplayName", + "guDisplayName", + "htDisplayName", + "haDisplayName", + "heDisplayName", + "hzDisplayName", + "hiDisplayName", + "hoDisplayName", + "huDisplayName", + "iaDisplayName", + "idDisplayName", + "ieDisplayName", + "gaDisplayName", + "igDisplayName", + "ikDisplayName", + "ioDisplayName", + "isDisplayName", + "itDisplayName", + "iuDisplayName", + "jaDisplayName", + "jvDisplayName", + "klDisplayName", + "knDisplayName", + "krDisplayName", + "ksDisplayName", + "kkDisplayName", + "kmDisplayName", + "kiDisplayName", + "rwDisplayName", + "kyDisplayName", + "kvDisplayName", + "kgDisplayName", + "koDisplayName", + "kuDisplayName", + "kjDisplayName", + "laDisplayName", + "lbDisplayName", + "lgDisplayName", + "liDisplayName", + "lnDisplayName", + "loDisplayName", + "ltDisplayName", + "luDisplayName", + "lvDisplayName", + "gvDisplayName", + "mkDisplayName", + "mgDisplayName", + "msDisplayName", + "mlDisplayName", + "mtDisplayName", + "miDisplayName", + "mrDisplayName", + "mhDisplayName", + "mnDisplayName", + "naDisplayName", + "nvDisplayName", + "nbDisplayName", + "ndDisplayName", + "neDisplayName", + "ngDisplayName", + "nnDisplayName", + "noDisplayName", + "iiDisplayName", + "nrDisplayName", + "ocDisplayName", + "ojDisplayName", + "cuDisplayName", + "omDisplayName", + "orDisplayName", + "osDisplayName", + "paDisplayName", + "piDisplayName", + "faDisplayName", + "plDisplayName", + "psDisplayName", + "ptDisplayName", + "quDisplayName", + "rmDisplayName", + "rnDisplayName", + "roDisplayName", + "ruDisplayName", + "saDisplayName", + "scDisplayName", + "sdDisplayName", + "seDisplayName", + "smDisplayName", + "sgDisplayName", + "srDisplayName", + "gdDisplayName", + "snDisplayName", + "siDisplayName", + "skDisplayName", + "slDisplayName", + "soDisplayName", + "stDisplayName", + "esDisplayName", + "suDisplayName", + "swDisplayName", + "ssDisplayName", + "svDisplayName", + "taDisplayName", + "teDisplayName", + "tgDisplayName", + "thDisplayName", + "tiDisplayName", + "boDisplayName", + "tkDisplayName", + "tlDisplayName", + "tnDisplayName", + "toDisplayName", + "trDisplayName", + "tsDisplayName", + "ttDisplayName", + "twDisplayName", + "tyDisplayName", + "ugDisplayName", + "ukDisplayName", + "urDisplayName", + "uzDisplayName", + "veDisplayName", + "viDisplayName", + "voDisplayName", + "waDisplayName", + "cyDisplayName", + "woDisplayName", + "fyDisplayName", + "xhDisplayName", + "yiDisplayName", + "yoDisplayName", + "zaDisplayName", + "unkDisplayName", + "zuDisplayName", + "hawDisplayName", + "hmnDisplayName", + "multiDisplayName", + "cebDisplayName", + "dzDisplayName", + "iwDisplayName", + "jwDisplayName", + "moDisplayName", + "shDisplayName", + "wwCountryDisplayName", + "afCountryDisplayName", + "axCountryDisplayName", + "alCountryDisplayName", + "dzCountryDisplayName", + "asCountryDisplayName", + "adCountryDisplayName", + "aoCountryDisplayName", + "aiCountryDisplayName", + "agCountryDisplayName", + "arCountryDisplayName", + "amCountryDisplayName", + "awCountryDisplayName", + "acCountryDisplayName", + "auCountryDisplayName", + "atCountryDisplayName", + "azCountryDisplayName", + "bsCountryDisplayName", + "bhCountryDisplayName", + "bdCountryDisplayName", + "bbCountryDisplayName", + "byCountryDisplayName", + "beCountryDisplayName", + "bzCountryDisplayName", + "bjCountryDisplayName", + "bmCountryDisplayName", + "btCountryDisplayName", + "boCountryDisplayName", + "baCountryDisplayName", + "bwCountryDisplayName", + "brCountryDisplayName", + "ioCountryDisplayName", + "vgCountryDisplayName", + "bnCountryDisplayName", + "bgCountryDisplayName", + "bfCountryDisplayName", + "biCountryDisplayName", + "khCountryDisplayName", + "cmCountryDisplayName", + "caCountryDisplayName", + "cvCountryDisplayName", + "bqCountryDisplayName", + "kyCountryDisplayName", + "cfCountryDisplayName", + "tdCountryDisplayName", + "clCountryDisplayName", + "cnCountryDisplayName", + "cxCountryDisplayName", + "ccCountryDisplayName", + "coCountryDisplayName", + "kmCountryDisplayName", + "cdCountryDisplayName", + "cgCountryDisplayName", + "ckCountryDisplayName", + "crCountryDisplayName", + "ciCountryDisplayName", + "hrCountryDisplayName", + "cuCountryDisplayName", + "cwCountryDisplayName", + "cyCountryDisplayName", + "czCountryDisplayName", + "dkCountryDisplayName", + "djCountryDisplayName", + "dmCountryDisplayName", + "doCountryDisplayName", + "tlCountryDisplayName", + "ecCountryDisplayName", + "egCountryDisplayName", + "svCountryDisplayName", + "gqCountryDisplayName", + "erCountryDisplayName", + "eeCountryDisplayName", + "szCountryDisplayName", + "etCountryDisplayName", + "fkCountryDisplayName", + "foCountryDisplayName", + "fjCountryDisplayName", + "fiCountryDisplayName", + "frCountryDisplayName", + "gfCountryDisplayName", + "pfCountryDisplayName", + "gaCountryDisplayName", + "gmCountryDisplayName", + "geCountryDisplayName", + "deCountryDisplayName", + "ghCountryDisplayName", + "giCountryDisplayName", + "grCountryDisplayName", + "glCountryDisplayName", + "gdCountryDisplayName", + "gpCountryDisplayName", + "guCountryDisplayName", + "gtCountryDisplayName", + "ggCountryDisplayName", + "gnCountryDisplayName", + "gwCountryDisplayName", + "gyCountryDisplayName", + "htCountryDisplayName", + "hmCountryDisplayName", + "hnCountryDisplayName", + "hkCountryDisplayName", + "huCountryDisplayName", + "isCountryDisplayName", + "inCountryDisplayName", + "idCountryDisplayName", + "irCountryDisplayName", + "iqCountryDisplayName", + "ieCountryDisplayName", + "imCountryDisplayName", + "ilCountryDisplayName", + "itCountryDisplayName", + "jmCountryDisplayName", + "jpCountryDisplayName", + "jeCountryDisplayName", + "joCountryDisplayName", + "kzCountryDisplayName", + "keCountryDisplayName", + "kiCountryDisplayName", + "xkCountryDisplayName", + "kwCountryDisplayName", + "kgCountryDisplayName", + "laCountryDisplayName", + "lvCountryDisplayName", + "lbCountryDisplayName", + "lsCountryDisplayName", + "lrCountryDisplayName", + "lyCountryDisplayName", + "liCountryDisplayName", + "ltCountryDisplayName", + "luCountryDisplayName", + "moCountryDisplayName", + "mkCountryDisplayName", + "mgCountryDisplayName", + "mwCountryDisplayName", + "myCountryDisplayName", + "mvCountryDisplayName", + "mlCountryDisplayName", + "mtCountryDisplayName", + "mhCountryDisplayName", + "mqCountryDisplayName", + "mrCountryDisplayName", + "muCountryDisplayName", + "ytCountryDisplayName", + "mxCountryDisplayName", + "fmCountryDisplayName", + "mdCountryDisplayName", + "mcCountryDisplayName", + "mnCountryDisplayName", + "meCountryDisplayName", + "msCountryDisplayName", + "maCountryDisplayName", + "mzCountryDisplayName", + "mmCountryDisplayName", + "naCountryDisplayName", + "nrCountryDisplayName", + "npCountryDisplayName", + "nlCountryDisplayName", + "ncCountryDisplayName", + "nzCountryDisplayName", + "niCountryDisplayName", + "neCountryDisplayName", + "ngCountryDisplayName", + "nuCountryDisplayName", + "nfCountryDisplayName", + "kpCountryDisplayName", + "mpCountryDisplayName", + "noCountryDisplayName", + "omCountryDisplayName", + "pkCountryDisplayName", + "pwCountryDisplayName", + "psCountryDisplayName", + "paCountryDisplayName", + "pgCountryDisplayName", + "pyCountryDisplayName", + "peCountryDisplayName", + "phCountryDisplayName", + "plCountryDisplayName", + "ptCountryDisplayName", + "prCountryDisplayName", + "qaCountryDisplayName", + "reCountryDisplayName", + "roCountryDisplayName", + "ruCountryDisplayName", + "rwCountryDisplayName", + "blCountryDisplayName", + "shCountryDisplayName", + "knCountryDisplayName", + "lcCountryDisplayName", + "mfCountryDisplayName", + "pmCountryDisplayName", + "vcCountryDisplayName", + "wsCountryDisplayName", + "smCountryDisplayName", + "stCountryDisplayName", + "saCountryDisplayName", + "snCountryDisplayName", + "rsCountryDisplayName", + "scCountryDisplayName", + "slCountryDisplayName", + "sgCountryDisplayName", + "sxCountryDisplayName", + "skCountryDisplayName", + "siCountryDisplayName", + "sbCountryDisplayName", + "soCountryDisplayName", + "zaCountryDisplayName", + "gsCountryDisplayName", + "krCountryDisplayName", + "ssCountryDisplayName", + "esCountryDisplayName", + "lkCountryDisplayName", + "sdCountryDisplayName", + "srCountryDisplayName", + "sjCountryDisplayName", + "seCountryDisplayName", + "chCountryDisplayName", + "syCountryDisplayName", + "twCountryDisplayName", + "tjCountryDisplayName", + "tzCountryDisplayName", + "thCountryDisplayName", + "tgCountryDisplayName", + "tkCountryDisplayName", + "toCountryDisplayName", + "ttCountryDisplayName", + "tnCountryDisplayName", + "trCountryDisplayName", + "tmCountryDisplayName", + "tcCountryDisplayName", + "tvCountryDisplayName", + "viCountryDisplayName", + "ugCountryDisplayName", + "uaCountryDisplayName", + "aeCountryDisplayName", + "gbCountryDisplayName", + "usCountryDisplayName", + "uyCountryDisplayName", + "uzCountryDisplayName", + "vuCountryDisplayName", + "vaCountryDisplayName", + "veCountryDisplayName", + "vnCountryDisplayName", + "wfCountryDisplayName", + "ehCountryDisplayName", + "yeCountryDisplayName", + "zmCountryDisplayName", + "zwCountryDisplayName", + "pay", + "allPrivateChats", + "unknownPrivateChat", + "copyClassCodeDesc", + "addToClassDesc", + "addToClassOrExchange", + "addToClassOrExchangeDesc", + "invitedToClassOrExchange", + "decline", + "declinedInvitation", + "acceptedInvitation", + "youreInvited", + "studentPermissionsDesc", + "noEligibleSpaces", + "youAddedToSpace", + "youRemovedFromSpace", + "invitedToChat", + "monthlySubscription", + "yearlySubscription", + "defaultSubscription", + "freeTrial", + "grammarAnalytics", + "total", + "noDataFound", + "promoSubscriptionExpirationDesc", + "emptyChatNameWarning", + "emptyClassNameWarning", + "emptyExchangeNameWarning", + "blurMeansTranslateTitle", + "blurMeansTranslateBody", + "someErrorTitle", + "someErrorBody", + "bestCorrectionFeedback", + "distractorFeedback", + "bestAnswerFeedback", + "definitionDefaultPrompt", + "practiceDefaultPrompt", + "correctionDefaultPrompt", + "itStartDefaultPrompt", + "languageLevelWarning", + "lockedChatWarning", + "lockSpace", + "lockChat", + "archiveSpace", + "suggestTo", + "suggestChatDesc", + "suggestExchangeDesc", + "acceptSelection", + "acceptSelectionAnyway", + "makingActivity", + "why", + "definition", + "exampleSentence", + "addToClassTitle", + "reportToTeacher", + "reportMessageTitle", + "reportMessageBody", + "noTeachersFound", + "noAddToSpacePermissions", + "alreadyInSpace", + "yourGlobalUserIdIs", + "noUsersFoundWithQuery", + "searchChatsRooms", + "groupName", + "createGroupAndInviteUsers", + "groupCanBeFoundViaSearch", + "inNoSpaces" + ], + + "lt": [ + "accountInformation", + "addNewFriend", + "alreadyHaveAnAccount", + "classes", + "allCorrect", + "newWayAllGood", + "othersAreBetter", + "holdForInfo", + "greenFeedback", + "yellowFeedback", + "redFeedback", + "customInputFeedbackChoice", + "itInstructionsTitle", + "itInstructionsBody", + "toggleLanguages", + "classWelcomeChat", + "deleteSpace", + "deleteGroup", + "areYouSureDeleteClass", + "areYouSureDeleteGroup", + "cannotBeReversed", + "enterDeletedClassName", + "incorrectClassName", + "oneday", + "oneweek", + "onemonth", + "sixmonth", + "oneyear", + "gaTooltip", + "taTooltip", + "unTooltip", + "interactiveTranslatorSliderHeader", + "interactiveGrammarSliderHeader", + "interactiveTranslatorNotAllowed", + "interactiveTranslatorAllowed", + "interactiveTranslatorRequired", + "interactiveTranslatorNotAllowedDesc", + "interactiveTranslatorAllowedDesc", + "interactiveTranslatorRequiredDesc", + "notYetSet", + "multiLingualClass", + "classAnalytics", + "allClasses", + "myLearning", + "allChatsAndClasses", + "timeOfLastMessage", + "totalMessages", + "waTooltip", + "changeDateRange", + "numberOfStudents", + "classDescription", + "classDescriptionDesc", + "requestToEnroll", + "requestAnExchange", + "findLanguageExchange", + "classAnalyticsDesc", + "addStudents", + "copyClassLink", + "copyClassLinkDesc", + "copyClassCode", + "inviteStudentByUserName", + "classSettings", + "classSettingsDesc", + "selectClassRoomDominantLanguage", + "selectTargetLanguage", + "whatIsYourClassLanguageLevel", + "studentPermissions", + "interactiveTranslator", + "oneToOneChatsWithinClass", + "oneToOneChatsWithinClassDesc", + "createGroupChats", + "createGroupChatsDesc", + "shareVideo", + "shareVideoDesc", + "sharePhotos", + "sharePhotosDesc", + "shareFiles", + "shareFilesDesc", + "shareLocationDesc", + "selectLanguageLevel", + "noIdenticalLanguages", + "iWantALanguagePartnerFrom", + "worldWide", + "noResults", + "searchBy", + "iWantAConversationPartner", + "iWantALanguagePartnerWhoSpeaks", + "iWantALanguagePartnerWhoIsLearning", + "yourBirthdayPlease", + "invalidDob", + "enterYourDob", + "getStarted", + "mustBe13", + "yourBirthdayPleaseShort", + "errorPleaseRefresh", + "joinWithClassCode", + "joinWithClassCodeDesc", + "joinWithClassCodeHint", + "unableToFindClass", + "languageLevelPreA1", + "languageLevelA1", + "languageLevelA2", + "languageLevelB1", + "languageLevelB2", + "languageLevelC1", + "languageLevelC2", + "changeTheNameOfTheClass", + "changeTheNameOfTheChat", + "welcomeToYourNewClass", + "welcomeToClass", + "welcomeToPangea18Plus", + "welcomeToPangeaMinor", + "findALanguagePartner", + "setToPublicSettingsTitle", + "setToPublicSettingsDesc", + "accountSettings", + "unableToFindClassCode", + "askPangeaBot", + "sorryNoResults", + "ignoreInThisText", + "helpMeTranslate", + "needsItShortMessage", + "needsIGCShortMessage", + "needsItMessage", + "needsIgcMessage", + "tokenTranslationTitle", + "spanTranslationDesc", + "spanTranslationTitle", + "l1SpanAndGrammarTitle", + "l1SpanAndGrammarDesc", + "otherTitle", + "otherDesc", + "countryInformation", + "myLanguages", + "targetLanguage", + "sourceLanguage", + "languagesISpeak", + "updateLanguage", + "whatLanguageYouWantToLearn", + "whatIsYourBaseLanguage", + "saveChanges", + "publicProfileTitle", + "publicProfileDesc", + "error502504Title", + "error502504Desc", + "error404Title", + "error404Desc", + "errorDisableIT", + "errorDisableIGC", + "errorDisableLanguageAssistance", + "errorDisableITUserDesc", + "errorDisableIGCUserDesc", + "errorDisableLanguageAssistanceUserDesc", + "errorDisableITClassDesc", + "errorDisableIGCClassDesc", + "errorDisableLanguageAssistanceClassDesc", + "itIsDisabled", + "igcIsDisabled", + "goToLearningSettings", + "error405Title", + "error405Desc", + "loginOrSignup", + "iAgreeToThe", + "termsAndConditions", + "andCertifyIAmAtLeast13YearsOfAge", + "findAClass", + "toggleIT", + "toggleIGC", + "toggleToolSettingsDescription", + "connectedToStaging", + "learningSettings", + "classNameRequired", + "sendVoiceNotes", + "sendVoiceNotesDesc", + "chatTopic", + "chatTopicDesc", + "inviteStudentByUserNameDesc", + "classRoster", + "almostPerfect", + "prettyGood", + "letMeThink", + "clickMessageTitle", + "clickMessageBody", + "understandingMessagesTitle", + "addToClass", + "understandingMessagesBody", + "allDone", + "vocab", + "low", + "medium", + "high", + "unknownProficiency", + "changeView", + "clearAll", + "generateVocabulary", + "generatePrompts", + "subscribe", + "getAccess", + "subscriptionDesc", + "subscriptionManagement", + "currentSubscription", + "changeSubscription", + "cancelSubscription", + "selectYourPlan", + "subsciptionPlatformTooltip", + "subscriptionManagementUnavailable", + "paymentMethod", + "paymentHistory", + "emptyChatDownloadWarning", + "appUpdateAvailable", + "update", + "updateDesc", + "maybeLater", + "mainMenu", + "toggleImmersionMode", + "toggleImmersionModeDesc", + "itToggleDescription", + "igcToggleDescription", + "sendOnEnterDescription", + "alreadyInClass", + "pleaseLoginFirst", + "originalMessage", + "sentMessage", + "useType", + "notAvailable", + "taAndGaTooltip", + "definitionsToolName", + "messageTranslationsToolName", + "definitionsToolDescription", + "translationsToolDescrption", + "welcomeBack", + "classExchanges", + "createNewClass", + "newExchange", + "kickAllStudents", + "kickAllStudentsConfirmation", + "inviteAllStudents", + "inviteAllStudentsConfirmation", + "inviteStudentsFromOtherClasses", + "inviteUsersFromPangea", + "allExchanges", + "redeemPromoCode", + "enterPromoCode", + "downloadTxtFile", + "downloadCSVFile", + "promotionalSubscriptionDesc", + "originalSubscriptionPlatform", + "oneWeekTrial", + "creatingSpacePleaseWait", + "downloadXLSXFile", + "abDisplayName", + "aaDisplayName", + "afDisplayName", + "akDisplayName", + "sqDisplayName", + "amDisplayName", + "arDisplayName", + "anDisplayName", + "hyDisplayName", + "asDisplayName", + "avDisplayName", + "aeDisplayName", + "ayDisplayName", + "azDisplayName", + "bmDisplayName", + "baDisplayName", + "euDisplayName", + "beDisplayName", + "bnDisplayName", + "bhDisplayName", + "biDisplayName", + "bsDisplayName", + "brDisplayName", + "bgDisplayName", + "myDisplayName", + "caDisplayName", + "chDisplayName", + "ceDisplayName", + "nyDisplayName", + "zhDisplayName", + "cvDisplayName", + "kwDisplayName", + "coDisplayName", + "crDisplayName", + "hrDisplayName", + "csDisplayName", + "daDisplayName", + "dvDisplayName", + "nlDisplayName", + "enDisplayName", + "eoDisplayName", + "etDisplayName", + "eeDisplayName", + "foDisplayName", + "fjDisplayName", + "fiDisplayName", + "frDisplayName", + "ffDisplayName", + "glDisplayName", + "kaDisplayName", + "deDisplayName", + "elDisplayName", + "gnDisplayName", + "guDisplayName", + "htDisplayName", + "haDisplayName", + "heDisplayName", + "hzDisplayName", + "hiDisplayName", + "hoDisplayName", + "huDisplayName", + "iaDisplayName", + "idDisplayName", + "ieDisplayName", + "gaDisplayName", + "igDisplayName", + "ikDisplayName", + "ioDisplayName", + "isDisplayName", + "itDisplayName", + "iuDisplayName", + "jaDisplayName", + "jvDisplayName", + "klDisplayName", + "knDisplayName", + "krDisplayName", + "ksDisplayName", + "kkDisplayName", + "kmDisplayName", + "kiDisplayName", + "rwDisplayName", + "kyDisplayName", + "kvDisplayName", + "kgDisplayName", + "koDisplayName", + "kuDisplayName", + "kjDisplayName", + "laDisplayName", + "lbDisplayName", + "lgDisplayName", + "liDisplayName", + "lnDisplayName", + "loDisplayName", + "ltDisplayName", + "luDisplayName", + "lvDisplayName", + "gvDisplayName", + "mkDisplayName", + "mgDisplayName", + "msDisplayName", + "mlDisplayName", + "mtDisplayName", + "miDisplayName", + "mrDisplayName", + "mhDisplayName", + "mnDisplayName", + "naDisplayName", + "nvDisplayName", + "nbDisplayName", + "ndDisplayName", + "neDisplayName", + "ngDisplayName", + "nnDisplayName", + "noDisplayName", + "iiDisplayName", + "nrDisplayName", + "ocDisplayName", + "ojDisplayName", + "cuDisplayName", + "omDisplayName", + "orDisplayName", + "osDisplayName", + "paDisplayName", + "piDisplayName", + "faDisplayName", + "plDisplayName", + "psDisplayName", + "ptDisplayName", + "quDisplayName", + "rmDisplayName", + "rnDisplayName", + "roDisplayName", + "ruDisplayName", + "saDisplayName", + "scDisplayName", + "sdDisplayName", + "seDisplayName", + "smDisplayName", + "sgDisplayName", + "srDisplayName", + "gdDisplayName", + "snDisplayName", + "siDisplayName", + "skDisplayName", + "slDisplayName", + "soDisplayName", + "stDisplayName", + "esDisplayName", + "suDisplayName", + "swDisplayName", + "ssDisplayName", + "svDisplayName", + "taDisplayName", + "teDisplayName", + "tgDisplayName", + "thDisplayName", + "tiDisplayName", + "boDisplayName", + "tkDisplayName", + "tlDisplayName", + "tnDisplayName", + "toDisplayName", + "trDisplayName", + "tsDisplayName", + "ttDisplayName", + "twDisplayName", + "tyDisplayName", + "ugDisplayName", + "ukDisplayName", + "urDisplayName", + "uzDisplayName", + "veDisplayName", + "viDisplayName", + "voDisplayName", + "waDisplayName", + "cyDisplayName", + "woDisplayName", + "fyDisplayName", + "xhDisplayName", + "yiDisplayName", + "yoDisplayName", + "zaDisplayName", + "unkDisplayName", + "zuDisplayName", + "hawDisplayName", + "hmnDisplayName", + "multiDisplayName", + "cebDisplayName", + "dzDisplayName", + "iwDisplayName", + "jwDisplayName", + "moDisplayName", + "shDisplayName", + "wwCountryDisplayName", + "afCountryDisplayName", + "axCountryDisplayName", + "alCountryDisplayName", + "dzCountryDisplayName", + "asCountryDisplayName", + "adCountryDisplayName", + "aoCountryDisplayName", + "aiCountryDisplayName", + "agCountryDisplayName", + "arCountryDisplayName", + "amCountryDisplayName", + "awCountryDisplayName", + "acCountryDisplayName", + "auCountryDisplayName", + "atCountryDisplayName", + "azCountryDisplayName", + "bsCountryDisplayName", + "bhCountryDisplayName", + "bdCountryDisplayName", + "bbCountryDisplayName", + "byCountryDisplayName", + "beCountryDisplayName", + "bzCountryDisplayName", + "bjCountryDisplayName", + "bmCountryDisplayName", + "btCountryDisplayName", + "boCountryDisplayName", + "baCountryDisplayName", + "bwCountryDisplayName", + "brCountryDisplayName", + "ioCountryDisplayName", + "vgCountryDisplayName", + "bnCountryDisplayName", + "bgCountryDisplayName", + "bfCountryDisplayName", + "biCountryDisplayName", + "khCountryDisplayName", + "cmCountryDisplayName", + "caCountryDisplayName", + "cvCountryDisplayName", + "bqCountryDisplayName", + "kyCountryDisplayName", + "cfCountryDisplayName", + "tdCountryDisplayName", + "clCountryDisplayName", + "cnCountryDisplayName", + "cxCountryDisplayName", + "ccCountryDisplayName", + "coCountryDisplayName", + "kmCountryDisplayName", + "cdCountryDisplayName", + "cgCountryDisplayName", + "ckCountryDisplayName", + "crCountryDisplayName", + "ciCountryDisplayName", + "hrCountryDisplayName", + "cuCountryDisplayName", + "cwCountryDisplayName", + "cyCountryDisplayName", + "czCountryDisplayName", + "dkCountryDisplayName", + "djCountryDisplayName", + "dmCountryDisplayName", + "doCountryDisplayName", + "tlCountryDisplayName", + "ecCountryDisplayName", + "egCountryDisplayName", + "svCountryDisplayName", + "gqCountryDisplayName", + "erCountryDisplayName", + "eeCountryDisplayName", + "szCountryDisplayName", + "etCountryDisplayName", + "fkCountryDisplayName", + "foCountryDisplayName", + "fjCountryDisplayName", + "fiCountryDisplayName", + "frCountryDisplayName", + "gfCountryDisplayName", + "pfCountryDisplayName", + "gaCountryDisplayName", + "gmCountryDisplayName", + "geCountryDisplayName", + "deCountryDisplayName", + "ghCountryDisplayName", + "giCountryDisplayName", + "grCountryDisplayName", + "glCountryDisplayName", + "gdCountryDisplayName", + "gpCountryDisplayName", + "guCountryDisplayName", + "gtCountryDisplayName", + "ggCountryDisplayName", + "gnCountryDisplayName", + "gwCountryDisplayName", + "gyCountryDisplayName", + "htCountryDisplayName", + "hmCountryDisplayName", + "hnCountryDisplayName", + "hkCountryDisplayName", + "huCountryDisplayName", + "isCountryDisplayName", + "inCountryDisplayName", + "idCountryDisplayName", + "irCountryDisplayName", + "iqCountryDisplayName", + "ieCountryDisplayName", + "imCountryDisplayName", + "ilCountryDisplayName", + "itCountryDisplayName", + "jmCountryDisplayName", + "jpCountryDisplayName", + "jeCountryDisplayName", + "joCountryDisplayName", + "kzCountryDisplayName", + "keCountryDisplayName", + "kiCountryDisplayName", + "xkCountryDisplayName", + "kwCountryDisplayName", + "kgCountryDisplayName", + "laCountryDisplayName", + "lvCountryDisplayName", + "lbCountryDisplayName", + "lsCountryDisplayName", + "lrCountryDisplayName", + "lyCountryDisplayName", + "liCountryDisplayName", + "ltCountryDisplayName", + "luCountryDisplayName", + "moCountryDisplayName", + "mkCountryDisplayName", + "mgCountryDisplayName", + "mwCountryDisplayName", + "myCountryDisplayName", + "mvCountryDisplayName", + "mlCountryDisplayName", + "mtCountryDisplayName", + "mhCountryDisplayName", + "mqCountryDisplayName", + "mrCountryDisplayName", + "muCountryDisplayName", + "ytCountryDisplayName", + "mxCountryDisplayName", + "fmCountryDisplayName", + "mdCountryDisplayName", + "mcCountryDisplayName", + "mnCountryDisplayName", + "meCountryDisplayName", + "msCountryDisplayName", + "maCountryDisplayName", + "mzCountryDisplayName", + "mmCountryDisplayName", + "naCountryDisplayName", + "nrCountryDisplayName", + "npCountryDisplayName", + "nlCountryDisplayName", + "ncCountryDisplayName", + "nzCountryDisplayName", + "niCountryDisplayName", + "neCountryDisplayName", + "ngCountryDisplayName", + "nuCountryDisplayName", + "nfCountryDisplayName", + "kpCountryDisplayName", + "mpCountryDisplayName", + "noCountryDisplayName", + "omCountryDisplayName", + "pkCountryDisplayName", + "pwCountryDisplayName", + "psCountryDisplayName", + "paCountryDisplayName", + "pgCountryDisplayName", + "pyCountryDisplayName", + "peCountryDisplayName", + "phCountryDisplayName", + "plCountryDisplayName", + "ptCountryDisplayName", + "prCountryDisplayName", + "qaCountryDisplayName", + "reCountryDisplayName", + "roCountryDisplayName", + "ruCountryDisplayName", + "rwCountryDisplayName", + "blCountryDisplayName", + "shCountryDisplayName", + "knCountryDisplayName", + "lcCountryDisplayName", + "mfCountryDisplayName", + "pmCountryDisplayName", + "vcCountryDisplayName", + "wsCountryDisplayName", + "smCountryDisplayName", + "stCountryDisplayName", + "saCountryDisplayName", + "snCountryDisplayName", + "rsCountryDisplayName", + "scCountryDisplayName", + "slCountryDisplayName", + "sgCountryDisplayName", + "sxCountryDisplayName", + "skCountryDisplayName", + "siCountryDisplayName", + "sbCountryDisplayName", + "soCountryDisplayName", + "zaCountryDisplayName", + "gsCountryDisplayName", + "krCountryDisplayName", + "ssCountryDisplayName", + "esCountryDisplayName", + "lkCountryDisplayName", + "sdCountryDisplayName", + "srCountryDisplayName", + "sjCountryDisplayName", + "seCountryDisplayName", + "chCountryDisplayName", + "syCountryDisplayName", + "twCountryDisplayName", + "tjCountryDisplayName", + "tzCountryDisplayName", + "thCountryDisplayName", + "tgCountryDisplayName", + "tkCountryDisplayName", + "toCountryDisplayName", + "ttCountryDisplayName", + "tnCountryDisplayName", + "trCountryDisplayName", + "tmCountryDisplayName", + "tcCountryDisplayName", + "tvCountryDisplayName", + "viCountryDisplayName", + "ugCountryDisplayName", + "uaCountryDisplayName", + "aeCountryDisplayName", + "gbCountryDisplayName", + "usCountryDisplayName", + "uyCountryDisplayName", + "uzCountryDisplayName", + "vuCountryDisplayName", + "vaCountryDisplayName", + "veCountryDisplayName", + "vnCountryDisplayName", + "wfCountryDisplayName", + "ehCountryDisplayName", + "yeCountryDisplayName", + "zmCountryDisplayName", + "zwCountryDisplayName", + "pay", + "allPrivateChats", + "unknownPrivateChat", + "copyClassCodeDesc", + "addToClassDesc", + "addToClassOrExchange", + "addToClassOrExchangeDesc", + "invitedToClassOrExchange", + "decline", + "declinedInvitation", + "acceptedInvitation", + "youreInvited", + "studentPermissionsDesc", + "noEligibleSpaces", + "youAddedToSpace", + "youRemovedFromSpace", + "invitedToChat", + "monthlySubscription", + "yearlySubscription", + "defaultSubscription", + "freeTrial", + "grammarAnalytics", + "total", + "noDataFound", + "promoSubscriptionExpirationDesc", + "emptyChatNameWarning", + "emptyClassNameWarning", + "emptyExchangeNameWarning", + "blurMeansTranslateTitle", + "blurMeansTranslateBody", + "someErrorTitle", + "someErrorBody", + "bestCorrectionFeedback", + "distractorFeedback", + "bestAnswerFeedback", + "definitionDefaultPrompt", + "practiceDefaultPrompt", + "correctionDefaultPrompt", + "itStartDefaultPrompt", + "languageLevelWarning", + "lockedChatWarning", + "lockSpace", + "lockChat", + "archiveSpace", + "suggestTo", + "suggestChatDesc", + "suggestExchangeDesc", + "acceptSelection", + "acceptSelectionAnyway", + "makingActivity", + "why", + "definition", + "exampleSentence", + "addToClassTitle", + "reportToTeacher", + "reportMessageTitle", + "reportMessageBody", + "noTeachersFound", + "noAddToSpacePermissions", + "alreadyInSpace", + "yourGlobalUserIdIs", + "noUsersFoundWithQuery", + "searchChatsRooms", + "groupName", + "createGroupAndInviteUsers", + "groupCanBeFoundViaSearch", + "inNoSpaces" + ], + + "lv": [ + "accountInformation", + "addGroupDescription", + "addNewFriend", + "alreadyHaveAnAccount", + "classes", + "createNewGroup", + "editChatPermissions", + "groupDescription", + "groupDescriptionHasBeenChanged", + "allCorrect", + "newWayAllGood", + "othersAreBetter", + "holdForInfo", + "greenFeedback", + "yellowFeedback", + "redFeedback", + "customInputFeedbackChoice", + "itInstructionsTitle", + "itInstructionsBody", + "toggleLanguages", + "classWelcomeChat", + "deleteSpace", + "deleteGroup", + "areYouSureDeleteClass", + "areYouSureDeleteGroup", + "cannotBeReversed", + "enterDeletedClassName", + "incorrectClassName", + "oneday", + "oneweek", + "onemonth", + "sixmonth", + "oneyear", + "gaTooltip", + "taTooltip", + "unTooltip", + "interactiveTranslatorSliderHeader", + "interactiveGrammarSliderHeader", + "interactiveTranslatorNotAllowed", + "interactiveTranslatorAllowed", + "interactiveTranslatorRequired", + "interactiveTranslatorNotAllowedDesc", + "interactiveTranslatorAllowedDesc", + "interactiveTranslatorRequiredDesc", + "notYetSet", + "multiLingualClass", + "classAnalytics", + "allClasses", + "myLearning", + "allChatsAndClasses", + "timeOfLastMessage", + "totalMessages", + "waTooltip", + "changeDateRange", + "numberOfStudents", + "classDescription", + "classDescriptionDesc", + "requestToEnroll", + "requestAnExchange", + "findLanguageExchange", + "classAnalyticsDesc", + "addStudents", + "copyClassLink", + "copyClassLinkDesc", + "copyClassCode", + "inviteStudentByUserName", + "classSettings", + "classSettingsDesc", + "selectClassRoomDominantLanguage", + "selectTargetLanguage", + "whatIsYourClassLanguageLevel", + "studentPermissions", + "interactiveTranslator", + "oneToOneChatsWithinClass", + "oneToOneChatsWithinClassDesc", + "createGroupChats", + "createGroupChatsDesc", + "shareVideo", + "shareVideoDesc", + "sharePhotos", + "sharePhotosDesc", + "shareFiles", + "shareFilesDesc", + "shareLocationDesc", + "selectLanguageLevel", + "noIdenticalLanguages", + "iWantALanguagePartnerFrom", + "worldWide", + "noResults", + "searchBy", + "iWantAConversationPartner", + "iWantALanguagePartnerWhoSpeaks", + "iWantALanguagePartnerWhoIsLearning", + "yourBirthdayPlease", + "invalidDob", + "enterYourDob", + "getStarted", + "mustBe13", + "yourBirthdayPleaseShort", + "errorPleaseRefresh", + "joinWithClassCode", + "joinWithClassCodeDesc", + "joinWithClassCodeHint", + "unableToFindClass", + "languageLevelPreA1", + "languageLevelA1", + "languageLevelA2", + "languageLevelB1", + "languageLevelB2", + "languageLevelC1", + "languageLevelC2", + "changeTheNameOfTheClass", + "changeTheNameOfTheChat", + "welcomeToYourNewClass", + "welcomeToClass", + "welcomeToPangea18Plus", + "welcomeToPangeaMinor", + "findALanguagePartner", + "setToPublicSettingsTitle", + "setToPublicSettingsDesc", + "accountSettings", + "unableToFindClassCode", + "askPangeaBot", + "sorryNoResults", + "ignoreInThisText", + "helpMeTranslate", + "needsItShortMessage", + "needsIGCShortMessage", + "needsItMessage", + "needsIgcMessage", + "tokenTranslationTitle", + "spanTranslationDesc", + "spanTranslationTitle", + "l1SpanAndGrammarTitle", + "l1SpanAndGrammarDesc", + "otherTitle", + "otherDesc", + "countryInformation", + "myLanguages", + "targetLanguage", + "sourceLanguage", + "languagesISpeak", + "updateLanguage", + "whatLanguageYouWantToLearn", + "whatIsYourBaseLanguage", + "saveChanges", + "publicProfileTitle", + "publicProfileDesc", + "error502504Title", + "error502504Desc", + "error404Title", + "error404Desc", + "errorDisableIT", + "errorDisableIGC", + "errorDisableLanguageAssistance", + "errorDisableITUserDesc", + "errorDisableIGCUserDesc", + "errorDisableLanguageAssistanceUserDesc", + "errorDisableITClassDesc", + "errorDisableIGCClassDesc", + "errorDisableLanguageAssistanceClassDesc", + "itIsDisabled", + "igcIsDisabled", + "goToLearningSettings", + "error405Title", + "error405Desc", + "loginOrSignup", + "iAgreeToThe", + "termsAndConditions", + "andCertifyIAmAtLeast13YearsOfAge", + "findAClass", + "toggleIT", + "toggleIGC", + "toggleToolSettingsDescription", + "connectedToStaging", + "learningSettings", + "classNameRequired", + "sendVoiceNotes", + "sendVoiceNotesDesc", + "chatTopic", + "chatTopicDesc", + "inviteStudentByUserNameDesc", + "classRoster", + "almostPerfect", + "prettyGood", + "letMeThink", + "clickMessageTitle", + "clickMessageBody", + "understandingMessagesTitle", + "addToClass", + "understandingMessagesBody", + "allDone", + "vocab", + "low", + "medium", + "high", + "unknownProficiency", + "changeView", + "clearAll", + "generateVocabulary", + "generatePrompts", + "subscribe", + "getAccess", + "subscriptionDesc", + "subscriptionManagement", + "currentSubscription", + "changeSubscription", + "cancelSubscription", + "selectYourPlan", + "subsciptionPlatformTooltip", + "subscriptionManagementUnavailable", + "paymentMethod", + "paymentHistory", + "emptyChatDownloadWarning", + "appUpdateAvailable", + "update", + "updateDesc", + "maybeLater", + "mainMenu", + "toggleImmersionMode", + "toggleImmersionModeDesc", + "itToggleDescription", + "igcToggleDescription", + "sendOnEnterDescription", + "alreadyInClass", + "pleaseLoginFirst", + "originalMessage", + "sentMessage", + "useType", + "notAvailable", + "taAndGaTooltip", + "definitionsToolName", + "messageTranslationsToolName", + "definitionsToolDescription", + "translationsToolDescrption", + "welcomeBack", + "classExchanges", + "createNewClass", + "newExchange", + "kickAllStudents", + "kickAllStudentsConfirmation", + "inviteAllStudents", + "inviteAllStudentsConfirmation", + "inviteStudentsFromOtherClasses", + "inviteUsersFromPangea", + "allExchanges", + "redeemPromoCode", + "enterPromoCode", + "downloadTxtFile", + "downloadCSVFile", + "promotionalSubscriptionDesc", + "originalSubscriptionPlatform", + "oneWeekTrial", + "creatingSpacePleaseWait", + "downloadXLSXFile", + "abDisplayName", + "aaDisplayName", + "afDisplayName", + "akDisplayName", + "sqDisplayName", + "amDisplayName", + "arDisplayName", + "anDisplayName", + "hyDisplayName", + "asDisplayName", + "avDisplayName", + "aeDisplayName", + "ayDisplayName", + "azDisplayName", + "bmDisplayName", + "baDisplayName", + "euDisplayName", + "beDisplayName", + "bnDisplayName", + "bhDisplayName", + "biDisplayName", + "bsDisplayName", + "brDisplayName", + "bgDisplayName", + "myDisplayName", + "caDisplayName", + "chDisplayName", + "ceDisplayName", + "nyDisplayName", + "zhDisplayName", + "cvDisplayName", + "kwDisplayName", + "coDisplayName", + "crDisplayName", + "hrDisplayName", + "csDisplayName", + "daDisplayName", + "dvDisplayName", + "nlDisplayName", + "enDisplayName", + "eoDisplayName", + "etDisplayName", + "eeDisplayName", + "foDisplayName", + "fjDisplayName", + "fiDisplayName", + "frDisplayName", + "ffDisplayName", + "glDisplayName", + "kaDisplayName", + "deDisplayName", + "elDisplayName", + "gnDisplayName", + "guDisplayName", + "htDisplayName", + "haDisplayName", + "heDisplayName", + "hzDisplayName", + "hiDisplayName", + "hoDisplayName", + "huDisplayName", + "iaDisplayName", + "idDisplayName", + "ieDisplayName", + "gaDisplayName", + "igDisplayName", + "ikDisplayName", + "ioDisplayName", + "isDisplayName", + "itDisplayName", + "iuDisplayName", + "jaDisplayName", + "jvDisplayName", + "klDisplayName", + "knDisplayName", + "krDisplayName", + "ksDisplayName", + "kkDisplayName", + "kmDisplayName", + "kiDisplayName", + "rwDisplayName", + "kyDisplayName", + "kvDisplayName", + "kgDisplayName", + "koDisplayName", + "kuDisplayName", + "kjDisplayName", + "laDisplayName", + "lbDisplayName", + "lgDisplayName", + "liDisplayName", + "lnDisplayName", + "loDisplayName", + "ltDisplayName", + "luDisplayName", + "lvDisplayName", + "gvDisplayName", + "mkDisplayName", + "mgDisplayName", + "msDisplayName", + "mlDisplayName", + "mtDisplayName", + "miDisplayName", + "mrDisplayName", + "mhDisplayName", + "mnDisplayName", + "naDisplayName", + "nvDisplayName", + "nbDisplayName", + "ndDisplayName", + "neDisplayName", + "ngDisplayName", + "nnDisplayName", + "noDisplayName", + "iiDisplayName", + "nrDisplayName", + "ocDisplayName", + "ojDisplayName", + "cuDisplayName", + "omDisplayName", + "orDisplayName", + "osDisplayName", + "paDisplayName", + "piDisplayName", + "faDisplayName", + "plDisplayName", + "psDisplayName", + "ptDisplayName", + "quDisplayName", + "rmDisplayName", + "rnDisplayName", + "roDisplayName", + "ruDisplayName", + "saDisplayName", + "scDisplayName", + "sdDisplayName", + "seDisplayName", + "smDisplayName", + "sgDisplayName", + "srDisplayName", + "gdDisplayName", + "snDisplayName", + "siDisplayName", + "skDisplayName", + "slDisplayName", + "soDisplayName", + "stDisplayName", + "esDisplayName", + "suDisplayName", + "swDisplayName", + "ssDisplayName", + "svDisplayName", + "taDisplayName", + "teDisplayName", + "tgDisplayName", + "thDisplayName", + "tiDisplayName", + "boDisplayName", + "tkDisplayName", + "tlDisplayName", + "tnDisplayName", + "toDisplayName", + "trDisplayName", + "tsDisplayName", + "ttDisplayName", + "twDisplayName", + "tyDisplayName", + "ugDisplayName", + "ukDisplayName", + "urDisplayName", + "uzDisplayName", + "veDisplayName", + "viDisplayName", + "voDisplayName", + "waDisplayName", + "cyDisplayName", + "woDisplayName", + "fyDisplayName", + "xhDisplayName", + "yiDisplayName", + "yoDisplayName", + "zaDisplayName", + "unkDisplayName", + "zuDisplayName", + "hawDisplayName", + "hmnDisplayName", + "multiDisplayName", + "cebDisplayName", + "dzDisplayName", + "iwDisplayName", + "jwDisplayName", + "moDisplayName", + "shDisplayName", + "wwCountryDisplayName", + "afCountryDisplayName", + "axCountryDisplayName", + "alCountryDisplayName", + "dzCountryDisplayName", + "asCountryDisplayName", + "adCountryDisplayName", + "aoCountryDisplayName", + "aiCountryDisplayName", + "agCountryDisplayName", + "arCountryDisplayName", + "amCountryDisplayName", + "awCountryDisplayName", + "acCountryDisplayName", + "auCountryDisplayName", + "atCountryDisplayName", + "azCountryDisplayName", + "bsCountryDisplayName", + "bhCountryDisplayName", + "bdCountryDisplayName", + "bbCountryDisplayName", + "byCountryDisplayName", + "beCountryDisplayName", + "bzCountryDisplayName", + "bjCountryDisplayName", + "bmCountryDisplayName", + "btCountryDisplayName", + "boCountryDisplayName", + "baCountryDisplayName", + "bwCountryDisplayName", + "brCountryDisplayName", + "ioCountryDisplayName", + "vgCountryDisplayName", + "bnCountryDisplayName", + "bgCountryDisplayName", + "bfCountryDisplayName", + "biCountryDisplayName", + "khCountryDisplayName", + "cmCountryDisplayName", + "caCountryDisplayName", + "cvCountryDisplayName", + "bqCountryDisplayName", + "kyCountryDisplayName", + "cfCountryDisplayName", + "tdCountryDisplayName", + "clCountryDisplayName", + "cnCountryDisplayName", + "cxCountryDisplayName", + "ccCountryDisplayName", + "coCountryDisplayName", + "kmCountryDisplayName", + "cdCountryDisplayName", + "cgCountryDisplayName", + "ckCountryDisplayName", + "crCountryDisplayName", + "ciCountryDisplayName", + "hrCountryDisplayName", + "cuCountryDisplayName", + "cwCountryDisplayName", + "cyCountryDisplayName", + "czCountryDisplayName", + "dkCountryDisplayName", + "djCountryDisplayName", + "dmCountryDisplayName", + "doCountryDisplayName", + "tlCountryDisplayName", + "ecCountryDisplayName", + "egCountryDisplayName", + "svCountryDisplayName", + "gqCountryDisplayName", + "erCountryDisplayName", + "eeCountryDisplayName", + "szCountryDisplayName", + "etCountryDisplayName", + "fkCountryDisplayName", + "foCountryDisplayName", + "fjCountryDisplayName", + "fiCountryDisplayName", + "frCountryDisplayName", + "gfCountryDisplayName", + "pfCountryDisplayName", + "gaCountryDisplayName", + "gmCountryDisplayName", + "geCountryDisplayName", + "deCountryDisplayName", + "ghCountryDisplayName", + "giCountryDisplayName", + "grCountryDisplayName", + "glCountryDisplayName", + "gdCountryDisplayName", + "gpCountryDisplayName", + "guCountryDisplayName", + "gtCountryDisplayName", + "ggCountryDisplayName", + "gnCountryDisplayName", + "gwCountryDisplayName", + "gyCountryDisplayName", + "htCountryDisplayName", + "hmCountryDisplayName", + "hnCountryDisplayName", + "hkCountryDisplayName", + "huCountryDisplayName", + "isCountryDisplayName", + "inCountryDisplayName", + "idCountryDisplayName", + "irCountryDisplayName", + "iqCountryDisplayName", + "ieCountryDisplayName", + "imCountryDisplayName", + "ilCountryDisplayName", + "itCountryDisplayName", + "jmCountryDisplayName", + "jpCountryDisplayName", + "jeCountryDisplayName", + "joCountryDisplayName", + "kzCountryDisplayName", + "keCountryDisplayName", + "kiCountryDisplayName", + "xkCountryDisplayName", + "kwCountryDisplayName", + "kgCountryDisplayName", + "laCountryDisplayName", + "lvCountryDisplayName", + "lbCountryDisplayName", + "lsCountryDisplayName", + "lrCountryDisplayName", + "lyCountryDisplayName", + "liCountryDisplayName", + "ltCountryDisplayName", + "luCountryDisplayName", + "moCountryDisplayName", + "mkCountryDisplayName", + "mgCountryDisplayName", + "mwCountryDisplayName", + "myCountryDisplayName", + "mvCountryDisplayName", + "mlCountryDisplayName", + "mtCountryDisplayName", + "mhCountryDisplayName", + "mqCountryDisplayName", + "mrCountryDisplayName", + "muCountryDisplayName", + "ytCountryDisplayName", + "mxCountryDisplayName", + "fmCountryDisplayName", + "mdCountryDisplayName", + "mcCountryDisplayName", + "mnCountryDisplayName", + "meCountryDisplayName", + "msCountryDisplayName", + "maCountryDisplayName", + "mzCountryDisplayName", + "mmCountryDisplayName", + "naCountryDisplayName", + "nrCountryDisplayName", + "npCountryDisplayName", + "nlCountryDisplayName", + "ncCountryDisplayName", + "nzCountryDisplayName", + "niCountryDisplayName", + "neCountryDisplayName", + "ngCountryDisplayName", + "nuCountryDisplayName", + "nfCountryDisplayName", + "kpCountryDisplayName", + "mpCountryDisplayName", + "noCountryDisplayName", + "omCountryDisplayName", + "pkCountryDisplayName", + "pwCountryDisplayName", + "psCountryDisplayName", + "paCountryDisplayName", + "pgCountryDisplayName", + "pyCountryDisplayName", + "peCountryDisplayName", + "phCountryDisplayName", + "plCountryDisplayName", + "ptCountryDisplayName", + "prCountryDisplayName", + "qaCountryDisplayName", + "reCountryDisplayName", + "roCountryDisplayName", + "ruCountryDisplayName", + "rwCountryDisplayName", + "blCountryDisplayName", + "shCountryDisplayName", + "knCountryDisplayName", + "lcCountryDisplayName", + "mfCountryDisplayName", + "pmCountryDisplayName", + "vcCountryDisplayName", + "wsCountryDisplayName", + "smCountryDisplayName", + "stCountryDisplayName", + "saCountryDisplayName", + "snCountryDisplayName", + "rsCountryDisplayName", + "scCountryDisplayName", + "slCountryDisplayName", + "sgCountryDisplayName", + "sxCountryDisplayName", + "skCountryDisplayName", + "siCountryDisplayName", + "sbCountryDisplayName", + "soCountryDisplayName", + "zaCountryDisplayName", + "gsCountryDisplayName", + "krCountryDisplayName", + "ssCountryDisplayName", + "esCountryDisplayName", + "lkCountryDisplayName", + "sdCountryDisplayName", + "srCountryDisplayName", + "sjCountryDisplayName", + "seCountryDisplayName", + "chCountryDisplayName", + "syCountryDisplayName", + "twCountryDisplayName", + "tjCountryDisplayName", + "tzCountryDisplayName", + "thCountryDisplayName", + "tgCountryDisplayName", + "tkCountryDisplayName", + "toCountryDisplayName", + "ttCountryDisplayName", + "tnCountryDisplayName", + "trCountryDisplayName", + "tmCountryDisplayName", + "tcCountryDisplayName", + "tvCountryDisplayName", + "viCountryDisplayName", + "ugCountryDisplayName", + "uaCountryDisplayName", + "aeCountryDisplayName", + "gbCountryDisplayName", + "usCountryDisplayName", + "uyCountryDisplayName", + "uzCountryDisplayName", + "vuCountryDisplayName", + "vaCountryDisplayName", + "veCountryDisplayName", + "vnCountryDisplayName", + "wfCountryDisplayName", + "ehCountryDisplayName", + "yeCountryDisplayName", + "zmCountryDisplayName", + "zwCountryDisplayName", + "pay", + "allPrivateChats", + "unknownPrivateChat", + "copyClassCodeDesc", + "addToClassDesc", + "addToClassOrExchange", + "addToClassOrExchangeDesc", + "invitedToClassOrExchange", + "decline", + "declinedInvitation", + "acceptedInvitation", + "youreInvited", + "studentPermissionsDesc", + "noEligibleSpaces", + "youAddedToSpace", + "youRemovedFromSpace", + "invitedToChat", + "monthlySubscription", + "yearlySubscription", + "defaultSubscription", + "freeTrial", + "grammarAnalytics", + "total", + "noDataFound", + "promoSubscriptionExpirationDesc", + "emptyChatNameWarning", + "emptyClassNameWarning", + "emptyExchangeNameWarning", + "blurMeansTranslateTitle", + "blurMeansTranslateBody", + "someErrorTitle", + "someErrorBody", + "bestCorrectionFeedback", + "distractorFeedback", + "bestAnswerFeedback", + "definitionDefaultPrompt", + "practiceDefaultPrompt", + "correctionDefaultPrompt", + "itStartDefaultPrompt", + "languageLevelWarning", + "lockedChatWarning", + "lockSpace", + "lockChat", + "archiveSpace", + "suggestTo", + "suggestChatDesc", + "suggestExchangeDesc", + "acceptSelection", + "acceptSelectionAnyway", + "makingActivity", + "why", + "definition", + "exampleSentence", + "addToClassTitle", + "reportToTeacher", + "reportMessageTitle", + "reportMessageBody", + "noTeachersFound", + "noAddToSpacePermissions", + "alreadyInSpace", + "yourGlobalUserIdIs", + "noUsersFoundWithQuery", + "searchChatsRooms", + "groupName", + "createGroupAndInviteUsers", + "groupCanBeFoundViaSearch", + "inNoSpaces" + ], + + "nb": [ + "accountInformation", + "addNewFriend", + "alreadyHaveAnAccount", + "classes", + "allCorrect", + "newWayAllGood", + "othersAreBetter", + "holdForInfo", + "greenFeedback", + "yellowFeedback", + "redFeedback", + "customInputFeedbackChoice", + "itInstructionsTitle", + "itInstructionsBody", + "toggleLanguages", + "classWelcomeChat", + "deleteSpace", + "deleteGroup", + "areYouSureDeleteClass", + "areYouSureDeleteGroup", + "cannotBeReversed", + "enterDeletedClassName", + "incorrectClassName", + "oneday", + "oneweek", + "onemonth", + "sixmonth", + "oneyear", + "gaTooltip", + "taTooltip", + "unTooltip", + "interactiveTranslatorSliderHeader", + "interactiveGrammarSliderHeader", + "interactiveTranslatorNotAllowed", + "interactiveTranslatorAllowed", + "interactiveTranslatorRequired", + "interactiveTranslatorNotAllowedDesc", + "interactiveTranslatorAllowedDesc", + "interactiveTranslatorRequiredDesc", + "notYetSet", + "multiLingualClass", + "classAnalytics", + "allClasses", + "myLearning", + "allChatsAndClasses", + "timeOfLastMessage", + "totalMessages", + "waTooltip", + "changeDateRange", + "numberOfStudents", + "classDescription", + "classDescriptionDesc", + "requestToEnroll", + "requestAnExchange", + "findLanguageExchange", + "classAnalyticsDesc", + "addStudents", + "copyClassLink", + "copyClassLinkDesc", + "copyClassCode", + "inviteStudentByUserName", + "classSettings", + "classSettingsDesc", + "selectClassRoomDominantLanguage", + "selectTargetLanguage", + "whatIsYourClassLanguageLevel", + "studentPermissions", + "interactiveTranslator", + "oneToOneChatsWithinClass", + "oneToOneChatsWithinClassDesc", + "createGroupChats", + "createGroupChatsDesc", + "shareVideo", + "shareVideoDesc", + "sharePhotos", + "sharePhotosDesc", + "shareFiles", + "shareFilesDesc", + "shareLocationDesc", + "selectLanguageLevel", + "noIdenticalLanguages", + "iWantALanguagePartnerFrom", + "worldWide", + "noResults", + "searchBy", + "iWantAConversationPartner", + "iWantALanguagePartnerWhoSpeaks", + "iWantALanguagePartnerWhoIsLearning", + "yourBirthdayPlease", + "invalidDob", + "enterYourDob", + "getStarted", + "mustBe13", + "yourBirthdayPleaseShort", + "errorPleaseRefresh", + "joinWithClassCode", + "joinWithClassCodeDesc", + "joinWithClassCodeHint", + "unableToFindClass", + "languageLevelPreA1", + "languageLevelA1", + "languageLevelA2", + "languageLevelB1", + "languageLevelB2", + "languageLevelC1", + "languageLevelC2", + "changeTheNameOfTheClass", + "changeTheNameOfTheChat", + "welcomeToYourNewClass", + "welcomeToClass", + "welcomeToPangea18Plus", + "welcomeToPangeaMinor", + "findALanguagePartner", + "setToPublicSettingsTitle", + "setToPublicSettingsDesc", + "accountSettings", + "unableToFindClassCode", + "askPangeaBot", + "sorryNoResults", + "ignoreInThisText", + "helpMeTranslate", + "needsItShortMessage", + "needsIGCShortMessage", + "needsItMessage", + "needsIgcMessage", + "tokenTranslationTitle", + "spanTranslationDesc", + "spanTranslationTitle", + "l1SpanAndGrammarTitle", + "l1SpanAndGrammarDesc", + "otherTitle", + "otherDesc", + "countryInformation", + "myLanguages", + "targetLanguage", + "sourceLanguage", + "languagesISpeak", + "updateLanguage", + "whatLanguageYouWantToLearn", + "whatIsYourBaseLanguage", + "saveChanges", + "publicProfileTitle", + "publicProfileDesc", + "error502504Title", + "error502504Desc", + "error404Title", + "error404Desc", + "errorDisableIT", + "errorDisableIGC", + "errorDisableLanguageAssistance", + "errorDisableITUserDesc", + "errorDisableIGCUserDesc", + "errorDisableLanguageAssistanceUserDesc", + "errorDisableITClassDesc", + "errorDisableIGCClassDesc", + "errorDisableLanguageAssistanceClassDesc", + "itIsDisabled", + "igcIsDisabled", + "goToLearningSettings", + "error405Title", + "error405Desc", + "loginOrSignup", + "iAgreeToThe", + "termsAndConditions", + "andCertifyIAmAtLeast13YearsOfAge", + "findAClass", + "toggleIT", + "toggleIGC", + "toggleToolSettingsDescription", + "connectedToStaging", + "learningSettings", + "classNameRequired", + "sendVoiceNotes", + "sendVoiceNotesDesc", + "chatTopic", + "chatTopicDesc", + "inviteStudentByUserNameDesc", + "classRoster", + "almostPerfect", + "prettyGood", + "letMeThink", + "clickMessageTitle", + "clickMessageBody", + "understandingMessagesTitle", + "addToClass", + "understandingMessagesBody", + "allDone", + "vocab", + "low", + "medium", + "high", + "unknownProficiency", + "changeView", + "clearAll", + "generateVocabulary", + "generatePrompts", + "subscribe", + "getAccess", + "subscriptionDesc", + "subscriptionManagement", + "currentSubscription", + "changeSubscription", + "cancelSubscription", + "selectYourPlan", + "subsciptionPlatformTooltip", + "subscriptionManagementUnavailable", + "paymentMethod", + "paymentHistory", + "emptyChatDownloadWarning", + "appUpdateAvailable", + "update", + "updateDesc", + "maybeLater", + "mainMenu", + "toggleImmersionMode", + "toggleImmersionModeDesc", + "itToggleDescription", + "igcToggleDescription", + "sendOnEnterDescription", + "alreadyInClass", + "pleaseLoginFirst", + "originalMessage", + "sentMessage", + "useType", + "notAvailable", + "taAndGaTooltip", + "definitionsToolName", + "messageTranslationsToolName", + "definitionsToolDescription", + "translationsToolDescrption", + "welcomeBack", + "classExchanges", + "createNewClass", + "newExchange", + "kickAllStudents", + "kickAllStudentsConfirmation", + "inviteAllStudents", + "inviteAllStudentsConfirmation", + "inviteStudentsFromOtherClasses", + "inviteUsersFromPangea", + "allExchanges", + "redeemPromoCode", + "enterPromoCode", + "downloadTxtFile", + "downloadCSVFile", + "promotionalSubscriptionDesc", + "originalSubscriptionPlatform", + "oneWeekTrial", + "creatingSpacePleaseWait", + "downloadXLSXFile", + "abDisplayName", + "aaDisplayName", + "afDisplayName", + "akDisplayName", + "sqDisplayName", + "amDisplayName", + "arDisplayName", + "anDisplayName", + "hyDisplayName", + "asDisplayName", + "avDisplayName", + "aeDisplayName", + "ayDisplayName", + "azDisplayName", + "bmDisplayName", + "baDisplayName", + "euDisplayName", + "beDisplayName", + "bnDisplayName", + "bhDisplayName", + "biDisplayName", + "bsDisplayName", + "brDisplayName", + "bgDisplayName", + "myDisplayName", + "caDisplayName", + "chDisplayName", + "ceDisplayName", + "nyDisplayName", + "zhDisplayName", + "cvDisplayName", + "kwDisplayName", + "coDisplayName", + "crDisplayName", + "hrDisplayName", + "csDisplayName", + "daDisplayName", + "dvDisplayName", + "nlDisplayName", + "enDisplayName", + "eoDisplayName", + "etDisplayName", + "eeDisplayName", + "foDisplayName", + "fjDisplayName", + "fiDisplayName", + "frDisplayName", + "ffDisplayName", + "glDisplayName", + "kaDisplayName", + "deDisplayName", + "elDisplayName", + "gnDisplayName", + "guDisplayName", + "htDisplayName", + "haDisplayName", + "heDisplayName", + "hzDisplayName", + "hiDisplayName", + "hoDisplayName", + "huDisplayName", + "iaDisplayName", + "idDisplayName", + "ieDisplayName", + "gaDisplayName", + "igDisplayName", + "ikDisplayName", + "ioDisplayName", + "isDisplayName", + "itDisplayName", + "iuDisplayName", + "jaDisplayName", + "jvDisplayName", + "klDisplayName", + "knDisplayName", + "krDisplayName", + "ksDisplayName", + "kkDisplayName", + "kmDisplayName", + "kiDisplayName", + "rwDisplayName", + "kyDisplayName", + "kvDisplayName", + "kgDisplayName", + "koDisplayName", + "kuDisplayName", + "kjDisplayName", + "laDisplayName", + "lbDisplayName", + "lgDisplayName", + "liDisplayName", + "lnDisplayName", + "loDisplayName", + "ltDisplayName", + "luDisplayName", + "lvDisplayName", + "gvDisplayName", + "mkDisplayName", + "mgDisplayName", + "msDisplayName", + "mlDisplayName", + "mtDisplayName", + "miDisplayName", + "mrDisplayName", + "mhDisplayName", + "mnDisplayName", + "naDisplayName", + "nvDisplayName", + "nbDisplayName", + "ndDisplayName", + "neDisplayName", + "ngDisplayName", + "nnDisplayName", + "noDisplayName", + "iiDisplayName", + "nrDisplayName", + "ocDisplayName", + "ojDisplayName", + "cuDisplayName", + "omDisplayName", + "orDisplayName", + "osDisplayName", + "paDisplayName", + "piDisplayName", + "faDisplayName", + "plDisplayName", + "psDisplayName", + "ptDisplayName", + "quDisplayName", + "rmDisplayName", + "rnDisplayName", + "roDisplayName", + "ruDisplayName", + "saDisplayName", + "scDisplayName", + "sdDisplayName", + "seDisplayName", + "smDisplayName", + "sgDisplayName", + "srDisplayName", + "gdDisplayName", + "snDisplayName", + "siDisplayName", + "skDisplayName", + "slDisplayName", + "soDisplayName", + "stDisplayName", + "esDisplayName", + "suDisplayName", + "swDisplayName", + "ssDisplayName", + "svDisplayName", + "taDisplayName", + "teDisplayName", + "tgDisplayName", + "thDisplayName", + "tiDisplayName", + "boDisplayName", + "tkDisplayName", + "tlDisplayName", + "tnDisplayName", + "toDisplayName", + "trDisplayName", + "tsDisplayName", + "ttDisplayName", + "twDisplayName", + "tyDisplayName", + "ugDisplayName", + "ukDisplayName", + "urDisplayName", + "uzDisplayName", + "veDisplayName", + "viDisplayName", + "voDisplayName", + "waDisplayName", + "cyDisplayName", + "woDisplayName", + "fyDisplayName", + "xhDisplayName", + "yiDisplayName", + "yoDisplayName", + "zaDisplayName", + "unkDisplayName", + "zuDisplayName", + "hawDisplayName", + "hmnDisplayName", + "multiDisplayName", + "cebDisplayName", + "dzDisplayName", + "iwDisplayName", + "jwDisplayName", + "moDisplayName", + "shDisplayName", + "wwCountryDisplayName", + "afCountryDisplayName", + "axCountryDisplayName", + "alCountryDisplayName", + "dzCountryDisplayName", + "asCountryDisplayName", + "adCountryDisplayName", + "aoCountryDisplayName", + "aiCountryDisplayName", + "agCountryDisplayName", + "arCountryDisplayName", + "amCountryDisplayName", + "awCountryDisplayName", + "acCountryDisplayName", + "auCountryDisplayName", + "atCountryDisplayName", + "azCountryDisplayName", + "bsCountryDisplayName", + "bhCountryDisplayName", + "bdCountryDisplayName", + "bbCountryDisplayName", + "byCountryDisplayName", + "beCountryDisplayName", + "bzCountryDisplayName", + "bjCountryDisplayName", + "bmCountryDisplayName", + "btCountryDisplayName", + "boCountryDisplayName", + "baCountryDisplayName", + "bwCountryDisplayName", + "brCountryDisplayName", + "ioCountryDisplayName", + "vgCountryDisplayName", + "bnCountryDisplayName", + "bgCountryDisplayName", + "bfCountryDisplayName", + "biCountryDisplayName", + "khCountryDisplayName", + "cmCountryDisplayName", + "caCountryDisplayName", + "cvCountryDisplayName", + "bqCountryDisplayName", + "kyCountryDisplayName", + "cfCountryDisplayName", + "tdCountryDisplayName", + "clCountryDisplayName", + "cnCountryDisplayName", + "cxCountryDisplayName", + "ccCountryDisplayName", + "coCountryDisplayName", + "kmCountryDisplayName", + "cdCountryDisplayName", + "cgCountryDisplayName", + "ckCountryDisplayName", + "crCountryDisplayName", + "ciCountryDisplayName", + "hrCountryDisplayName", + "cuCountryDisplayName", + "cwCountryDisplayName", + "cyCountryDisplayName", + "czCountryDisplayName", + "dkCountryDisplayName", + "djCountryDisplayName", + "dmCountryDisplayName", + "doCountryDisplayName", + "tlCountryDisplayName", + "ecCountryDisplayName", + "egCountryDisplayName", + "svCountryDisplayName", + "gqCountryDisplayName", + "erCountryDisplayName", + "eeCountryDisplayName", + "szCountryDisplayName", + "etCountryDisplayName", + "fkCountryDisplayName", + "foCountryDisplayName", + "fjCountryDisplayName", + "fiCountryDisplayName", + "frCountryDisplayName", + "gfCountryDisplayName", + "pfCountryDisplayName", + "gaCountryDisplayName", + "gmCountryDisplayName", + "geCountryDisplayName", + "deCountryDisplayName", + "ghCountryDisplayName", + "giCountryDisplayName", + "grCountryDisplayName", + "glCountryDisplayName", + "gdCountryDisplayName", + "gpCountryDisplayName", + "guCountryDisplayName", + "gtCountryDisplayName", + "ggCountryDisplayName", + "gnCountryDisplayName", + "gwCountryDisplayName", + "gyCountryDisplayName", + "htCountryDisplayName", + "hmCountryDisplayName", + "hnCountryDisplayName", + "hkCountryDisplayName", + "huCountryDisplayName", + "isCountryDisplayName", + "inCountryDisplayName", + "idCountryDisplayName", + "irCountryDisplayName", + "iqCountryDisplayName", + "ieCountryDisplayName", + "imCountryDisplayName", + "ilCountryDisplayName", + "itCountryDisplayName", + "jmCountryDisplayName", + "jpCountryDisplayName", + "jeCountryDisplayName", + "joCountryDisplayName", + "kzCountryDisplayName", + "keCountryDisplayName", + "kiCountryDisplayName", + "xkCountryDisplayName", + "kwCountryDisplayName", + "kgCountryDisplayName", + "laCountryDisplayName", + "lvCountryDisplayName", + "lbCountryDisplayName", + "lsCountryDisplayName", + "lrCountryDisplayName", + "lyCountryDisplayName", + "liCountryDisplayName", + "ltCountryDisplayName", + "luCountryDisplayName", + "moCountryDisplayName", + "mkCountryDisplayName", + "mgCountryDisplayName", + "mwCountryDisplayName", + "myCountryDisplayName", + "mvCountryDisplayName", + "mlCountryDisplayName", + "mtCountryDisplayName", + "mhCountryDisplayName", + "mqCountryDisplayName", + "mrCountryDisplayName", + "muCountryDisplayName", + "ytCountryDisplayName", + "mxCountryDisplayName", + "fmCountryDisplayName", + "mdCountryDisplayName", + "mcCountryDisplayName", + "mnCountryDisplayName", + "meCountryDisplayName", + "msCountryDisplayName", + "maCountryDisplayName", + "mzCountryDisplayName", + "mmCountryDisplayName", + "naCountryDisplayName", + "nrCountryDisplayName", + "npCountryDisplayName", + "nlCountryDisplayName", + "ncCountryDisplayName", + "nzCountryDisplayName", + "niCountryDisplayName", + "neCountryDisplayName", + "ngCountryDisplayName", + "nuCountryDisplayName", + "nfCountryDisplayName", + "kpCountryDisplayName", + "mpCountryDisplayName", + "noCountryDisplayName", + "omCountryDisplayName", + "pkCountryDisplayName", + "pwCountryDisplayName", + "psCountryDisplayName", + "paCountryDisplayName", + "pgCountryDisplayName", + "pyCountryDisplayName", + "peCountryDisplayName", + "phCountryDisplayName", + "plCountryDisplayName", + "ptCountryDisplayName", + "prCountryDisplayName", + "qaCountryDisplayName", + "reCountryDisplayName", + "roCountryDisplayName", + "ruCountryDisplayName", + "rwCountryDisplayName", + "blCountryDisplayName", + "shCountryDisplayName", + "knCountryDisplayName", + "lcCountryDisplayName", + "mfCountryDisplayName", + "pmCountryDisplayName", + "vcCountryDisplayName", + "wsCountryDisplayName", + "smCountryDisplayName", + "stCountryDisplayName", + "saCountryDisplayName", + "snCountryDisplayName", + "rsCountryDisplayName", + "scCountryDisplayName", + "slCountryDisplayName", + "sgCountryDisplayName", + "sxCountryDisplayName", + "skCountryDisplayName", + "siCountryDisplayName", + "sbCountryDisplayName", + "soCountryDisplayName", + "zaCountryDisplayName", + "gsCountryDisplayName", + "krCountryDisplayName", + "ssCountryDisplayName", + "esCountryDisplayName", + "lkCountryDisplayName", + "sdCountryDisplayName", + "srCountryDisplayName", + "sjCountryDisplayName", + "seCountryDisplayName", + "chCountryDisplayName", + "syCountryDisplayName", + "twCountryDisplayName", + "tjCountryDisplayName", + "tzCountryDisplayName", + "thCountryDisplayName", + "tgCountryDisplayName", + "tkCountryDisplayName", + "toCountryDisplayName", + "ttCountryDisplayName", + "tnCountryDisplayName", + "trCountryDisplayName", + "tmCountryDisplayName", + "tcCountryDisplayName", + "tvCountryDisplayName", + "viCountryDisplayName", + "ugCountryDisplayName", + "uaCountryDisplayName", + "aeCountryDisplayName", + "gbCountryDisplayName", + "usCountryDisplayName", + "uyCountryDisplayName", + "uzCountryDisplayName", + "vuCountryDisplayName", + "vaCountryDisplayName", + "veCountryDisplayName", + "vnCountryDisplayName", + "wfCountryDisplayName", + "ehCountryDisplayName", + "yeCountryDisplayName", + "zmCountryDisplayName", + "zwCountryDisplayName", + "pay", + "allPrivateChats", + "unknownPrivateChat", + "copyClassCodeDesc", + "addToClassDesc", + "addToClassOrExchange", + "addToClassOrExchangeDesc", + "invitedToClassOrExchange", + "decline", + "declinedInvitation", + "acceptedInvitation", + "youreInvited", + "studentPermissionsDesc", + "noEligibleSpaces", + "youAddedToSpace", + "youRemovedFromSpace", + "invitedToChat", + "monthlySubscription", + "yearlySubscription", + "defaultSubscription", + "freeTrial", + "grammarAnalytics", + "total", + "noDataFound", + "promoSubscriptionExpirationDesc", + "emptyChatNameWarning", + "emptyClassNameWarning", + "emptyExchangeNameWarning", + "blurMeansTranslateTitle", + "blurMeansTranslateBody", + "someErrorTitle", + "someErrorBody", + "bestCorrectionFeedback", + "distractorFeedback", + "bestAnswerFeedback", + "definitionDefaultPrompt", + "practiceDefaultPrompt", + "correctionDefaultPrompt", + "itStartDefaultPrompt", + "languageLevelWarning", + "lockedChatWarning", + "lockSpace", + "lockChat", + "archiveSpace", + "suggestTo", + "suggestChatDesc", + "suggestExchangeDesc", + "acceptSelection", + "acceptSelectionAnyway", + "makingActivity", + "why", + "definition", + "exampleSentence", + "addToClassTitle", + "reportToTeacher", + "reportMessageTitle", + "reportMessageBody", + "noTeachersFound", + "noAddToSpacePermissions", + "alreadyInSpace", + "yourGlobalUserIdIs", + "noUsersFoundWithQuery", + "searchChatsRooms", + "groupName", + "createGroupAndInviteUsers", + "groupCanBeFoundViaSearch", + "inNoSpaces" + ], + + "nl": [ + "accountInformation", + "addNewFriend", + "alreadyHaveAnAccount", + "classes", + "allCorrect", + "newWayAllGood", + "othersAreBetter", + "holdForInfo", + "greenFeedback", + "yellowFeedback", + "redFeedback", + "customInputFeedbackChoice", + "itInstructionsTitle", + "itInstructionsBody", + "toggleLanguages", + "classWelcomeChat", + "deleteSpace", + "deleteGroup", + "areYouSureDeleteClass", + "areYouSureDeleteGroup", + "cannotBeReversed", + "enterDeletedClassName", + "incorrectClassName", + "oneday", + "oneweek", + "onemonth", + "sixmonth", + "oneyear", + "gaTooltip", + "taTooltip", + "unTooltip", + "interactiveTranslatorSliderHeader", + "interactiveGrammarSliderHeader", + "interactiveTranslatorNotAllowed", + "interactiveTranslatorAllowed", + "interactiveTranslatorRequired", + "interactiveTranslatorNotAllowedDesc", + "interactiveTranslatorAllowedDesc", + "interactiveTranslatorRequiredDesc", + "notYetSet", + "multiLingualClass", + "classAnalytics", + "allClasses", + "myLearning", + "allChatsAndClasses", + "timeOfLastMessage", + "totalMessages", + "waTooltip", + "changeDateRange", + "numberOfStudents", + "classDescription", + "classDescriptionDesc", + "requestToEnroll", + "requestAnExchange", + "findLanguageExchange", + "classAnalyticsDesc", + "addStudents", + "copyClassLink", + "copyClassLinkDesc", + "copyClassCode", + "inviteStudentByUserName", + "classSettings", + "classSettingsDesc", + "selectClassRoomDominantLanguage", + "selectTargetLanguage", + "whatIsYourClassLanguageLevel", + "studentPermissions", + "interactiveTranslator", + "oneToOneChatsWithinClass", + "oneToOneChatsWithinClassDesc", + "createGroupChats", + "createGroupChatsDesc", + "shareVideo", + "shareVideoDesc", + "sharePhotos", + "sharePhotosDesc", + "shareFiles", + "shareFilesDesc", + "shareLocationDesc", + "selectLanguageLevel", + "noIdenticalLanguages", + "iWantALanguagePartnerFrom", + "worldWide", + "noResults", + "searchBy", + "iWantAConversationPartner", + "iWantALanguagePartnerWhoSpeaks", + "iWantALanguagePartnerWhoIsLearning", + "yourBirthdayPlease", + "invalidDob", + "enterYourDob", + "getStarted", + "mustBe13", + "yourBirthdayPleaseShort", + "errorPleaseRefresh", + "joinWithClassCode", + "joinWithClassCodeDesc", + "joinWithClassCodeHint", + "unableToFindClass", + "languageLevelPreA1", + "languageLevelA1", + "languageLevelA2", + "languageLevelB1", + "languageLevelB2", + "languageLevelC1", + "languageLevelC2", + "changeTheNameOfTheClass", + "changeTheNameOfTheChat", + "welcomeToYourNewClass", + "welcomeToClass", + "welcomeToPangea18Plus", + "welcomeToPangeaMinor", + "findALanguagePartner", + "setToPublicSettingsTitle", + "setToPublicSettingsDesc", + "accountSettings", + "unableToFindClassCode", + "askPangeaBot", + "sorryNoResults", + "ignoreInThisText", + "helpMeTranslate", + "needsItShortMessage", + "needsIGCShortMessage", + "needsItMessage", + "needsIgcMessage", + "tokenTranslationTitle", + "spanTranslationDesc", + "spanTranslationTitle", + "l1SpanAndGrammarTitle", + "l1SpanAndGrammarDesc", + "otherTitle", + "otherDesc", + "countryInformation", + "myLanguages", + "targetLanguage", + "sourceLanguage", + "languagesISpeak", + "updateLanguage", + "whatLanguageYouWantToLearn", + "whatIsYourBaseLanguage", + "saveChanges", + "publicProfileTitle", + "publicProfileDesc", + "error502504Title", + "error502504Desc", + "error404Title", + "error404Desc", + "errorDisableIT", + "errorDisableIGC", + "errorDisableLanguageAssistance", + "errorDisableITUserDesc", + "errorDisableIGCUserDesc", + "errorDisableLanguageAssistanceUserDesc", + "errorDisableITClassDesc", + "errorDisableIGCClassDesc", + "errorDisableLanguageAssistanceClassDesc", + "itIsDisabled", + "igcIsDisabled", + "goToLearningSettings", + "error405Title", + "error405Desc", + "loginOrSignup", + "iAgreeToThe", + "termsAndConditions", + "andCertifyIAmAtLeast13YearsOfAge", + "findAClass", + "toggleIT", + "toggleIGC", + "toggleToolSettingsDescription", + "connectedToStaging", + "learningSettings", + "classNameRequired", + "sendVoiceNotes", + "sendVoiceNotesDesc", + "chatTopic", + "chatTopicDesc", + "inviteStudentByUserNameDesc", + "classRoster", + "almostPerfect", + "prettyGood", + "letMeThink", + "clickMessageTitle", + "clickMessageBody", + "understandingMessagesTitle", + "addToClass", + "understandingMessagesBody", + "allDone", + "vocab", + "low", + "medium", + "high", + "unknownProficiency", + "changeView", + "clearAll", + "generateVocabulary", + "generatePrompts", + "subscribe", + "getAccess", + "subscriptionDesc", + "subscriptionManagement", + "currentSubscription", + "changeSubscription", + "cancelSubscription", + "selectYourPlan", + "subsciptionPlatformTooltip", + "subscriptionManagementUnavailable", + "paymentMethod", + "paymentHistory", + "emptyChatDownloadWarning", + "appUpdateAvailable", + "update", + "updateDesc", + "maybeLater", + "mainMenu", + "toggleImmersionMode", + "toggleImmersionModeDesc", + "itToggleDescription", + "igcToggleDescription", + "sendOnEnterDescription", + "alreadyInClass", + "pleaseLoginFirst", + "originalMessage", + "sentMessage", + "useType", + "notAvailable", + "taAndGaTooltip", + "definitionsToolName", + "messageTranslationsToolName", + "definitionsToolDescription", + "translationsToolDescrption", + "welcomeBack", + "classExchanges", + "createNewClass", + "newExchange", + "kickAllStudents", + "kickAllStudentsConfirmation", + "inviteAllStudents", + "inviteAllStudentsConfirmation", + "inviteStudentsFromOtherClasses", + "inviteUsersFromPangea", + "allExchanges", + "redeemPromoCode", + "enterPromoCode", + "downloadTxtFile", + "downloadCSVFile", + "promotionalSubscriptionDesc", + "originalSubscriptionPlatform", + "oneWeekTrial", + "creatingSpacePleaseWait", + "downloadXLSXFile", + "abDisplayName", + "aaDisplayName", + "afDisplayName", + "akDisplayName", + "sqDisplayName", + "amDisplayName", + "arDisplayName", + "anDisplayName", + "hyDisplayName", + "asDisplayName", + "avDisplayName", + "aeDisplayName", + "ayDisplayName", + "azDisplayName", + "bmDisplayName", + "baDisplayName", + "euDisplayName", + "beDisplayName", + "bnDisplayName", + "bhDisplayName", + "biDisplayName", + "bsDisplayName", + "brDisplayName", + "bgDisplayName", + "myDisplayName", + "caDisplayName", + "chDisplayName", + "ceDisplayName", + "nyDisplayName", + "zhDisplayName", + "cvDisplayName", + "kwDisplayName", + "coDisplayName", + "crDisplayName", + "hrDisplayName", + "csDisplayName", + "daDisplayName", + "dvDisplayName", + "nlDisplayName", + "enDisplayName", + "eoDisplayName", + "etDisplayName", + "eeDisplayName", + "foDisplayName", + "fjDisplayName", + "fiDisplayName", + "frDisplayName", + "ffDisplayName", + "glDisplayName", + "kaDisplayName", + "deDisplayName", + "elDisplayName", + "gnDisplayName", + "guDisplayName", + "htDisplayName", + "haDisplayName", + "heDisplayName", + "hzDisplayName", + "hiDisplayName", + "hoDisplayName", + "huDisplayName", + "iaDisplayName", + "idDisplayName", + "ieDisplayName", + "gaDisplayName", + "igDisplayName", + "ikDisplayName", + "ioDisplayName", + "isDisplayName", + "itDisplayName", + "iuDisplayName", + "jaDisplayName", + "jvDisplayName", + "klDisplayName", + "knDisplayName", + "krDisplayName", + "ksDisplayName", + "kkDisplayName", + "kmDisplayName", + "kiDisplayName", + "rwDisplayName", + "kyDisplayName", + "kvDisplayName", + "kgDisplayName", + "koDisplayName", + "kuDisplayName", + "kjDisplayName", + "laDisplayName", + "lbDisplayName", + "lgDisplayName", + "liDisplayName", + "lnDisplayName", + "loDisplayName", + "ltDisplayName", + "luDisplayName", + "lvDisplayName", + "gvDisplayName", + "mkDisplayName", + "mgDisplayName", + "msDisplayName", + "mlDisplayName", + "mtDisplayName", + "miDisplayName", + "mrDisplayName", + "mhDisplayName", + "mnDisplayName", + "naDisplayName", + "nvDisplayName", + "nbDisplayName", + "ndDisplayName", + "neDisplayName", + "ngDisplayName", + "nnDisplayName", + "noDisplayName", + "iiDisplayName", + "nrDisplayName", + "ocDisplayName", + "ojDisplayName", + "cuDisplayName", + "omDisplayName", + "orDisplayName", + "osDisplayName", + "paDisplayName", + "piDisplayName", + "faDisplayName", + "plDisplayName", + "psDisplayName", + "ptDisplayName", + "quDisplayName", + "rmDisplayName", + "rnDisplayName", + "roDisplayName", + "ruDisplayName", + "saDisplayName", + "scDisplayName", + "sdDisplayName", + "seDisplayName", + "smDisplayName", + "sgDisplayName", + "srDisplayName", + "gdDisplayName", + "snDisplayName", + "siDisplayName", + "skDisplayName", + "slDisplayName", + "soDisplayName", + "stDisplayName", + "esDisplayName", + "suDisplayName", + "swDisplayName", + "ssDisplayName", + "svDisplayName", + "taDisplayName", + "teDisplayName", + "tgDisplayName", + "thDisplayName", + "tiDisplayName", + "boDisplayName", + "tkDisplayName", + "tlDisplayName", + "tnDisplayName", + "toDisplayName", + "trDisplayName", + "tsDisplayName", + "ttDisplayName", + "twDisplayName", + "tyDisplayName", + "ugDisplayName", + "ukDisplayName", + "urDisplayName", + "uzDisplayName", + "veDisplayName", + "viDisplayName", + "voDisplayName", + "waDisplayName", + "cyDisplayName", + "woDisplayName", + "fyDisplayName", + "xhDisplayName", + "yiDisplayName", + "yoDisplayName", + "zaDisplayName", + "unkDisplayName", + "zuDisplayName", + "hawDisplayName", + "hmnDisplayName", + "multiDisplayName", + "cebDisplayName", + "dzDisplayName", + "iwDisplayName", + "jwDisplayName", + "moDisplayName", + "shDisplayName", + "wwCountryDisplayName", + "afCountryDisplayName", + "axCountryDisplayName", + "alCountryDisplayName", + "dzCountryDisplayName", + "asCountryDisplayName", + "adCountryDisplayName", + "aoCountryDisplayName", + "aiCountryDisplayName", + "agCountryDisplayName", + "arCountryDisplayName", + "amCountryDisplayName", + "awCountryDisplayName", + "acCountryDisplayName", + "auCountryDisplayName", + "atCountryDisplayName", + "azCountryDisplayName", + "bsCountryDisplayName", + "bhCountryDisplayName", + "bdCountryDisplayName", + "bbCountryDisplayName", + "byCountryDisplayName", + "beCountryDisplayName", + "bzCountryDisplayName", + "bjCountryDisplayName", + "bmCountryDisplayName", + "btCountryDisplayName", + "boCountryDisplayName", + "baCountryDisplayName", + "bwCountryDisplayName", + "brCountryDisplayName", + "ioCountryDisplayName", + "vgCountryDisplayName", + "bnCountryDisplayName", + "bgCountryDisplayName", + "bfCountryDisplayName", + "biCountryDisplayName", + "khCountryDisplayName", + "cmCountryDisplayName", + "caCountryDisplayName", + "cvCountryDisplayName", + "bqCountryDisplayName", + "kyCountryDisplayName", + "cfCountryDisplayName", + "tdCountryDisplayName", + "clCountryDisplayName", + "cnCountryDisplayName", + "cxCountryDisplayName", + "ccCountryDisplayName", + "coCountryDisplayName", + "kmCountryDisplayName", + "cdCountryDisplayName", + "cgCountryDisplayName", + "ckCountryDisplayName", + "crCountryDisplayName", + "ciCountryDisplayName", + "hrCountryDisplayName", + "cuCountryDisplayName", + "cwCountryDisplayName", + "cyCountryDisplayName", + "czCountryDisplayName", + "dkCountryDisplayName", + "djCountryDisplayName", + "dmCountryDisplayName", + "doCountryDisplayName", + "tlCountryDisplayName", + "ecCountryDisplayName", + "egCountryDisplayName", + "svCountryDisplayName", + "gqCountryDisplayName", + "erCountryDisplayName", + "eeCountryDisplayName", + "szCountryDisplayName", + "etCountryDisplayName", + "fkCountryDisplayName", + "foCountryDisplayName", + "fjCountryDisplayName", + "fiCountryDisplayName", + "frCountryDisplayName", + "gfCountryDisplayName", + "pfCountryDisplayName", + "gaCountryDisplayName", + "gmCountryDisplayName", + "geCountryDisplayName", + "deCountryDisplayName", + "ghCountryDisplayName", + "giCountryDisplayName", + "grCountryDisplayName", + "glCountryDisplayName", + "gdCountryDisplayName", + "gpCountryDisplayName", + "guCountryDisplayName", + "gtCountryDisplayName", + "ggCountryDisplayName", + "gnCountryDisplayName", + "gwCountryDisplayName", + "gyCountryDisplayName", + "htCountryDisplayName", + "hmCountryDisplayName", + "hnCountryDisplayName", + "hkCountryDisplayName", + "huCountryDisplayName", + "isCountryDisplayName", + "inCountryDisplayName", + "idCountryDisplayName", + "irCountryDisplayName", + "iqCountryDisplayName", + "ieCountryDisplayName", + "imCountryDisplayName", + "ilCountryDisplayName", + "itCountryDisplayName", + "jmCountryDisplayName", + "jpCountryDisplayName", + "jeCountryDisplayName", + "joCountryDisplayName", + "kzCountryDisplayName", + "keCountryDisplayName", + "kiCountryDisplayName", + "xkCountryDisplayName", + "kwCountryDisplayName", + "kgCountryDisplayName", + "laCountryDisplayName", + "lvCountryDisplayName", + "lbCountryDisplayName", + "lsCountryDisplayName", + "lrCountryDisplayName", + "lyCountryDisplayName", + "liCountryDisplayName", + "ltCountryDisplayName", + "luCountryDisplayName", + "moCountryDisplayName", + "mkCountryDisplayName", + "mgCountryDisplayName", + "mwCountryDisplayName", + "myCountryDisplayName", + "mvCountryDisplayName", + "mlCountryDisplayName", + "mtCountryDisplayName", + "mhCountryDisplayName", + "mqCountryDisplayName", + "mrCountryDisplayName", + "muCountryDisplayName", + "ytCountryDisplayName", + "mxCountryDisplayName", + "fmCountryDisplayName", + "mdCountryDisplayName", + "mcCountryDisplayName", + "mnCountryDisplayName", + "meCountryDisplayName", + "msCountryDisplayName", + "maCountryDisplayName", + "mzCountryDisplayName", + "mmCountryDisplayName", + "naCountryDisplayName", + "nrCountryDisplayName", + "npCountryDisplayName", + "nlCountryDisplayName", + "ncCountryDisplayName", + "nzCountryDisplayName", + "niCountryDisplayName", + "neCountryDisplayName", + "ngCountryDisplayName", + "nuCountryDisplayName", + "nfCountryDisplayName", + "kpCountryDisplayName", + "mpCountryDisplayName", + "noCountryDisplayName", + "omCountryDisplayName", + "pkCountryDisplayName", + "pwCountryDisplayName", + "psCountryDisplayName", + "paCountryDisplayName", + "pgCountryDisplayName", + "pyCountryDisplayName", + "peCountryDisplayName", + "phCountryDisplayName", + "plCountryDisplayName", + "ptCountryDisplayName", + "prCountryDisplayName", + "qaCountryDisplayName", + "reCountryDisplayName", + "roCountryDisplayName", + "ruCountryDisplayName", + "rwCountryDisplayName", + "blCountryDisplayName", + "shCountryDisplayName", + "knCountryDisplayName", + "lcCountryDisplayName", + "mfCountryDisplayName", + "pmCountryDisplayName", + "vcCountryDisplayName", + "wsCountryDisplayName", + "smCountryDisplayName", + "stCountryDisplayName", + "saCountryDisplayName", + "snCountryDisplayName", + "rsCountryDisplayName", + "scCountryDisplayName", + "slCountryDisplayName", + "sgCountryDisplayName", + "sxCountryDisplayName", + "skCountryDisplayName", + "siCountryDisplayName", + "sbCountryDisplayName", + "soCountryDisplayName", + "zaCountryDisplayName", + "gsCountryDisplayName", + "krCountryDisplayName", + "ssCountryDisplayName", + "esCountryDisplayName", + "lkCountryDisplayName", + "sdCountryDisplayName", + "srCountryDisplayName", + "sjCountryDisplayName", + "seCountryDisplayName", + "chCountryDisplayName", + "syCountryDisplayName", + "twCountryDisplayName", + "tjCountryDisplayName", + "tzCountryDisplayName", + "thCountryDisplayName", + "tgCountryDisplayName", + "tkCountryDisplayName", + "toCountryDisplayName", + "ttCountryDisplayName", + "tnCountryDisplayName", + "trCountryDisplayName", + "tmCountryDisplayName", + "tcCountryDisplayName", + "tvCountryDisplayName", + "viCountryDisplayName", + "ugCountryDisplayName", + "uaCountryDisplayName", + "aeCountryDisplayName", + "gbCountryDisplayName", + "usCountryDisplayName", + "uyCountryDisplayName", + "uzCountryDisplayName", + "vuCountryDisplayName", + "vaCountryDisplayName", + "veCountryDisplayName", + "vnCountryDisplayName", + "wfCountryDisplayName", + "ehCountryDisplayName", + "yeCountryDisplayName", + "zmCountryDisplayName", + "zwCountryDisplayName", + "pay", + "allPrivateChats", + "unknownPrivateChat", + "copyClassCodeDesc", + "addToClassDesc", + "addToClassOrExchange", + "addToClassOrExchangeDesc", + "invitedToClassOrExchange", + "decline", + "declinedInvitation", + "acceptedInvitation", + "youreInvited", + "studentPermissionsDesc", + "noEligibleSpaces", + "youAddedToSpace", + "youRemovedFromSpace", + "invitedToChat", + "monthlySubscription", + "yearlySubscription", + "defaultSubscription", + "freeTrial", + "grammarAnalytics", + "total", + "noDataFound", + "promoSubscriptionExpirationDesc", + "emptyChatNameWarning", + "emptyClassNameWarning", + "emptyExchangeNameWarning", + "blurMeansTranslateTitle", + "blurMeansTranslateBody", + "someErrorTitle", + "someErrorBody", + "bestCorrectionFeedback", + "distractorFeedback", + "bestAnswerFeedback", + "definitionDefaultPrompt", + "practiceDefaultPrompt", + "correctionDefaultPrompt", + "itStartDefaultPrompt", + "languageLevelWarning", + "lockedChatWarning", + "lockSpace", + "lockChat", + "archiveSpace", + "suggestTo", + "suggestChatDesc", + "suggestExchangeDesc", + "acceptSelection", + "acceptSelectionAnyway", + "makingActivity", + "why", + "definition", + "exampleSentence", + "addToClassTitle", + "reportToTeacher", + "reportMessageTitle", + "reportMessageBody", + "noTeachersFound", + "noAddToSpacePermissions", + "alreadyInSpace", + "yourGlobalUserIdIs", + "noUsersFoundWithQuery", + "searchChatsRooms", + "groupName", + "createGroupAndInviteUsers", + "groupCanBeFoundViaSearch", + "inNoSpaces" + ], + + "pl": [ + "accountInformation", + "addNewFriend", + "alreadyHaveAnAccount", + "classes", + "allCorrect", + "newWayAllGood", + "othersAreBetter", + "holdForInfo", + "greenFeedback", + "yellowFeedback", + "redFeedback", + "customInputFeedbackChoice", + "itInstructionsTitle", + "itInstructionsBody", + "toggleLanguages", + "classWelcomeChat", + "deleteSpace", + "deleteGroup", + "areYouSureDeleteClass", + "areYouSureDeleteGroup", + "cannotBeReversed", + "enterDeletedClassName", + "incorrectClassName", + "oneday", + "oneweek", + "onemonth", + "sixmonth", + "oneyear", + "gaTooltip", + "taTooltip", + "unTooltip", + "interactiveTranslatorSliderHeader", + "interactiveGrammarSliderHeader", + "interactiveTranslatorNotAllowed", + "interactiveTranslatorAllowed", + "interactiveTranslatorRequired", + "interactiveTranslatorNotAllowedDesc", + "interactiveTranslatorAllowedDesc", + "interactiveTranslatorRequiredDesc", + "notYetSet", + "multiLingualClass", + "classAnalytics", + "allClasses", + "myLearning", + "allChatsAndClasses", + "timeOfLastMessage", + "totalMessages", + "waTooltip", + "changeDateRange", + "numberOfStudents", + "classDescription", + "classDescriptionDesc", + "requestToEnroll", + "requestAnExchange", + "findLanguageExchange", + "classAnalyticsDesc", + "addStudents", + "copyClassLink", + "copyClassLinkDesc", + "copyClassCode", + "inviteStudentByUserName", + "classSettings", + "classSettingsDesc", + "selectClassRoomDominantLanguage", + "selectTargetLanguage", + "whatIsYourClassLanguageLevel", + "studentPermissions", + "interactiveTranslator", + "oneToOneChatsWithinClass", + "oneToOneChatsWithinClassDesc", + "createGroupChats", + "createGroupChatsDesc", + "shareVideo", + "shareVideoDesc", + "sharePhotos", + "sharePhotosDesc", + "shareFiles", + "shareFilesDesc", + "shareLocationDesc", + "selectLanguageLevel", + "noIdenticalLanguages", + "iWantALanguagePartnerFrom", + "worldWide", + "noResults", + "searchBy", + "iWantAConversationPartner", + "iWantALanguagePartnerWhoSpeaks", + "iWantALanguagePartnerWhoIsLearning", + "yourBirthdayPlease", + "invalidDob", + "enterYourDob", + "getStarted", + "mustBe13", + "yourBirthdayPleaseShort", + "errorPleaseRefresh", + "joinWithClassCode", + "joinWithClassCodeDesc", + "joinWithClassCodeHint", + "unableToFindClass", + "languageLevelPreA1", + "languageLevelA1", + "languageLevelA2", + "languageLevelB1", + "languageLevelB2", + "languageLevelC1", + "languageLevelC2", + "changeTheNameOfTheClass", + "changeTheNameOfTheChat", + "welcomeToYourNewClass", + "welcomeToClass", + "welcomeToPangea18Plus", + "welcomeToPangeaMinor", + "findALanguagePartner", + "setToPublicSettingsTitle", + "setToPublicSettingsDesc", + "accountSettings", + "unableToFindClassCode", + "askPangeaBot", + "sorryNoResults", + "ignoreInThisText", + "helpMeTranslate", + "needsItShortMessage", + "needsIGCShortMessage", + "needsItMessage", + "needsIgcMessage", + "tokenTranslationTitle", + "spanTranslationDesc", + "spanTranslationTitle", + "l1SpanAndGrammarTitle", + "l1SpanAndGrammarDesc", + "otherTitle", + "otherDesc", + "countryInformation", + "myLanguages", + "targetLanguage", + "sourceLanguage", + "languagesISpeak", + "updateLanguage", + "whatLanguageYouWantToLearn", + "whatIsYourBaseLanguage", + "saveChanges", + "publicProfileTitle", + "publicProfileDesc", + "error502504Title", + "error502504Desc", + "error404Title", + "error404Desc", + "errorDisableIT", + "errorDisableIGC", + "errorDisableLanguageAssistance", + "errorDisableITUserDesc", + "errorDisableIGCUserDesc", + "errorDisableLanguageAssistanceUserDesc", + "errorDisableITClassDesc", + "errorDisableIGCClassDesc", + "errorDisableLanguageAssistanceClassDesc", + "itIsDisabled", + "igcIsDisabled", + "goToLearningSettings", + "error405Title", + "error405Desc", + "loginOrSignup", + "iAgreeToThe", + "termsAndConditions", + "andCertifyIAmAtLeast13YearsOfAge", + "findAClass", + "toggleIT", + "toggleIGC", + "toggleToolSettingsDescription", + "connectedToStaging", + "learningSettings", + "classNameRequired", + "sendVoiceNotes", + "sendVoiceNotesDesc", + "chatTopic", + "chatTopicDesc", + "inviteStudentByUserNameDesc", + "classRoster", + "almostPerfect", + "prettyGood", + "letMeThink", + "clickMessageTitle", + "clickMessageBody", + "understandingMessagesTitle", + "addToClass", + "understandingMessagesBody", + "allDone", + "vocab", + "low", + "medium", + "high", + "unknownProficiency", + "changeView", + "clearAll", + "generateVocabulary", + "generatePrompts", + "subscribe", + "getAccess", + "subscriptionDesc", + "subscriptionManagement", + "currentSubscription", + "changeSubscription", + "cancelSubscription", + "selectYourPlan", + "subsciptionPlatformTooltip", + "subscriptionManagementUnavailable", + "paymentMethod", + "paymentHistory", + "emptyChatDownloadWarning", + "appUpdateAvailable", + "update", + "updateDesc", + "maybeLater", + "mainMenu", + "toggleImmersionMode", + "toggleImmersionModeDesc", + "itToggleDescription", + "igcToggleDescription", + "sendOnEnterDescription", + "alreadyInClass", + "pleaseLoginFirst", + "originalMessage", + "sentMessage", + "useType", + "notAvailable", + "taAndGaTooltip", + "definitionsToolName", + "messageTranslationsToolName", + "definitionsToolDescription", + "translationsToolDescrption", + "welcomeBack", + "classExchanges", + "createNewClass", + "newExchange", + "kickAllStudents", + "kickAllStudentsConfirmation", + "inviteAllStudents", + "inviteAllStudentsConfirmation", + "inviteStudentsFromOtherClasses", + "inviteUsersFromPangea", + "allExchanges", + "redeemPromoCode", + "enterPromoCode", + "downloadTxtFile", + "downloadCSVFile", + "promotionalSubscriptionDesc", + "originalSubscriptionPlatform", + "oneWeekTrial", + "creatingSpacePleaseWait", + "downloadXLSXFile", + "abDisplayName", + "aaDisplayName", + "afDisplayName", + "akDisplayName", + "sqDisplayName", + "amDisplayName", + "arDisplayName", + "anDisplayName", + "hyDisplayName", + "asDisplayName", + "avDisplayName", + "aeDisplayName", + "ayDisplayName", + "azDisplayName", + "bmDisplayName", + "baDisplayName", + "euDisplayName", + "beDisplayName", + "bnDisplayName", + "bhDisplayName", + "biDisplayName", + "bsDisplayName", + "brDisplayName", + "bgDisplayName", + "myDisplayName", + "caDisplayName", + "chDisplayName", + "ceDisplayName", + "nyDisplayName", + "zhDisplayName", + "cvDisplayName", + "kwDisplayName", + "coDisplayName", + "crDisplayName", + "hrDisplayName", + "csDisplayName", + "daDisplayName", + "dvDisplayName", + "nlDisplayName", + "enDisplayName", + "eoDisplayName", + "etDisplayName", + "eeDisplayName", + "foDisplayName", + "fjDisplayName", + "fiDisplayName", + "frDisplayName", + "ffDisplayName", + "glDisplayName", + "kaDisplayName", + "deDisplayName", + "elDisplayName", + "gnDisplayName", + "guDisplayName", + "htDisplayName", + "haDisplayName", + "heDisplayName", + "hzDisplayName", + "hiDisplayName", + "hoDisplayName", + "huDisplayName", + "iaDisplayName", + "idDisplayName", + "ieDisplayName", + "gaDisplayName", + "igDisplayName", + "ikDisplayName", + "ioDisplayName", + "isDisplayName", + "itDisplayName", + "iuDisplayName", + "jaDisplayName", + "jvDisplayName", + "klDisplayName", + "knDisplayName", + "krDisplayName", + "ksDisplayName", + "kkDisplayName", + "kmDisplayName", + "kiDisplayName", + "rwDisplayName", + "kyDisplayName", + "kvDisplayName", + "kgDisplayName", + "koDisplayName", + "kuDisplayName", + "kjDisplayName", + "laDisplayName", + "lbDisplayName", + "lgDisplayName", + "liDisplayName", + "lnDisplayName", + "loDisplayName", + "ltDisplayName", + "luDisplayName", + "lvDisplayName", + "gvDisplayName", + "mkDisplayName", + "mgDisplayName", + "msDisplayName", + "mlDisplayName", + "mtDisplayName", + "miDisplayName", + "mrDisplayName", + "mhDisplayName", + "mnDisplayName", + "naDisplayName", + "nvDisplayName", + "nbDisplayName", + "ndDisplayName", + "neDisplayName", + "ngDisplayName", + "nnDisplayName", + "noDisplayName", + "iiDisplayName", + "nrDisplayName", + "ocDisplayName", + "ojDisplayName", + "cuDisplayName", + "omDisplayName", + "orDisplayName", + "osDisplayName", + "paDisplayName", + "piDisplayName", + "faDisplayName", + "plDisplayName", + "psDisplayName", + "ptDisplayName", + "quDisplayName", + "rmDisplayName", + "rnDisplayName", + "roDisplayName", + "ruDisplayName", + "saDisplayName", + "scDisplayName", + "sdDisplayName", + "seDisplayName", + "smDisplayName", + "sgDisplayName", + "srDisplayName", + "gdDisplayName", + "snDisplayName", + "siDisplayName", + "skDisplayName", + "slDisplayName", + "soDisplayName", + "stDisplayName", + "esDisplayName", + "suDisplayName", + "swDisplayName", + "ssDisplayName", + "svDisplayName", + "taDisplayName", + "teDisplayName", + "tgDisplayName", + "thDisplayName", + "tiDisplayName", + "boDisplayName", + "tkDisplayName", + "tlDisplayName", + "tnDisplayName", + "toDisplayName", + "trDisplayName", + "tsDisplayName", + "ttDisplayName", + "twDisplayName", + "tyDisplayName", + "ugDisplayName", + "ukDisplayName", + "urDisplayName", + "uzDisplayName", + "veDisplayName", + "viDisplayName", + "voDisplayName", + "waDisplayName", + "cyDisplayName", + "woDisplayName", + "fyDisplayName", + "xhDisplayName", + "yiDisplayName", + "yoDisplayName", + "zaDisplayName", + "unkDisplayName", + "zuDisplayName", + "hawDisplayName", + "hmnDisplayName", + "multiDisplayName", + "cebDisplayName", + "dzDisplayName", + "iwDisplayName", + "jwDisplayName", + "moDisplayName", + "shDisplayName", + "wwCountryDisplayName", + "afCountryDisplayName", + "axCountryDisplayName", + "alCountryDisplayName", + "dzCountryDisplayName", + "asCountryDisplayName", + "adCountryDisplayName", + "aoCountryDisplayName", + "aiCountryDisplayName", + "agCountryDisplayName", + "arCountryDisplayName", + "amCountryDisplayName", + "awCountryDisplayName", + "acCountryDisplayName", + "auCountryDisplayName", + "atCountryDisplayName", + "azCountryDisplayName", + "bsCountryDisplayName", + "bhCountryDisplayName", + "bdCountryDisplayName", + "bbCountryDisplayName", + "byCountryDisplayName", + "beCountryDisplayName", + "bzCountryDisplayName", + "bjCountryDisplayName", + "bmCountryDisplayName", + "btCountryDisplayName", + "boCountryDisplayName", + "baCountryDisplayName", + "bwCountryDisplayName", + "brCountryDisplayName", + "ioCountryDisplayName", + "vgCountryDisplayName", + "bnCountryDisplayName", + "bgCountryDisplayName", + "bfCountryDisplayName", + "biCountryDisplayName", + "khCountryDisplayName", + "cmCountryDisplayName", + "caCountryDisplayName", + "cvCountryDisplayName", + "bqCountryDisplayName", + "kyCountryDisplayName", + "cfCountryDisplayName", + "tdCountryDisplayName", + "clCountryDisplayName", + "cnCountryDisplayName", + "cxCountryDisplayName", + "ccCountryDisplayName", + "coCountryDisplayName", + "kmCountryDisplayName", + "cdCountryDisplayName", + "cgCountryDisplayName", + "ckCountryDisplayName", + "crCountryDisplayName", + "ciCountryDisplayName", + "hrCountryDisplayName", + "cuCountryDisplayName", + "cwCountryDisplayName", + "cyCountryDisplayName", + "czCountryDisplayName", + "dkCountryDisplayName", + "djCountryDisplayName", + "dmCountryDisplayName", + "doCountryDisplayName", + "tlCountryDisplayName", + "ecCountryDisplayName", + "egCountryDisplayName", + "svCountryDisplayName", + "gqCountryDisplayName", + "erCountryDisplayName", + "eeCountryDisplayName", + "szCountryDisplayName", + "etCountryDisplayName", + "fkCountryDisplayName", + "foCountryDisplayName", + "fjCountryDisplayName", + "fiCountryDisplayName", + "frCountryDisplayName", + "gfCountryDisplayName", + "pfCountryDisplayName", + "gaCountryDisplayName", + "gmCountryDisplayName", + "geCountryDisplayName", + "deCountryDisplayName", + "ghCountryDisplayName", + "giCountryDisplayName", + "grCountryDisplayName", + "glCountryDisplayName", + "gdCountryDisplayName", + "gpCountryDisplayName", + "guCountryDisplayName", + "gtCountryDisplayName", + "ggCountryDisplayName", + "gnCountryDisplayName", + "gwCountryDisplayName", + "gyCountryDisplayName", + "htCountryDisplayName", + "hmCountryDisplayName", + "hnCountryDisplayName", + "hkCountryDisplayName", + "huCountryDisplayName", + "isCountryDisplayName", + "inCountryDisplayName", + "idCountryDisplayName", + "irCountryDisplayName", + "iqCountryDisplayName", + "ieCountryDisplayName", + "imCountryDisplayName", + "ilCountryDisplayName", + "itCountryDisplayName", + "jmCountryDisplayName", + "jpCountryDisplayName", + "jeCountryDisplayName", + "joCountryDisplayName", + "kzCountryDisplayName", + "keCountryDisplayName", + "kiCountryDisplayName", + "xkCountryDisplayName", + "kwCountryDisplayName", + "kgCountryDisplayName", + "laCountryDisplayName", + "lvCountryDisplayName", + "lbCountryDisplayName", + "lsCountryDisplayName", + "lrCountryDisplayName", + "lyCountryDisplayName", + "liCountryDisplayName", + "ltCountryDisplayName", + "luCountryDisplayName", + "moCountryDisplayName", + "mkCountryDisplayName", + "mgCountryDisplayName", + "mwCountryDisplayName", + "myCountryDisplayName", + "mvCountryDisplayName", + "mlCountryDisplayName", + "mtCountryDisplayName", + "mhCountryDisplayName", + "mqCountryDisplayName", + "mrCountryDisplayName", + "muCountryDisplayName", + "ytCountryDisplayName", + "mxCountryDisplayName", + "fmCountryDisplayName", + "mdCountryDisplayName", + "mcCountryDisplayName", + "mnCountryDisplayName", + "meCountryDisplayName", + "msCountryDisplayName", + "maCountryDisplayName", + "mzCountryDisplayName", + "mmCountryDisplayName", + "naCountryDisplayName", + "nrCountryDisplayName", + "npCountryDisplayName", + "nlCountryDisplayName", + "ncCountryDisplayName", + "nzCountryDisplayName", + "niCountryDisplayName", + "neCountryDisplayName", + "ngCountryDisplayName", + "nuCountryDisplayName", + "nfCountryDisplayName", + "kpCountryDisplayName", + "mpCountryDisplayName", + "noCountryDisplayName", + "omCountryDisplayName", + "pkCountryDisplayName", + "pwCountryDisplayName", + "psCountryDisplayName", + "paCountryDisplayName", + "pgCountryDisplayName", + "pyCountryDisplayName", + "peCountryDisplayName", + "phCountryDisplayName", + "plCountryDisplayName", + "ptCountryDisplayName", + "prCountryDisplayName", + "qaCountryDisplayName", + "reCountryDisplayName", + "roCountryDisplayName", + "ruCountryDisplayName", + "rwCountryDisplayName", + "blCountryDisplayName", + "shCountryDisplayName", + "knCountryDisplayName", + "lcCountryDisplayName", + "mfCountryDisplayName", + "pmCountryDisplayName", + "vcCountryDisplayName", + "wsCountryDisplayName", + "smCountryDisplayName", + "stCountryDisplayName", + "saCountryDisplayName", + "snCountryDisplayName", + "rsCountryDisplayName", + "scCountryDisplayName", + "slCountryDisplayName", + "sgCountryDisplayName", + "sxCountryDisplayName", + "skCountryDisplayName", + "siCountryDisplayName", + "sbCountryDisplayName", + "soCountryDisplayName", + "zaCountryDisplayName", + "gsCountryDisplayName", + "krCountryDisplayName", + "ssCountryDisplayName", + "esCountryDisplayName", + "lkCountryDisplayName", + "sdCountryDisplayName", + "srCountryDisplayName", + "sjCountryDisplayName", + "seCountryDisplayName", + "chCountryDisplayName", + "syCountryDisplayName", + "twCountryDisplayName", + "tjCountryDisplayName", + "tzCountryDisplayName", + "thCountryDisplayName", + "tgCountryDisplayName", + "tkCountryDisplayName", + "toCountryDisplayName", + "ttCountryDisplayName", + "tnCountryDisplayName", + "trCountryDisplayName", + "tmCountryDisplayName", + "tcCountryDisplayName", + "tvCountryDisplayName", + "viCountryDisplayName", + "ugCountryDisplayName", + "uaCountryDisplayName", + "aeCountryDisplayName", + "gbCountryDisplayName", + "usCountryDisplayName", + "uyCountryDisplayName", + "uzCountryDisplayName", + "vuCountryDisplayName", + "vaCountryDisplayName", + "veCountryDisplayName", + "vnCountryDisplayName", + "wfCountryDisplayName", + "ehCountryDisplayName", + "yeCountryDisplayName", + "zmCountryDisplayName", + "zwCountryDisplayName", + "pay", + "allPrivateChats", + "unknownPrivateChat", + "copyClassCodeDesc", + "addToClassDesc", + "addToClassOrExchange", + "addToClassOrExchangeDesc", + "invitedToClassOrExchange", + "decline", + "declinedInvitation", + "acceptedInvitation", + "youreInvited", + "studentPermissionsDesc", + "noEligibleSpaces", + "youAddedToSpace", + "youRemovedFromSpace", + "invitedToChat", + "monthlySubscription", + "yearlySubscription", + "defaultSubscription", + "freeTrial", + "grammarAnalytics", + "total", + "noDataFound", + "promoSubscriptionExpirationDesc", + "emptyChatNameWarning", + "emptyClassNameWarning", + "emptyExchangeNameWarning", + "blurMeansTranslateTitle", + "blurMeansTranslateBody", + "someErrorTitle", + "someErrorBody", + "bestCorrectionFeedback", + "distractorFeedback", + "bestAnswerFeedback", + "definitionDefaultPrompt", + "practiceDefaultPrompt", + "correctionDefaultPrompt", + "itStartDefaultPrompt", + "languageLevelWarning", + "lockedChatWarning", + "lockSpace", + "lockChat", + "archiveSpace", + "suggestTo", + "suggestChatDesc", + "suggestExchangeDesc", + "acceptSelection", + "acceptSelectionAnyway", + "makingActivity", + "why", + "definition", + "exampleSentence", + "addToClassTitle", + "reportToTeacher", + "reportMessageTitle", + "reportMessageBody", + "noTeachersFound", + "noAddToSpacePermissions", + "alreadyInSpace", + "yourGlobalUserIdIs", + "noUsersFoundWithQuery", + "searchChatsRooms", + "groupName", + "createGroupAndInviteUsers", + "groupCanBeFoundViaSearch", + "inNoSpaces" + ], + + "pt": [ + "accountInformation", + "addGroupDescription", + "addNewFriend", + "alreadyHaveAnAccount", + "classes", + "createNewGroup", + "editChatPermissions", + "groupDescription", + "groupDescriptionHasBeenChanged", + "allCorrect", + "newWayAllGood", + "othersAreBetter", + "holdForInfo", + "greenFeedback", + "yellowFeedback", + "redFeedback", + "customInputFeedbackChoice", + "itInstructionsTitle", + "itInstructionsBody", + "toggleLanguages", + "classWelcomeChat", + "deleteSpace", + "deleteGroup", + "areYouSureDeleteClass", + "areYouSureDeleteGroup", + "cannotBeReversed", + "enterDeletedClassName", + "incorrectClassName", + "oneday", + "oneweek", + "onemonth", + "sixmonth", + "oneyear", + "gaTooltip", + "taTooltip", + "unTooltip", + "interactiveTranslatorSliderHeader", + "interactiveGrammarSliderHeader", + "interactiveTranslatorNotAllowed", + "interactiveTranslatorAllowed", + "interactiveTranslatorRequired", + "interactiveTranslatorNotAllowedDesc", + "interactiveTranslatorAllowedDesc", + "interactiveTranslatorRequiredDesc", + "notYetSet", + "multiLingualClass", + "classAnalytics", + "allClasses", + "myLearning", + "allChatsAndClasses", + "timeOfLastMessage", + "totalMessages", + "waTooltip", + "changeDateRange", + "numberOfStudents", + "classDescription", + "classDescriptionDesc", + "requestToEnroll", + "requestAnExchange", + "findLanguageExchange", + "classAnalyticsDesc", + "addStudents", + "copyClassLink", + "copyClassLinkDesc", + "copyClassCode", + "inviteStudentByUserName", + "classSettings", + "classSettingsDesc", + "selectClassRoomDominantLanguage", + "selectTargetLanguage", + "whatIsYourClassLanguageLevel", + "studentPermissions", + "interactiveTranslator", + "oneToOneChatsWithinClass", + "oneToOneChatsWithinClassDesc", + "createGroupChats", + "createGroupChatsDesc", + "shareVideo", + "shareVideoDesc", + "sharePhotos", + "sharePhotosDesc", + "shareFiles", + "shareFilesDesc", + "shareLocationDesc", + "selectLanguageLevel", + "noIdenticalLanguages", + "iWantALanguagePartnerFrom", + "worldWide", + "noResults", + "searchBy", + "iWantAConversationPartner", + "iWantALanguagePartnerWhoSpeaks", + "iWantALanguagePartnerWhoIsLearning", + "yourBirthdayPlease", + "invalidDob", + "enterYourDob", + "getStarted", + "mustBe13", + "yourBirthdayPleaseShort", + "errorPleaseRefresh", + "joinWithClassCode", + "joinWithClassCodeDesc", + "joinWithClassCodeHint", + "unableToFindClass", + "languageLevelPreA1", + "languageLevelA1", + "languageLevelA2", + "languageLevelB1", + "languageLevelB2", + "languageLevelC1", + "languageLevelC2", + "changeTheNameOfTheClass", + "changeTheNameOfTheChat", + "welcomeToYourNewClass", + "welcomeToClass", + "welcomeToPangea18Plus", + "welcomeToPangeaMinor", + "findALanguagePartner", + "setToPublicSettingsTitle", + "setToPublicSettingsDesc", + "accountSettings", + "unableToFindClassCode", + "askPangeaBot", + "sorryNoResults", + "ignoreInThisText", + "helpMeTranslate", + "needsItShortMessage", + "needsIGCShortMessage", + "needsItMessage", + "needsIgcMessage", + "tokenTranslationTitle", + "spanTranslationDesc", + "spanTranslationTitle", + "l1SpanAndGrammarTitle", + "l1SpanAndGrammarDesc", + "otherTitle", + "otherDesc", + "countryInformation", + "myLanguages", + "targetLanguage", + "sourceLanguage", + "languagesISpeak", + "updateLanguage", + "whatLanguageYouWantToLearn", + "whatIsYourBaseLanguage", + "saveChanges", + "publicProfileTitle", + "publicProfileDesc", + "error502504Title", + "error502504Desc", + "error404Title", + "error404Desc", + "errorDisableIT", + "errorDisableIGC", + "errorDisableLanguageAssistance", + "errorDisableITUserDesc", + "errorDisableIGCUserDesc", + "errorDisableLanguageAssistanceUserDesc", + "errorDisableITClassDesc", + "errorDisableIGCClassDesc", + "errorDisableLanguageAssistanceClassDesc", + "itIsDisabled", + "igcIsDisabled", + "goToLearningSettings", + "error405Title", + "error405Desc", + "loginOrSignup", + "iAgreeToThe", + "termsAndConditions", + "andCertifyIAmAtLeast13YearsOfAge", + "findAClass", + "toggleIT", + "toggleIGC", + "toggleToolSettingsDescription", + "connectedToStaging", + "learningSettings", + "classNameRequired", + "sendVoiceNotes", + "sendVoiceNotesDesc", + "chatTopic", + "chatTopicDesc", + "inviteStudentByUserNameDesc", + "classRoster", + "almostPerfect", + "prettyGood", + "letMeThink", + "clickMessageTitle", + "clickMessageBody", + "understandingMessagesTitle", + "addToClass", + "understandingMessagesBody", + "allDone", + "vocab", + "low", + "medium", + "high", + "unknownProficiency", + "changeView", + "clearAll", + "generateVocabulary", + "generatePrompts", + "subscribe", + "getAccess", + "subscriptionDesc", + "subscriptionManagement", + "currentSubscription", + "changeSubscription", + "cancelSubscription", + "selectYourPlan", + "subsciptionPlatformTooltip", + "subscriptionManagementUnavailable", + "paymentMethod", + "paymentHistory", + "emptyChatDownloadWarning", + "appUpdateAvailable", + "update", + "updateDesc", + "maybeLater", + "mainMenu", + "toggleImmersionMode", + "toggleImmersionModeDesc", + "itToggleDescription", + "igcToggleDescription", + "sendOnEnterDescription", + "alreadyInClass", + "pleaseLoginFirst", + "originalMessage", + "sentMessage", + "useType", + "notAvailable", + "taAndGaTooltip", + "definitionsToolName", + "messageTranslationsToolName", + "definitionsToolDescription", + "translationsToolDescrption", + "welcomeBack", + "classExchanges", + "createNewClass", + "newExchange", + "kickAllStudents", + "kickAllStudentsConfirmation", + "inviteAllStudents", + "inviteAllStudentsConfirmation", + "inviteStudentsFromOtherClasses", + "inviteUsersFromPangea", + "allExchanges", + "redeemPromoCode", + "enterPromoCode", + "downloadTxtFile", + "downloadCSVFile", + "promotionalSubscriptionDesc", + "originalSubscriptionPlatform", + "oneWeekTrial", + "creatingSpacePleaseWait", + "downloadXLSXFile", + "abDisplayName", + "aaDisplayName", + "afDisplayName", + "akDisplayName", + "sqDisplayName", + "amDisplayName", + "arDisplayName", + "anDisplayName", + "hyDisplayName", + "asDisplayName", + "avDisplayName", + "aeDisplayName", + "ayDisplayName", + "azDisplayName", + "bmDisplayName", + "baDisplayName", + "euDisplayName", + "beDisplayName", + "bnDisplayName", + "bhDisplayName", + "biDisplayName", + "bsDisplayName", + "brDisplayName", + "bgDisplayName", + "myDisplayName", + "caDisplayName", + "chDisplayName", + "ceDisplayName", + "nyDisplayName", + "zhDisplayName", + "cvDisplayName", + "kwDisplayName", + "coDisplayName", + "crDisplayName", + "hrDisplayName", + "csDisplayName", + "daDisplayName", + "dvDisplayName", + "nlDisplayName", + "enDisplayName", + "eoDisplayName", + "etDisplayName", + "eeDisplayName", + "foDisplayName", + "fjDisplayName", + "fiDisplayName", + "frDisplayName", + "ffDisplayName", + "glDisplayName", + "kaDisplayName", + "deDisplayName", + "elDisplayName", + "gnDisplayName", + "guDisplayName", + "htDisplayName", + "haDisplayName", + "heDisplayName", + "hzDisplayName", + "hiDisplayName", + "hoDisplayName", + "huDisplayName", + "iaDisplayName", + "idDisplayName", + "ieDisplayName", + "gaDisplayName", + "igDisplayName", + "ikDisplayName", + "ioDisplayName", + "isDisplayName", + "itDisplayName", + "iuDisplayName", + "jaDisplayName", + "jvDisplayName", + "klDisplayName", + "knDisplayName", + "krDisplayName", + "ksDisplayName", + "kkDisplayName", + "kmDisplayName", + "kiDisplayName", + "rwDisplayName", + "kyDisplayName", + "kvDisplayName", + "kgDisplayName", + "koDisplayName", + "kuDisplayName", + "kjDisplayName", + "laDisplayName", + "lbDisplayName", + "lgDisplayName", + "liDisplayName", + "lnDisplayName", + "loDisplayName", + "ltDisplayName", + "luDisplayName", + "lvDisplayName", + "gvDisplayName", + "mkDisplayName", + "mgDisplayName", + "msDisplayName", + "mlDisplayName", + "mtDisplayName", + "miDisplayName", + "mrDisplayName", + "mhDisplayName", + "mnDisplayName", + "naDisplayName", + "nvDisplayName", + "nbDisplayName", + "ndDisplayName", + "neDisplayName", + "ngDisplayName", + "nnDisplayName", + "noDisplayName", + "iiDisplayName", + "nrDisplayName", + "ocDisplayName", + "ojDisplayName", + "cuDisplayName", + "omDisplayName", + "orDisplayName", + "osDisplayName", + "paDisplayName", + "piDisplayName", + "faDisplayName", + "plDisplayName", + "psDisplayName", + "ptDisplayName", + "quDisplayName", + "rmDisplayName", + "rnDisplayName", + "roDisplayName", + "ruDisplayName", + "saDisplayName", + "scDisplayName", + "sdDisplayName", + "seDisplayName", + "smDisplayName", + "sgDisplayName", + "srDisplayName", + "gdDisplayName", + "snDisplayName", + "siDisplayName", + "skDisplayName", + "slDisplayName", + "soDisplayName", + "stDisplayName", + "esDisplayName", + "suDisplayName", + "swDisplayName", + "ssDisplayName", + "svDisplayName", + "taDisplayName", + "teDisplayName", + "tgDisplayName", + "thDisplayName", + "tiDisplayName", + "boDisplayName", + "tkDisplayName", + "tlDisplayName", + "tnDisplayName", + "toDisplayName", + "trDisplayName", + "tsDisplayName", + "ttDisplayName", + "twDisplayName", + "tyDisplayName", + "ugDisplayName", + "ukDisplayName", + "urDisplayName", + "uzDisplayName", + "veDisplayName", + "viDisplayName", + "voDisplayName", + "waDisplayName", + "cyDisplayName", + "woDisplayName", + "fyDisplayName", + "xhDisplayName", + "yiDisplayName", + "yoDisplayName", + "zaDisplayName", + "unkDisplayName", + "zuDisplayName", + "hawDisplayName", + "hmnDisplayName", + "multiDisplayName", + "cebDisplayName", + "dzDisplayName", + "iwDisplayName", + "jwDisplayName", + "moDisplayName", + "shDisplayName", + "wwCountryDisplayName", + "afCountryDisplayName", + "axCountryDisplayName", + "alCountryDisplayName", + "dzCountryDisplayName", + "asCountryDisplayName", + "adCountryDisplayName", + "aoCountryDisplayName", + "aiCountryDisplayName", + "agCountryDisplayName", + "arCountryDisplayName", + "amCountryDisplayName", + "awCountryDisplayName", + "acCountryDisplayName", + "auCountryDisplayName", + "atCountryDisplayName", + "azCountryDisplayName", + "bsCountryDisplayName", + "bhCountryDisplayName", + "bdCountryDisplayName", + "bbCountryDisplayName", + "byCountryDisplayName", + "beCountryDisplayName", + "bzCountryDisplayName", + "bjCountryDisplayName", + "bmCountryDisplayName", + "btCountryDisplayName", + "boCountryDisplayName", + "baCountryDisplayName", + "bwCountryDisplayName", + "brCountryDisplayName", + "ioCountryDisplayName", + "vgCountryDisplayName", + "bnCountryDisplayName", + "bgCountryDisplayName", + "bfCountryDisplayName", + "biCountryDisplayName", + "khCountryDisplayName", + "cmCountryDisplayName", + "caCountryDisplayName", + "cvCountryDisplayName", + "bqCountryDisplayName", + "kyCountryDisplayName", + "cfCountryDisplayName", + "tdCountryDisplayName", + "clCountryDisplayName", + "cnCountryDisplayName", + "cxCountryDisplayName", + "ccCountryDisplayName", + "coCountryDisplayName", + "kmCountryDisplayName", + "cdCountryDisplayName", + "cgCountryDisplayName", + "ckCountryDisplayName", + "crCountryDisplayName", + "ciCountryDisplayName", + "hrCountryDisplayName", + "cuCountryDisplayName", + "cwCountryDisplayName", + "cyCountryDisplayName", + "czCountryDisplayName", + "dkCountryDisplayName", + "djCountryDisplayName", + "dmCountryDisplayName", + "doCountryDisplayName", + "tlCountryDisplayName", + "ecCountryDisplayName", + "egCountryDisplayName", + "svCountryDisplayName", + "gqCountryDisplayName", + "erCountryDisplayName", + "eeCountryDisplayName", + "szCountryDisplayName", + "etCountryDisplayName", + "fkCountryDisplayName", + "foCountryDisplayName", + "fjCountryDisplayName", + "fiCountryDisplayName", + "frCountryDisplayName", + "gfCountryDisplayName", + "pfCountryDisplayName", + "gaCountryDisplayName", + "gmCountryDisplayName", + "geCountryDisplayName", + "deCountryDisplayName", + "ghCountryDisplayName", + "giCountryDisplayName", + "grCountryDisplayName", + "glCountryDisplayName", + "gdCountryDisplayName", + "gpCountryDisplayName", + "guCountryDisplayName", + "gtCountryDisplayName", + "ggCountryDisplayName", + "gnCountryDisplayName", + "gwCountryDisplayName", + "gyCountryDisplayName", + "htCountryDisplayName", + "hmCountryDisplayName", + "hnCountryDisplayName", + "hkCountryDisplayName", + "huCountryDisplayName", + "isCountryDisplayName", + "inCountryDisplayName", + "idCountryDisplayName", + "irCountryDisplayName", + "iqCountryDisplayName", + "ieCountryDisplayName", + "imCountryDisplayName", + "ilCountryDisplayName", + "itCountryDisplayName", + "jmCountryDisplayName", + "jpCountryDisplayName", + "jeCountryDisplayName", + "joCountryDisplayName", + "kzCountryDisplayName", + "keCountryDisplayName", + "kiCountryDisplayName", + "xkCountryDisplayName", + "kwCountryDisplayName", + "kgCountryDisplayName", + "laCountryDisplayName", + "lvCountryDisplayName", + "lbCountryDisplayName", + "lsCountryDisplayName", + "lrCountryDisplayName", + "lyCountryDisplayName", + "liCountryDisplayName", + "ltCountryDisplayName", + "luCountryDisplayName", + "moCountryDisplayName", + "mkCountryDisplayName", + "mgCountryDisplayName", + "mwCountryDisplayName", + "myCountryDisplayName", + "mvCountryDisplayName", + "mlCountryDisplayName", + "mtCountryDisplayName", + "mhCountryDisplayName", + "mqCountryDisplayName", + "mrCountryDisplayName", + "muCountryDisplayName", + "ytCountryDisplayName", + "mxCountryDisplayName", + "fmCountryDisplayName", + "mdCountryDisplayName", + "mcCountryDisplayName", + "mnCountryDisplayName", + "meCountryDisplayName", + "msCountryDisplayName", + "maCountryDisplayName", + "mzCountryDisplayName", + "mmCountryDisplayName", + "naCountryDisplayName", + "nrCountryDisplayName", + "npCountryDisplayName", + "nlCountryDisplayName", + "ncCountryDisplayName", + "nzCountryDisplayName", + "niCountryDisplayName", + "neCountryDisplayName", + "ngCountryDisplayName", + "nuCountryDisplayName", + "nfCountryDisplayName", + "kpCountryDisplayName", + "mpCountryDisplayName", + "noCountryDisplayName", + "omCountryDisplayName", + "pkCountryDisplayName", + "pwCountryDisplayName", + "psCountryDisplayName", + "paCountryDisplayName", + "pgCountryDisplayName", + "pyCountryDisplayName", + "peCountryDisplayName", + "phCountryDisplayName", + "plCountryDisplayName", + "ptCountryDisplayName", + "prCountryDisplayName", + "qaCountryDisplayName", + "reCountryDisplayName", + "roCountryDisplayName", + "ruCountryDisplayName", + "rwCountryDisplayName", + "blCountryDisplayName", + "shCountryDisplayName", + "knCountryDisplayName", + "lcCountryDisplayName", + "mfCountryDisplayName", + "pmCountryDisplayName", + "vcCountryDisplayName", + "wsCountryDisplayName", + "smCountryDisplayName", + "stCountryDisplayName", + "saCountryDisplayName", + "snCountryDisplayName", + "rsCountryDisplayName", + "scCountryDisplayName", + "slCountryDisplayName", + "sgCountryDisplayName", + "sxCountryDisplayName", + "skCountryDisplayName", + "siCountryDisplayName", + "sbCountryDisplayName", + "soCountryDisplayName", + "zaCountryDisplayName", + "gsCountryDisplayName", + "krCountryDisplayName", + "ssCountryDisplayName", + "esCountryDisplayName", + "lkCountryDisplayName", + "sdCountryDisplayName", + "srCountryDisplayName", + "sjCountryDisplayName", + "seCountryDisplayName", + "chCountryDisplayName", + "syCountryDisplayName", + "twCountryDisplayName", + "tjCountryDisplayName", + "tzCountryDisplayName", + "thCountryDisplayName", + "tgCountryDisplayName", + "tkCountryDisplayName", + "toCountryDisplayName", + "ttCountryDisplayName", + "tnCountryDisplayName", + "trCountryDisplayName", + "tmCountryDisplayName", + "tcCountryDisplayName", + "tvCountryDisplayName", + "viCountryDisplayName", + "ugCountryDisplayName", + "uaCountryDisplayName", + "aeCountryDisplayName", + "gbCountryDisplayName", + "usCountryDisplayName", + "uyCountryDisplayName", + "uzCountryDisplayName", + "vuCountryDisplayName", + "vaCountryDisplayName", + "veCountryDisplayName", + "vnCountryDisplayName", + "wfCountryDisplayName", + "ehCountryDisplayName", + "yeCountryDisplayName", + "zmCountryDisplayName", + "zwCountryDisplayName", + "pay", + "allPrivateChats", + "unknownPrivateChat", + "copyClassCodeDesc", + "addToClassDesc", + "addToClassOrExchange", + "addToClassOrExchangeDesc", + "invitedToClassOrExchange", + "decline", + "declinedInvitation", + "acceptedInvitation", + "youreInvited", + "studentPermissionsDesc", + "noEligibleSpaces", + "youAddedToSpace", + "youRemovedFromSpace", + "invitedToChat", + "monthlySubscription", + "yearlySubscription", + "defaultSubscription", + "freeTrial", + "grammarAnalytics", + "total", + "noDataFound", + "promoSubscriptionExpirationDesc", + "emptyChatNameWarning", + "emptyClassNameWarning", + "emptyExchangeNameWarning", + "blurMeansTranslateTitle", + "blurMeansTranslateBody", + "someErrorTitle", + "someErrorBody", + "bestCorrectionFeedback", + "distractorFeedback", + "bestAnswerFeedback", + "definitionDefaultPrompt", + "practiceDefaultPrompt", + "correctionDefaultPrompt", + "itStartDefaultPrompt", + "languageLevelWarning", + "lockedChatWarning", + "lockSpace", + "lockChat", + "archiveSpace", + "suggestTo", + "suggestChatDesc", + "suggestExchangeDesc", + "acceptSelection", + "acceptSelectionAnyway", + "makingActivity", + "why", + "definition", + "exampleSentence", + "addToClassTitle", + "reportToTeacher", + "reportMessageTitle", + "reportMessageBody", + "noTeachersFound", + "noAddToSpacePermissions", + "alreadyInSpace", + "yourGlobalUserIdIs", + "noUsersFoundWithQuery", + "searchChatsRooms", + "groupName", + "createGroupAndInviteUsers", + "groupCanBeFoundViaSearch", + "inNoSpaces" + ], + + "pt_BR": [ + "accountInformation", + "addNewFriend", + "alreadyHaveAnAccount", + "classes", + "allCorrect", + "newWayAllGood", + "othersAreBetter", + "holdForInfo", + "greenFeedback", + "yellowFeedback", + "redFeedback", + "customInputFeedbackChoice", + "itInstructionsTitle", + "itInstructionsBody", + "toggleLanguages", + "classWelcomeChat", + "deleteSpace", + "deleteGroup", + "areYouSureDeleteClass", + "areYouSureDeleteGroup", + "cannotBeReversed", + "enterDeletedClassName", + "incorrectClassName", + "oneday", + "oneweek", + "onemonth", + "sixmonth", + "oneyear", + "gaTooltip", + "taTooltip", + "unTooltip", + "interactiveTranslatorSliderHeader", + "interactiveGrammarSliderHeader", + "interactiveTranslatorNotAllowed", + "interactiveTranslatorAllowed", + "interactiveTranslatorRequired", + "interactiveTranslatorNotAllowedDesc", + "interactiveTranslatorAllowedDesc", + "interactiveTranslatorRequiredDesc", + "notYetSet", + "multiLingualClass", + "classAnalytics", + "allClasses", + "myLearning", + "allChatsAndClasses", + "timeOfLastMessage", + "totalMessages", + "waTooltip", + "changeDateRange", + "numberOfStudents", + "classDescription", + "classDescriptionDesc", + "requestToEnroll", + "requestAnExchange", + "findLanguageExchange", + "classAnalyticsDesc", + "addStudents", + "copyClassLink", + "copyClassLinkDesc", + "copyClassCode", + "inviteStudentByUserName", + "classSettings", + "classSettingsDesc", + "selectClassRoomDominantLanguage", + "selectTargetLanguage", + "whatIsYourClassLanguageLevel", + "studentPermissions", + "interactiveTranslator", + "oneToOneChatsWithinClass", + "oneToOneChatsWithinClassDesc", + "createGroupChats", + "createGroupChatsDesc", + "shareVideo", + "shareVideoDesc", + "sharePhotos", + "sharePhotosDesc", + "shareFiles", + "shareFilesDesc", + "shareLocationDesc", + "selectLanguageLevel", + "noIdenticalLanguages", + "iWantALanguagePartnerFrom", + "worldWide", + "noResults", + "searchBy", + "iWantAConversationPartner", + "iWantALanguagePartnerWhoSpeaks", + "iWantALanguagePartnerWhoIsLearning", + "yourBirthdayPlease", + "invalidDob", + "enterYourDob", + "getStarted", + "mustBe13", + "yourBirthdayPleaseShort", + "errorPleaseRefresh", + "joinWithClassCode", + "joinWithClassCodeDesc", + "joinWithClassCodeHint", + "unableToFindClass", + "languageLevelPreA1", + "languageLevelA1", + "languageLevelA2", + "languageLevelB1", + "languageLevelB2", + "languageLevelC1", + "languageLevelC2", + "changeTheNameOfTheClass", + "changeTheNameOfTheChat", + "welcomeToYourNewClass", + "welcomeToClass", + "welcomeToPangea18Plus", + "welcomeToPangeaMinor", + "findALanguagePartner", + "setToPublicSettingsTitle", + "setToPublicSettingsDesc", + "accountSettings", + "unableToFindClassCode", + "askPangeaBot", + "sorryNoResults", + "ignoreInThisText", + "helpMeTranslate", + "needsItShortMessage", + "needsIGCShortMessage", + "needsItMessage", + "needsIgcMessage", + "tokenTranslationTitle", + "spanTranslationDesc", + "spanTranslationTitle", + "l1SpanAndGrammarTitle", + "l1SpanAndGrammarDesc", + "otherTitle", + "otherDesc", + "countryInformation", + "myLanguages", + "targetLanguage", + "sourceLanguage", + "languagesISpeak", + "updateLanguage", + "whatLanguageYouWantToLearn", + "whatIsYourBaseLanguage", + "saveChanges", + "publicProfileTitle", + "publicProfileDesc", + "error502504Title", + "error502504Desc", + "error404Title", + "error404Desc", + "errorDisableIT", + "errorDisableIGC", + "errorDisableLanguageAssistance", + "errorDisableITUserDesc", + "errorDisableIGCUserDesc", + "errorDisableLanguageAssistanceUserDesc", + "errorDisableITClassDesc", + "errorDisableIGCClassDesc", + "errorDisableLanguageAssistanceClassDesc", + "itIsDisabled", + "igcIsDisabled", + "goToLearningSettings", + "error405Title", + "error405Desc", + "loginOrSignup", + "iAgreeToThe", + "termsAndConditions", + "andCertifyIAmAtLeast13YearsOfAge", + "findAClass", + "toggleIT", + "toggleIGC", + "toggleToolSettingsDescription", + "connectedToStaging", + "learningSettings", + "classNameRequired", + "sendVoiceNotes", + "sendVoiceNotesDesc", + "chatTopic", + "chatTopicDesc", + "inviteStudentByUserNameDesc", + "classRoster", + "almostPerfect", + "prettyGood", + "letMeThink", + "clickMessageTitle", + "clickMessageBody", + "understandingMessagesTitle", + "addToClass", + "understandingMessagesBody", + "allDone", + "vocab", + "low", + "medium", + "high", + "unknownProficiency", + "changeView", + "clearAll", + "generateVocabulary", + "generatePrompts", + "subscribe", + "getAccess", + "subscriptionDesc", + "subscriptionManagement", + "currentSubscription", + "changeSubscription", + "cancelSubscription", + "selectYourPlan", + "subsciptionPlatformTooltip", + "subscriptionManagementUnavailable", + "paymentMethod", + "paymentHistory", + "emptyChatDownloadWarning", + "appUpdateAvailable", + "update", + "updateDesc", + "maybeLater", + "mainMenu", + "toggleImmersionMode", + "toggleImmersionModeDesc", + "itToggleDescription", + "igcToggleDescription", + "sendOnEnterDescription", + "alreadyInClass", + "pleaseLoginFirst", + "originalMessage", + "sentMessage", + "useType", + "notAvailable", + "taAndGaTooltip", + "definitionsToolName", + "messageTranslationsToolName", + "definitionsToolDescription", + "translationsToolDescrption", + "welcomeBack", + "classExchanges", + "createNewClass", + "newExchange", + "kickAllStudents", + "kickAllStudentsConfirmation", + "inviteAllStudents", + "inviteAllStudentsConfirmation", + "inviteStudentsFromOtherClasses", + "inviteUsersFromPangea", + "allExchanges", + "redeemPromoCode", + "enterPromoCode", + "downloadTxtFile", + "downloadCSVFile", + "promotionalSubscriptionDesc", + "originalSubscriptionPlatform", + "oneWeekTrial", + "creatingSpacePleaseWait", + "downloadXLSXFile", + "abDisplayName", + "aaDisplayName", + "afDisplayName", + "akDisplayName", + "sqDisplayName", + "amDisplayName", + "arDisplayName", + "anDisplayName", + "hyDisplayName", + "asDisplayName", + "avDisplayName", + "aeDisplayName", + "ayDisplayName", + "azDisplayName", + "bmDisplayName", + "baDisplayName", + "euDisplayName", + "beDisplayName", + "bnDisplayName", + "bhDisplayName", + "biDisplayName", + "bsDisplayName", + "brDisplayName", + "bgDisplayName", + "myDisplayName", + "caDisplayName", + "chDisplayName", + "ceDisplayName", + "nyDisplayName", + "zhDisplayName", + "cvDisplayName", + "kwDisplayName", + "coDisplayName", + "crDisplayName", + "hrDisplayName", + "csDisplayName", + "daDisplayName", + "dvDisplayName", + "nlDisplayName", + "enDisplayName", + "eoDisplayName", + "etDisplayName", + "eeDisplayName", + "foDisplayName", + "fjDisplayName", + "fiDisplayName", + "frDisplayName", + "ffDisplayName", + "glDisplayName", + "kaDisplayName", + "deDisplayName", + "elDisplayName", + "gnDisplayName", + "guDisplayName", + "htDisplayName", + "haDisplayName", + "heDisplayName", + "hzDisplayName", + "hiDisplayName", + "hoDisplayName", + "huDisplayName", + "iaDisplayName", + "idDisplayName", + "ieDisplayName", + "gaDisplayName", + "igDisplayName", + "ikDisplayName", + "ioDisplayName", + "isDisplayName", + "itDisplayName", + "iuDisplayName", + "jaDisplayName", + "jvDisplayName", + "klDisplayName", + "knDisplayName", + "krDisplayName", + "ksDisplayName", + "kkDisplayName", + "kmDisplayName", + "kiDisplayName", + "rwDisplayName", + "kyDisplayName", + "kvDisplayName", + "kgDisplayName", + "koDisplayName", + "kuDisplayName", + "kjDisplayName", + "laDisplayName", + "lbDisplayName", + "lgDisplayName", + "liDisplayName", + "lnDisplayName", + "loDisplayName", + "ltDisplayName", + "luDisplayName", + "lvDisplayName", + "gvDisplayName", + "mkDisplayName", + "mgDisplayName", + "msDisplayName", + "mlDisplayName", + "mtDisplayName", + "miDisplayName", + "mrDisplayName", + "mhDisplayName", + "mnDisplayName", + "naDisplayName", + "nvDisplayName", + "nbDisplayName", + "ndDisplayName", + "neDisplayName", + "ngDisplayName", + "nnDisplayName", + "noDisplayName", + "iiDisplayName", + "nrDisplayName", + "ocDisplayName", + "ojDisplayName", + "cuDisplayName", + "omDisplayName", + "orDisplayName", + "osDisplayName", + "paDisplayName", + "piDisplayName", + "faDisplayName", + "plDisplayName", + "psDisplayName", + "ptDisplayName", + "quDisplayName", + "rmDisplayName", + "rnDisplayName", + "roDisplayName", + "ruDisplayName", + "saDisplayName", + "scDisplayName", + "sdDisplayName", + "seDisplayName", + "smDisplayName", + "sgDisplayName", + "srDisplayName", + "gdDisplayName", + "snDisplayName", + "siDisplayName", + "skDisplayName", + "slDisplayName", + "soDisplayName", + "stDisplayName", + "esDisplayName", + "suDisplayName", + "swDisplayName", + "ssDisplayName", + "svDisplayName", + "taDisplayName", + "teDisplayName", + "tgDisplayName", + "thDisplayName", + "tiDisplayName", + "boDisplayName", + "tkDisplayName", + "tlDisplayName", + "tnDisplayName", + "toDisplayName", + "trDisplayName", + "tsDisplayName", + "ttDisplayName", + "twDisplayName", + "tyDisplayName", + "ugDisplayName", + "ukDisplayName", + "urDisplayName", + "uzDisplayName", + "veDisplayName", + "viDisplayName", + "voDisplayName", + "waDisplayName", + "cyDisplayName", + "woDisplayName", + "fyDisplayName", + "xhDisplayName", + "yiDisplayName", + "yoDisplayName", + "zaDisplayName", + "unkDisplayName", + "zuDisplayName", + "hawDisplayName", + "hmnDisplayName", + "multiDisplayName", + "cebDisplayName", + "dzDisplayName", + "iwDisplayName", + "jwDisplayName", + "moDisplayName", + "shDisplayName", + "wwCountryDisplayName", + "afCountryDisplayName", + "axCountryDisplayName", + "alCountryDisplayName", + "dzCountryDisplayName", + "asCountryDisplayName", + "adCountryDisplayName", + "aoCountryDisplayName", + "aiCountryDisplayName", + "agCountryDisplayName", + "arCountryDisplayName", + "amCountryDisplayName", + "awCountryDisplayName", + "acCountryDisplayName", + "auCountryDisplayName", + "atCountryDisplayName", + "azCountryDisplayName", + "bsCountryDisplayName", + "bhCountryDisplayName", + "bdCountryDisplayName", + "bbCountryDisplayName", + "byCountryDisplayName", + "beCountryDisplayName", + "bzCountryDisplayName", + "bjCountryDisplayName", + "bmCountryDisplayName", + "btCountryDisplayName", + "boCountryDisplayName", + "baCountryDisplayName", + "bwCountryDisplayName", + "brCountryDisplayName", + "ioCountryDisplayName", + "vgCountryDisplayName", + "bnCountryDisplayName", + "bgCountryDisplayName", + "bfCountryDisplayName", + "biCountryDisplayName", + "khCountryDisplayName", + "cmCountryDisplayName", + "caCountryDisplayName", + "cvCountryDisplayName", + "bqCountryDisplayName", + "kyCountryDisplayName", + "cfCountryDisplayName", + "tdCountryDisplayName", + "clCountryDisplayName", + "cnCountryDisplayName", + "cxCountryDisplayName", + "ccCountryDisplayName", + "coCountryDisplayName", + "kmCountryDisplayName", + "cdCountryDisplayName", + "cgCountryDisplayName", + "ckCountryDisplayName", + "crCountryDisplayName", + "ciCountryDisplayName", + "hrCountryDisplayName", + "cuCountryDisplayName", + "cwCountryDisplayName", + "cyCountryDisplayName", + "czCountryDisplayName", + "dkCountryDisplayName", + "djCountryDisplayName", + "dmCountryDisplayName", + "doCountryDisplayName", + "tlCountryDisplayName", + "ecCountryDisplayName", + "egCountryDisplayName", + "svCountryDisplayName", + "gqCountryDisplayName", + "erCountryDisplayName", + "eeCountryDisplayName", + "szCountryDisplayName", + "etCountryDisplayName", + "fkCountryDisplayName", + "foCountryDisplayName", + "fjCountryDisplayName", + "fiCountryDisplayName", + "frCountryDisplayName", + "gfCountryDisplayName", + "pfCountryDisplayName", + "gaCountryDisplayName", + "gmCountryDisplayName", + "geCountryDisplayName", + "deCountryDisplayName", + "ghCountryDisplayName", + "giCountryDisplayName", + "grCountryDisplayName", + "glCountryDisplayName", + "gdCountryDisplayName", + "gpCountryDisplayName", + "guCountryDisplayName", + "gtCountryDisplayName", + "ggCountryDisplayName", + "gnCountryDisplayName", + "gwCountryDisplayName", + "gyCountryDisplayName", + "htCountryDisplayName", + "hmCountryDisplayName", + "hnCountryDisplayName", + "hkCountryDisplayName", + "huCountryDisplayName", + "isCountryDisplayName", + "inCountryDisplayName", + "idCountryDisplayName", + "irCountryDisplayName", + "iqCountryDisplayName", + "ieCountryDisplayName", + "imCountryDisplayName", + "ilCountryDisplayName", + "itCountryDisplayName", + "jmCountryDisplayName", + "jpCountryDisplayName", + "jeCountryDisplayName", + "joCountryDisplayName", + "kzCountryDisplayName", + "keCountryDisplayName", + "kiCountryDisplayName", + "xkCountryDisplayName", + "kwCountryDisplayName", + "kgCountryDisplayName", + "laCountryDisplayName", + "lvCountryDisplayName", + "lbCountryDisplayName", + "lsCountryDisplayName", + "lrCountryDisplayName", + "lyCountryDisplayName", + "liCountryDisplayName", + "ltCountryDisplayName", + "luCountryDisplayName", + "moCountryDisplayName", + "mkCountryDisplayName", + "mgCountryDisplayName", + "mwCountryDisplayName", + "myCountryDisplayName", + "mvCountryDisplayName", + "mlCountryDisplayName", + "mtCountryDisplayName", + "mhCountryDisplayName", + "mqCountryDisplayName", + "mrCountryDisplayName", + "muCountryDisplayName", + "ytCountryDisplayName", + "mxCountryDisplayName", + "fmCountryDisplayName", + "mdCountryDisplayName", + "mcCountryDisplayName", + "mnCountryDisplayName", + "meCountryDisplayName", + "msCountryDisplayName", + "maCountryDisplayName", + "mzCountryDisplayName", + "mmCountryDisplayName", + "naCountryDisplayName", + "nrCountryDisplayName", + "npCountryDisplayName", + "nlCountryDisplayName", + "ncCountryDisplayName", + "nzCountryDisplayName", + "niCountryDisplayName", + "neCountryDisplayName", + "ngCountryDisplayName", + "nuCountryDisplayName", + "nfCountryDisplayName", + "kpCountryDisplayName", + "mpCountryDisplayName", + "noCountryDisplayName", + "omCountryDisplayName", + "pkCountryDisplayName", + "pwCountryDisplayName", + "psCountryDisplayName", + "paCountryDisplayName", + "pgCountryDisplayName", + "pyCountryDisplayName", + "peCountryDisplayName", + "phCountryDisplayName", + "plCountryDisplayName", + "ptCountryDisplayName", + "prCountryDisplayName", + "qaCountryDisplayName", + "reCountryDisplayName", + "roCountryDisplayName", + "ruCountryDisplayName", + "rwCountryDisplayName", + "blCountryDisplayName", + "shCountryDisplayName", + "knCountryDisplayName", + "lcCountryDisplayName", + "mfCountryDisplayName", + "pmCountryDisplayName", + "vcCountryDisplayName", + "wsCountryDisplayName", + "smCountryDisplayName", + "stCountryDisplayName", + "saCountryDisplayName", + "snCountryDisplayName", + "rsCountryDisplayName", + "scCountryDisplayName", + "slCountryDisplayName", + "sgCountryDisplayName", + "sxCountryDisplayName", + "skCountryDisplayName", + "siCountryDisplayName", + "sbCountryDisplayName", + "soCountryDisplayName", + "zaCountryDisplayName", + "gsCountryDisplayName", + "krCountryDisplayName", + "ssCountryDisplayName", + "esCountryDisplayName", + "lkCountryDisplayName", + "sdCountryDisplayName", + "srCountryDisplayName", + "sjCountryDisplayName", + "seCountryDisplayName", + "chCountryDisplayName", + "syCountryDisplayName", + "twCountryDisplayName", + "tjCountryDisplayName", + "tzCountryDisplayName", + "thCountryDisplayName", + "tgCountryDisplayName", + "tkCountryDisplayName", + "toCountryDisplayName", + "ttCountryDisplayName", + "tnCountryDisplayName", + "trCountryDisplayName", + "tmCountryDisplayName", + "tcCountryDisplayName", + "tvCountryDisplayName", + "viCountryDisplayName", + "ugCountryDisplayName", + "uaCountryDisplayName", + "aeCountryDisplayName", + "gbCountryDisplayName", + "usCountryDisplayName", + "uyCountryDisplayName", + "uzCountryDisplayName", + "vuCountryDisplayName", + "vaCountryDisplayName", + "veCountryDisplayName", + "vnCountryDisplayName", + "wfCountryDisplayName", + "ehCountryDisplayName", + "yeCountryDisplayName", + "zmCountryDisplayName", + "zwCountryDisplayName", + "pay", + "allPrivateChats", + "unknownPrivateChat", + "copyClassCodeDesc", + "addToClassDesc", + "addToClassOrExchange", + "addToClassOrExchangeDesc", + "invitedToClassOrExchange", + "decline", + "declinedInvitation", + "acceptedInvitation", + "youreInvited", + "studentPermissionsDesc", + "noEligibleSpaces", + "youAddedToSpace", + "youRemovedFromSpace", + "invitedToChat", + "monthlySubscription", + "yearlySubscription", + "defaultSubscription", + "freeTrial", + "grammarAnalytics", + "total", + "noDataFound", + "promoSubscriptionExpirationDesc", + "emptyChatNameWarning", + "emptyClassNameWarning", + "emptyExchangeNameWarning", + "blurMeansTranslateTitle", + "blurMeansTranslateBody", + "someErrorTitle", + "someErrorBody", + "bestCorrectionFeedback", + "distractorFeedback", + "bestAnswerFeedback", + "definitionDefaultPrompt", + "practiceDefaultPrompt", + "correctionDefaultPrompt", + "itStartDefaultPrompt", + "languageLevelWarning", + "lockedChatWarning", + "lockSpace", + "lockChat", + "archiveSpace", + "suggestTo", + "suggestChatDesc", + "suggestExchangeDesc", + "acceptSelection", + "acceptSelectionAnyway", + "makingActivity", + "why", + "definition", + "exampleSentence", + "addToClassTitle", + "reportToTeacher", + "reportMessageTitle", + "reportMessageBody", + "noTeachersFound", + "noAddToSpacePermissions", + "alreadyInSpace", + "yourGlobalUserIdIs", + "noUsersFoundWithQuery", + "searchChatsRooms", + "groupName", + "createGroupAndInviteUsers", + "groupCanBeFoundViaSearch", + "inNoSpaces" + ], + + "pt_PT": [ + "accountInformation", + "addNewFriend", + "alreadyHaveAnAccount", + "classes", + "allCorrect", + "newWayAllGood", + "othersAreBetter", + "holdForInfo", + "greenFeedback", + "yellowFeedback", + "redFeedback", + "customInputFeedbackChoice", + "itInstructionsTitle", + "itInstructionsBody", + "toggleLanguages", + "classWelcomeChat", + "deleteSpace", + "deleteGroup", + "areYouSureDeleteClass", + "areYouSureDeleteGroup", + "cannotBeReversed", + "enterDeletedClassName", + "incorrectClassName", + "oneday", + "oneweek", + "onemonth", + "sixmonth", + "oneyear", + "gaTooltip", + "taTooltip", + "unTooltip", + "interactiveTranslatorSliderHeader", + "interactiveGrammarSliderHeader", + "interactiveTranslatorNotAllowed", + "interactiveTranslatorAllowed", + "interactiveTranslatorRequired", + "interactiveTranslatorNotAllowedDesc", + "interactiveTranslatorAllowedDesc", + "interactiveTranslatorRequiredDesc", + "notYetSet", + "multiLingualClass", + "classAnalytics", + "allClasses", + "myLearning", + "allChatsAndClasses", + "timeOfLastMessage", + "totalMessages", + "waTooltip", + "changeDateRange", + "numberOfStudents", + "classDescription", + "classDescriptionDesc", + "requestToEnroll", + "requestAnExchange", + "findLanguageExchange", + "classAnalyticsDesc", + "addStudents", + "copyClassLink", + "copyClassLinkDesc", + "copyClassCode", + "inviteStudentByUserName", + "classSettings", + "classSettingsDesc", + "selectClassRoomDominantLanguage", + "selectTargetLanguage", + "whatIsYourClassLanguageLevel", + "studentPermissions", + "interactiveTranslator", + "oneToOneChatsWithinClass", + "oneToOneChatsWithinClassDesc", + "createGroupChats", + "createGroupChatsDesc", + "shareVideo", + "shareVideoDesc", + "sharePhotos", + "sharePhotosDesc", + "shareFiles", + "shareFilesDesc", + "shareLocationDesc", + "selectLanguageLevel", + "noIdenticalLanguages", + "iWantALanguagePartnerFrom", + "worldWide", + "noResults", + "searchBy", + "iWantAConversationPartner", + "iWantALanguagePartnerWhoSpeaks", + "iWantALanguagePartnerWhoIsLearning", + "yourBirthdayPlease", + "invalidDob", + "enterYourDob", + "getStarted", + "mustBe13", + "yourBirthdayPleaseShort", + "errorPleaseRefresh", + "joinWithClassCode", + "joinWithClassCodeDesc", + "joinWithClassCodeHint", + "unableToFindClass", + "languageLevelPreA1", + "languageLevelA1", + "languageLevelA2", + "languageLevelB1", + "languageLevelB2", + "languageLevelC1", + "languageLevelC2", + "changeTheNameOfTheClass", + "changeTheNameOfTheChat", + "welcomeToYourNewClass", + "welcomeToClass", + "welcomeToPangea18Plus", + "welcomeToPangeaMinor", + "findALanguagePartner", + "setToPublicSettingsTitle", + "setToPublicSettingsDesc", + "accountSettings", + "unableToFindClassCode", + "askPangeaBot", + "sorryNoResults", + "ignoreInThisText", + "helpMeTranslate", + "needsItShortMessage", + "needsIGCShortMessage", + "needsItMessage", + "needsIgcMessage", + "tokenTranslationTitle", + "spanTranslationDesc", + "spanTranslationTitle", + "l1SpanAndGrammarTitle", + "l1SpanAndGrammarDesc", + "otherTitle", + "otherDesc", + "countryInformation", + "myLanguages", + "targetLanguage", + "sourceLanguage", + "languagesISpeak", + "updateLanguage", + "whatLanguageYouWantToLearn", + "whatIsYourBaseLanguage", + "saveChanges", + "publicProfileTitle", + "publicProfileDesc", + "error502504Title", + "error502504Desc", + "error404Title", + "error404Desc", + "errorDisableIT", + "errorDisableIGC", + "errorDisableLanguageAssistance", + "errorDisableITUserDesc", + "errorDisableIGCUserDesc", + "errorDisableLanguageAssistanceUserDesc", + "errorDisableITClassDesc", + "errorDisableIGCClassDesc", + "errorDisableLanguageAssistanceClassDesc", + "itIsDisabled", + "igcIsDisabled", + "goToLearningSettings", + "error405Title", + "error405Desc", + "loginOrSignup", + "iAgreeToThe", + "termsAndConditions", + "andCertifyIAmAtLeast13YearsOfAge", + "findAClass", + "toggleIT", + "toggleIGC", + "toggleToolSettingsDescription", + "connectedToStaging", + "learningSettings", + "classNameRequired", + "sendVoiceNotes", + "sendVoiceNotesDesc", + "chatTopic", + "chatTopicDesc", + "inviteStudentByUserNameDesc", + "classRoster", + "almostPerfect", + "prettyGood", + "letMeThink", + "clickMessageTitle", + "clickMessageBody", + "understandingMessagesTitle", + "addToClass", + "understandingMessagesBody", + "allDone", + "vocab", + "low", + "medium", + "high", + "unknownProficiency", + "changeView", + "clearAll", + "generateVocabulary", + "generatePrompts", + "subscribe", + "getAccess", + "subscriptionDesc", + "subscriptionManagement", + "currentSubscription", + "changeSubscription", + "cancelSubscription", + "selectYourPlan", + "subsciptionPlatformTooltip", + "subscriptionManagementUnavailable", + "paymentMethod", + "paymentHistory", + "emptyChatDownloadWarning", + "appUpdateAvailable", + "update", + "updateDesc", + "maybeLater", + "mainMenu", + "toggleImmersionMode", + "toggleImmersionModeDesc", + "itToggleDescription", + "igcToggleDescription", + "sendOnEnterDescription", + "alreadyInClass", + "pleaseLoginFirst", + "originalMessage", + "sentMessage", + "useType", + "notAvailable", + "taAndGaTooltip", + "definitionsToolName", + "messageTranslationsToolName", + "definitionsToolDescription", + "translationsToolDescrption", + "welcomeBack", + "classExchanges", + "createNewClass", + "newExchange", + "kickAllStudents", + "kickAllStudentsConfirmation", + "inviteAllStudents", + "inviteAllStudentsConfirmation", + "inviteStudentsFromOtherClasses", + "inviteUsersFromPangea", + "allExchanges", + "redeemPromoCode", + "enterPromoCode", + "downloadTxtFile", + "downloadCSVFile", + "promotionalSubscriptionDesc", + "originalSubscriptionPlatform", + "oneWeekTrial", + "creatingSpacePleaseWait", + "downloadXLSXFile", + "abDisplayName", + "aaDisplayName", + "afDisplayName", + "akDisplayName", + "sqDisplayName", + "amDisplayName", + "arDisplayName", + "anDisplayName", + "hyDisplayName", + "asDisplayName", + "avDisplayName", + "aeDisplayName", + "ayDisplayName", + "azDisplayName", + "bmDisplayName", + "baDisplayName", + "euDisplayName", + "beDisplayName", + "bnDisplayName", + "bhDisplayName", + "biDisplayName", + "bsDisplayName", + "brDisplayName", + "bgDisplayName", + "myDisplayName", + "caDisplayName", + "chDisplayName", + "ceDisplayName", + "nyDisplayName", + "zhDisplayName", + "cvDisplayName", + "kwDisplayName", + "coDisplayName", + "crDisplayName", + "hrDisplayName", + "csDisplayName", + "daDisplayName", + "dvDisplayName", + "nlDisplayName", + "enDisplayName", + "eoDisplayName", + "etDisplayName", + "eeDisplayName", + "foDisplayName", + "fjDisplayName", + "fiDisplayName", + "frDisplayName", + "ffDisplayName", + "glDisplayName", + "kaDisplayName", + "deDisplayName", + "elDisplayName", + "gnDisplayName", + "guDisplayName", + "htDisplayName", + "haDisplayName", + "heDisplayName", + "hzDisplayName", + "hiDisplayName", + "hoDisplayName", + "huDisplayName", + "iaDisplayName", + "idDisplayName", + "ieDisplayName", + "gaDisplayName", + "igDisplayName", + "ikDisplayName", + "ioDisplayName", + "isDisplayName", + "itDisplayName", + "iuDisplayName", + "jaDisplayName", + "jvDisplayName", + "klDisplayName", + "knDisplayName", + "krDisplayName", + "ksDisplayName", + "kkDisplayName", + "kmDisplayName", + "kiDisplayName", + "rwDisplayName", + "kyDisplayName", + "kvDisplayName", + "kgDisplayName", + "koDisplayName", + "kuDisplayName", + "kjDisplayName", + "laDisplayName", + "lbDisplayName", + "lgDisplayName", + "liDisplayName", + "lnDisplayName", + "loDisplayName", + "ltDisplayName", + "luDisplayName", + "lvDisplayName", + "gvDisplayName", + "mkDisplayName", + "mgDisplayName", + "msDisplayName", + "mlDisplayName", + "mtDisplayName", + "miDisplayName", + "mrDisplayName", + "mhDisplayName", + "mnDisplayName", + "naDisplayName", + "nvDisplayName", + "nbDisplayName", + "ndDisplayName", + "neDisplayName", + "ngDisplayName", + "nnDisplayName", + "noDisplayName", + "iiDisplayName", + "nrDisplayName", + "ocDisplayName", + "ojDisplayName", + "cuDisplayName", + "omDisplayName", + "orDisplayName", + "osDisplayName", + "paDisplayName", + "piDisplayName", + "faDisplayName", + "plDisplayName", + "psDisplayName", + "ptDisplayName", + "quDisplayName", + "rmDisplayName", + "rnDisplayName", + "roDisplayName", + "ruDisplayName", + "saDisplayName", + "scDisplayName", + "sdDisplayName", + "seDisplayName", + "smDisplayName", + "sgDisplayName", + "srDisplayName", + "gdDisplayName", + "snDisplayName", + "siDisplayName", + "skDisplayName", + "slDisplayName", + "soDisplayName", + "stDisplayName", + "esDisplayName", + "suDisplayName", + "swDisplayName", + "ssDisplayName", + "svDisplayName", + "taDisplayName", + "teDisplayName", + "tgDisplayName", + "thDisplayName", + "tiDisplayName", + "boDisplayName", + "tkDisplayName", + "tlDisplayName", + "tnDisplayName", + "toDisplayName", + "trDisplayName", + "tsDisplayName", + "ttDisplayName", + "twDisplayName", + "tyDisplayName", + "ugDisplayName", + "ukDisplayName", + "urDisplayName", + "uzDisplayName", + "veDisplayName", + "viDisplayName", + "voDisplayName", + "waDisplayName", + "cyDisplayName", + "woDisplayName", + "fyDisplayName", + "xhDisplayName", + "yiDisplayName", + "yoDisplayName", + "zaDisplayName", + "unkDisplayName", + "zuDisplayName", + "hawDisplayName", + "hmnDisplayName", + "multiDisplayName", + "cebDisplayName", + "dzDisplayName", + "iwDisplayName", + "jwDisplayName", + "moDisplayName", + "shDisplayName", + "wwCountryDisplayName", + "afCountryDisplayName", + "axCountryDisplayName", + "alCountryDisplayName", + "dzCountryDisplayName", + "asCountryDisplayName", + "adCountryDisplayName", + "aoCountryDisplayName", + "aiCountryDisplayName", + "agCountryDisplayName", + "arCountryDisplayName", + "amCountryDisplayName", + "awCountryDisplayName", + "acCountryDisplayName", + "auCountryDisplayName", + "atCountryDisplayName", + "azCountryDisplayName", + "bsCountryDisplayName", + "bhCountryDisplayName", + "bdCountryDisplayName", + "bbCountryDisplayName", + "byCountryDisplayName", + "beCountryDisplayName", + "bzCountryDisplayName", + "bjCountryDisplayName", + "bmCountryDisplayName", + "btCountryDisplayName", + "boCountryDisplayName", + "baCountryDisplayName", + "bwCountryDisplayName", + "brCountryDisplayName", + "ioCountryDisplayName", + "vgCountryDisplayName", + "bnCountryDisplayName", + "bgCountryDisplayName", + "bfCountryDisplayName", + "biCountryDisplayName", + "khCountryDisplayName", + "cmCountryDisplayName", + "caCountryDisplayName", + "cvCountryDisplayName", + "bqCountryDisplayName", + "kyCountryDisplayName", + "cfCountryDisplayName", + "tdCountryDisplayName", + "clCountryDisplayName", + "cnCountryDisplayName", + "cxCountryDisplayName", + "ccCountryDisplayName", + "coCountryDisplayName", + "kmCountryDisplayName", + "cdCountryDisplayName", + "cgCountryDisplayName", + "ckCountryDisplayName", + "crCountryDisplayName", + "ciCountryDisplayName", + "hrCountryDisplayName", + "cuCountryDisplayName", + "cwCountryDisplayName", + "cyCountryDisplayName", + "czCountryDisplayName", + "dkCountryDisplayName", + "djCountryDisplayName", + "dmCountryDisplayName", + "doCountryDisplayName", + "tlCountryDisplayName", + "ecCountryDisplayName", + "egCountryDisplayName", + "svCountryDisplayName", + "gqCountryDisplayName", + "erCountryDisplayName", + "eeCountryDisplayName", + "szCountryDisplayName", + "etCountryDisplayName", + "fkCountryDisplayName", + "foCountryDisplayName", + "fjCountryDisplayName", + "fiCountryDisplayName", + "frCountryDisplayName", + "gfCountryDisplayName", + "pfCountryDisplayName", + "gaCountryDisplayName", + "gmCountryDisplayName", + "geCountryDisplayName", + "deCountryDisplayName", + "ghCountryDisplayName", + "giCountryDisplayName", + "grCountryDisplayName", + "glCountryDisplayName", + "gdCountryDisplayName", + "gpCountryDisplayName", + "guCountryDisplayName", + "gtCountryDisplayName", + "ggCountryDisplayName", + "gnCountryDisplayName", + "gwCountryDisplayName", + "gyCountryDisplayName", + "htCountryDisplayName", + "hmCountryDisplayName", + "hnCountryDisplayName", + "hkCountryDisplayName", + "huCountryDisplayName", + "isCountryDisplayName", + "inCountryDisplayName", + "idCountryDisplayName", + "irCountryDisplayName", + "iqCountryDisplayName", + "ieCountryDisplayName", + "imCountryDisplayName", + "ilCountryDisplayName", + "itCountryDisplayName", + "jmCountryDisplayName", + "jpCountryDisplayName", + "jeCountryDisplayName", + "joCountryDisplayName", + "kzCountryDisplayName", + "keCountryDisplayName", + "kiCountryDisplayName", + "xkCountryDisplayName", + "kwCountryDisplayName", + "kgCountryDisplayName", + "laCountryDisplayName", + "lvCountryDisplayName", + "lbCountryDisplayName", + "lsCountryDisplayName", + "lrCountryDisplayName", + "lyCountryDisplayName", + "liCountryDisplayName", + "ltCountryDisplayName", + "luCountryDisplayName", + "moCountryDisplayName", + "mkCountryDisplayName", + "mgCountryDisplayName", + "mwCountryDisplayName", + "myCountryDisplayName", + "mvCountryDisplayName", + "mlCountryDisplayName", + "mtCountryDisplayName", + "mhCountryDisplayName", + "mqCountryDisplayName", + "mrCountryDisplayName", + "muCountryDisplayName", + "ytCountryDisplayName", + "mxCountryDisplayName", + "fmCountryDisplayName", + "mdCountryDisplayName", + "mcCountryDisplayName", + "mnCountryDisplayName", + "meCountryDisplayName", + "msCountryDisplayName", + "maCountryDisplayName", + "mzCountryDisplayName", + "mmCountryDisplayName", + "naCountryDisplayName", + "nrCountryDisplayName", + "npCountryDisplayName", + "nlCountryDisplayName", + "ncCountryDisplayName", + "nzCountryDisplayName", + "niCountryDisplayName", + "neCountryDisplayName", + "ngCountryDisplayName", + "nuCountryDisplayName", + "nfCountryDisplayName", + "kpCountryDisplayName", + "mpCountryDisplayName", + "noCountryDisplayName", + "omCountryDisplayName", + "pkCountryDisplayName", + "pwCountryDisplayName", + "psCountryDisplayName", + "paCountryDisplayName", + "pgCountryDisplayName", + "pyCountryDisplayName", + "peCountryDisplayName", + "phCountryDisplayName", + "plCountryDisplayName", + "ptCountryDisplayName", + "prCountryDisplayName", + "qaCountryDisplayName", + "reCountryDisplayName", + "roCountryDisplayName", + "ruCountryDisplayName", + "rwCountryDisplayName", + "blCountryDisplayName", + "shCountryDisplayName", + "knCountryDisplayName", + "lcCountryDisplayName", + "mfCountryDisplayName", + "pmCountryDisplayName", + "vcCountryDisplayName", + "wsCountryDisplayName", + "smCountryDisplayName", + "stCountryDisplayName", + "saCountryDisplayName", + "snCountryDisplayName", + "rsCountryDisplayName", + "scCountryDisplayName", + "slCountryDisplayName", + "sgCountryDisplayName", + "sxCountryDisplayName", + "skCountryDisplayName", + "siCountryDisplayName", + "sbCountryDisplayName", + "soCountryDisplayName", + "zaCountryDisplayName", + "gsCountryDisplayName", + "krCountryDisplayName", + "ssCountryDisplayName", + "esCountryDisplayName", + "lkCountryDisplayName", + "sdCountryDisplayName", + "srCountryDisplayName", + "sjCountryDisplayName", + "seCountryDisplayName", + "chCountryDisplayName", + "syCountryDisplayName", + "twCountryDisplayName", + "tjCountryDisplayName", + "tzCountryDisplayName", + "thCountryDisplayName", + "tgCountryDisplayName", + "tkCountryDisplayName", + "toCountryDisplayName", + "ttCountryDisplayName", + "tnCountryDisplayName", + "trCountryDisplayName", + "tmCountryDisplayName", + "tcCountryDisplayName", + "tvCountryDisplayName", + "viCountryDisplayName", + "ugCountryDisplayName", + "uaCountryDisplayName", + "aeCountryDisplayName", + "gbCountryDisplayName", + "usCountryDisplayName", + "uyCountryDisplayName", + "uzCountryDisplayName", + "vuCountryDisplayName", + "vaCountryDisplayName", + "veCountryDisplayName", + "vnCountryDisplayName", + "wfCountryDisplayName", + "ehCountryDisplayName", + "yeCountryDisplayName", + "zmCountryDisplayName", + "zwCountryDisplayName", + "pay", + "allPrivateChats", + "unknownPrivateChat", + "copyClassCodeDesc", + "addToClassDesc", + "addToClassOrExchange", + "addToClassOrExchangeDesc", + "invitedToClassOrExchange", + "decline", + "declinedInvitation", + "acceptedInvitation", + "youreInvited", + "studentPermissionsDesc", + "noEligibleSpaces", + "youAddedToSpace", + "youRemovedFromSpace", + "invitedToChat", + "monthlySubscription", + "yearlySubscription", + "defaultSubscription", + "freeTrial", + "grammarAnalytics", + "total", + "noDataFound", + "promoSubscriptionExpirationDesc", + "emptyChatNameWarning", + "emptyClassNameWarning", + "emptyExchangeNameWarning", + "blurMeansTranslateTitle", + "blurMeansTranslateBody", + "someErrorTitle", + "someErrorBody", + "bestCorrectionFeedback", + "distractorFeedback", + "bestAnswerFeedback", + "definitionDefaultPrompt", + "practiceDefaultPrompt", + "correctionDefaultPrompt", + "itStartDefaultPrompt", + "languageLevelWarning", + "lockedChatWarning", + "lockSpace", + "lockChat", + "archiveSpace", + "suggestTo", + "suggestChatDesc", + "suggestExchangeDesc", + "acceptSelection", + "acceptSelectionAnyway", + "makingActivity", + "why", + "definition", + "exampleSentence", + "addToClassTitle", + "reportToTeacher", + "reportMessageTitle", + "reportMessageBody", + "noTeachersFound", + "noAddToSpacePermissions", + "alreadyInSpace", + "yourGlobalUserIdIs", + "noUsersFoundWithQuery", + "searchChatsRooms", + "groupName", + "createGroupAndInviteUsers", + "groupCanBeFoundViaSearch", + "inNoSpaces" + ], + + "ro": [ + "accountInformation", + "addNewFriend", + "alreadyHaveAnAccount", + "classes", + "allCorrect", + "newWayAllGood", + "othersAreBetter", + "holdForInfo", + "greenFeedback", + "yellowFeedback", + "redFeedback", + "customInputFeedbackChoice", + "itInstructionsTitle", + "itInstructionsBody", + "toggleLanguages", + "classWelcomeChat", + "deleteSpace", + "deleteGroup", + "areYouSureDeleteClass", + "areYouSureDeleteGroup", + "cannotBeReversed", + "enterDeletedClassName", + "incorrectClassName", + "oneday", + "oneweek", + "onemonth", + "sixmonth", + "oneyear", + "gaTooltip", + "taTooltip", + "unTooltip", + "interactiveTranslatorSliderHeader", + "interactiveGrammarSliderHeader", + "interactiveTranslatorNotAllowed", + "interactiveTranslatorAllowed", + "interactiveTranslatorRequired", + "interactiveTranslatorNotAllowedDesc", + "interactiveTranslatorAllowedDesc", + "interactiveTranslatorRequiredDesc", + "notYetSet", + "multiLingualClass", + "classAnalytics", + "allClasses", + "myLearning", + "allChatsAndClasses", + "timeOfLastMessage", + "totalMessages", + "waTooltip", + "changeDateRange", + "numberOfStudents", + "classDescription", + "classDescriptionDesc", + "requestToEnroll", + "requestAnExchange", + "findLanguageExchange", + "classAnalyticsDesc", + "addStudents", + "copyClassLink", + "copyClassLinkDesc", + "copyClassCode", + "inviteStudentByUserName", + "classSettings", + "classSettingsDesc", + "selectClassRoomDominantLanguage", + "selectTargetLanguage", + "whatIsYourClassLanguageLevel", + "studentPermissions", + "interactiveTranslator", + "oneToOneChatsWithinClass", + "oneToOneChatsWithinClassDesc", + "createGroupChats", + "createGroupChatsDesc", + "shareVideo", + "shareVideoDesc", + "sharePhotos", + "sharePhotosDesc", + "shareFiles", + "shareFilesDesc", + "shareLocationDesc", + "selectLanguageLevel", + "noIdenticalLanguages", + "iWantALanguagePartnerFrom", + "worldWide", + "noResults", + "searchBy", + "iWantAConversationPartner", + "iWantALanguagePartnerWhoSpeaks", + "iWantALanguagePartnerWhoIsLearning", + "yourBirthdayPlease", + "invalidDob", + "enterYourDob", + "getStarted", + "mustBe13", + "yourBirthdayPleaseShort", + "errorPleaseRefresh", + "joinWithClassCode", + "joinWithClassCodeDesc", + "joinWithClassCodeHint", + "unableToFindClass", + "languageLevelPreA1", + "languageLevelA1", + "languageLevelA2", + "languageLevelB1", + "languageLevelB2", + "languageLevelC1", + "languageLevelC2", + "changeTheNameOfTheClass", + "changeTheNameOfTheChat", + "welcomeToYourNewClass", + "welcomeToClass", + "welcomeToPangea18Plus", + "welcomeToPangeaMinor", + "findALanguagePartner", + "setToPublicSettingsTitle", + "setToPublicSettingsDesc", + "accountSettings", + "unableToFindClassCode", + "askPangeaBot", + "sorryNoResults", + "ignoreInThisText", + "helpMeTranslate", + "needsItShortMessage", + "needsIGCShortMessage", + "needsItMessage", + "needsIgcMessage", + "tokenTranslationTitle", + "spanTranslationDesc", + "spanTranslationTitle", + "l1SpanAndGrammarTitle", + "l1SpanAndGrammarDesc", + "otherTitle", + "otherDesc", + "countryInformation", + "myLanguages", + "targetLanguage", + "sourceLanguage", + "languagesISpeak", + "updateLanguage", + "whatLanguageYouWantToLearn", + "whatIsYourBaseLanguage", + "saveChanges", + "publicProfileTitle", + "publicProfileDesc", + "error502504Title", + "error502504Desc", + "error404Title", + "error404Desc", + "errorDisableIT", + "errorDisableIGC", + "errorDisableLanguageAssistance", + "errorDisableITUserDesc", + "errorDisableIGCUserDesc", + "errorDisableLanguageAssistanceUserDesc", + "errorDisableITClassDesc", + "errorDisableIGCClassDesc", + "errorDisableLanguageAssistanceClassDesc", + "itIsDisabled", + "igcIsDisabled", + "goToLearningSettings", + "error405Title", + "error405Desc", + "loginOrSignup", + "iAgreeToThe", + "termsAndConditions", + "andCertifyIAmAtLeast13YearsOfAge", + "findAClass", + "toggleIT", + "toggleIGC", + "toggleToolSettingsDescription", + "connectedToStaging", + "learningSettings", + "classNameRequired", + "sendVoiceNotes", + "sendVoiceNotesDesc", + "chatTopic", + "chatTopicDesc", + "inviteStudentByUserNameDesc", + "classRoster", + "almostPerfect", + "prettyGood", + "letMeThink", + "clickMessageTitle", + "clickMessageBody", + "understandingMessagesTitle", + "addToClass", + "understandingMessagesBody", + "allDone", + "vocab", + "low", + "medium", + "high", + "unknownProficiency", + "changeView", + "clearAll", + "generateVocabulary", + "generatePrompts", + "subscribe", + "getAccess", + "subscriptionDesc", + "subscriptionManagement", + "currentSubscription", + "changeSubscription", + "cancelSubscription", + "selectYourPlan", + "subsciptionPlatformTooltip", + "subscriptionManagementUnavailable", + "paymentMethod", + "paymentHistory", + "emptyChatDownloadWarning", + "appUpdateAvailable", + "update", + "updateDesc", + "maybeLater", + "mainMenu", + "toggleImmersionMode", + "toggleImmersionModeDesc", + "itToggleDescription", + "igcToggleDescription", + "sendOnEnterDescription", + "alreadyInClass", + "pleaseLoginFirst", + "originalMessage", + "sentMessage", + "useType", + "notAvailable", + "taAndGaTooltip", + "definitionsToolName", + "messageTranslationsToolName", + "definitionsToolDescription", + "translationsToolDescrption", + "welcomeBack", + "classExchanges", + "createNewClass", + "newExchange", + "kickAllStudents", + "kickAllStudentsConfirmation", + "inviteAllStudents", + "inviteAllStudentsConfirmation", + "inviteStudentsFromOtherClasses", + "inviteUsersFromPangea", + "allExchanges", + "redeemPromoCode", + "enterPromoCode", + "downloadTxtFile", + "downloadCSVFile", + "promotionalSubscriptionDesc", + "originalSubscriptionPlatform", + "oneWeekTrial", + "creatingSpacePleaseWait", + "downloadXLSXFile", + "abDisplayName", + "aaDisplayName", + "afDisplayName", + "akDisplayName", + "sqDisplayName", + "amDisplayName", + "arDisplayName", + "anDisplayName", + "hyDisplayName", + "asDisplayName", + "avDisplayName", + "aeDisplayName", + "ayDisplayName", + "azDisplayName", + "bmDisplayName", + "baDisplayName", + "euDisplayName", + "beDisplayName", + "bnDisplayName", + "bhDisplayName", + "biDisplayName", + "bsDisplayName", + "brDisplayName", + "bgDisplayName", + "myDisplayName", + "caDisplayName", + "chDisplayName", + "ceDisplayName", + "nyDisplayName", + "zhDisplayName", + "cvDisplayName", + "kwDisplayName", + "coDisplayName", + "crDisplayName", + "hrDisplayName", + "csDisplayName", + "daDisplayName", + "dvDisplayName", + "nlDisplayName", + "enDisplayName", + "eoDisplayName", + "etDisplayName", + "eeDisplayName", + "foDisplayName", + "fjDisplayName", + "fiDisplayName", + "frDisplayName", + "ffDisplayName", + "glDisplayName", + "kaDisplayName", + "deDisplayName", + "elDisplayName", + "gnDisplayName", + "guDisplayName", + "htDisplayName", + "haDisplayName", + "heDisplayName", + "hzDisplayName", + "hiDisplayName", + "hoDisplayName", + "huDisplayName", + "iaDisplayName", + "idDisplayName", + "ieDisplayName", + "gaDisplayName", + "igDisplayName", + "ikDisplayName", + "ioDisplayName", + "isDisplayName", + "itDisplayName", + "iuDisplayName", + "jaDisplayName", + "jvDisplayName", + "klDisplayName", + "knDisplayName", + "krDisplayName", + "ksDisplayName", + "kkDisplayName", + "kmDisplayName", + "kiDisplayName", + "rwDisplayName", + "kyDisplayName", + "kvDisplayName", + "kgDisplayName", + "koDisplayName", + "kuDisplayName", + "kjDisplayName", + "laDisplayName", + "lbDisplayName", + "lgDisplayName", + "liDisplayName", + "lnDisplayName", + "loDisplayName", + "ltDisplayName", + "luDisplayName", + "lvDisplayName", + "gvDisplayName", + "mkDisplayName", + "mgDisplayName", + "msDisplayName", + "mlDisplayName", + "mtDisplayName", + "miDisplayName", + "mrDisplayName", + "mhDisplayName", + "mnDisplayName", + "naDisplayName", + "nvDisplayName", + "nbDisplayName", + "ndDisplayName", + "neDisplayName", + "ngDisplayName", + "nnDisplayName", + "noDisplayName", + "iiDisplayName", + "nrDisplayName", + "ocDisplayName", + "ojDisplayName", + "cuDisplayName", + "omDisplayName", + "orDisplayName", + "osDisplayName", + "paDisplayName", + "piDisplayName", + "faDisplayName", + "plDisplayName", + "psDisplayName", + "ptDisplayName", + "quDisplayName", + "rmDisplayName", + "rnDisplayName", + "roDisplayName", + "ruDisplayName", + "saDisplayName", + "scDisplayName", + "sdDisplayName", + "seDisplayName", + "smDisplayName", + "sgDisplayName", + "srDisplayName", + "gdDisplayName", + "snDisplayName", + "siDisplayName", + "skDisplayName", + "slDisplayName", + "soDisplayName", + "stDisplayName", + "esDisplayName", + "suDisplayName", + "swDisplayName", + "ssDisplayName", + "svDisplayName", + "taDisplayName", + "teDisplayName", + "tgDisplayName", + "thDisplayName", + "tiDisplayName", + "boDisplayName", + "tkDisplayName", + "tlDisplayName", + "tnDisplayName", + "toDisplayName", + "trDisplayName", + "tsDisplayName", + "ttDisplayName", + "twDisplayName", + "tyDisplayName", + "ugDisplayName", + "ukDisplayName", + "urDisplayName", + "uzDisplayName", + "veDisplayName", + "viDisplayName", + "voDisplayName", + "waDisplayName", + "cyDisplayName", + "woDisplayName", + "fyDisplayName", + "xhDisplayName", + "yiDisplayName", + "yoDisplayName", + "zaDisplayName", + "unkDisplayName", + "zuDisplayName", + "hawDisplayName", + "hmnDisplayName", + "multiDisplayName", + "cebDisplayName", + "dzDisplayName", + "iwDisplayName", + "jwDisplayName", + "moDisplayName", + "shDisplayName", + "wwCountryDisplayName", + "afCountryDisplayName", + "axCountryDisplayName", + "alCountryDisplayName", + "dzCountryDisplayName", + "asCountryDisplayName", + "adCountryDisplayName", + "aoCountryDisplayName", + "aiCountryDisplayName", + "agCountryDisplayName", + "arCountryDisplayName", + "amCountryDisplayName", + "awCountryDisplayName", + "acCountryDisplayName", + "auCountryDisplayName", + "atCountryDisplayName", + "azCountryDisplayName", + "bsCountryDisplayName", + "bhCountryDisplayName", + "bdCountryDisplayName", + "bbCountryDisplayName", + "byCountryDisplayName", + "beCountryDisplayName", + "bzCountryDisplayName", + "bjCountryDisplayName", + "bmCountryDisplayName", + "btCountryDisplayName", + "boCountryDisplayName", + "baCountryDisplayName", + "bwCountryDisplayName", + "brCountryDisplayName", + "ioCountryDisplayName", + "vgCountryDisplayName", + "bnCountryDisplayName", + "bgCountryDisplayName", + "bfCountryDisplayName", + "biCountryDisplayName", + "khCountryDisplayName", + "cmCountryDisplayName", + "caCountryDisplayName", + "cvCountryDisplayName", + "bqCountryDisplayName", + "kyCountryDisplayName", + "cfCountryDisplayName", + "tdCountryDisplayName", + "clCountryDisplayName", + "cnCountryDisplayName", + "cxCountryDisplayName", + "ccCountryDisplayName", + "coCountryDisplayName", + "kmCountryDisplayName", + "cdCountryDisplayName", + "cgCountryDisplayName", + "ckCountryDisplayName", + "crCountryDisplayName", + "ciCountryDisplayName", + "hrCountryDisplayName", + "cuCountryDisplayName", + "cwCountryDisplayName", + "cyCountryDisplayName", + "czCountryDisplayName", + "dkCountryDisplayName", + "djCountryDisplayName", + "dmCountryDisplayName", + "doCountryDisplayName", + "tlCountryDisplayName", + "ecCountryDisplayName", + "egCountryDisplayName", + "svCountryDisplayName", + "gqCountryDisplayName", + "erCountryDisplayName", + "eeCountryDisplayName", + "szCountryDisplayName", + "etCountryDisplayName", + "fkCountryDisplayName", + "foCountryDisplayName", + "fjCountryDisplayName", + "fiCountryDisplayName", + "frCountryDisplayName", + "gfCountryDisplayName", + "pfCountryDisplayName", + "gaCountryDisplayName", + "gmCountryDisplayName", + "geCountryDisplayName", + "deCountryDisplayName", + "ghCountryDisplayName", + "giCountryDisplayName", + "grCountryDisplayName", + "glCountryDisplayName", + "gdCountryDisplayName", + "gpCountryDisplayName", + "guCountryDisplayName", + "gtCountryDisplayName", + "ggCountryDisplayName", + "gnCountryDisplayName", + "gwCountryDisplayName", + "gyCountryDisplayName", + "htCountryDisplayName", + "hmCountryDisplayName", + "hnCountryDisplayName", + "hkCountryDisplayName", + "huCountryDisplayName", + "isCountryDisplayName", + "inCountryDisplayName", + "idCountryDisplayName", + "irCountryDisplayName", + "iqCountryDisplayName", + "ieCountryDisplayName", + "imCountryDisplayName", + "ilCountryDisplayName", + "itCountryDisplayName", + "jmCountryDisplayName", + "jpCountryDisplayName", + "jeCountryDisplayName", + "joCountryDisplayName", + "kzCountryDisplayName", + "keCountryDisplayName", + "kiCountryDisplayName", + "xkCountryDisplayName", + "kwCountryDisplayName", + "kgCountryDisplayName", + "laCountryDisplayName", + "lvCountryDisplayName", + "lbCountryDisplayName", + "lsCountryDisplayName", + "lrCountryDisplayName", + "lyCountryDisplayName", + "liCountryDisplayName", + "ltCountryDisplayName", + "luCountryDisplayName", + "moCountryDisplayName", + "mkCountryDisplayName", + "mgCountryDisplayName", + "mwCountryDisplayName", + "myCountryDisplayName", + "mvCountryDisplayName", + "mlCountryDisplayName", + "mtCountryDisplayName", + "mhCountryDisplayName", + "mqCountryDisplayName", + "mrCountryDisplayName", + "muCountryDisplayName", + "ytCountryDisplayName", + "mxCountryDisplayName", + "fmCountryDisplayName", + "mdCountryDisplayName", + "mcCountryDisplayName", + "mnCountryDisplayName", + "meCountryDisplayName", + "msCountryDisplayName", + "maCountryDisplayName", + "mzCountryDisplayName", + "mmCountryDisplayName", + "naCountryDisplayName", + "nrCountryDisplayName", + "npCountryDisplayName", + "nlCountryDisplayName", + "ncCountryDisplayName", + "nzCountryDisplayName", + "niCountryDisplayName", + "neCountryDisplayName", + "ngCountryDisplayName", + "nuCountryDisplayName", + "nfCountryDisplayName", + "kpCountryDisplayName", + "mpCountryDisplayName", + "noCountryDisplayName", + "omCountryDisplayName", + "pkCountryDisplayName", + "pwCountryDisplayName", + "psCountryDisplayName", + "paCountryDisplayName", + "pgCountryDisplayName", + "pyCountryDisplayName", + "peCountryDisplayName", + "phCountryDisplayName", + "plCountryDisplayName", + "ptCountryDisplayName", + "prCountryDisplayName", + "qaCountryDisplayName", + "reCountryDisplayName", + "roCountryDisplayName", + "ruCountryDisplayName", + "rwCountryDisplayName", + "blCountryDisplayName", + "shCountryDisplayName", + "knCountryDisplayName", + "lcCountryDisplayName", + "mfCountryDisplayName", + "pmCountryDisplayName", + "vcCountryDisplayName", + "wsCountryDisplayName", + "smCountryDisplayName", + "stCountryDisplayName", + "saCountryDisplayName", + "snCountryDisplayName", + "rsCountryDisplayName", + "scCountryDisplayName", + "slCountryDisplayName", + "sgCountryDisplayName", + "sxCountryDisplayName", + "skCountryDisplayName", + "siCountryDisplayName", + "sbCountryDisplayName", + "soCountryDisplayName", + "zaCountryDisplayName", + "gsCountryDisplayName", + "krCountryDisplayName", + "ssCountryDisplayName", + "esCountryDisplayName", + "lkCountryDisplayName", + "sdCountryDisplayName", + "srCountryDisplayName", + "sjCountryDisplayName", + "seCountryDisplayName", + "chCountryDisplayName", + "syCountryDisplayName", + "twCountryDisplayName", + "tjCountryDisplayName", + "tzCountryDisplayName", + "thCountryDisplayName", + "tgCountryDisplayName", + "tkCountryDisplayName", + "toCountryDisplayName", + "ttCountryDisplayName", + "tnCountryDisplayName", + "trCountryDisplayName", + "tmCountryDisplayName", + "tcCountryDisplayName", + "tvCountryDisplayName", + "viCountryDisplayName", + "ugCountryDisplayName", + "uaCountryDisplayName", + "aeCountryDisplayName", + "gbCountryDisplayName", + "usCountryDisplayName", + "uyCountryDisplayName", + "uzCountryDisplayName", + "vuCountryDisplayName", + "vaCountryDisplayName", + "veCountryDisplayName", + "vnCountryDisplayName", + "wfCountryDisplayName", + "ehCountryDisplayName", + "yeCountryDisplayName", + "zmCountryDisplayName", + "zwCountryDisplayName", + "pay", + "allPrivateChats", + "unknownPrivateChat", + "copyClassCodeDesc", + "addToClassDesc", + "addToClassOrExchange", + "addToClassOrExchangeDesc", + "invitedToClassOrExchange", + "decline", + "declinedInvitation", + "acceptedInvitation", + "youreInvited", + "studentPermissionsDesc", + "noEligibleSpaces", + "youAddedToSpace", + "youRemovedFromSpace", + "invitedToChat", + "monthlySubscription", + "yearlySubscription", + "defaultSubscription", + "freeTrial", + "grammarAnalytics", + "total", + "noDataFound", + "promoSubscriptionExpirationDesc", + "emptyChatNameWarning", + "emptyClassNameWarning", + "emptyExchangeNameWarning", + "blurMeansTranslateTitle", + "blurMeansTranslateBody", + "someErrorTitle", + "someErrorBody", + "bestCorrectionFeedback", + "distractorFeedback", + "bestAnswerFeedback", + "definitionDefaultPrompt", + "practiceDefaultPrompt", + "correctionDefaultPrompt", + "itStartDefaultPrompt", + "languageLevelWarning", + "lockedChatWarning", + "lockSpace", + "lockChat", + "archiveSpace", + "suggestTo", + "suggestChatDesc", + "suggestExchangeDesc", + "acceptSelection", + "acceptSelectionAnyway", + "makingActivity", + "why", + "definition", + "exampleSentence", + "addToClassTitle", + "reportToTeacher", + "reportMessageTitle", + "reportMessageBody", + "noTeachersFound", + "noAddToSpacePermissions", + "alreadyInSpace", + "yourGlobalUserIdIs", + "noUsersFoundWithQuery", + "searchChatsRooms", + "groupName", + "createGroupAndInviteUsers", + "groupCanBeFoundViaSearch", + "inNoSpaces" + ], + + "ru": [ + "accountInformation", + "addNewFriend", + "alreadyHaveAnAccount", + "classes", + "allCorrect", + "newWayAllGood", + "othersAreBetter", + "holdForInfo", + "greenFeedback", + "yellowFeedback", + "redFeedback", + "customInputFeedbackChoice", + "itInstructionsTitle", + "itInstructionsBody", + "toggleLanguages", + "classWelcomeChat", + "deleteSpace", + "deleteGroup", + "areYouSureDeleteClass", + "areYouSureDeleteGroup", + "cannotBeReversed", + "enterDeletedClassName", + "incorrectClassName", + "oneday", + "oneweek", + "onemonth", + "sixmonth", + "oneyear", + "gaTooltip", + "taTooltip", + "unTooltip", + "interactiveTranslatorSliderHeader", + "interactiveGrammarSliderHeader", + "interactiveTranslatorNotAllowed", + "interactiveTranslatorAllowed", + "interactiveTranslatorRequired", + "interactiveTranslatorNotAllowedDesc", + "interactiveTranslatorAllowedDesc", + "interactiveTranslatorRequiredDesc", + "notYetSet", + "multiLingualClass", + "classAnalytics", + "allClasses", + "myLearning", + "allChatsAndClasses", + "timeOfLastMessage", + "totalMessages", + "waTooltip", + "changeDateRange", + "numberOfStudents", + "classDescription", + "classDescriptionDesc", + "requestToEnroll", + "requestAnExchange", + "findLanguageExchange", + "classAnalyticsDesc", + "addStudents", + "copyClassLink", + "copyClassLinkDesc", + "copyClassCode", + "inviteStudentByUserName", + "classSettings", + "classSettingsDesc", + "selectClassRoomDominantLanguage", + "selectTargetLanguage", + "whatIsYourClassLanguageLevel", + "studentPermissions", + "interactiveTranslator", + "oneToOneChatsWithinClass", + "oneToOneChatsWithinClassDesc", + "createGroupChats", + "createGroupChatsDesc", + "shareVideo", + "shareVideoDesc", + "sharePhotos", + "sharePhotosDesc", + "shareFiles", + "shareFilesDesc", + "shareLocationDesc", + "selectLanguageLevel", + "noIdenticalLanguages", + "iWantALanguagePartnerFrom", + "worldWide", + "noResults", + "searchBy", + "iWantAConversationPartner", + "iWantALanguagePartnerWhoSpeaks", + "iWantALanguagePartnerWhoIsLearning", + "yourBirthdayPlease", + "invalidDob", + "enterYourDob", + "getStarted", + "mustBe13", + "yourBirthdayPleaseShort", + "errorPleaseRefresh", + "joinWithClassCode", + "joinWithClassCodeDesc", + "joinWithClassCodeHint", + "unableToFindClass", + "languageLevelPreA1", + "languageLevelA1", + "languageLevelA2", + "languageLevelB1", + "languageLevelB2", + "languageLevelC1", + "languageLevelC2", + "changeTheNameOfTheClass", + "changeTheNameOfTheChat", + "welcomeToYourNewClass", + "welcomeToClass", + "welcomeToPangea18Plus", + "welcomeToPangeaMinor", + "findALanguagePartner", + "setToPublicSettingsTitle", + "setToPublicSettingsDesc", + "accountSettings", + "unableToFindClassCode", + "askPangeaBot", + "sorryNoResults", + "ignoreInThisText", + "helpMeTranslate", + "needsItShortMessage", + "needsIGCShortMessage", + "needsItMessage", + "needsIgcMessage", + "tokenTranslationTitle", + "spanTranslationDesc", + "spanTranslationTitle", + "l1SpanAndGrammarTitle", + "l1SpanAndGrammarDesc", + "otherTitle", + "otherDesc", + "countryInformation", + "myLanguages", + "targetLanguage", + "sourceLanguage", + "languagesISpeak", + "updateLanguage", + "whatLanguageYouWantToLearn", + "whatIsYourBaseLanguage", + "saveChanges", + "publicProfileTitle", + "publicProfileDesc", + "error502504Title", + "error502504Desc", + "error404Title", + "error404Desc", + "errorDisableIT", + "errorDisableIGC", + "errorDisableLanguageAssistance", + "errorDisableITUserDesc", + "errorDisableIGCUserDesc", + "errorDisableLanguageAssistanceUserDesc", + "errorDisableITClassDesc", + "errorDisableIGCClassDesc", + "errorDisableLanguageAssistanceClassDesc", + "itIsDisabled", + "igcIsDisabled", + "goToLearningSettings", + "error405Title", + "error405Desc", + "loginOrSignup", + "iAgreeToThe", + "termsAndConditions", + "andCertifyIAmAtLeast13YearsOfAge", + "findAClass", + "toggleIT", + "toggleIGC", + "toggleToolSettingsDescription", + "connectedToStaging", + "learningSettings", + "classNameRequired", + "sendVoiceNotes", + "sendVoiceNotesDesc", + "chatTopic", + "chatTopicDesc", + "inviteStudentByUserNameDesc", + "classRoster", + "almostPerfect", + "prettyGood", + "letMeThink", + "clickMessageTitle", + "clickMessageBody", + "understandingMessagesTitle", + "addToClass", + "understandingMessagesBody", + "allDone", + "vocab", + "low", + "medium", + "high", + "unknownProficiency", + "changeView", + "clearAll", + "generateVocabulary", + "generatePrompts", + "subscribe", + "getAccess", + "subscriptionDesc", + "subscriptionManagement", + "currentSubscription", + "changeSubscription", + "cancelSubscription", + "selectYourPlan", + "subsciptionPlatformTooltip", + "subscriptionManagementUnavailable", + "paymentMethod", + "paymentHistory", + "emptyChatDownloadWarning", + "appUpdateAvailable", + "update", + "updateDesc", + "maybeLater", + "mainMenu", + "toggleImmersionMode", + "toggleImmersionModeDesc", + "itToggleDescription", + "igcToggleDescription", + "sendOnEnterDescription", + "alreadyInClass", + "pleaseLoginFirst", + "originalMessage", + "sentMessage", + "useType", + "notAvailable", + "taAndGaTooltip", + "definitionsToolName", + "messageTranslationsToolName", + "definitionsToolDescription", + "translationsToolDescrption", + "welcomeBack", + "classExchanges", + "createNewClass", + "newExchange", + "kickAllStudents", + "kickAllStudentsConfirmation", + "inviteAllStudents", + "inviteAllStudentsConfirmation", + "inviteStudentsFromOtherClasses", + "inviteUsersFromPangea", + "allExchanges", + "redeemPromoCode", + "enterPromoCode", + "downloadTxtFile", + "downloadCSVFile", + "promotionalSubscriptionDesc", + "originalSubscriptionPlatform", + "oneWeekTrial", + "creatingSpacePleaseWait", + "downloadXLSXFile", + "abDisplayName", + "aaDisplayName", + "afDisplayName", + "akDisplayName", + "sqDisplayName", + "amDisplayName", + "arDisplayName", + "anDisplayName", + "hyDisplayName", + "asDisplayName", + "avDisplayName", + "aeDisplayName", + "ayDisplayName", + "azDisplayName", + "bmDisplayName", + "baDisplayName", + "euDisplayName", + "beDisplayName", + "bnDisplayName", + "bhDisplayName", + "biDisplayName", + "bsDisplayName", + "brDisplayName", + "bgDisplayName", + "myDisplayName", + "caDisplayName", + "chDisplayName", + "ceDisplayName", + "nyDisplayName", + "zhDisplayName", + "cvDisplayName", + "kwDisplayName", + "coDisplayName", + "crDisplayName", + "hrDisplayName", + "csDisplayName", + "daDisplayName", + "dvDisplayName", + "nlDisplayName", + "enDisplayName", + "eoDisplayName", + "etDisplayName", + "eeDisplayName", + "foDisplayName", + "fjDisplayName", + "fiDisplayName", + "frDisplayName", + "ffDisplayName", + "glDisplayName", + "kaDisplayName", + "deDisplayName", + "elDisplayName", + "gnDisplayName", + "guDisplayName", + "htDisplayName", + "haDisplayName", + "heDisplayName", + "hzDisplayName", + "hiDisplayName", + "hoDisplayName", + "huDisplayName", + "iaDisplayName", + "idDisplayName", + "ieDisplayName", + "gaDisplayName", + "igDisplayName", + "ikDisplayName", + "ioDisplayName", + "isDisplayName", + "itDisplayName", + "iuDisplayName", + "jaDisplayName", + "jvDisplayName", + "klDisplayName", + "knDisplayName", + "krDisplayName", + "ksDisplayName", + "kkDisplayName", + "kmDisplayName", + "kiDisplayName", + "rwDisplayName", + "kyDisplayName", + "kvDisplayName", + "kgDisplayName", + "koDisplayName", + "kuDisplayName", + "kjDisplayName", + "laDisplayName", + "lbDisplayName", + "lgDisplayName", + "liDisplayName", + "lnDisplayName", + "loDisplayName", + "ltDisplayName", + "luDisplayName", + "lvDisplayName", + "gvDisplayName", + "mkDisplayName", + "mgDisplayName", + "msDisplayName", + "mlDisplayName", + "mtDisplayName", + "miDisplayName", + "mrDisplayName", + "mhDisplayName", + "mnDisplayName", + "naDisplayName", + "nvDisplayName", + "nbDisplayName", + "ndDisplayName", + "neDisplayName", + "ngDisplayName", + "nnDisplayName", + "noDisplayName", + "iiDisplayName", + "nrDisplayName", + "ocDisplayName", + "ojDisplayName", + "cuDisplayName", + "omDisplayName", + "orDisplayName", + "osDisplayName", + "paDisplayName", + "piDisplayName", + "faDisplayName", + "plDisplayName", + "psDisplayName", + "ptDisplayName", + "quDisplayName", + "rmDisplayName", + "rnDisplayName", + "roDisplayName", + "ruDisplayName", + "saDisplayName", + "scDisplayName", + "sdDisplayName", + "seDisplayName", + "smDisplayName", + "sgDisplayName", + "srDisplayName", + "gdDisplayName", + "snDisplayName", + "siDisplayName", + "skDisplayName", + "slDisplayName", + "soDisplayName", + "stDisplayName", + "esDisplayName", + "suDisplayName", + "swDisplayName", + "ssDisplayName", + "svDisplayName", + "taDisplayName", + "teDisplayName", + "tgDisplayName", + "thDisplayName", + "tiDisplayName", + "boDisplayName", + "tkDisplayName", + "tlDisplayName", + "tnDisplayName", + "toDisplayName", + "trDisplayName", + "tsDisplayName", + "ttDisplayName", + "twDisplayName", + "tyDisplayName", + "ugDisplayName", + "ukDisplayName", + "urDisplayName", + "uzDisplayName", + "veDisplayName", + "viDisplayName", + "voDisplayName", + "waDisplayName", + "cyDisplayName", + "woDisplayName", + "fyDisplayName", + "xhDisplayName", + "yiDisplayName", + "yoDisplayName", + "zaDisplayName", + "unkDisplayName", + "zuDisplayName", + "hawDisplayName", + "hmnDisplayName", + "multiDisplayName", + "cebDisplayName", + "dzDisplayName", + "iwDisplayName", + "jwDisplayName", + "moDisplayName", + "shDisplayName", + "wwCountryDisplayName", + "afCountryDisplayName", + "axCountryDisplayName", + "alCountryDisplayName", + "dzCountryDisplayName", + "asCountryDisplayName", + "adCountryDisplayName", + "aoCountryDisplayName", + "aiCountryDisplayName", + "agCountryDisplayName", + "arCountryDisplayName", + "amCountryDisplayName", + "awCountryDisplayName", + "acCountryDisplayName", + "auCountryDisplayName", + "atCountryDisplayName", + "azCountryDisplayName", + "bsCountryDisplayName", + "bhCountryDisplayName", + "bdCountryDisplayName", + "bbCountryDisplayName", + "byCountryDisplayName", + "beCountryDisplayName", + "bzCountryDisplayName", + "bjCountryDisplayName", + "bmCountryDisplayName", + "btCountryDisplayName", + "boCountryDisplayName", + "baCountryDisplayName", + "bwCountryDisplayName", + "brCountryDisplayName", + "ioCountryDisplayName", + "vgCountryDisplayName", + "bnCountryDisplayName", + "bgCountryDisplayName", + "bfCountryDisplayName", + "biCountryDisplayName", + "khCountryDisplayName", + "cmCountryDisplayName", + "caCountryDisplayName", + "cvCountryDisplayName", + "bqCountryDisplayName", + "kyCountryDisplayName", + "cfCountryDisplayName", + "tdCountryDisplayName", + "clCountryDisplayName", + "cnCountryDisplayName", + "cxCountryDisplayName", + "ccCountryDisplayName", + "coCountryDisplayName", + "kmCountryDisplayName", + "cdCountryDisplayName", + "cgCountryDisplayName", + "ckCountryDisplayName", + "crCountryDisplayName", + "ciCountryDisplayName", + "hrCountryDisplayName", + "cuCountryDisplayName", + "cwCountryDisplayName", + "cyCountryDisplayName", + "czCountryDisplayName", + "dkCountryDisplayName", + "djCountryDisplayName", + "dmCountryDisplayName", + "doCountryDisplayName", + "tlCountryDisplayName", + "ecCountryDisplayName", + "egCountryDisplayName", + "svCountryDisplayName", + "gqCountryDisplayName", + "erCountryDisplayName", + "eeCountryDisplayName", + "szCountryDisplayName", + "etCountryDisplayName", + "fkCountryDisplayName", + "foCountryDisplayName", + "fjCountryDisplayName", + "fiCountryDisplayName", + "frCountryDisplayName", + "gfCountryDisplayName", + "pfCountryDisplayName", + "gaCountryDisplayName", + "gmCountryDisplayName", + "geCountryDisplayName", + "deCountryDisplayName", + "ghCountryDisplayName", + "giCountryDisplayName", + "grCountryDisplayName", + "glCountryDisplayName", + "gdCountryDisplayName", + "gpCountryDisplayName", + "guCountryDisplayName", + "gtCountryDisplayName", + "ggCountryDisplayName", + "gnCountryDisplayName", + "gwCountryDisplayName", + "gyCountryDisplayName", + "htCountryDisplayName", + "hmCountryDisplayName", + "hnCountryDisplayName", + "hkCountryDisplayName", + "huCountryDisplayName", + "isCountryDisplayName", + "inCountryDisplayName", + "idCountryDisplayName", + "irCountryDisplayName", + "iqCountryDisplayName", + "ieCountryDisplayName", + "imCountryDisplayName", + "ilCountryDisplayName", + "itCountryDisplayName", + "jmCountryDisplayName", + "jpCountryDisplayName", + "jeCountryDisplayName", + "joCountryDisplayName", + "kzCountryDisplayName", + "keCountryDisplayName", + "kiCountryDisplayName", + "xkCountryDisplayName", + "kwCountryDisplayName", + "kgCountryDisplayName", + "laCountryDisplayName", + "lvCountryDisplayName", + "lbCountryDisplayName", + "lsCountryDisplayName", + "lrCountryDisplayName", + "lyCountryDisplayName", + "liCountryDisplayName", + "ltCountryDisplayName", + "luCountryDisplayName", + "moCountryDisplayName", + "mkCountryDisplayName", + "mgCountryDisplayName", + "mwCountryDisplayName", + "myCountryDisplayName", + "mvCountryDisplayName", + "mlCountryDisplayName", + "mtCountryDisplayName", + "mhCountryDisplayName", + "mqCountryDisplayName", + "mrCountryDisplayName", + "muCountryDisplayName", + "ytCountryDisplayName", + "mxCountryDisplayName", + "fmCountryDisplayName", + "mdCountryDisplayName", + "mcCountryDisplayName", + "mnCountryDisplayName", + "meCountryDisplayName", + "msCountryDisplayName", + "maCountryDisplayName", + "mzCountryDisplayName", + "mmCountryDisplayName", + "naCountryDisplayName", + "nrCountryDisplayName", + "npCountryDisplayName", + "nlCountryDisplayName", + "ncCountryDisplayName", + "nzCountryDisplayName", + "niCountryDisplayName", + "neCountryDisplayName", + "ngCountryDisplayName", + "nuCountryDisplayName", + "nfCountryDisplayName", + "kpCountryDisplayName", + "mpCountryDisplayName", + "noCountryDisplayName", + "omCountryDisplayName", + "pkCountryDisplayName", + "pwCountryDisplayName", + "psCountryDisplayName", + "paCountryDisplayName", + "pgCountryDisplayName", + "pyCountryDisplayName", + "peCountryDisplayName", + "phCountryDisplayName", + "plCountryDisplayName", + "ptCountryDisplayName", + "prCountryDisplayName", + "qaCountryDisplayName", + "reCountryDisplayName", + "roCountryDisplayName", + "ruCountryDisplayName", + "rwCountryDisplayName", + "blCountryDisplayName", + "shCountryDisplayName", + "knCountryDisplayName", + "lcCountryDisplayName", + "mfCountryDisplayName", + "pmCountryDisplayName", + "vcCountryDisplayName", + "wsCountryDisplayName", + "smCountryDisplayName", + "stCountryDisplayName", + "saCountryDisplayName", + "snCountryDisplayName", + "rsCountryDisplayName", + "scCountryDisplayName", + "slCountryDisplayName", + "sgCountryDisplayName", + "sxCountryDisplayName", + "skCountryDisplayName", + "siCountryDisplayName", + "sbCountryDisplayName", + "soCountryDisplayName", + "zaCountryDisplayName", + "gsCountryDisplayName", + "krCountryDisplayName", + "ssCountryDisplayName", + "esCountryDisplayName", + "lkCountryDisplayName", + "sdCountryDisplayName", + "srCountryDisplayName", + "sjCountryDisplayName", + "seCountryDisplayName", + "chCountryDisplayName", + "syCountryDisplayName", + "twCountryDisplayName", + "tjCountryDisplayName", + "tzCountryDisplayName", + "thCountryDisplayName", + "tgCountryDisplayName", + "tkCountryDisplayName", + "toCountryDisplayName", + "ttCountryDisplayName", + "tnCountryDisplayName", + "trCountryDisplayName", + "tmCountryDisplayName", + "tcCountryDisplayName", + "tvCountryDisplayName", + "viCountryDisplayName", + "ugCountryDisplayName", + "uaCountryDisplayName", + "aeCountryDisplayName", + "gbCountryDisplayName", + "usCountryDisplayName", + "uyCountryDisplayName", + "uzCountryDisplayName", + "vuCountryDisplayName", + "vaCountryDisplayName", + "veCountryDisplayName", + "vnCountryDisplayName", + "wfCountryDisplayName", + "ehCountryDisplayName", + "yeCountryDisplayName", + "zmCountryDisplayName", + "zwCountryDisplayName", + "pay", + "allPrivateChats", + "unknownPrivateChat", + "copyClassCodeDesc", + "addToClassDesc", + "addToClassOrExchange", + "addToClassOrExchangeDesc", + "invitedToClassOrExchange", + "decline", + "declinedInvitation", + "acceptedInvitation", + "youreInvited", + "studentPermissionsDesc", + "noEligibleSpaces", + "youAddedToSpace", + "youRemovedFromSpace", + "invitedToChat", + "monthlySubscription", + "yearlySubscription", + "defaultSubscription", + "freeTrial", + "grammarAnalytics", + "total", + "noDataFound", + "promoSubscriptionExpirationDesc", + "emptyChatNameWarning", + "emptyClassNameWarning", + "emptyExchangeNameWarning", + "blurMeansTranslateTitle", + "blurMeansTranslateBody", + "someErrorTitle", + "someErrorBody", + "bestCorrectionFeedback", + "distractorFeedback", + "bestAnswerFeedback", + "definitionDefaultPrompt", + "practiceDefaultPrompt", + "correctionDefaultPrompt", + "itStartDefaultPrompt", + "languageLevelWarning", + "lockedChatWarning", + "lockSpace", + "lockChat", + "archiveSpace", + "suggestTo", + "suggestChatDesc", + "suggestExchangeDesc", + "acceptSelection", + "acceptSelectionAnyway", + "makingActivity", + "why", + "definition", + "exampleSentence", + "addToClassTitle", + "reportToTeacher", + "reportMessageTitle", + "reportMessageBody", + "noTeachersFound", + "noAddToSpacePermissions", + "alreadyInSpace", + "yourGlobalUserIdIs", + "noUsersFoundWithQuery", + "searchChatsRooms", + "groupName", + "createGroupAndInviteUsers", + "groupCanBeFoundViaSearch", + "inNoSpaces" + ], + + "sk": [ + "accountInformation", + "addNewFriend", + "alreadyHaveAnAccount", + "classes", + "editChatPermissions", + "allCorrect", + "newWayAllGood", + "othersAreBetter", + "holdForInfo", + "greenFeedback", + "yellowFeedback", + "redFeedback", + "customInputFeedbackChoice", + "itInstructionsTitle", + "itInstructionsBody", + "toggleLanguages", + "classWelcomeChat", + "deleteSpace", + "deleteGroup", + "areYouSureDeleteClass", + "areYouSureDeleteGroup", + "cannotBeReversed", + "enterDeletedClassName", + "incorrectClassName", + "oneday", + "oneweek", + "onemonth", + "sixmonth", + "oneyear", + "gaTooltip", + "taTooltip", + "unTooltip", + "interactiveTranslatorSliderHeader", + "interactiveGrammarSliderHeader", + "interactiveTranslatorNotAllowed", + "interactiveTranslatorAllowed", + "interactiveTranslatorRequired", + "interactiveTranslatorNotAllowedDesc", + "interactiveTranslatorAllowedDesc", + "interactiveTranslatorRequiredDesc", + "notYetSet", + "multiLingualClass", + "classAnalytics", + "allClasses", + "myLearning", + "allChatsAndClasses", + "timeOfLastMessage", + "totalMessages", + "waTooltip", + "changeDateRange", + "numberOfStudents", + "classDescription", + "classDescriptionDesc", + "requestToEnroll", + "requestAnExchange", + "findLanguageExchange", + "classAnalyticsDesc", + "addStudents", + "copyClassLink", + "copyClassLinkDesc", + "copyClassCode", + "inviteStudentByUserName", + "classSettings", + "classSettingsDesc", + "selectClassRoomDominantLanguage", + "selectTargetLanguage", + "whatIsYourClassLanguageLevel", + "studentPermissions", + "interactiveTranslator", + "oneToOneChatsWithinClass", + "oneToOneChatsWithinClassDesc", + "createGroupChats", + "createGroupChatsDesc", + "shareVideo", + "shareVideoDesc", + "sharePhotos", + "sharePhotosDesc", + "shareFiles", + "shareFilesDesc", + "shareLocationDesc", + "selectLanguageLevel", + "noIdenticalLanguages", + "iWantALanguagePartnerFrom", + "worldWide", + "noResults", + "searchBy", + "iWantAConversationPartner", + "iWantALanguagePartnerWhoSpeaks", + "iWantALanguagePartnerWhoIsLearning", + "yourBirthdayPlease", + "invalidDob", + "enterYourDob", + "getStarted", + "mustBe13", + "yourBirthdayPleaseShort", + "errorPleaseRefresh", + "joinWithClassCode", + "joinWithClassCodeDesc", + "joinWithClassCodeHint", + "unableToFindClass", + "languageLevelPreA1", + "languageLevelA1", + "languageLevelA2", + "languageLevelB1", + "languageLevelB2", + "languageLevelC1", + "languageLevelC2", + "changeTheNameOfTheClass", + "changeTheNameOfTheChat", + "welcomeToYourNewClass", + "welcomeToClass", + "welcomeToPangea18Plus", + "welcomeToPangeaMinor", + "findALanguagePartner", + "setToPublicSettingsTitle", + "setToPublicSettingsDesc", + "accountSettings", + "unableToFindClassCode", + "askPangeaBot", + "sorryNoResults", + "ignoreInThisText", + "helpMeTranslate", + "needsItShortMessage", + "needsIGCShortMessage", + "needsItMessage", + "needsIgcMessage", + "tokenTranslationTitle", + "spanTranslationDesc", + "spanTranslationTitle", + "l1SpanAndGrammarTitle", + "l1SpanAndGrammarDesc", + "otherTitle", + "otherDesc", + "countryInformation", + "myLanguages", + "targetLanguage", + "sourceLanguage", + "languagesISpeak", + "updateLanguage", + "whatLanguageYouWantToLearn", + "whatIsYourBaseLanguage", + "saveChanges", + "publicProfileTitle", + "publicProfileDesc", + "error502504Title", + "error502504Desc", + "error404Title", + "error404Desc", + "errorDisableIT", + "errorDisableIGC", + "errorDisableLanguageAssistance", + "errorDisableITUserDesc", + "errorDisableIGCUserDesc", + "errorDisableLanguageAssistanceUserDesc", + "errorDisableITClassDesc", + "errorDisableIGCClassDesc", + "errorDisableLanguageAssistanceClassDesc", + "itIsDisabled", + "igcIsDisabled", + "goToLearningSettings", + "error405Title", + "error405Desc", + "loginOrSignup", + "iAgreeToThe", + "termsAndConditions", + "andCertifyIAmAtLeast13YearsOfAge", + "findAClass", + "toggleIT", + "toggleIGC", + "toggleToolSettingsDescription", + "connectedToStaging", + "learningSettings", + "classNameRequired", + "sendVoiceNotes", + "sendVoiceNotesDesc", + "chatTopic", + "chatTopicDesc", + "inviteStudentByUserNameDesc", + "classRoster", + "almostPerfect", + "prettyGood", + "letMeThink", + "clickMessageTitle", + "clickMessageBody", + "understandingMessagesTitle", + "addToClass", + "understandingMessagesBody", + "allDone", + "vocab", + "low", + "medium", + "high", + "unknownProficiency", + "changeView", + "clearAll", + "generateVocabulary", + "generatePrompts", + "subscribe", + "getAccess", + "subscriptionDesc", + "subscriptionManagement", + "currentSubscription", + "changeSubscription", + "cancelSubscription", + "selectYourPlan", + "subsciptionPlatformTooltip", + "subscriptionManagementUnavailable", + "paymentMethod", + "paymentHistory", + "emptyChatDownloadWarning", + "appUpdateAvailable", + "update", + "updateDesc", + "maybeLater", + "mainMenu", + "toggleImmersionMode", + "toggleImmersionModeDesc", + "itToggleDescription", + "igcToggleDescription", + "sendOnEnterDescription", + "alreadyInClass", + "pleaseLoginFirst", + "originalMessage", + "sentMessage", + "useType", + "notAvailable", + "taAndGaTooltip", + "definitionsToolName", + "messageTranslationsToolName", + "definitionsToolDescription", + "translationsToolDescrption", + "welcomeBack", + "classExchanges", + "createNewClass", + "newExchange", + "kickAllStudents", + "kickAllStudentsConfirmation", + "inviteAllStudents", + "inviteAllStudentsConfirmation", + "inviteStudentsFromOtherClasses", + "inviteUsersFromPangea", + "allExchanges", + "redeemPromoCode", + "enterPromoCode", + "downloadTxtFile", + "downloadCSVFile", + "promotionalSubscriptionDesc", + "originalSubscriptionPlatform", + "oneWeekTrial", + "creatingSpacePleaseWait", + "downloadXLSXFile", + "abDisplayName", + "aaDisplayName", + "afDisplayName", + "akDisplayName", + "sqDisplayName", + "amDisplayName", + "arDisplayName", + "anDisplayName", + "hyDisplayName", + "asDisplayName", + "avDisplayName", + "aeDisplayName", + "ayDisplayName", + "azDisplayName", + "bmDisplayName", + "baDisplayName", + "euDisplayName", + "beDisplayName", + "bnDisplayName", + "bhDisplayName", + "biDisplayName", + "bsDisplayName", + "brDisplayName", + "bgDisplayName", + "myDisplayName", + "caDisplayName", + "chDisplayName", + "ceDisplayName", + "nyDisplayName", + "zhDisplayName", + "cvDisplayName", + "kwDisplayName", + "coDisplayName", + "crDisplayName", + "hrDisplayName", + "csDisplayName", + "daDisplayName", + "dvDisplayName", + "nlDisplayName", + "enDisplayName", + "eoDisplayName", + "etDisplayName", + "eeDisplayName", + "foDisplayName", + "fjDisplayName", + "fiDisplayName", + "frDisplayName", + "ffDisplayName", + "glDisplayName", + "kaDisplayName", + "deDisplayName", + "elDisplayName", + "gnDisplayName", + "guDisplayName", + "htDisplayName", + "haDisplayName", + "heDisplayName", + "hzDisplayName", + "hiDisplayName", + "hoDisplayName", + "huDisplayName", + "iaDisplayName", + "idDisplayName", + "ieDisplayName", + "gaDisplayName", + "igDisplayName", + "ikDisplayName", + "ioDisplayName", + "isDisplayName", + "itDisplayName", + "iuDisplayName", + "jaDisplayName", + "jvDisplayName", + "klDisplayName", + "knDisplayName", + "krDisplayName", + "ksDisplayName", + "kkDisplayName", + "kmDisplayName", + "kiDisplayName", + "rwDisplayName", + "kyDisplayName", + "kvDisplayName", + "kgDisplayName", + "koDisplayName", + "kuDisplayName", + "kjDisplayName", + "laDisplayName", + "lbDisplayName", + "lgDisplayName", + "liDisplayName", + "lnDisplayName", + "loDisplayName", + "ltDisplayName", + "luDisplayName", + "lvDisplayName", + "gvDisplayName", + "mkDisplayName", + "mgDisplayName", + "msDisplayName", + "mlDisplayName", + "mtDisplayName", + "miDisplayName", + "mrDisplayName", + "mhDisplayName", + "mnDisplayName", + "naDisplayName", + "nvDisplayName", + "nbDisplayName", + "ndDisplayName", + "neDisplayName", + "ngDisplayName", + "nnDisplayName", + "noDisplayName", + "iiDisplayName", + "nrDisplayName", + "ocDisplayName", + "ojDisplayName", + "cuDisplayName", + "omDisplayName", + "orDisplayName", + "osDisplayName", + "paDisplayName", + "piDisplayName", + "faDisplayName", + "plDisplayName", + "psDisplayName", + "ptDisplayName", + "quDisplayName", + "rmDisplayName", + "rnDisplayName", + "roDisplayName", + "ruDisplayName", + "saDisplayName", + "scDisplayName", + "sdDisplayName", + "seDisplayName", + "smDisplayName", + "sgDisplayName", + "srDisplayName", + "gdDisplayName", + "snDisplayName", + "siDisplayName", + "skDisplayName", + "slDisplayName", + "soDisplayName", + "stDisplayName", + "esDisplayName", + "suDisplayName", + "swDisplayName", + "ssDisplayName", + "svDisplayName", + "taDisplayName", + "teDisplayName", + "tgDisplayName", + "thDisplayName", + "tiDisplayName", + "boDisplayName", + "tkDisplayName", + "tlDisplayName", + "tnDisplayName", + "toDisplayName", + "trDisplayName", + "tsDisplayName", + "ttDisplayName", + "twDisplayName", + "tyDisplayName", + "ugDisplayName", + "ukDisplayName", + "urDisplayName", + "uzDisplayName", + "veDisplayName", + "viDisplayName", + "voDisplayName", + "waDisplayName", + "cyDisplayName", + "woDisplayName", + "fyDisplayName", + "xhDisplayName", + "yiDisplayName", + "yoDisplayName", + "zaDisplayName", + "unkDisplayName", + "zuDisplayName", + "hawDisplayName", + "hmnDisplayName", + "multiDisplayName", + "cebDisplayName", + "dzDisplayName", + "iwDisplayName", + "jwDisplayName", + "moDisplayName", + "shDisplayName", + "wwCountryDisplayName", + "afCountryDisplayName", + "axCountryDisplayName", + "alCountryDisplayName", + "dzCountryDisplayName", + "asCountryDisplayName", + "adCountryDisplayName", + "aoCountryDisplayName", + "aiCountryDisplayName", + "agCountryDisplayName", + "arCountryDisplayName", + "amCountryDisplayName", + "awCountryDisplayName", + "acCountryDisplayName", + "auCountryDisplayName", + "atCountryDisplayName", + "azCountryDisplayName", + "bsCountryDisplayName", + "bhCountryDisplayName", + "bdCountryDisplayName", + "bbCountryDisplayName", + "byCountryDisplayName", + "beCountryDisplayName", + "bzCountryDisplayName", + "bjCountryDisplayName", + "bmCountryDisplayName", + "btCountryDisplayName", + "boCountryDisplayName", + "baCountryDisplayName", + "bwCountryDisplayName", + "brCountryDisplayName", + "ioCountryDisplayName", + "vgCountryDisplayName", + "bnCountryDisplayName", + "bgCountryDisplayName", + "bfCountryDisplayName", + "biCountryDisplayName", + "khCountryDisplayName", + "cmCountryDisplayName", + "caCountryDisplayName", + "cvCountryDisplayName", + "bqCountryDisplayName", + "kyCountryDisplayName", + "cfCountryDisplayName", + "tdCountryDisplayName", + "clCountryDisplayName", + "cnCountryDisplayName", + "cxCountryDisplayName", + "ccCountryDisplayName", + "coCountryDisplayName", + "kmCountryDisplayName", + "cdCountryDisplayName", + "cgCountryDisplayName", + "ckCountryDisplayName", + "crCountryDisplayName", + "ciCountryDisplayName", + "hrCountryDisplayName", + "cuCountryDisplayName", + "cwCountryDisplayName", + "cyCountryDisplayName", + "czCountryDisplayName", + "dkCountryDisplayName", + "djCountryDisplayName", + "dmCountryDisplayName", + "doCountryDisplayName", + "tlCountryDisplayName", + "ecCountryDisplayName", + "egCountryDisplayName", + "svCountryDisplayName", + "gqCountryDisplayName", + "erCountryDisplayName", + "eeCountryDisplayName", + "szCountryDisplayName", + "etCountryDisplayName", + "fkCountryDisplayName", + "foCountryDisplayName", + "fjCountryDisplayName", + "fiCountryDisplayName", + "frCountryDisplayName", + "gfCountryDisplayName", + "pfCountryDisplayName", + "gaCountryDisplayName", + "gmCountryDisplayName", + "geCountryDisplayName", + "deCountryDisplayName", + "ghCountryDisplayName", + "giCountryDisplayName", + "grCountryDisplayName", + "glCountryDisplayName", + "gdCountryDisplayName", + "gpCountryDisplayName", + "guCountryDisplayName", + "gtCountryDisplayName", + "ggCountryDisplayName", + "gnCountryDisplayName", + "gwCountryDisplayName", + "gyCountryDisplayName", + "htCountryDisplayName", + "hmCountryDisplayName", + "hnCountryDisplayName", + "hkCountryDisplayName", + "huCountryDisplayName", + "isCountryDisplayName", + "inCountryDisplayName", + "idCountryDisplayName", + "irCountryDisplayName", + "iqCountryDisplayName", + "ieCountryDisplayName", + "imCountryDisplayName", + "ilCountryDisplayName", + "itCountryDisplayName", + "jmCountryDisplayName", + "jpCountryDisplayName", + "jeCountryDisplayName", + "joCountryDisplayName", + "kzCountryDisplayName", + "keCountryDisplayName", + "kiCountryDisplayName", + "xkCountryDisplayName", + "kwCountryDisplayName", + "kgCountryDisplayName", + "laCountryDisplayName", + "lvCountryDisplayName", + "lbCountryDisplayName", + "lsCountryDisplayName", + "lrCountryDisplayName", + "lyCountryDisplayName", + "liCountryDisplayName", + "ltCountryDisplayName", + "luCountryDisplayName", + "moCountryDisplayName", + "mkCountryDisplayName", + "mgCountryDisplayName", + "mwCountryDisplayName", + "myCountryDisplayName", + "mvCountryDisplayName", + "mlCountryDisplayName", + "mtCountryDisplayName", + "mhCountryDisplayName", + "mqCountryDisplayName", + "mrCountryDisplayName", + "muCountryDisplayName", + "ytCountryDisplayName", + "mxCountryDisplayName", + "fmCountryDisplayName", + "mdCountryDisplayName", + "mcCountryDisplayName", + "mnCountryDisplayName", + "meCountryDisplayName", + "msCountryDisplayName", + "maCountryDisplayName", + "mzCountryDisplayName", + "mmCountryDisplayName", + "naCountryDisplayName", + "nrCountryDisplayName", + "npCountryDisplayName", + "nlCountryDisplayName", + "ncCountryDisplayName", + "nzCountryDisplayName", + "niCountryDisplayName", + "neCountryDisplayName", + "ngCountryDisplayName", + "nuCountryDisplayName", + "nfCountryDisplayName", + "kpCountryDisplayName", + "mpCountryDisplayName", + "noCountryDisplayName", + "omCountryDisplayName", + "pkCountryDisplayName", + "pwCountryDisplayName", + "psCountryDisplayName", + "paCountryDisplayName", + "pgCountryDisplayName", + "pyCountryDisplayName", + "peCountryDisplayName", + "phCountryDisplayName", + "plCountryDisplayName", + "ptCountryDisplayName", + "prCountryDisplayName", + "qaCountryDisplayName", + "reCountryDisplayName", + "roCountryDisplayName", + "ruCountryDisplayName", + "rwCountryDisplayName", + "blCountryDisplayName", + "shCountryDisplayName", + "knCountryDisplayName", + "lcCountryDisplayName", + "mfCountryDisplayName", + "pmCountryDisplayName", + "vcCountryDisplayName", + "wsCountryDisplayName", + "smCountryDisplayName", + "stCountryDisplayName", + "saCountryDisplayName", + "snCountryDisplayName", + "rsCountryDisplayName", + "scCountryDisplayName", + "slCountryDisplayName", + "sgCountryDisplayName", + "sxCountryDisplayName", + "skCountryDisplayName", + "siCountryDisplayName", + "sbCountryDisplayName", + "soCountryDisplayName", + "zaCountryDisplayName", + "gsCountryDisplayName", + "krCountryDisplayName", + "ssCountryDisplayName", + "esCountryDisplayName", + "lkCountryDisplayName", + "sdCountryDisplayName", + "srCountryDisplayName", + "sjCountryDisplayName", + "seCountryDisplayName", + "chCountryDisplayName", + "syCountryDisplayName", + "twCountryDisplayName", + "tjCountryDisplayName", + "tzCountryDisplayName", + "thCountryDisplayName", + "tgCountryDisplayName", + "tkCountryDisplayName", + "toCountryDisplayName", + "ttCountryDisplayName", + "tnCountryDisplayName", + "trCountryDisplayName", + "tmCountryDisplayName", + "tcCountryDisplayName", + "tvCountryDisplayName", + "viCountryDisplayName", + "ugCountryDisplayName", + "uaCountryDisplayName", + "aeCountryDisplayName", + "gbCountryDisplayName", + "usCountryDisplayName", + "uyCountryDisplayName", + "uzCountryDisplayName", + "vuCountryDisplayName", + "vaCountryDisplayName", + "veCountryDisplayName", + "vnCountryDisplayName", + "wfCountryDisplayName", + "ehCountryDisplayName", + "yeCountryDisplayName", + "zmCountryDisplayName", + "zwCountryDisplayName", + "pay", + "allPrivateChats", + "unknownPrivateChat", + "copyClassCodeDesc", + "addToClassDesc", + "addToClassOrExchange", + "addToClassOrExchangeDesc", + "invitedToClassOrExchange", + "decline", + "declinedInvitation", + "acceptedInvitation", + "youreInvited", + "studentPermissionsDesc", + "noEligibleSpaces", + "youAddedToSpace", + "youRemovedFromSpace", + "invitedToChat", + "monthlySubscription", + "yearlySubscription", + "defaultSubscription", + "freeTrial", + "grammarAnalytics", + "total", + "noDataFound", + "promoSubscriptionExpirationDesc", + "emptyChatNameWarning", + "emptyClassNameWarning", + "emptyExchangeNameWarning", + "blurMeansTranslateTitle", + "blurMeansTranslateBody", + "someErrorTitle", + "someErrorBody", + "bestCorrectionFeedback", + "distractorFeedback", + "bestAnswerFeedback", + "definitionDefaultPrompt", + "practiceDefaultPrompt", + "correctionDefaultPrompt", + "itStartDefaultPrompt", + "languageLevelWarning", + "lockedChatWarning", + "lockSpace", + "lockChat", + "archiveSpace", + "suggestTo", + "suggestChatDesc", + "suggestExchangeDesc", + "acceptSelection", + "acceptSelectionAnyway", + "makingActivity", + "why", + "definition", + "exampleSentence", + "addToClassTitle", + "reportToTeacher", + "reportMessageTitle", + "reportMessageBody", + "noTeachersFound", + "noAddToSpacePermissions", + "alreadyInSpace", + "yourGlobalUserIdIs", + "noUsersFoundWithQuery", + "searchChatsRooms", + "groupName", + "createGroupAndInviteUsers", + "groupCanBeFoundViaSearch", + "inNoSpaces" + ], + + "sl": [ + "accountInformation", + "addNewFriend", + "alreadyHaveAnAccount", + "classes", + "editChatPermissions", + "groupDescription", + "groupDescriptionHasBeenChanged", + "allCorrect", + "newWayAllGood", + "othersAreBetter", + "holdForInfo", + "greenFeedback", + "yellowFeedback", + "redFeedback", + "customInputFeedbackChoice", + "itInstructionsTitle", + "itInstructionsBody", + "toggleLanguages", + "classWelcomeChat", + "deleteSpace", + "deleteGroup", + "areYouSureDeleteClass", + "areYouSureDeleteGroup", + "cannotBeReversed", + "enterDeletedClassName", + "incorrectClassName", + "oneday", + "oneweek", + "onemonth", + "sixmonth", + "oneyear", + "gaTooltip", + "taTooltip", + "unTooltip", + "interactiveTranslatorSliderHeader", + "interactiveGrammarSliderHeader", + "interactiveTranslatorNotAllowed", + "interactiveTranslatorAllowed", + "interactiveTranslatorRequired", + "interactiveTranslatorNotAllowedDesc", + "interactiveTranslatorAllowedDesc", + "interactiveTranslatorRequiredDesc", + "notYetSet", + "multiLingualClass", + "classAnalytics", + "allClasses", + "myLearning", + "allChatsAndClasses", + "timeOfLastMessage", + "totalMessages", + "waTooltip", + "changeDateRange", + "numberOfStudents", + "classDescription", + "classDescriptionDesc", + "requestToEnroll", + "requestAnExchange", + "findLanguageExchange", + "classAnalyticsDesc", + "addStudents", + "copyClassLink", + "copyClassLinkDesc", + "copyClassCode", + "inviteStudentByUserName", + "classSettings", + "classSettingsDesc", + "selectClassRoomDominantLanguage", + "selectTargetLanguage", + "whatIsYourClassLanguageLevel", + "studentPermissions", + "interactiveTranslator", + "oneToOneChatsWithinClass", + "oneToOneChatsWithinClassDesc", + "createGroupChats", + "createGroupChatsDesc", + "shareVideo", + "shareVideoDesc", + "sharePhotos", + "sharePhotosDesc", + "shareFiles", + "shareFilesDesc", + "shareLocationDesc", + "selectLanguageLevel", + "noIdenticalLanguages", + "iWantALanguagePartnerFrom", + "worldWide", + "noResults", + "searchBy", + "iWantAConversationPartner", + "iWantALanguagePartnerWhoSpeaks", + "iWantALanguagePartnerWhoIsLearning", + "yourBirthdayPlease", + "invalidDob", + "enterYourDob", + "getStarted", + "mustBe13", + "yourBirthdayPleaseShort", + "errorPleaseRefresh", + "joinWithClassCode", + "joinWithClassCodeDesc", + "joinWithClassCodeHint", + "unableToFindClass", + "languageLevelPreA1", + "languageLevelA1", + "languageLevelA2", + "languageLevelB1", + "languageLevelB2", + "languageLevelC1", + "languageLevelC2", + "changeTheNameOfTheClass", + "changeTheNameOfTheChat", + "welcomeToYourNewClass", + "welcomeToClass", + "welcomeToPangea18Plus", + "welcomeToPangeaMinor", + "findALanguagePartner", + "setToPublicSettingsTitle", + "setToPublicSettingsDesc", + "accountSettings", + "unableToFindClassCode", + "askPangeaBot", + "sorryNoResults", + "ignoreInThisText", + "helpMeTranslate", + "needsItShortMessage", + "needsIGCShortMessage", + "needsItMessage", + "needsIgcMessage", + "tokenTranslationTitle", + "spanTranslationDesc", + "spanTranslationTitle", + "l1SpanAndGrammarTitle", + "l1SpanAndGrammarDesc", + "otherTitle", + "otherDesc", + "countryInformation", + "myLanguages", + "targetLanguage", + "sourceLanguage", + "languagesISpeak", + "updateLanguage", + "whatLanguageYouWantToLearn", + "whatIsYourBaseLanguage", + "saveChanges", + "publicProfileTitle", + "publicProfileDesc", + "error502504Title", + "error502504Desc", + "error404Title", + "error404Desc", + "errorDisableIT", + "errorDisableIGC", + "errorDisableLanguageAssistance", + "errorDisableITUserDesc", + "errorDisableIGCUserDesc", + "errorDisableLanguageAssistanceUserDesc", + "errorDisableITClassDesc", + "errorDisableIGCClassDesc", + "errorDisableLanguageAssistanceClassDesc", + "itIsDisabled", + "igcIsDisabled", + "goToLearningSettings", + "error405Title", + "error405Desc", + "loginOrSignup", + "iAgreeToThe", + "termsAndConditions", + "andCertifyIAmAtLeast13YearsOfAge", + "findAClass", + "toggleIT", + "toggleIGC", + "toggleToolSettingsDescription", + "connectedToStaging", + "learningSettings", + "classNameRequired", + "sendVoiceNotes", + "sendVoiceNotesDesc", + "chatTopic", + "chatTopicDesc", + "inviteStudentByUserNameDesc", + "classRoster", + "almostPerfect", + "prettyGood", + "letMeThink", + "clickMessageTitle", + "clickMessageBody", + "understandingMessagesTitle", + "addToClass", + "understandingMessagesBody", + "allDone", + "vocab", + "low", + "medium", + "high", + "unknownProficiency", + "changeView", + "clearAll", + "generateVocabulary", + "generatePrompts", + "subscribe", + "getAccess", + "subscriptionDesc", + "subscriptionManagement", + "currentSubscription", + "changeSubscription", + "cancelSubscription", + "selectYourPlan", + "subsciptionPlatformTooltip", + "subscriptionManagementUnavailable", + "paymentMethod", + "paymentHistory", + "emptyChatDownloadWarning", + "appUpdateAvailable", + "update", + "updateDesc", + "maybeLater", + "mainMenu", + "toggleImmersionMode", + "toggleImmersionModeDesc", + "itToggleDescription", + "igcToggleDescription", + "sendOnEnterDescription", + "alreadyInClass", + "pleaseLoginFirst", + "originalMessage", + "sentMessage", + "useType", + "notAvailable", + "taAndGaTooltip", + "definitionsToolName", + "messageTranslationsToolName", + "definitionsToolDescription", + "translationsToolDescrption", + "welcomeBack", + "classExchanges", + "createNewClass", + "newExchange", + "kickAllStudents", + "kickAllStudentsConfirmation", + "inviteAllStudents", + "inviteAllStudentsConfirmation", + "inviteStudentsFromOtherClasses", + "inviteUsersFromPangea", + "allExchanges", + "redeemPromoCode", + "enterPromoCode", + "downloadTxtFile", + "downloadCSVFile", + "promotionalSubscriptionDesc", + "originalSubscriptionPlatform", + "oneWeekTrial", + "creatingSpacePleaseWait", + "downloadXLSXFile", + "abDisplayName", + "aaDisplayName", + "afDisplayName", + "akDisplayName", + "sqDisplayName", + "amDisplayName", + "arDisplayName", + "anDisplayName", + "hyDisplayName", + "asDisplayName", + "avDisplayName", + "aeDisplayName", + "ayDisplayName", + "azDisplayName", + "bmDisplayName", + "baDisplayName", + "euDisplayName", + "beDisplayName", + "bnDisplayName", + "bhDisplayName", + "biDisplayName", + "bsDisplayName", + "brDisplayName", + "bgDisplayName", + "myDisplayName", + "caDisplayName", + "chDisplayName", + "ceDisplayName", + "nyDisplayName", + "zhDisplayName", + "cvDisplayName", + "kwDisplayName", + "coDisplayName", + "crDisplayName", + "hrDisplayName", + "csDisplayName", + "daDisplayName", + "dvDisplayName", + "nlDisplayName", + "enDisplayName", + "eoDisplayName", + "etDisplayName", + "eeDisplayName", + "foDisplayName", + "fjDisplayName", + "fiDisplayName", + "frDisplayName", + "ffDisplayName", + "glDisplayName", + "kaDisplayName", + "deDisplayName", + "elDisplayName", + "gnDisplayName", + "guDisplayName", + "htDisplayName", + "haDisplayName", + "heDisplayName", + "hzDisplayName", + "hiDisplayName", + "hoDisplayName", + "huDisplayName", + "iaDisplayName", + "idDisplayName", + "ieDisplayName", + "gaDisplayName", + "igDisplayName", + "ikDisplayName", + "ioDisplayName", + "isDisplayName", + "itDisplayName", + "iuDisplayName", + "jaDisplayName", + "jvDisplayName", + "klDisplayName", + "knDisplayName", + "krDisplayName", + "ksDisplayName", + "kkDisplayName", + "kmDisplayName", + "kiDisplayName", + "rwDisplayName", + "kyDisplayName", + "kvDisplayName", + "kgDisplayName", + "koDisplayName", + "kuDisplayName", + "kjDisplayName", + "laDisplayName", + "lbDisplayName", + "lgDisplayName", + "liDisplayName", + "lnDisplayName", + "loDisplayName", + "ltDisplayName", + "luDisplayName", + "lvDisplayName", + "gvDisplayName", + "mkDisplayName", + "mgDisplayName", + "msDisplayName", + "mlDisplayName", + "mtDisplayName", + "miDisplayName", + "mrDisplayName", + "mhDisplayName", + "mnDisplayName", + "naDisplayName", + "nvDisplayName", + "nbDisplayName", + "ndDisplayName", + "neDisplayName", + "ngDisplayName", + "nnDisplayName", + "noDisplayName", + "iiDisplayName", + "nrDisplayName", + "ocDisplayName", + "ojDisplayName", + "cuDisplayName", + "omDisplayName", + "orDisplayName", + "osDisplayName", + "paDisplayName", + "piDisplayName", + "faDisplayName", + "plDisplayName", + "psDisplayName", + "ptDisplayName", + "quDisplayName", + "rmDisplayName", + "rnDisplayName", + "roDisplayName", + "ruDisplayName", + "saDisplayName", + "scDisplayName", + "sdDisplayName", + "seDisplayName", + "smDisplayName", + "sgDisplayName", + "srDisplayName", + "gdDisplayName", + "snDisplayName", + "siDisplayName", + "skDisplayName", + "slDisplayName", + "soDisplayName", + "stDisplayName", + "esDisplayName", + "suDisplayName", + "swDisplayName", + "ssDisplayName", + "svDisplayName", + "taDisplayName", + "teDisplayName", + "tgDisplayName", + "thDisplayName", + "tiDisplayName", + "boDisplayName", + "tkDisplayName", + "tlDisplayName", + "tnDisplayName", + "toDisplayName", + "trDisplayName", + "tsDisplayName", + "ttDisplayName", + "twDisplayName", + "tyDisplayName", + "ugDisplayName", + "ukDisplayName", + "urDisplayName", + "uzDisplayName", + "veDisplayName", + "viDisplayName", + "voDisplayName", + "waDisplayName", + "cyDisplayName", + "woDisplayName", + "fyDisplayName", + "xhDisplayName", + "yiDisplayName", + "yoDisplayName", + "zaDisplayName", + "unkDisplayName", + "zuDisplayName", + "hawDisplayName", + "hmnDisplayName", + "multiDisplayName", + "cebDisplayName", + "dzDisplayName", + "iwDisplayName", + "jwDisplayName", + "moDisplayName", + "shDisplayName", + "wwCountryDisplayName", + "afCountryDisplayName", + "axCountryDisplayName", + "alCountryDisplayName", + "dzCountryDisplayName", + "asCountryDisplayName", + "adCountryDisplayName", + "aoCountryDisplayName", + "aiCountryDisplayName", + "agCountryDisplayName", + "arCountryDisplayName", + "amCountryDisplayName", + "awCountryDisplayName", + "acCountryDisplayName", + "auCountryDisplayName", + "atCountryDisplayName", + "azCountryDisplayName", + "bsCountryDisplayName", + "bhCountryDisplayName", + "bdCountryDisplayName", + "bbCountryDisplayName", + "byCountryDisplayName", + "beCountryDisplayName", + "bzCountryDisplayName", + "bjCountryDisplayName", + "bmCountryDisplayName", + "btCountryDisplayName", + "boCountryDisplayName", + "baCountryDisplayName", + "bwCountryDisplayName", + "brCountryDisplayName", + "ioCountryDisplayName", + "vgCountryDisplayName", + "bnCountryDisplayName", + "bgCountryDisplayName", + "bfCountryDisplayName", + "biCountryDisplayName", + "khCountryDisplayName", + "cmCountryDisplayName", + "caCountryDisplayName", + "cvCountryDisplayName", + "bqCountryDisplayName", + "kyCountryDisplayName", + "cfCountryDisplayName", + "tdCountryDisplayName", + "clCountryDisplayName", + "cnCountryDisplayName", + "cxCountryDisplayName", + "ccCountryDisplayName", + "coCountryDisplayName", + "kmCountryDisplayName", + "cdCountryDisplayName", + "cgCountryDisplayName", + "ckCountryDisplayName", + "crCountryDisplayName", + "ciCountryDisplayName", + "hrCountryDisplayName", + "cuCountryDisplayName", + "cwCountryDisplayName", + "cyCountryDisplayName", + "czCountryDisplayName", + "dkCountryDisplayName", + "djCountryDisplayName", + "dmCountryDisplayName", + "doCountryDisplayName", + "tlCountryDisplayName", + "ecCountryDisplayName", + "egCountryDisplayName", + "svCountryDisplayName", + "gqCountryDisplayName", + "erCountryDisplayName", + "eeCountryDisplayName", + "szCountryDisplayName", + "etCountryDisplayName", + "fkCountryDisplayName", + "foCountryDisplayName", + "fjCountryDisplayName", + "fiCountryDisplayName", + "frCountryDisplayName", + "gfCountryDisplayName", + "pfCountryDisplayName", + "gaCountryDisplayName", + "gmCountryDisplayName", + "geCountryDisplayName", + "deCountryDisplayName", + "ghCountryDisplayName", + "giCountryDisplayName", + "grCountryDisplayName", + "glCountryDisplayName", + "gdCountryDisplayName", + "gpCountryDisplayName", + "guCountryDisplayName", + "gtCountryDisplayName", + "ggCountryDisplayName", + "gnCountryDisplayName", + "gwCountryDisplayName", + "gyCountryDisplayName", + "htCountryDisplayName", + "hmCountryDisplayName", + "hnCountryDisplayName", + "hkCountryDisplayName", + "huCountryDisplayName", + "isCountryDisplayName", + "inCountryDisplayName", + "idCountryDisplayName", + "irCountryDisplayName", + "iqCountryDisplayName", + "ieCountryDisplayName", + "imCountryDisplayName", + "ilCountryDisplayName", + "itCountryDisplayName", + "jmCountryDisplayName", + "jpCountryDisplayName", + "jeCountryDisplayName", + "joCountryDisplayName", + "kzCountryDisplayName", + "keCountryDisplayName", + "kiCountryDisplayName", + "xkCountryDisplayName", + "kwCountryDisplayName", + "kgCountryDisplayName", + "laCountryDisplayName", + "lvCountryDisplayName", + "lbCountryDisplayName", + "lsCountryDisplayName", + "lrCountryDisplayName", + "lyCountryDisplayName", + "liCountryDisplayName", + "ltCountryDisplayName", + "luCountryDisplayName", + "moCountryDisplayName", + "mkCountryDisplayName", + "mgCountryDisplayName", + "mwCountryDisplayName", + "myCountryDisplayName", + "mvCountryDisplayName", + "mlCountryDisplayName", + "mtCountryDisplayName", + "mhCountryDisplayName", + "mqCountryDisplayName", + "mrCountryDisplayName", + "muCountryDisplayName", + "ytCountryDisplayName", + "mxCountryDisplayName", + "fmCountryDisplayName", + "mdCountryDisplayName", + "mcCountryDisplayName", + "mnCountryDisplayName", + "meCountryDisplayName", + "msCountryDisplayName", + "maCountryDisplayName", + "mzCountryDisplayName", + "mmCountryDisplayName", + "naCountryDisplayName", + "nrCountryDisplayName", + "npCountryDisplayName", + "nlCountryDisplayName", + "ncCountryDisplayName", + "nzCountryDisplayName", + "niCountryDisplayName", + "neCountryDisplayName", + "ngCountryDisplayName", + "nuCountryDisplayName", + "nfCountryDisplayName", + "kpCountryDisplayName", + "mpCountryDisplayName", + "noCountryDisplayName", + "omCountryDisplayName", + "pkCountryDisplayName", + "pwCountryDisplayName", + "psCountryDisplayName", + "paCountryDisplayName", + "pgCountryDisplayName", + "pyCountryDisplayName", + "peCountryDisplayName", + "phCountryDisplayName", + "plCountryDisplayName", + "ptCountryDisplayName", + "prCountryDisplayName", + "qaCountryDisplayName", + "reCountryDisplayName", + "roCountryDisplayName", + "ruCountryDisplayName", + "rwCountryDisplayName", + "blCountryDisplayName", + "shCountryDisplayName", + "knCountryDisplayName", + "lcCountryDisplayName", + "mfCountryDisplayName", + "pmCountryDisplayName", + "vcCountryDisplayName", + "wsCountryDisplayName", + "smCountryDisplayName", + "stCountryDisplayName", + "saCountryDisplayName", + "snCountryDisplayName", + "rsCountryDisplayName", + "scCountryDisplayName", + "slCountryDisplayName", + "sgCountryDisplayName", + "sxCountryDisplayName", + "skCountryDisplayName", + "siCountryDisplayName", + "sbCountryDisplayName", + "soCountryDisplayName", + "zaCountryDisplayName", + "gsCountryDisplayName", + "krCountryDisplayName", + "ssCountryDisplayName", + "esCountryDisplayName", + "lkCountryDisplayName", + "sdCountryDisplayName", + "srCountryDisplayName", + "sjCountryDisplayName", + "seCountryDisplayName", + "chCountryDisplayName", + "syCountryDisplayName", + "twCountryDisplayName", + "tjCountryDisplayName", + "tzCountryDisplayName", + "thCountryDisplayName", + "tgCountryDisplayName", + "tkCountryDisplayName", + "toCountryDisplayName", + "ttCountryDisplayName", + "tnCountryDisplayName", + "trCountryDisplayName", + "tmCountryDisplayName", + "tcCountryDisplayName", + "tvCountryDisplayName", + "viCountryDisplayName", + "ugCountryDisplayName", + "uaCountryDisplayName", + "aeCountryDisplayName", + "gbCountryDisplayName", + "usCountryDisplayName", + "uyCountryDisplayName", + "uzCountryDisplayName", + "vuCountryDisplayName", + "vaCountryDisplayName", + "veCountryDisplayName", + "vnCountryDisplayName", + "wfCountryDisplayName", + "ehCountryDisplayName", + "yeCountryDisplayName", + "zmCountryDisplayName", + "zwCountryDisplayName", + "pay", + "allPrivateChats", + "unknownPrivateChat", + "copyClassCodeDesc", + "addToClassDesc", + "addToClassOrExchange", + "addToClassOrExchangeDesc", + "invitedToClassOrExchange", + "decline", + "declinedInvitation", + "acceptedInvitation", + "youreInvited", + "studentPermissionsDesc", + "noEligibleSpaces", + "youAddedToSpace", + "youRemovedFromSpace", + "invitedToChat", + "monthlySubscription", + "yearlySubscription", + "defaultSubscription", + "freeTrial", + "grammarAnalytics", + "total", + "noDataFound", + "promoSubscriptionExpirationDesc", + "emptyChatNameWarning", + "emptyClassNameWarning", + "emptyExchangeNameWarning", + "blurMeansTranslateTitle", + "blurMeansTranslateBody", + "someErrorTitle", + "someErrorBody", + "bestCorrectionFeedback", + "distractorFeedback", + "bestAnswerFeedback", + "definitionDefaultPrompt", + "practiceDefaultPrompt", + "correctionDefaultPrompt", + "itStartDefaultPrompt", + "languageLevelWarning", + "lockedChatWarning", + "lockSpace", + "lockChat", + "archiveSpace", + "suggestTo", + "suggestChatDesc", + "suggestExchangeDesc", + "acceptSelection", + "acceptSelectionAnyway", + "makingActivity", + "why", + "definition", + "exampleSentence", + "addToClassTitle", + "reportToTeacher", + "reportMessageTitle", + "reportMessageBody", + "noTeachersFound", + "noAddToSpacePermissions", + "alreadyInSpace", + "yourGlobalUserIdIs", + "noUsersFoundWithQuery", + "searchChatsRooms", + "groupName", + "createGroupAndInviteUsers", + "groupCanBeFoundViaSearch", + "inNoSpaces" + ], + + "sr": [ + "accountInformation", + "addNewFriend", + "alreadyHaveAnAccount", + "classes", + "allCorrect", + "newWayAllGood", + "othersAreBetter", + "holdForInfo", + "greenFeedback", + "yellowFeedback", + "redFeedback", + "customInputFeedbackChoice", + "itInstructionsTitle", + "itInstructionsBody", + "toggleLanguages", + "classWelcomeChat", + "deleteSpace", + "deleteGroup", + "areYouSureDeleteClass", + "areYouSureDeleteGroup", + "cannotBeReversed", + "enterDeletedClassName", + "incorrectClassName", + "oneday", + "oneweek", + "onemonth", + "sixmonth", + "oneyear", + "gaTooltip", + "taTooltip", + "unTooltip", + "interactiveTranslatorSliderHeader", + "interactiveGrammarSliderHeader", + "interactiveTranslatorNotAllowed", + "interactiveTranslatorAllowed", + "interactiveTranslatorRequired", + "interactiveTranslatorNotAllowedDesc", + "interactiveTranslatorAllowedDesc", + "interactiveTranslatorRequiredDesc", + "notYetSet", + "multiLingualClass", + "classAnalytics", + "allClasses", + "myLearning", + "allChatsAndClasses", + "timeOfLastMessage", + "totalMessages", + "waTooltip", + "changeDateRange", + "numberOfStudents", + "classDescription", + "classDescriptionDesc", + "requestToEnroll", + "requestAnExchange", + "findLanguageExchange", + "classAnalyticsDesc", + "addStudents", + "copyClassLink", + "copyClassLinkDesc", + "copyClassCode", + "inviteStudentByUserName", + "classSettings", + "classSettingsDesc", + "selectClassRoomDominantLanguage", + "selectTargetLanguage", + "whatIsYourClassLanguageLevel", + "studentPermissions", + "interactiveTranslator", + "oneToOneChatsWithinClass", + "oneToOneChatsWithinClassDesc", + "createGroupChats", + "createGroupChatsDesc", + "shareVideo", + "shareVideoDesc", + "sharePhotos", + "sharePhotosDesc", + "shareFiles", + "shareFilesDesc", + "shareLocationDesc", + "selectLanguageLevel", + "noIdenticalLanguages", + "iWantALanguagePartnerFrom", + "worldWide", + "noResults", + "searchBy", + "iWantAConversationPartner", + "iWantALanguagePartnerWhoSpeaks", + "iWantALanguagePartnerWhoIsLearning", + "yourBirthdayPlease", + "invalidDob", + "enterYourDob", + "getStarted", + "mustBe13", + "yourBirthdayPleaseShort", + "errorPleaseRefresh", + "joinWithClassCode", + "joinWithClassCodeDesc", + "joinWithClassCodeHint", + "unableToFindClass", + "languageLevelPreA1", + "languageLevelA1", + "languageLevelA2", + "languageLevelB1", + "languageLevelB2", + "languageLevelC1", + "languageLevelC2", + "changeTheNameOfTheClass", + "changeTheNameOfTheChat", + "welcomeToYourNewClass", + "welcomeToClass", + "welcomeToPangea18Plus", + "welcomeToPangeaMinor", + "findALanguagePartner", + "setToPublicSettingsTitle", + "setToPublicSettingsDesc", + "accountSettings", + "unableToFindClassCode", + "askPangeaBot", + "sorryNoResults", + "ignoreInThisText", + "helpMeTranslate", + "needsItShortMessage", + "needsIGCShortMessage", + "needsItMessage", + "needsIgcMessage", + "tokenTranslationTitle", + "spanTranslationDesc", + "spanTranslationTitle", + "l1SpanAndGrammarTitle", + "l1SpanAndGrammarDesc", + "otherTitle", + "otherDesc", + "countryInformation", + "myLanguages", + "targetLanguage", + "sourceLanguage", + "languagesISpeak", + "updateLanguage", + "whatLanguageYouWantToLearn", + "whatIsYourBaseLanguage", + "saveChanges", + "publicProfileTitle", + "publicProfileDesc", + "error502504Title", + "error502504Desc", + "error404Title", + "error404Desc", + "errorDisableIT", + "errorDisableIGC", + "errorDisableLanguageAssistance", + "errorDisableITUserDesc", + "errorDisableIGCUserDesc", + "errorDisableLanguageAssistanceUserDesc", + "errorDisableITClassDesc", + "errorDisableIGCClassDesc", + "errorDisableLanguageAssistanceClassDesc", + "itIsDisabled", + "igcIsDisabled", + "goToLearningSettings", + "error405Title", + "error405Desc", + "loginOrSignup", + "iAgreeToThe", + "termsAndConditions", + "andCertifyIAmAtLeast13YearsOfAge", + "findAClass", + "toggleIT", + "toggleIGC", + "toggleToolSettingsDescription", + "connectedToStaging", + "learningSettings", + "classNameRequired", + "sendVoiceNotes", + "sendVoiceNotesDesc", + "chatTopic", + "chatTopicDesc", + "inviteStudentByUserNameDesc", + "classRoster", + "almostPerfect", + "prettyGood", + "letMeThink", + "clickMessageTitle", + "clickMessageBody", + "understandingMessagesTitle", + "addToClass", + "understandingMessagesBody", + "allDone", + "vocab", + "low", + "medium", + "high", + "unknownProficiency", + "changeView", + "clearAll", + "generateVocabulary", + "generatePrompts", + "subscribe", + "getAccess", + "subscriptionDesc", + "subscriptionManagement", + "currentSubscription", + "changeSubscription", + "cancelSubscription", + "selectYourPlan", + "subsciptionPlatformTooltip", + "subscriptionManagementUnavailable", + "paymentMethod", + "paymentHistory", + "emptyChatDownloadWarning", + "appUpdateAvailable", + "update", + "updateDesc", + "maybeLater", + "mainMenu", + "toggleImmersionMode", + "toggleImmersionModeDesc", + "itToggleDescription", + "igcToggleDescription", + "sendOnEnterDescription", + "alreadyInClass", + "pleaseLoginFirst", + "originalMessage", + "sentMessage", + "useType", + "notAvailable", + "taAndGaTooltip", + "definitionsToolName", + "messageTranslationsToolName", + "definitionsToolDescription", + "translationsToolDescrption", + "welcomeBack", + "classExchanges", + "createNewClass", + "newExchange", + "kickAllStudents", + "kickAllStudentsConfirmation", + "inviteAllStudents", + "inviteAllStudentsConfirmation", + "inviteStudentsFromOtherClasses", + "inviteUsersFromPangea", + "allExchanges", + "redeemPromoCode", + "enterPromoCode", + "downloadTxtFile", + "downloadCSVFile", + "promotionalSubscriptionDesc", + "originalSubscriptionPlatform", + "oneWeekTrial", + "creatingSpacePleaseWait", + "downloadXLSXFile", + "abDisplayName", + "aaDisplayName", + "afDisplayName", + "akDisplayName", + "sqDisplayName", + "amDisplayName", + "arDisplayName", + "anDisplayName", + "hyDisplayName", + "asDisplayName", + "avDisplayName", + "aeDisplayName", + "ayDisplayName", + "azDisplayName", + "bmDisplayName", + "baDisplayName", + "euDisplayName", + "beDisplayName", + "bnDisplayName", + "bhDisplayName", + "biDisplayName", + "bsDisplayName", + "brDisplayName", + "bgDisplayName", + "myDisplayName", + "caDisplayName", + "chDisplayName", + "ceDisplayName", + "nyDisplayName", + "zhDisplayName", + "cvDisplayName", + "kwDisplayName", + "coDisplayName", + "crDisplayName", + "hrDisplayName", + "csDisplayName", + "daDisplayName", + "dvDisplayName", + "nlDisplayName", + "enDisplayName", + "eoDisplayName", + "etDisplayName", + "eeDisplayName", + "foDisplayName", + "fjDisplayName", + "fiDisplayName", + "frDisplayName", + "ffDisplayName", + "glDisplayName", + "kaDisplayName", + "deDisplayName", + "elDisplayName", + "gnDisplayName", + "guDisplayName", + "htDisplayName", + "haDisplayName", + "heDisplayName", + "hzDisplayName", + "hiDisplayName", + "hoDisplayName", + "huDisplayName", + "iaDisplayName", + "idDisplayName", + "ieDisplayName", + "gaDisplayName", + "igDisplayName", + "ikDisplayName", + "ioDisplayName", + "isDisplayName", + "itDisplayName", + "iuDisplayName", + "jaDisplayName", + "jvDisplayName", + "klDisplayName", + "knDisplayName", + "krDisplayName", + "ksDisplayName", + "kkDisplayName", + "kmDisplayName", + "kiDisplayName", + "rwDisplayName", + "kyDisplayName", + "kvDisplayName", + "kgDisplayName", + "koDisplayName", + "kuDisplayName", + "kjDisplayName", + "laDisplayName", + "lbDisplayName", + "lgDisplayName", + "liDisplayName", + "lnDisplayName", + "loDisplayName", + "ltDisplayName", + "luDisplayName", + "lvDisplayName", + "gvDisplayName", + "mkDisplayName", + "mgDisplayName", + "msDisplayName", + "mlDisplayName", + "mtDisplayName", + "miDisplayName", + "mrDisplayName", + "mhDisplayName", + "mnDisplayName", + "naDisplayName", + "nvDisplayName", + "nbDisplayName", + "ndDisplayName", + "neDisplayName", + "ngDisplayName", + "nnDisplayName", + "noDisplayName", + "iiDisplayName", + "nrDisplayName", + "ocDisplayName", + "ojDisplayName", + "cuDisplayName", + "omDisplayName", + "orDisplayName", + "osDisplayName", + "paDisplayName", + "piDisplayName", + "faDisplayName", + "plDisplayName", + "psDisplayName", + "ptDisplayName", + "quDisplayName", + "rmDisplayName", + "rnDisplayName", + "roDisplayName", + "ruDisplayName", + "saDisplayName", + "scDisplayName", + "sdDisplayName", + "seDisplayName", + "smDisplayName", + "sgDisplayName", + "srDisplayName", + "gdDisplayName", + "snDisplayName", + "siDisplayName", + "skDisplayName", + "slDisplayName", + "soDisplayName", + "stDisplayName", + "esDisplayName", + "suDisplayName", + "swDisplayName", + "ssDisplayName", + "svDisplayName", + "taDisplayName", + "teDisplayName", + "tgDisplayName", + "thDisplayName", + "tiDisplayName", + "boDisplayName", + "tkDisplayName", + "tlDisplayName", + "tnDisplayName", + "toDisplayName", + "trDisplayName", + "tsDisplayName", + "ttDisplayName", + "twDisplayName", + "tyDisplayName", + "ugDisplayName", + "ukDisplayName", + "urDisplayName", + "uzDisplayName", + "veDisplayName", + "viDisplayName", + "voDisplayName", + "waDisplayName", + "cyDisplayName", + "woDisplayName", + "fyDisplayName", + "xhDisplayName", + "yiDisplayName", + "yoDisplayName", + "zaDisplayName", + "unkDisplayName", + "zuDisplayName", + "hawDisplayName", + "hmnDisplayName", + "multiDisplayName", + "cebDisplayName", + "dzDisplayName", + "iwDisplayName", + "jwDisplayName", + "moDisplayName", + "shDisplayName", + "wwCountryDisplayName", + "afCountryDisplayName", + "axCountryDisplayName", + "alCountryDisplayName", + "dzCountryDisplayName", + "asCountryDisplayName", + "adCountryDisplayName", + "aoCountryDisplayName", + "aiCountryDisplayName", + "agCountryDisplayName", + "arCountryDisplayName", + "amCountryDisplayName", + "awCountryDisplayName", + "acCountryDisplayName", + "auCountryDisplayName", + "atCountryDisplayName", + "azCountryDisplayName", + "bsCountryDisplayName", + "bhCountryDisplayName", + "bdCountryDisplayName", + "bbCountryDisplayName", + "byCountryDisplayName", + "beCountryDisplayName", + "bzCountryDisplayName", + "bjCountryDisplayName", + "bmCountryDisplayName", + "btCountryDisplayName", + "boCountryDisplayName", + "baCountryDisplayName", + "bwCountryDisplayName", + "brCountryDisplayName", + "ioCountryDisplayName", + "vgCountryDisplayName", + "bnCountryDisplayName", + "bgCountryDisplayName", + "bfCountryDisplayName", + "biCountryDisplayName", + "khCountryDisplayName", + "cmCountryDisplayName", + "caCountryDisplayName", + "cvCountryDisplayName", + "bqCountryDisplayName", + "kyCountryDisplayName", + "cfCountryDisplayName", + "tdCountryDisplayName", + "clCountryDisplayName", + "cnCountryDisplayName", + "cxCountryDisplayName", + "ccCountryDisplayName", + "coCountryDisplayName", + "kmCountryDisplayName", + "cdCountryDisplayName", + "cgCountryDisplayName", + "ckCountryDisplayName", + "crCountryDisplayName", + "ciCountryDisplayName", + "hrCountryDisplayName", + "cuCountryDisplayName", + "cwCountryDisplayName", + "cyCountryDisplayName", + "czCountryDisplayName", + "dkCountryDisplayName", + "djCountryDisplayName", + "dmCountryDisplayName", + "doCountryDisplayName", + "tlCountryDisplayName", + "ecCountryDisplayName", + "egCountryDisplayName", + "svCountryDisplayName", + "gqCountryDisplayName", + "erCountryDisplayName", + "eeCountryDisplayName", + "szCountryDisplayName", + "etCountryDisplayName", + "fkCountryDisplayName", + "foCountryDisplayName", + "fjCountryDisplayName", + "fiCountryDisplayName", + "frCountryDisplayName", + "gfCountryDisplayName", + "pfCountryDisplayName", + "gaCountryDisplayName", + "gmCountryDisplayName", + "geCountryDisplayName", + "deCountryDisplayName", + "ghCountryDisplayName", + "giCountryDisplayName", + "grCountryDisplayName", + "glCountryDisplayName", + "gdCountryDisplayName", + "gpCountryDisplayName", + "guCountryDisplayName", + "gtCountryDisplayName", + "ggCountryDisplayName", + "gnCountryDisplayName", + "gwCountryDisplayName", + "gyCountryDisplayName", + "htCountryDisplayName", + "hmCountryDisplayName", + "hnCountryDisplayName", + "hkCountryDisplayName", + "huCountryDisplayName", + "isCountryDisplayName", + "inCountryDisplayName", + "idCountryDisplayName", + "irCountryDisplayName", + "iqCountryDisplayName", + "ieCountryDisplayName", + "imCountryDisplayName", + "ilCountryDisplayName", + "itCountryDisplayName", + "jmCountryDisplayName", + "jpCountryDisplayName", + "jeCountryDisplayName", + "joCountryDisplayName", + "kzCountryDisplayName", + "keCountryDisplayName", + "kiCountryDisplayName", + "xkCountryDisplayName", + "kwCountryDisplayName", + "kgCountryDisplayName", + "laCountryDisplayName", + "lvCountryDisplayName", + "lbCountryDisplayName", + "lsCountryDisplayName", + "lrCountryDisplayName", + "lyCountryDisplayName", + "liCountryDisplayName", + "ltCountryDisplayName", + "luCountryDisplayName", + "moCountryDisplayName", + "mkCountryDisplayName", + "mgCountryDisplayName", + "mwCountryDisplayName", + "myCountryDisplayName", + "mvCountryDisplayName", + "mlCountryDisplayName", + "mtCountryDisplayName", + "mhCountryDisplayName", + "mqCountryDisplayName", + "mrCountryDisplayName", + "muCountryDisplayName", + "ytCountryDisplayName", + "mxCountryDisplayName", + "fmCountryDisplayName", + "mdCountryDisplayName", + "mcCountryDisplayName", + "mnCountryDisplayName", + "meCountryDisplayName", + "msCountryDisplayName", + "maCountryDisplayName", + "mzCountryDisplayName", + "mmCountryDisplayName", + "naCountryDisplayName", + "nrCountryDisplayName", + "npCountryDisplayName", + "nlCountryDisplayName", + "ncCountryDisplayName", + "nzCountryDisplayName", + "niCountryDisplayName", + "neCountryDisplayName", + "ngCountryDisplayName", + "nuCountryDisplayName", + "nfCountryDisplayName", + "kpCountryDisplayName", + "mpCountryDisplayName", + "noCountryDisplayName", + "omCountryDisplayName", + "pkCountryDisplayName", + "pwCountryDisplayName", + "psCountryDisplayName", + "paCountryDisplayName", + "pgCountryDisplayName", + "pyCountryDisplayName", + "peCountryDisplayName", + "phCountryDisplayName", + "plCountryDisplayName", + "ptCountryDisplayName", + "prCountryDisplayName", + "qaCountryDisplayName", + "reCountryDisplayName", + "roCountryDisplayName", + "ruCountryDisplayName", + "rwCountryDisplayName", + "blCountryDisplayName", + "shCountryDisplayName", + "knCountryDisplayName", + "lcCountryDisplayName", + "mfCountryDisplayName", + "pmCountryDisplayName", + "vcCountryDisplayName", + "wsCountryDisplayName", + "smCountryDisplayName", + "stCountryDisplayName", + "saCountryDisplayName", + "snCountryDisplayName", + "rsCountryDisplayName", + "scCountryDisplayName", + "slCountryDisplayName", + "sgCountryDisplayName", + "sxCountryDisplayName", + "skCountryDisplayName", + "siCountryDisplayName", + "sbCountryDisplayName", + "soCountryDisplayName", + "zaCountryDisplayName", + "gsCountryDisplayName", + "krCountryDisplayName", + "ssCountryDisplayName", + "esCountryDisplayName", + "lkCountryDisplayName", + "sdCountryDisplayName", + "srCountryDisplayName", + "sjCountryDisplayName", + "seCountryDisplayName", + "chCountryDisplayName", + "syCountryDisplayName", + "twCountryDisplayName", + "tjCountryDisplayName", + "tzCountryDisplayName", + "thCountryDisplayName", + "tgCountryDisplayName", + "tkCountryDisplayName", + "toCountryDisplayName", + "ttCountryDisplayName", + "tnCountryDisplayName", + "trCountryDisplayName", + "tmCountryDisplayName", + "tcCountryDisplayName", + "tvCountryDisplayName", + "viCountryDisplayName", + "ugCountryDisplayName", + "uaCountryDisplayName", + "aeCountryDisplayName", + "gbCountryDisplayName", + "usCountryDisplayName", + "uyCountryDisplayName", + "uzCountryDisplayName", + "vuCountryDisplayName", + "vaCountryDisplayName", + "veCountryDisplayName", + "vnCountryDisplayName", + "wfCountryDisplayName", + "ehCountryDisplayName", + "yeCountryDisplayName", + "zmCountryDisplayName", + "zwCountryDisplayName", + "pay", + "allPrivateChats", + "unknownPrivateChat", + "copyClassCodeDesc", + "addToClassDesc", + "addToClassOrExchange", + "addToClassOrExchangeDesc", + "invitedToClassOrExchange", + "decline", + "declinedInvitation", + "acceptedInvitation", + "youreInvited", + "studentPermissionsDesc", + "noEligibleSpaces", + "youAddedToSpace", + "youRemovedFromSpace", + "invitedToChat", + "monthlySubscription", + "yearlySubscription", + "defaultSubscription", + "freeTrial", + "grammarAnalytics", + "total", + "noDataFound", + "promoSubscriptionExpirationDesc", + "emptyChatNameWarning", + "emptyClassNameWarning", + "emptyExchangeNameWarning", + "blurMeansTranslateTitle", + "blurMeansTranslateBody", + "someErrorTitle", + "someErrorBody", + "bestCorrectionFeedback", + "distractorFeedback", + "bestAnswerFeedback", + "definitionDefaultPrompt", + "practiceDefaultPrompt", + "correctionDefaultPrompt", + "itStartDefaultPrompt", + "languageLevelWarning", + "lockedChatWarning", + "lockSpace", + "lockChat", + "archiveSpace", + "suggestTo", + "suggestChatDesc", + "suggestExchangeDesc", + "acceptSelection", + "acceptSelectionAnyway", + "makingActivity", + "why", + "definition", + "exampleSentence", + "addToClassTitle", + "reportToTeacher", + "reportMessageTitle", + "reportMessageBody", + "noTeachersFound", + "noAddToSpacePermissions", + "alreadyInSpace", + "yourGlobalUserIdIs", + "noUsersFoundWithQuery", + "searchChatsRooms", + "groupName", + "createGroupAndInviteUsers", + "groupCanBeFoundViaSearch", + "inNoSpaces" + ], + + "sv": [ + "accountInformation", + "addNewFriend", + "alreadyHaveAnAccount", + "classes", + "allCorrect", + "newWayAllGood", + "othersAreBetter", + "holdForInfo", + "greenFeedback", + "yellowFeedback", + "redFeedback", + "customInputFeedbackChoice", + "itInstructionsTitle", + "itInstructionsBody", + "toggleLanguages", + "classWelcomeChat", + "deleteSpace", + "deleteGroup", + "areYouSureDeleteClass", + "areYouSureDeleteGroup", + "cannotBeReversed", + "enterDeletedClassName", + "incorrectClassName", + "oneday", + "oneweek", + "onemonth", + "sixmonth", + "oneyear", + "gaTooltip", + "taTooltip", + "unTooltip", + "interactiveTranslatorSliderHeader", + "interactiveGrammarSliderHeader", + "interactiveTranslatorNotAllowed", + "interactiveTranslatorAllowed", + "interactiveTranslatorRequired", + "interactiveTranslatorNotAllowedDesc", + "interactiveTranslatorAllowedDesc", + "interactiveTranslatorRequiredDesc", + "notYetSet", + "multiLingualClass", + "classAnalytics", + "allClasses", + "myLearning", + "allChatsAndClasses", + "timeOfLastMessage", + "totalMessages", + "waTooltip", + "changeDateRange", + "numberOfStudents", + "classDescription", + "classDescriptionDesc", + "requestToEnroll", + "requestAnExchange", + "findLanguageExchange", + "classAnalyticsDesc", + "addStudents", + "copyClassLink", + "copyClassLinkDesc", + "copyClassCode", + "inviteStudentByUserName", + "classSettings", + "classSettingsDesc", + "selectClassRoomDominantLanguage", + "selectTargetLanguage", + "whatIsYourClassLanguageLevel", + "studentPermissions", + "interactiveTranslator", + "oneToOneChatsWithinClass", + "oneToOneChatsWithinClassDesc", + "createGroupChats", + "createGroupChatsDesc", + "shareVideo", + "shareVideoDesc", + "sharePhotos", + "sharePhotosDesc", + "shareFiles", + "shareFilesDesc", + "shareLocationDesc", + "selectLanguageLevel", + "noIdenticalLanguages", + "iWantALanguagePartnerFrom", + "worldWide", + "noResults", + "searchBy", + "iWantAConversationPartner", + "iWantALanguagePartnerWhoSpeaks", + "iWantALanguagePartnerWhoIsLearning", + "yourBirthdayPlease", + "invalidDob", + "enterYourDob", + "getStarted", + "mustBe13", + "yourBirthdayPleaseShort", + "errorPleaseRefresh", + "joinWithClassCode", + "joinWithClassCodeDesc", + "joinWithClassCodeHint", + "unableToFindClass", + "languageLevelPreA1", + "languageLevelA1", + "languageLevelA2", + "languageLevelB1", + "languageLevelB2", + "languageLevelC1", + "languageLevelC2", + "changeTheNameOfTheClass", + "changeTheNameOfTheChat", + "welcomeToYourNewClass", + "welcomeToClass", + "welcomeToPangea18Plus", + "welcomeToPangeaMinor", + "findALanguagePartner", + "setToPublicSettingsTitle", + "setToPublicSettingsDesc", + "accountSettings", + "unableToFindClassCode", + "askPangeaBot", + "sorryNoResults", + "ignoreInThisText", + "helpMeTranslate", + "needsItShortMessage", + "needsIGCShortMessage", + "needsItMessage", + "needsIgcMessage", + "tokenTranslationTitle", + "spanTranslationDesc", + "spanTranslationTitle", + "l1SpanAndGrammarTitle", + "l1SpanAndGrammarDesc", + "otherTitle", + "otherDesc", + "countryInformation", + "myLanguages", + "targetLanguage", + "sourceLanguage", + "languagesISpeak", + "updateLanguage", + "whatLanguageYouWantToLearn", + "whatIsYourBaseLanguage", + "saveChanges", + "publicProfileTitle", + "publicProfileDesc", + "error502504Title", + "error502504Desc", + "error404Title", + "error404Desc", + "errorDisableIT", + "errorDisableIGC", + "errorDisableLanguageAssistance", + "errorDisableITUserDesc", + "errorDisableIGCUserDesc", + "errorDisableLanguageAssistanceUserDesc", + "errorDisableITClassDesc", + "errorDisableIGCClassDesc", + "errorDisableLanguageAssistanceClassDesc", + "itIsDisabled", + "igcIsDisabled", + "goToLearningSettings", + "error405Title", + "error405Desc", + "loginOrSignup", + "iAgreeToThe", + "termsAndConditions", + "andCertifyIAmAtLeast13YearsOfAge", + "findAClass", + "toggleIT", + "toggleIGC", + "toggleToolSettingsDescription", + "connectedToStaging", + "learningSettings", + "classNameRequired", + "sendVoiceNotes", + "sendVoiceNotesDesc", + "chatTopic", + "chatTopicDesc", + "inviteStudentByUserNameDesc", + "classRoster", + "almostPerfect", + "prettyGood", + "letMeThink", + "clickMessageTitle", + "clickMessageBody", + "understandingMessagesTitle", + "addToClass", + "understandingMessagesBody", + "allDone", + "vocab", + "low", + "medium", + "high", + "unknownProficiency", + "changeView", + "clearAll", + "generateVocabulary", + "generatePrompts", + "subscribe", + "getAccess", + "subscriptionDesc", + "subscriptionManagement", + "currentSubscription", + "changeSubscription", + "cancelSubscription", + "selectYourPlan", + "subsciptionPlatformTooltip", + "subscriptionManagementUnavailable", + "paymentMethod", + "paymentHistory", + "emptyChatDownloadWarning", + "appUpdateAvailable", + "update", + "updateDesc", + "maybeLater", + "mainMenu", + "toggleImmersionMode", + "toggleImmersionModeDesc", + "itToggleDescription", + "igcToggleDescription", + "sendOnEnterDescription", + "alreadyInClass", + "pleaseLoginFirst", + "originalMessage", + "sentMessage", + "useType", + "notAvailable", + "taAndGaTooltip", + "definitionsToolName", + "messageTranslationsToolName", + "definitionsToolDescription", + "translationsToolDescrption", + "welcomeBack", + "classExchanges", + "createNewClass", + "newExchange", + "kickAllStudents", + "kickAllStudentsConfirmation", + "inviteAllStudents", + "inviteAllStudentsConfirmation", + "inviteStudentsFromOtherClasses", + "inviteUsersFromPangea", + "allExchanges", + "redeemPromoCode", + "enterPromoCode", + "downloadTxtFile", + "downloadCSVFile", + "promotionalSubscriptionDesc", + "originalSubscriptionPlatform", + "oneWeekTrial", + "creatingSpacePleaseWait", + "downloadXLSXFile", + "abDisplayName", + "aaDisplayName", + "afDisplayName", + "akDisplayName", + "sqDisplayName", + "amDisplayName", + "arDisplayName", + "anDisplayName", + "hyDisplayName", + "asDisplayName", + "avDisplayName", + "aeDisplayName", + "ayDisplayName", + "azDisplayName", + "bmDisplayName", + "baDisplayName", + "euDisplayName", + "beDisplayName", + "bnDisplayName", + "bhDisplayName", + "biDisplayName", + "bsDisplayName", + "brDisplayName", + "bgDisplayName", + "myDisplayName", + "caDisplayName", + "chDisplayName", + "ceDisplayName", + "nyDisplayName", + "zhDisplayName", + "cvDisplayName", + "kwDisplayName", + "coDisplayName", + "crDisplayName", + "hrDisplayName", + "csDisplayName", + "daDisplayName", + "dvDisplayName", + "nlDisplayName", + "enDisplayName", + "eoDisplayName", + "etDisplayName", + "eeDisplayName", + "foDisplayName", + "fjDisplayName", + "fiDisplayName", + "frDisplayName", + "ffDisplayName", + "glDisplayName", + "kaDisplayName", + "deDisplayName", + "elDisplayName", + "gnDisplayName", + "guDisplayName", + "htDisplayName", + "haDisplayName", + "heDisplayName", + "hzDisplayName", + "hiDisplayName", + "hoDisplayName", + "huDisplayName", + "iaDisplayName", + "idDisplayName", + "ieDisplayName", + "gaDisplayName", + "igDisplayName", + "ikDisplayName", + "ioDisplayName", + "isDisplayName", + "itDisplayName", + "iuDisplayName", + "jaDisplayName", + "jvDisplayName", + "klDisplayName", + "knDisplayName", + "krDisplayName", + "ksDisplayName", + "kkDisplayName", + "kmDisplayName", + "kiDisplayName", + "rwDisplayName", + "kyDisplayName", + "kvDisplayName", + "kgDisplayName", + "koDisplayName", + "kuDisplayName", + "kjDisplayName", + "laDisplayName", + "lbDisplayName", + "lgDisplayName", + "liDisplayName", + "lnDisplayName", + "loDisplayName", + "ltDisplayName", + "luDisplayName", + "lvDisplayName", + "gvDisplayName", + "mkDisplayName", + "mgDisplayName", + "msDisplayName", + "mlDisplayName", + "mtDisplayName", + "miDisplayName", + "mrDisplayName", + "mhDisplayName", + "mnDisplayName", + "naDisplayName", + "nvDisplayName", + "nbDisplayName", + "ndDisplayName", + "neDisplayName", + "ngDisplayName", + "nnDisplayName", + "noDisplayName", + "iiDisplayName", + "nrDisplayName", + "ocDisplayName", + "ojDisplayName", + "cuDisplayName", + "omDisplayName", + "orDisplayName", + "osDisplayName", + "paDisplayName", + "piDisplayName", + "faDisplayName", + "plDisplayName", + "psDisplayName", + "ptDisplayName", + "quDisplayName", + "rmDisplayName", + "rnDisplayName", + "roDisplayName", + "ruDisplayName", + "saDisplayName", + "scDisplayName", + "sdDisplayName", + "seDisplayName", + "smDisplayName", + "sgDisplayName", + "srDisplayName", + "gdDisplayName", + "snDisplayName", + "siDisplayName", + "skDisplayName", + "slDisplayName", + "soDisplayName", + "stDisplayName", + "esDisplayName", + "suDisplayName", + "swDisplayName", + "ssDisplayName", + "svDisplayName", + "taDisplayName", + "teDisplayName", + "tgDisplayName", + "thDisplayName", + "tiDisplayName", + "boDisplayName", + "tkDisplayName", + "tlDisplayName", + "tnDisplayName", + "toDisplayName", + "trDisplayName", + "tsDisplayName", + "ttDisplayName", + "twDisplayName", + "tyDisplayName", + "ugDisplayName", + "ukDisplayName", + "urDisplayName", + "uzDisplayName", + "veDisplayName", + "viDisplayName", + "voDisplayName", + "waDisplayName", + "cyDisplayName", + "woDisplayName", + "fyDisplayName", + "xhDisplayName", + "yiDisplayName", + "yoDisplayName", + "zaDisplayName", + "unkDisplayName", + "zuDisplayName", + "hawDisplayName", + "hmnDisplayName", + "multiDisplayName", + "cebDisplayName", + "dzDisplayName", + "iwDisplayName", + "jwDisplayName", + "moDisplayName", + "shDisplayName", + "wwCountryDisplayName", + "afCountryDisplayName", + "axCountryDisplayName", + "alCountryDisplayName", + "dzCountryDisplayName", + "asCountryDisplayName", + "adCountryDisplayName", + "aoCountryDisplayName", + "aiCountryDisplayName", + "agCountryDisplayName", + "arCountryDisplayName", + "amCountryDisplayName", + "awCountryDisplayName", + "acCountryDisplayName", + "auCountryDisplayName", + "atCountryDisplayName", + "azCountryDisplayName", + "bsCountryDisplayName", + "bhCountryDisplayName", + "bdCountryDisplayName", + "bbCountryDisplayName", + "byCountryDisplayName", + "beCountryDisplayName", + "bzCountryDisplayName", + "bjCountryDisplayName", + "bmCountryDisplayName", + "btCountryDisplayName", + "boCountryDisplayName", + "baCountryDisplayName", + "bwCountryDisplayName", + "brCountryDisplayName", + "ioCountryDisplayName", + "vgCountryDisplayName", + "bnCountryDisplayName", + "bgCountryDisplayName", + "bfCountryDisplayName", + "biCountryDisplayName", + "khCountryDisplayName", + "cmCountryDisplayName", + "caCountryDisplayName", + "cvCountryDisplayName", + "bqCountryDisplayName", + "kyCountryDisplayName", + "cfCountryDisplayName", + "tdCountryDisplayName", + "clCountryDisplayName", + "cnCountryDisplayName", + "cxCountryDisplayName", + "ccCountryDisplayName", + "coCountryDisplayName", + "kmCountryDisplayName", + "cdCountryDisplayName", + "cgCountryDisplayName", + "ckCountryDisplayName", + "crCountryDisplayName", + "ciCountryDisplayName", + "hrCountryDisplayName", + "cuCountryDisplayName", + "cwCountryDisplayName", + "cyCountryDisplayName", + "czCountryDisplayName", + "dkCountryDisplayName", + "djCountryDisplayName", + "dmCountryDisplayName", + "doCountryDisplayName", + "tlCountryDisplayName", + "ecCountryDisplayName", + "egCountryDisplayName", + "svCountryDisplayName", + "gqCountryDisplayName", + "erCountryDisplayName", + "eeCountryDisplayName", + "szCountryDisplayName", + "etCountryDisplayName", + "fkCountryDisplayName", + "foCountryDisplayName", + "fjCountryDisplayName", + "fiCountryDisplayName", + "frCountryDisplayName", + "gfCountryDisplayName", + "pfCountryDisplayName", + "gaCountryDisplayName", + "gmCountryDisplayName", + "geCountryDisplayName", + "deCountryDisplayName", + "ghCountryDisplayName", + "giCountryDisplayName", + "grCountryDisplayName", + "glCountryDisplayName", + "gdCountryDisplayName", + "gpCountryDisplayName", + "guCountryDisplayName", + "gtCountryDisplayName", + "ggCountryDisplayName", + "gnCountryDisplayName", + "gwCountryDisplayName", + "gyCountryDisplayName", + "htCountryDisplayName", + "hmCountryDisplayName", + "hnCountryDisplayName", + "hkCountryDisplayName", + "huCountryDisplayName", + "isCountryDisplayName", + "inCountryDisplayName", + "idCountryDisplayName", + "irCountryDisplayName", + "iqCountryDisplayName", + "ieCountryDisplayName", + "imCountryDisplayName", + "ilCountryDisplayName", + "itCountryDisplayName", + "jmCountryDisplayName", + "jpCountryDisplayName", + "jeCountryDisplayName", + "joCountryDisplayName", + "kzCountryDisplayName", + "keCountryDisplayName", + "kiCountryDisplayName", + "xkCountryDisplayName", + "kwCountryDisplayName", + "kgCountryDisplayName", + "laCountryDisplayName", + "lvCountryDisplayName", + "lbCountryDisplayName", + "lsCountryDisplayName", + "lrCountryDisplayName", + "lyCountryDisplayName", + "liCountryDisplayName", + "ltCountryDisplayName", + "luCountryDisplayName", + "moCountryDisplayName", + "mkCountryDisplayName", + "mgCountryDisplayName", + "mwCountryDisplayName", + "myCountryDisplayName", + "mvCountryDisplayName", + "mlCountryDisplayName", + "mtCountryDisplayName", + "mhCountryDisplayName", + "mqCountryDisplayName", + "mrCountryDisplayName", + "muCountryDisplayName", + "ytCountryDisplayName", + "mxCountryDisplayName", + "fmCountryDisplayName", + "mdCountryDisplayName", + "mcCountryDisplayName", + "mnCountryDisplayName", + "meCountryDisplayName", + "msCountryDisplayName", + "maCountryDisplayName", + "mzCountryDisplayName", + "mmCountryDisplayName", + "naCountryDisplayName", + "nrCountryDisplayName", + "npCountryDisplayName", + "nlCountryDisplayName", + "ncCountryDisplayName", + "nzCountryDisplayName", + "niCountryDisplayName", + "neCountryDisplayName", + "ngCountryDisplayName", + "nuCountryDisplayName", + "nfCountryDisplayName", + "kpCountryDisplayName", + "mpCountryDisplayName", + "noCountryDisplayName", + "omCountryDisplayName", + "pkCountryDisplayName", + "pwCountryDisplayName", + "psCountryDisplayName", + "paCountryDisplayName", + "pgCountryDisplayName", + "pyCountryDisplayName", + "peCountryDisplayName", + "phCountryDisplayName", + "plCountryDisplayName", + "ptCountryDisplayName", + "prCountryDisplayName", + "qaCountryDisplayName", + "reCountryDisplayName", + "roCountryDisplayName", + "ruCountryDisplayName", + "rwCountryDisplayName", + "blCountryDisplayName", + "shCountryDisplayName", + "knCountryDisplayName", + "lcCountryDisplayName", + "mfCountryDisplayName", + "pmCountryDisplayName", + "vcCountryDisplayName", + "wsCountryDisplayName", + "smCountryDisplayName", + "stCountryDisplayName", + "saCountryDisplayName", + "snCountryDisplayName", + "rsCountryDisplayName", + "scCountryDisplayName", + "slCountryDisplayName", + "sgCountryDisplayName", + "sxCountryDisplayName", + "skCountryDisplayName", + "siCountryDisplayName", + "sbCountryDisplayName", + "soCountryDisplayName", + "zaCountryDisplayName", + "gsCountryDisplayName", + "krCountryDisplayName", + "ssCountryDisplayName", + "esCountryDisplayName", + "lkCountryDisplayName", + "sdCountryDisplayName", + "srCountryDisplayName", + "sjCountryDisplayName", + "seCountryDisplayName", + "chCountryDisplayName", + "syCountryDisplayName", + "twCountryDisplayName", + "tjCountryDisplayName", + "tzCountryDisplayName", + "thCountryDisplayName", + "tgCountryDisplayName", + "tkCountryDisplayName", + "toCountryDisplayName", + "ttCountryDisplayName", + "tnCountryDisplayName", + "trCountryDisplayName", + "tmCountryDisplayName", + "tcCountryDisplayName", + "tvCountryDisplayName", + "viCountryDisplayName", + "ugCountryDisplayName", + "uaCountryDisplayName", + "aeCountryDisplayName", + "gbCountryDisplayName", + "usCountryDisplayName", + "uyCountryDisplayName", + "uzCountryDisplayName", + "vuCountryDisplayName", + "vaCountryDisplayName", + "veCountryDisplayName", + "vnCountryDisplayName", + "wfCountryDisplayName", + "ehCountryDisplayName", + "yeCountryDisplayName", + "zmCountryDisplayName", + "zwCountryDisplayName", + "pay", + "allPrivateChats", + "unknownPrivateChat", + "copyClassCodeDesc", + "addToClassDesc", + "addToClassOrExchange", + "addToClassOrExchangeDesc", + "invitedToClassOrExchange", + "decline", + "declinedInvitation", + "acceptedInvitation", + "youreInvited", + "studentPermissionsDesc", + "noEligibleSpaces", + "youAddedToSpace", + "youRemovedFromSpace", + "invitedToChat", + "monthlySubscription", + "yearlySubscription", + "defaultSubscription", + "freeTrial", + "grammarAnalytics", + "total", + "noDataFound", + "promoSubscriptionExpirationDesc", + "emptyChatNameWarning", + "emptyClassNameWarning", + "emptyExchangeNameWarning", + "blurMeansTranslateTitle", + "blurMeansTranslateBody", + "someErrorTitle", + "someErrorBody", + "bestCorrectionFeedback", + "distractorFeedback", + "bestAnswerFeedback", + "definitionDefaultPrompt", + "practiceDefaultPrompt", + "correctionDefaultPrompt", + "itStartDefaultPrompt", + "languageLevelWarning", + "lockedChatWarning", + "lockSpace", + "lockChat", + "archiveSpace", + "suggestTo", + "suggestChatDesc", + "suggestExchangeDesc", + "acceptSelection", + "acceptSelectionAnyway", + "makingActivity", + "why", + "definition", + "exampleSentence", + "addToClassTitle", + "reportToTeacher", + "reportMessageTitle", + "reportMessageBody", + "noTeachersFound", + "noAddToSpacePermissions", + "alreadyInSpace", + "yourGlobalUserIdIs", + "noUsersFoundWithQuery", + "searchChatsRooms", + "groupName", + "createGroupAndInviteUsers", + "groupCanBeFoundViaSearch", + "inNoSpaces" + ], + + "ta": [ + "accountInformation", + "addGroupDescription", + "addNewFriend", + "alreadyHaveAnAccount", + "classes", + "createNewGroup", + "editChatPermissions", + "groupDescription", + "groupDescriptionHasBeenChanged", + "allCorrect", + "newWayAllGood", + "othersAreBetter", + "holdForInfo", + "greenFeedback", + "yellowFeedback", + "redFeedback", + "customInputFeedbackChoice", + "itInstructionsTitle", + "itInstructionsBody", + "toggleLanguages", + "classWelcomeChat", + "deleteSpace", + "deleteGroup", + "areYouSureDeleteClass", + "areYouSureDeleteGroup", + "cannotBeReversed", + "enterDeletedClassName", + "incorrectClassName", + "oneday", + "oneweek", + "onemonth", + "sixmonth", + "oneyear", + "gaTooltip", + "taTooltip", + "unTooltip", + "interactiveTranslatorSliderHeader", + "interactiveGrammarSliderHeader", + "interactiveTranslatorNotAllowed", + "interactiveTranslatorAllowed", + "interactiveTranslatorRequired", + "interactiveTranslatorNotAllowedDesc", + "interactiveTranslatorAllowedDesc", + "interactiveTranslatorRequiredDesc", + "notYetSet", + "multiLingualClass", + "classAnalytics", + "allClasses", + "myLearning", + "allChatsAndClasses", + "timeOfLastMessage", + "totalMessages", + "waTooltip", + "changeDateRange", + "numberOfStudents", + "classDescription", + "classDescriptionDesc", + "requestToEnroll", + "requestAnExchange", + "findLanguageExchange", + "classAnalyticsDesc", + "addStudents", + "copyClassLink", + "copyClassLinkDesc", + "copyClassCode", + "inviteStudentByUserName", + "classSettings", + "classSettingsDesc", + "selectClassRoomDominantLanguage", + "selectTargetLanguage", + "whatIsYourClassLanguageLevel", + "studentPermissions", + "interactiveTranslator", + "oneToOneChatsWithinClass", + "oneToOneChatsWithinClassDesc", + "createGroupChats", + "createGroupChatsDesc", + "shareVideo", + "shareVideoDesc", + "sharePhotos", + "sharePhotosDesc", + "shareFiles", + "shareFilesDesc", + "shareLocationDesc", + "selectLanguageLevel", + "noIdenticalLanguages", + "iWantALanguagePartnerFrom", + "worldWide", + "noResults", + "searchBy", + "iWantAConversationPartner", + "iWantALanguagePartnerWhoSpeaks", + "iWantALanguagePartnerWhoIsLearning", + "yourBirthdayPlease", + "invalidDob", + "enterYourDob", + "getStarted", + "mustBe13", + "yourBirthdayPleaseShort", + "errorPleaseRefresh", + "joinWithClassCode", + "joinWithClassCodeDesc", + "joinWithClassCodeHint", + "unableToFindClass", + "languageLevelPreA1", + "languageLevelA1", + "languageLevelA2", + "languageLevelB1", + "languageLevelB2", + "languageLevelC1", + "languageLevelC2", + "changeTheNameOfTheClass", + "changeTheNameOfTheChat", + "welcomeToYourNewClass", + "welcomeToClass", + "welcomeToPangea18Plus", + "welcomeToPangeaMinor", + "findALanguagePartner", + "setToPublicSettingsTitle", + "setToPublicSettingsDesc", + "accountSettings", + "unableToFindClassCode", + "askPangeaBot", + "sorryNoResults", + "ignoreInThisText", + "helpMeTranslate", + "needsItShortMessage", + "needsIGCShortMessage", + "needsItMessage", + "needsIgcMessage", + "tokenTranslationTitle", + "spanTranslationDesc", + "spanTranslationTitle", + "l1SpanAndGrammarTitle", + "l1SpanAndGrammarDesc", + "otherTitle", + "otherDesc", + "countryInformation", + "myLanguages", + "targetLanguage", + "sourceLanguage", + "languagesISpeak", + "updateLanguage", + "whatLanguageYouWantToLearn", + "whatIsYourBaseLanguage", + "saveChanges", + "publicProfileTitle", + "publicProfileDesc", + "error502504Title", + "error502504Desc", + "error404Title", + "error404Desc", + "errorDisableIT", + "errorDisableIGC", + "errorDisableLanguageAssistance", + "errorDisableITUserDesc", + "errorDisableIGCUserDesc", + "errorDisableLanguageAssistanceUserDesc", + "errorDisableITClassDesc", + "errorDisableIGCClassDesc", + "errorDisableLanguageAssistanceClassDesc", + "itIsDisabled", + "igcIsDisabled", + "goToLearningSettings", + "error405Title", + "error405Desc", + "loginOrSignup", + "iAgreeToThe", + "termsAndConditions", + "andCertifyIAmAtLeast13YearsOfAge", + "findAClass", + "toggleIT", + "toggleIGC", + "toggleToolSettingsDescription", + "connectedToStaging", + "learningSettings", + "classNameRequired", + "sendVoiceNotes", + "sendVoiceNotesDesc", + "chatTopic", + "chatTopicDesc", + "inviteStudentByUserNameDesc", + "classRoster", + "almostPerfect", + "prettyGood", + "letMeThink", + "clickMessageTitle", + "clickMessageBody", + "understandingMessagesTitle", + "addToClass", + "understandingMessagesBody", + "allDone", + "vocab", + "low", + "medium", + "high", + "unknownProficiency", + "changeView", + "clearAll", + "generateVocabulary", + "generatePrompts", + "subscribe", + "getAccess", + "subscriptionDesc", + "subscriptionManagement", + "currentSubscription", + "changeSubscription", + "cancelSubscription", + "selectYourPlan", + "subsciptionPlatformTooltip", + "subscriptionManagementUnavailable", + "paymentMethod", + "paymentHistory", + "emptyChatDownloadWarning", + "appUpdateAvailable", + "update", + "updateDesc", + "maybeLater", + "mainMenu", + "toggleImmersionMode", + "toggleImmersionModeDesc", + "itToggleDescription", + "igcToggleDescription", + "sendOnEnterDescription", + "alreadyInClass", + "pleaseLoginFirst", + "originalMessage", + "sentMessage", + "useType", + "notAvailable", + "taAndGaTooltip", + "definitionsToolName", + "messageTranslationsToolName", + "definitionsToolDescription", + "translationsToolDescrption", + "welcomeBack", + "classExchanges", + "createNewClass", + "newExchange", + "kickAllStudents", + "kickAllStudentsConfirmation", + "inviteAllStudents", + "inviteAllStudentsConfirmation", + "inviteStudentsFromOtherClasses", + "inviteUsersFromPangea", + "allExchanges", + "redeemPromoCode", + "enterPromoCode", + "downloadTxtFile", + "downloadCSVFile", + "promotionalSubscriptionDesc", + "originalSubscriptionPlatform", + "oneWeekTrial", + "creatingSpacePleaseWait", + "downloadXLSXFile", + "abDisplayName", + "aaDisplayName", + "afDisplayName", + "akDisplayName", + "sqDisplayName", + "amDisplayName", + "arDisplayName", + "anDisplayName", + "hyDisplayName", + "asDisplayName", + "avDisplayName", + "aeDisplayName", + "ayDisplayName", + "azDisplayName", + "bmDisplayName", + "baDisplayName", + "euDisplayName", + "beDisplayName", + "bnDisplayName", + "bhDisplayName", + "biDisplayName", + "bsDisplayName", + "brDisplayName", + "bgDisplayName", + "myDisplayName", + "caDisplayName", + "chDisplayName", + "ceDisplayName", + "nyDisplayName", + "zhDisplayName", + "cvDisplayName", + "kwDisplayName", + "coDisplayName", + "crDisplayName", + "hrDisplayName", + "csDisplayName", + "daDisplayName", + "dvDisplayName", + "nlDisplayName", + "enDisplayName", + "eoDisplayName", + "etDisplayName", + "eeDisplayName", + "foDisplayName", + "fjDisplayName", + "fiDisplayName", + "frDisplayName", + "ffDisplayName", + "glDisplayName", + "kaDisplayName", + "deDisplayName", + "elDisplayName", + "gnDisplayName", + "guDisplayName", + "htDisplayName", + "haDisplayName", + "heDisplayName", + "hzDisplayName", + "hiDisplayName", + "hoDisplayName", + "huDisplayName", + "iaDisplayName", + "idDisplayName", + "ieDisplayName", + "gaDisplayName", + "igDisplayName", + "ikDisplayName", + "ioDisplayName", + "isDisplayName", + "itDisplayName", + "iuDisplayName", + "jaDisplayName", + "jvDisplayName", + "klDisplayName", + "knDisplayName", + "krDisplayName", + "ksDisplayName", + "kkDisplayName", + "kmDisplayName", + "kiDisplayName", + "rwDisplayName", + "kyDisplayName", + "kvDisplayName", + "kgDisplayName", + "koDisplayName", + "kuDisplayName", + "kjDisplayName", + "laDisplayName", + "lbDisplayName", + "lgDisplayName", + "liDisplayName", + "lnDisplayName", + "loDisplayName", + "ltDisplayName", + "luDisplayName", + "lvDisplayName", + "gvDisplayName", + "mkDisplayName", + "mgDisplayName", + "msDisplayName", + "mlDisplayName", + "mtDisplayName", + "miDisplayName", + "mrDisplayName", + "mhDisplayName", + "mnDisplayName", + "naDisplayName", + "nvDisplayName", + "nbDisplayName", + "ndDisplayName", + "neDisplayName", + "ngDisplayName", + "nnDisplayName", + "noDisplayName", + "iiDisplayName", + "nrDisplayName", + "ocDisplayName", + "ojDisplayName", + "cuDisplayName", + "omDisplayName", + "orDisplayName", + "osDisplayName", + "paDisplayName", + "piDisplayName", + "faDisplayName", + "plDisplayName", + "psDisplayName", + "ptDisplayName", + "quDisplayName", + "rmDisplayName", + "rnDisplayName", + "roDisplayName", + "ruDisplayName", + "saDisplayName", + "scDisplayName", + "sdDisplayName", + "seDisplayName", + "smDisplayName", + "sgDisplayName", + "srDisplayName", + "gdDisplayName", + "snDisplayName", + "siDisplayName", + "skDisplayName", + "slDisplayName", + "soDisplayName", + "stDisplayName", + "esDisplayName", + "suDisplayName", + "swDisplayName", + "ssDisplayName", + "svDisplayName", + "taDisplayName", + "teDisplayName", + "tgDisplayName", + "thDisplayName", + "tiDisplayName", + "boDisplayName", + "tkDisplayName", + "tlDisplayName", + "tnDisplayName", + "toDisplayName", + "trDisplayName", + "tsDisplayName", + "ttDisplayName", + "twDisplayName", + "tyDisplayName", + "ugDisplayName", + "ukDisplayName", + "urDisplayName", + "uzDisplayName", + "veDisplayName", + "viDisplayName", + "voDisplayName", + "waDisplayName", + "cyDisplayName", + "woDisplayName", + "fyDisplayName", + "xhDisplayName", + "yiDisplayName", + "yoDisplayName", + "zaDisplayName", + "unkDisplayName", + "zuDisplayName", + "hawDisplayName", + "hmnDisplayName", + "multiDisplayName", + "cebDisplayName", + "dzDisplayName", + "iwDisplayName", + "jwDisplayName", + "moDisplayName", + "shDisplayName", + "wwCountryDisplayName", + "afCountryDisplayName", + "axCountryDisplayName", + "alCountryDisplayName", + "dzCountryDisplayName", + "asCountryDisplayName", + "adCountryDisplayName", + "aoCountryDisplayName", + "aiCountryDisplayName", + "agCountryDisplayName", + "arCountryDisplayName", + "amCountryDisplayName", + "awCountryDisplayName", + "acCountryDisplayName", + "auCountryDisplayName", + "atCountryDisplayName", + "azCountryDisplayName", + "bsCountryDisplayName", + "bhCountryDisplayName", + "bdCountryDisplayName", + "bbCountryDisplayName", + "byCountryDisplayName", + "beCountryDisplayName", + "bzCountryDisplayName", + "bjCountryDisplayName", + "bmCountryDisplayName", + "btCountryDisplayName", + "boCountryDisplayName", + "baCountryDisplayName", + "bwCountryDisplayName", + "brCountryDisplayName", + "ioCountryDisplayName", + "vgCountryDisplayName", + "bnCountryDisplayName", + "bgCountryDisplayName", + "bfCountryDisplayName", + "biCountryDisplayName", + "khCountryDisplayName", + "cmCountryDisplayName", + "caCountryDisplayName", + "cvCountryDisplayName", + "bqCountryDisplayName", + "kyCountryDisplayName", + "cfCountryDisplayName", + "tdCountryDisplayName", + "clCountryDisplayName", + "cnCountryDisplayName", + "cxCountryDisplayName", + "ccCountryDisplayName", + "coCountryDisplayName", + "kmCountryDisplayName", + "cdCountryDisplayName", + "cgCountryDisplayName", + "ckCountryDisplayName", + "crCountryDisplayName", + "ciCountryDisplayName", + "hrCountryDisplayName", + "cuCountryDisplayName", + "cwCountryDisplayName", + "cyCountryDisplayName", + "czCountryDisplayName", + "dkCountryDisplayName", + "djCountryDisplayName", + "dmCountryDisplayName", + "doCountryDisplayName", + "tlCountryDisplayName", + "ecCountryDisplayName", + "egCountryDisplayName", + "svCountryDisplayName", + "gqCountryDisplayName", + "erCountryDisplayName", + "eeCountryDisplayName", + "szCountryDisplayName", + "etCountryDisplayName", + "fkCountryDisplayName", + "foCountryDisplayName", + "fjCountryDisplayName", + "fiCountryDisplayName", + "frCountryDisplayName", + "gfCountryDisplayName", + "pfCountryDisplayName", + "gaCountryDisplayName", + "gmCountryDisplayName", + "geCountryDisplayName", + "deCountryDisplayName", + "ghCountryDisplayName", + "giCountryDisplayName", + "grCountryDisplayName", + "glCountryDisplayName", + "gdCountryDisplayName", + "gpCountryDisplayName", + "guCountryDisplayName", + "gtCountryDisplayName", + "ggCountryDisplayName", + "gnCountryDisplayName", + "gwCountryDisplayName", + "gyCountryDisplayName", + "htCountryDisplayName", + "hmCountryDisplayName", + "hnCountryDisplayName", + "hkCountryDisplayName", + "huCountryDisplayName", + "isCountryDisplayName", + "inCountryDisplayName", + "idCountryDisplayName", + "irCountryDisplayName", + "iqCountryDisplayName", + "ieCountryDisplayName", + "imCountryDisplayName", + "ilCountryDisplayName", + "itCountryDisplayName", + "jmCountryDisplayName", + "jpCountryDisplayName", + "jeCountryDisplayName", + "joCountryDisplayName", + "kzCountryDisplayName", + "keCountryDisplayName", + "kiCountryDisplayName", + "xkCountryDisplayName", + "kwCountryDisplayName", + "kgCountryDisplayName", + "laCountryDisplayName", + "lvCountryDisplayName", + "lbCountryDisplayName", + "lsCountryDisplayName", + "lrCountryDisplayName", + "lyCountryDisplayName", + "liCountryDisplayName", + "ltCountryDisplayName", + "luCountryDisplayName", + "moCountryDisplayName", + "mkCountryDisplayName", + "mgCountryDisplayName", + "mwCountryDisplayName", + "myCountryDisplayName", + "mvCountryDisplayName", + "mlCountryDisplayName", + "mtCountryDisplayName", + "mhCountryDisplayName", + "mqCountryDisplayName", + "mrCountryDisplayName", + "muCountryDisplayName", + "ytCountryDisplayName", + "mxCountryDisplayName", + "fmCountryDisplayName", + "mdCountryDisplayName", + "mcCountryDisplayName", + "mnCountryDisplayName", + "meCountryDisplayName", + "msCountryDisplayName", + "maCountryDisplayName", + "mzCountryDisplayName", + "mmCountryDisplayName", + "naCountryDisplayName", + "nrCountryDisplayName", + "npCountryDisplayName", + "nlCountryDisplayName", + "ncCountryDisplayName", + "nzCountryDisplayName", + "niCountryDisplayName", + "neCountryDisplayName", + "ngCountryDisplayName", + "nuCountryDisplayName", + "nfCountryDisplayName", + "kpCountryDisplayName", + "mpCountryDisplayName", + "noCountryDisplayName", + "omCountryDisplayName", + "pkCountryDisplayName", + "pwCountryDisplayName", + "psCountryDisplayName", + "paCountryDisplayName", + "pgCountryDisplayName", + "pyCountryDisplayName", + "peCountryDisplayName", + "phCountryDisplayName", + "plCountryDisplayName", + "ptCountryDisplayName", + "prCountryDisplayName", + "qaCountryDisplayName", + "reCountryDisplayName", + "roCountryDisplayName", + "ruCountryDisplayName", + "rwCountryDisplayName", + "blCountryDisplayName", + "shCountryDisplayName", + "knCountryDisplayName", + "lcCountryDisplayName", + "mfCountryDisplayName", + "pmCountryDisplayName", + "vcCountryDisplayName", + "wsCountryDisplayName", + "smCountryDisplayName", + "stCountryDisplayName", + "saCountryDisplayName", + "snCountryDisplayName", + "rsCountryDisplayName", + "scCountryDisplayName", + "slCountryDisplayName", + "sgCountryDisplayName", + "sxCountryDisplayName", + "skCountryDisplayName", + "siCountryDisplayName", + "sbCountryDisplayName", + "soCountryDisplayName", + "zaCountryDisplayName", + "gsCountryDisplayName", + "krCountryDisplayName", + "ssCountryDisplayName", + "esCountryDisplayName", + "lkCountryDisplayName", + "sdCountryDisplayName", + "srCountryDisplayName", + "sjCountryDisplayName", + "seCountryDisplayName", + "chCountryDisplayName", + "syCountryDisplayName", + "twCountryDisplayName", + "tjCountryDisplayName", + "tzCountryDisplayName", + "thCountryDisplayName", + "tgCountryDisplayName", + "tkCountryDisplayName", + "toCountryDisplayName", + "ttCountryDisplayName", + "tnCountryDisplayName", + "trCountryDisplayName", + "tmCountryDisplayName", + "tcCountryDisplayName", + "tvCountryDisplayName", + "viCountryDisplayName", + "ugCountryDisplayName", + "uaCountryDisplayName", + "aeCountryDisplayName", + "gbCountryDisplayName", + "usCountryDisplayName", + "uyCountryDisplayName", + "uzCountryDisplayName", + "vuCountryDisplayName", + "vaCountryDisplayName", + "veCountryDisplayName", + "vnCountryDisplayName", + "wfCountryDisplayName", + "ehCountryDisplayName", + "yeCountryDisplayName", + "zmCountryDisplayName", + "zwCountryDisplayName", + "pay", + "allPrivateChats", + "unknownPrivateChat", + "copyClassCodeDesc", + "addToClassDesc", + "addToClassOrExchange", + "addToClassOrExchangeDesc", + "invitedToClassOrExchange", + "decline", + "declinedInvitation", + "acceptedInvitation", + "youreInvited", + "studentPermissionsDesc", + "noEligibleSpaces", + "youAddedToSpace", + "youRemovedFromSpace", + "invitedToChat", + "monthlySubscription", + "yearlySubscription", + "defaultSubscription", + "freeTrial", + "grammarAnalytics", + "total", + "noDataFound", + "promoSubscriptionExpirationDesc", + "emptyChatNameWarning", + "emptyClassNameWarning", + "emptyExchangeNameWarning", + "blurMeansTranslateTitle", + "blurMeansTranslateBody", + "someErrorTitle", + "someErrorBody", + "bestCorrectionFeedback", + "distractorFeedback", + "bestAnswerFeedback", + "definitionDefaultPrompt", + "practiceDefaultPrompt", + "correctionDefaultPrompt", + "itStartDefaultPrompt", + "languageLevelWarning", + "lockedChatWarning", + "lockSpace", + "lockChat", + "archiveSpace", + "suggestTo", + "suggestChatDesc", + "suggestExchangeDesc", + "acceptSelection", + "acceptSelectionAnyway", + "makingActivity", + "why", + "definition", + "exampleSentence", + "addToClassTitle", + "reportToTeacher", + "reportMessageTitle", + "reportMessageBody", + "noTeachersFound", + "noAddToSpacePermissions", + "alreadyInSpace", + "yourGlobalUserIdIs", + "noUsersFoundWithQuery", + "searchChatsRooms", + "groupName", + "createGroupAndInviteUsers", + "groupCanBeFoundViaSearch", + "inNoSpaces" + ], + + "th": [ + "accountInformation", + "addGroupDescription", + "addNewFriend", + "alreadyHaveAnAccount", + "classes", + "createNewGroup", + "editChatPermissions", + "groupDescription", + "groupDescriptionHasBeenChanged", + "allCorrect", + "newWayAllGood", + "othersAreBetter", + "holdForInfo", + "greenFeedback", + "yellowFeedback", + "redFeedback", + "customInputFeedbackChoice", + "itInstructionsTitle", + "itInstructionsBody", + "toggleLanguages", + "classWelcomeChat", + "deleteSpace", + "deleteGroup", + "areYouSureDeleteClass", + "areYouSureDeleteGroup", + "cannotBeReversed", + "enterDeletedClassName", + "incorrectClassName", + "oneday", + "oneweek", + "onemonth", + "sixmonth", + "oneyear", + "gaTooltip", + "taTooltip", + "unTooltip", + "interactiveTranslatorSliderHeader", + "interactiveGrammarSliderHeader", + "interactiveTranslatorNotAllowed", + "interactiveTranslatorAllowed", + "interactiveTranslatorRequired", + "interactiveTranslatorNotAllowedDesc", + "interactiveTranslatorAllowedDesc", + "interactiveTranslatorRequiredDesc", + "notYetSet", + "multiLingualClass", + "classAnalytics", + "allClasses", + "myLearning", + "allChatsAndClasses", + "timeOfLastMessage", + "totalMessages", + "waTooltip", + "changeDateRange", + "numberOfStudents", + "classDescription", + "classDescriptionDesc", + "requestToEnroll", + "requestAnExchange", + "findLanguageExchange", + "classAnalyticsDesc", + "addStudents", + "copyClassLink", + "copyClassLinkDesc", + "copyClassCode", + "inviteStudentByUserName", + "classSettings", + "classSettingsDesc", + "selectClassRoomDominantLanguage", + "selectTargetLanguage", + "whatIsYourClassLanguageLevel", + "studentPermissions", + "interactiveTranslator", + "oneToOneChatsWithinClass", + "oneToOneChatsWithinClassDesc", + "createGroupChats", + "createGroupChatsDesc", + "shareVideo", + "shareVideoDesc", + "sharePhotos", + "sharePhotosDesc", + "shareFiles", + "shareFilesDesc", + "shareLocationDesc", + "selectLanguageLevel", + "noIdenticalLanguages", + "iWantALanguagePartnerFrom", + "worldWide", + "noResults", + "searchBy", + "iWantAConversationPartner", + "iWantALanguagePartnerWhoSpeaks", + "iWantALanguagePartnerWhoIsLearning", + "yourBirthdayPlease", + "invalidDob", + "enterYourDob", + "getStarted", + "mustBe13", + "yourBirthdayPleaseShort", + "errorPleaseRefresh", + "joinWithClassCode", + "joinWithClassCodeDesc", + "joinWithClassCodeHint", + "unableToFindClass", + "languageLevelPreA1", + "languageLevelA1", + "languageLevelA2", + "languageLevelB1", + "languageLevelB2", + "languageLevelC1", + "languageLevelC2", + "changeTheNameOfTheClass", + "changeTheNameOfTheChat", + "welcomeToYourNewClass", + "welcomeToClass", + "welcomeToPangea18Plus", + "welcomeToPangeaMinor", + "findALanguagePartner", + "setToPublicSettingsTitle", + "setToPublicSettingsDesc", + "accountSettings", + "unableToFindClassCode", + "askPangeaBot", + "sorryNoResults", + "ignoreInThisText", + "helpMeTranslate", + "needsItShortMessage", + "needsIGCShortMessage", + "needsItMessage", + "needsIgcMessage", + "tokenTranslationTitle", + "spanTranslationDesc", + "spanTranslationTitle", + "l1SpanAndGrammarTitle", + "l1SpanAndGrammarDesc", + "otherTitle", + "otherDesc", + "countryInformation", + "myLanguages", + "targetLanguage", + "sourceLanguage", + "languagesISpeak", + "updateLanguage", + "whatLanguageYouWantToLearn", + "whatIsYourBaseLanguage", + "saveChanges", + "publicProfileTitle", + "publicProfileDesc", + "error502504Title", + "error502504Desc", + "error404Title", + "error404Desc", + "errorDisableIT", + "errorDisableIGC", + "errorDisableLanguageAssistance", + "errorDisableITUserDesc", + "errorDisableIGCUserDesc", + "errorDisableLanguageAssistanceUserDesc", + "errorDisableITClassDesc", + "errorDisableIGCClassDesc", + "errorDisableLanguageAssistanceClassDesc", + "itIsDisabled", + "igcIsDisabled", + "goToLearningSettings", + "error405Title", + "error405Desc", + "loginOrSignup", + "iAgreeToThe", + "termsAndConditions", + "andCertifyIAmAtLeast13YearsOfAge", + "findAClass", + "toggleIT", + "toggleIGC", + "toggleToolSettingsDescription", + "connectedToStaging", + "learningSettings", + "classNameRequired", + "sendVoiceNotes", + "sendVoiceNotesDesc", + "chatTopic", + "chatTopicDesc", + "inviteStudentByUserNameDesc", + "classRoster", + "almostPerfect", + "prettyGood", + "letMeThink", + "clickMessageTitle", + "clickMessageBody", + "understandingMessagesTitle", + "addToClass", + "understandingMessagesBody", + "allDone", + "vocab", + "low", + "medium", + "high", + "unknownProficiency", + "changeView", + "clearAll", + "generateVocabulary", + "generatePrompts", + "subscribe", + "getAccess", + "subscriptionDesc", + "subscriptionManagement", + "currentSubscription", + "changeSubscription", + "cancelSubscription", + "selectYourPlan", + "subsciptionPlatformTooltip", + "subscriptionManagementUnavailable", + "paymentMethod", + "paymentHistory", + "emptyChatDownloadWarning", + "appUpdateAvailable", + "update", + "updateDesc", + "maybeLater", + "mainMenu", + "toggleImmersionMode", + "toggleImmersionModeDesc", + "itToggleDescription", + "igcToggleDescription", + "sendOnEnterDescription", + "alreadyInClass", + "pleaseLoginFirst", + "originalMessage", + "sentMessage", + "useType", + "notAvailable", + "taAndGaTooltip", + "definitionsToolName", + "messageTranslationsToolName", + "definitionsToolDescription", + "translationsToolDescrption", + "welcomeBack", + "classExchanges", + "createNewClass", + "newExchange", + "kickAllStudents", + "kickAllStudentsConfirmation", + "inviteAllStudents", + "inviteAllStudentsConfirmation", + "inviteStudentsFromOtherClasses", + "inviteUsersFromPangea", + "allExchanges", + "redeemPromoCode", + "enterPromoCode", + "downloadTxtFile", + "downloadCSVFile", + "promotionalSubscriptionDesc", + "originalSubscriptionPlatform", + "oneWeekTrial", + "creatingSpacePleaseWait", + "downloadXLSXFile", + "abDisplayName", + "aaDisplayName", + "afDisplayName", + "akDisplayName", + "sqDisplayName", + "amDisplayName", + "arDisplayName", + "anDisplayName", + "hyDisplayName", + "asDisplayName", + "avDisplayName", + "aeDisplayName", + "ayDisplayName", + "azDisplayName", + "bmDisplayName", + "baDisplayName", + "euDisplayName", + "beDisplayName", + "bnDisplayName", + "bhDisplayName", + "biDisplayName", + "bsDisplayName", + "brDisplayName", + "bgDisplayName", + "myDisplayName", + "caDisplayName", + "chDisplayName", + "ceDisplayName", + "nyDisplayName", + "zhDisplayName", + "cvDisplayName", + "kwDisplayName", + "coDisplayName", + "crDisplayName", + "hrDisplayName", + "csDisplayName", + "daDisplayName", + "dvDisplayName", + "nlDisplayName", + "enDisplayName", + "eoDisplayName", + "etDisplayName", + "eeDisplayName", + "foDisplayName", + "fjDisplayName", + "fiDisplayName", + "frDisplayName", + "ffDisplayName", + "glDisplayName", + "kaDisplayName", + "deDisplayName", + "elDisplayName", + "gnDisplayName", + "guDisplayName", + "htDisplayName", + "haDisplayName", + "heDisplayName", + "hzDisplayName", + "hiDisplayName", + "hoDisplayName", + "huDisplayName", + "iaDisplayName", + "idDisplayName", + "ieDisplayName", + "gaDisplayName", + "igDisplayName", + "ikDisplayName", + "ioDisplayName", + "isDisplayName", + "itDisplayName", + "iuDisplayName", + "jaDisplayName", + "jvDisplayName", + "klDisplayName", + "knDisplayName", + "krDisplayName", + "ksDisplayName", + "kkDisplayName", + "kmDisplayName", + "kiDisplayName", + "rwDisplayName", + "kyDisplayName", + "kvDisplayName", + "kgDisplayName", + "koDisplayName", + "kuDisplayName", + "kjDisplayName", + "laDisplayName", + "lbDisplayName", + "lgDisplayName", + "liDisplayName", + "lnDisplayName", + "loDisplayName", + "ltDisplayName", + "luDisplayName", + "lvDisplayName", + "gvDisplayName", + "mkDisplayName", + "mgDisplayName", + "msDisplayName", + "mlDisplayName", + "mtDisplayName", + "miDisplayName", + "mrDisplayName", + "mhDisplayName", + "mnDisplayName", + "naDisplayName", + "nvDisplayName", + "nbDisplayName", + "ndDisplayName", + "neDisplayName", + "ngDisplayName", + "nnDisplayName", + "noDisplayName", + "iiDisplayName", + "nrDisplayName", + "ocDisplayName", + "ojDisplayName", + "cuDisplayName", + "omDisplayName", + "orDisplayName", + "osDisplayName", + "paDisplayName", + "piDisplayName", + "faDisplayName", + "plDisplayName", + "psDisplayName", + "ptDisplayName", + "quDisplayName", + "rmDisplayName", + "rnDisplayName", + "roDisplayName", + "ruDisplayName", + "saDisplayName", + "scDisplayName", + "sdDisplayName", + "seDisplayName", + "smDisplayName", + "sgDisplayName", + "srDisplayName", + "gdDisplayName", + "snDisplayName", + "siDisplayName", + "skDisplayName", + "slDisplayName", + "soDisplayName", + "stDisplayName", + "esDisplayName", + "suDisplayName", + "swDisplayName", + "ssDisplayName", + "svDisplayName", + "taDisplayName", + "teDisplayName", + "tgDisplayName", + "thDisplayName", + "tiDisplayName", + "boDisplayName", + "tkDisplayName", + "tlDisplayName", + "tnDisplayName", + "toDisplayName", + "trDisplayName", + "tsDisplayName", + "ttDisplayName", + "twDisplayName", + "tyDisplayName", + "ugDisplayName", + "ukDisplayName", + "urDisplayName", + "uzDisplayName", + "veDisplayName", + "viDisplayName", + "voDisplayName", + "waDisplayName", + "cyDisplayName", + "woDisplayName", + "fyDisplayName", + "xhDisplayName", + "yiDisplayName", + "yoDisplayName", + "zaDisplayName", + "unkDisplayName", + "zuDisplayName", + "hawDisplayName", + "hmnDisplayName", + "multiDisplayName", + "cebDisplayName", + "dzDisplayName", + "iwDisplayName", + "jwDisplayName", + "moDisplayName", + "shDisplayName", + "wwCountryDisplayName", + "afCountryDisplayName", + "axCountryDisplayName", + "alCountryDisplayName", + "dzCountryDisplayName", + "asCountryDisplayName", + "adCountryDisplayName", + "aoCountryDisplayName", + "aiCountryDisplayName", + "agCountryDisplayName", + "arCountryDisplayName", + "amCountryDisplayName", + "awCountryDisplayName", + "acCountryDisplayName", + "auCountryDisplayName", + "atCountryDisplayName", + "azCountryDisplayName", + "bsCountryDisplayName", + "bhCountryDisplayName", + "bdCountryDisplayName", + "bbCountryDisplayName", + "byCountryDisplayName", + "beCountryDisplayName", + "bzCountryDisplayName", + "bjCountryDisplayName", + "bmCountryDisplayName", + "btCountryDisplayName", + "boCountryDisplayName", + "baCountryDisplayName", + "bwCountryDisplayName", + "brCountryDisplayName", + "ioCountryDisplayName", + "vgCountryDisplayName", + "bnCountryDisplayName", + "bgCountryDisplayName", + "bfCountryDisplayName", + "biCountryDisplayName", + "khCountryDisplayName", + "cmCountryDisplayName", + "caCountryDisplayName", + "cvCountryDisplayName", + "bqCountryDisplayName", + "kyCountryDisplayName", + "cfCountryDisplayName", + "tdCountryDisplayName", + "clCountryDisplayName", + "cnCountryDisplayName", + "cxCountryDisplayName", + "ccCountryDisplayName", + "coCountryDisplayName", + "kmCountryDisplayName", + "cdCountryDisplayName", + "cgCountryDisplayName", + "ckCountryDisplayName", + "crCountryDisplayName", + "ciCountryDisplayName", + "hrCountryDisplayName", + "cuCountryDisplayName", + "cwCountryDisplayName", + "cyCountryDisplayName", + "czCountryDisplayName", + "dkCountryDisplayName", + "djCountryDisplayName", + "dmCountryDisplayName", + "doCountryDisplayName", + "tlCountryDisplayName", + "ecCountryDisplayName", + "egCountryDisplayName", + "svCountryDisplayName", + "gqCountryDisplayName", + "erCountryDisplayName", + "eeCountryDisplayName", + "szCountryDisplayName", + "etCountryDisplayName", + "fkCountryDisplayName", + "foCountryDisplayName", + "fjCountryDisplayName", + "fiCountryDisplayName", + "frCountryDisplayName", + "gfCountryDisplayName", + "pfCountryDisplayName", + "gaCountryDisplayName", + "gmCountryDisplayName", + "geCountryDisplayName", + "deCountryDisplayName", + "ghCountryDisplayName", + "giCountryDisplayName", + "grCountryDisplayName", + "glCountryDisplayName", + "gdCountryDisplayName", + "gpCountryDisplayName", + "guCountryDisplayName", + "gtCountryDisplayName", + "ggCountryDisplayName", + "gnCountryDisplayName", + "gwCountryDisplayName", + "gyCountryDisplayName", + "htCountryDisplayName", + "hmCountryDisplayName", + "hnCountryDisplayName", + "hkCountryDisplayName", + "huCountryDisplayName", + "isCountryDisplayName", + "inCountryDisplayName", + "idCountryDisplayName", + "irCountryDisplayName", + "iqCountryDisplayName", + "ieCountryDisplayName", + "imCountryDisplayName", + "ilCountryDisplayName", + "itCountryDisplayName", + "jmCountryDisplayName", + "jpCountryDisplayName", + "jeCountryDisplayName", + "joCountryDisplayName", + "kzCountryDisplayName", + "keCountryDisplayName", + "kiCountryDisplayName", + "xkCountryDisplayName", + "kwCountryDisplayName", + "kgCountryDisplayName", + "laCountryDisplayName", + "lvCountryDisplayName", + "lbCountryDisplayName", + "lsCountryDisplayName", + "lrCountryDisplayName", + "lyCountryDisplayName", + "liCountryDisplayName", + "ltCountryDisplayName", + "luCountryDisplayName", + "moCountryDisplayName", + "mkCountryDisplayName", + "mgCountryDisplayName", + "mwCountryDisplayName", + "myCountryDisplayName", + "mvCountryDisplayName", + "mlCountryDisplayName", + "mtCountryDisplayName", + "mhCountryDisplayName", + "mqCountryDisplayName", + "mrCountryDisplayName", + "muCountryDisplayName", + "ytCountryDisplayName", + "mxCountryDisplayName", + "fmCountryDisplayName", + "mdCountryDisplayName", + "mcCountryDisplayName", + "mnCountryDisplayName", + "meCountryDisplayName", + "msCountryDisplayName", + "maCountryDisplayName", + "mzCountryDisplayName", + "mmCountryDisplayName", + "naCountryDisplayName", + "nrCountryDisplayName", + "npCountryDisplayName", + "nlCountryDisplayName", + "ncCountryDisplayName", + "nzCountryDisplayName", + "niCountryDisplayName", + "neCountryDisplayName", + "ngCountryDisplayName", + "nuCountryDisplayName", + "nfCountryDisplayName", + "kpCountryDisplayName", + "mpCountryDisplayName", + "noCountryDisplayName", + "omCountryDisplayName", + "pkCountryDisplayName", + "pwCountryDisplayName", + "psCountryDisplayName", + "paCountryDisplayName", + "pgCountryDisplayName", + "pyCountryDisplayName", + "peCountryDisplayName", + "phCountryDisplayName", + "plCountryDisplayName", + "ptCountryDisplayName", + "prCountryDisplayName", + "qaCountryDisplayName", + "reCountryDisplayName", + "roCountryDisplayName", + "ruCountryDisplayName", + "rwCountryDisplayName", + "blCountryDisplayName", + "shCountryDisplayName", + "knCountryDisplayName", + "lcCountryDisplayName", + "mfCountryDisplayName", + "pmCountryDisplayName", + "vcCountryDisplayName", + "wsCountryDisplayName", + "smCountryDisplayName", + "stCountryDisplayName", + "saCountryDisplayName", + "snCountryDisplayName", + "rsCountryDisplayName", + "scCountryDisplayName", + "slCountryDisplayName", + "sgCountryDisplayName", + "sxCountryDisplayName", + "skCountryDisplayName", + "siCountryDisplayName", + "sbCountryDisplayName", + "soCountryDisplayName", + "zaCountryDisplayName", + "gsCountryDisplayName", + "krCountryDisplayName", + "ssCountryDisplayName", + "esCountryDisplayName", + "lkCountryDisplayName", + "sdCountryDisplayName", + "srCountryDisplayName", + "sjCountryDisplayName", + "seCountryDisplayName", + "chCountryDisplayName", + "syCountryDisplayName", + "twCountryDisplayName", + "tjCountryDisplayName", + "tzCountryDisplayName", + "thCountryDisplayName", + "tgCountryDisplayName", + "tkCountryDisplayName", + "toCountryDisplayName", + "ttCountryDisplayName", + "tnCountryDisplayName", + "trCountryDisplayName", + "tmCountryDisplayName", + "tcCountryDisplayName", + "tvCountryDisplayName", + "viCountryDisplayName", + "ugCountryDisplayName", + "uaCountryDisplayName", + "aeCountryDisplayName", + "gbCountryDisplayName", + "usCountryDisplayName", + "uyCountryDisplayName", + "uzCountryDisplayName", + "vuCountryDisplayName", + "vaCountryDisplayName", + "veCountryDisplayName", + "vnCountryDisplayName", + "wfCountryDisplayName", + "ehCountryDisplayName", + "yeCountryDisplayName", + "zmCountryDisplayName", + "zwCountryDisplayName", + "pay", + "allPrivateChats", + "unknownPrivateChat", + "copyClassCodeDesc", + "addToClassDesc", + "addToClassOrExchange", + "addToClassOrExchangeDesc", + "invitedToClassOrExchange", + "decline", + "declinedInvitation", + "acceptedInvitation", + "youreInvited", + "studentPermissionsDesc", + "noEligibleSpaces", + "youAddedToSpace", + "youRemovedFromSpace", + "invitedToChat", + "monthlySubscription", + "yearlySubscription", + "defaultSubscription", + "freeTrial", + "grammarAnalytics", + "total", + "noDataFound", + "promoSubscriptionExpirationDesc", + "emptyChatNameWarning", + "emptyClassNameWarning", + "emptyExchangeNameWarning", + "blurMeansTranslateTitle", + "blurMeansTranslateBody", + "someErrorTitle", + "someErrorBody", + "bestCorrectionFeedback", + "distractorFeedback", + "bestAnswerFeedback", + "definitionDefaultPrompt", + "practiceDefaultPrompt", + "correctionDefaultPrompt", + "itStartDefaultPrompt", + "languageLevelWarning", + "lockedChatWarning", + "lockSpace", + "lockChat", + "archiveSpace", + "suggestTo", + "suggestChatDesc", + "suggestExchangeDesc", + "acceptSelection", + "acceptSelectionAnyway", + "makingActivity", + "why", + "definition", + "exampleSentence", + "addToClassTitle", + "reportToTeacher", + "reportMessageTitle", + "reportMessageBody", + "noTeachersFound", + "noAddToSpacePermissions", + "alreadyInSpace", + "yourGlobalUserIdIs", + "noUsersFoundWithQuery", + "searchChatsRooms", + "groupName", + "createGroupAndInviteUsers", + "groupCanBeFoundViaSearch", + "inNoSpaces" + ], + + "tr": [ + "accountInformation", + "addNewFriend", + "alreadyHaveAnAccount", + "classes", + "allCorrect", + "newWayAllGood", + "othersAreBetter", + "holdForInfo", + "greenFeedback", + "yellowFeedback", + "redFeedback", + "customInputFeedbackChoice", + "itInstructionsTitle", + "itInstructionsBody", + "toggleLanguages", + "classWelcomeChat", + "deleteSpace", + "deleteGroup", + "areYouSureDeleteClass", + "areYouSureDeleteGroup", + "cannotBeReversed", + "enterDeletedClassName", + "incorrectClassName", + "oneday", + "oneweek", + "onemonth", + "sixmonth", + "oneyear", + "gaTooltip", + "taTooltip", + "unTooltip", + "interactiveTranslatorSliderHeader", + "interactiveGrammarSliderHeader", + "interactiveTranslatorNotAllowed", + "interactiveTranslatorAllowed", + "interactiveTranslatorRequired", + "interactiveTranslatorNotAllowedDesc", + "interactiveTranslatorAllowedDesc", + "interactiveTranslatorRequiredDesc", + "notYetSet", + "multiLingualClass", + "classAnalytics", + "allClasses", + "myLearning", + "allChatsAndClasses", + "timeOfLastMessage", + "totalMessages", + "waTooltip", + "changeDateRange", + "numberOfStudents", + "classDescription", + "classDescriptionDesc", + "requestToEnroll", + "requestAnExchange", + "findLanguageExchange", + "classAnalyticsDesc", + "addStudents", + "copyClassLink", + "copyClassLinkDesc", + "copyClassCode", + "inviteStudentByUserName", + "classSettings", + "classSettingsDesc", + "selectClassRoomDominantLanguage", + "selectTargetLanguage", + "whatIsYourClassLanguageLevel", + "studentPermissions", + "interactiveTranslator", + "oneToOneChatsWithinClass", + "oneToOneChatsWithinClassDesc", + "createGroupChats", + "createGroupChatsDesc", + "shareVideo", + "shareVideoDesc", + "sharePhotos", + "sharePhotosDesc", + "shareFiles", + "shareFilesDesc", + "shareLocationDesc", + "selectLanguageLevel", + "noIdenticalLanguages", + "iWantALanguagePartnerFrom", + "worldWide", + "noResults", + "searchBy", + "iWantAConversationPartner", + "iWantALanguagePartnerWhoSpeaks", + "iWantALanguagePartnerWhoIsLearning", + "yourBirthdayPlease", + "invalidDob", + "enterYourDob", + "getStarted", + "mustBe13", + "yourBirthdayPleaseShort", + "errorPleaseRefresh", + "joinWithClassCode", + "joinWithClassCodeDesc", + "joinWithClassCodeHint", + "unableToFindClass", + "languageLevelPreA1", + "languageLevelA1", + "languageLevelA2", + "languageLevelB1", + "languageLevelB2", + "languageLevelC1", + "languageLevelC2", + "changeTheNameOfTheClass", + "changeTheNameOfTheChat", + "welcomeToYourNewClass", + "welcomeToClass", + "welcomeToPangea18Plus", + "welcomeToPangeaMinor", + "findALanguagePartner", + "setToPublicSettingsTitle", + "setToPublicSettingsDesc", + "accountSettings", + "unableToFindClassCode", + "askPangeaBot", + "sorryNoResults", + "ignoreInThisText", + "helpMeTranslate", + "needsItShortMessage", + "needsIGCShortMessage", + "needsItMessage", + "needsIgcMessage", + "tokenTranslationTitle", + "spanTranslationDesc", + "spanTranslationTitle", + "l1SpanAndGrammarTitle", + "l1SpanAndGrammarDesc", + "otherTitle", + "otherDesc", + "countryInformation", + "myLanguages", + "targetLanguage", + "sourceLanguage", + "languagesISpeak", + "updateLanguage", + "whatLanguageYouWantToLearn", + "whatIsYourBaseLanguage", + "saveChanges", + "publicProfileTitle", + "publicProfileDesc", + "error502504Title", + "error502504Desc", + "error404Title", + "error404Desc", + "errorDisableIT", + "errorDisableIGC", + "errorDisableLanguageAssistance", + "errorDisableITUserDesc", + "errorDisableIGCUserDesc", + "errorDisableLanguageAssistanceUserDesc", + "errorDisableITClassDesc", + "errorDisableIGCClassDesc", + "errorDisableLanguageAssistanceClassDesc", + "itIsDisabled", + "igcIsDisabled", + "goToLearningSettings", + "error405Title", + "error405Desc", + "loginOrSignup", + "iAgreeToThe", + "termsAndConditions", + "andCertifyIAmAtLeast13YearsOfAge", + "findAClass", + "toggleIT", + "toggleIGC", + "toggleToolSettingsDescription", + "connectedToStaging", + "learningSettings", + "classNameRequired", + "sendVoiceNotes", + "sendVoiceNotesDesc", + "chatTopic", + "chatTopicDesc", + "inviteStudentByUserNameDesc", + "classRoster", + "almostPerfect", + "prettyGood", + "letMeThink", + "clickMessageTitle", + "clickMessageBody", + "understandingMessagesTitle", + "addToClass", + "understandingMessagesBody", + "allDone", + "vocab", + "low", + "medium", + "high", + "unknownProficiency", + "changeView", + "clearAll", + "generateVocabulary", + "generatePrompts", + "subscribe", + "getAccess", + "subscriptionDesc", + "subscriptionManagement", + "currentSubscription", + "changeSubscription", + "cancelSubscription", + "selectYourPlan", + "subsciptionPlatformTooltip", + "subscriptionManagementUnavailable", + "paymentMethod", + "paymentHistory", + "emptyChatDownloadWarning", + "appUpdateAvailable", + "update", + "updateDesc", + "maybeLater", + "mainMenu", + "toggleImmersionMode", + "toggleImmersionModeDesc", + "itToggleDescription", + "igcToggleDescription", + "sendOnEnterDescription", + "alreadyInClass", + "pleaseLoginFirst", + "originalMessage", + "sentMessage", + "useType", + "notAvailable", + "taAndGaTooltip", + "definitionsToolName", + "messageTranslationsToolName", + "definitionsToolDescription", + "translationsToolDescrption", + "welcomeBack", + "classExchanges", + "createNewClass", + "newExchange", + "kickAllStudents", + "kickAllStudentsConfirmation", + "inviteAllStudents", + "inviteAllStudentsConfirmation", + "inviteStudentsFromOtherClasses", + "inviteUsersFromPangea", + "allExchanges", + "redeemPromoCode", + "enterPromoCode", + "downloadTxtFile", + "downloadCSVFile", + "promotionalSubscriptionDesc", + "originalSubscriptionPlatform", + "oneWeekTrial", + "creatingSpacePleaseWait", + "downloadXLSXFile", + "abDisplayName", + "aaDisplayName", + "afDisplayName", + "akDisplayName", + "sqDisplayName", + "amDisplayName", + "arDisplayName", + "anDisplayName", + "hyDisplayName", + "asDisplayName", + "avDisplayName", + "aeDisplayName", + "ayDisplayName", + "azDisplayName", + "bmDisplayName", + "baDisplayName", + "euDisplayName", + "beDisplayName", + "bnDisplayName", + "bhDisplayName", + "biDisplayName", + "bsDisplayName", + "brDisplayName", + "bgDisplayName", + "myDisplayName", + "caDisplayName", + "chDisplayName", + "ceDisplayName", + "nyDisplayName", + "zhDisplayName", + "cvDisplayName", + "kwDisplayName", + "coDisplayName", + "crDisplayName", + "hrDisplayName", + "csDisplayName", + "daDisplayName", + "dvDisplayName", + "nlDisplayName", + "enDisplayName", + "eoDisplayName", + "etDisplayName", + "eeDisplayName", + "foDisplayName", + "fjDisplayName", + "fiDisplayName", + "frDisplayName", + "ffDisplayName", + "glDisplayName", + "kaDisplayName", + "deDisplayName", + "elDisplayName", + "gnDisplayName", + "guDisplayName", + "htDisplayName", + "haDisplayName", + "heDisplayName", + "hzDisplayName", + "hiDisplayName", + "hoDisplayName", + "huDisplayName", + "iaDisplayName", + "idDisplayName", + "ieDisplayName", + "gaDisplayName", + "igDisplayName", + "ikDisplayName", + "ioDisplayName", + "isDisplayName", + "itDisplayName", + "iuDisplayName", + "jaDisplayName", + "jvDisplayName", + "klDisplayName", + "knDisplayName", + "krDisplayName", + "ksDisplayName", + "kkDisplayName", + "kmDisplayName", + "kiDisplayName", + "rwDisplayName", + "kyDisplayName", + "kvDisplayName", + "kgDisplayName", + "koDisplayName", + "kuDisplayName", + "kjDisplayName", + "laDisplayName", + "lbDisplayName", + "lgDisplayName", + "liDisplayName", + "lnDisplayName", + "loDisplayName", + "ltDisplayName", + "luDisplayName", + "lvDisplayName", + "gvDisplayName", + "mkDisplayName", + "mgDisplayName", + "msDisplayName", + "mlDisplayName", + "mtDisplayName", + "miDisplayName", + "mrDisplayName", + "mhDisplayName", + "mnDisplayName", + "naDisplayName", + "nvDisplayName", + "nbDisplayName", + "ndDisplayName", + "neDisplayName", + "ngDisplayName", + "nnDisplayName", + "noDisplayName", + "iiDisplayName", + "nrDisplayName", + "ocDisplayName", + "ojDisplayName", + "cuDisplayName", + "omDisplayName", + "orDisplayName", + "osDisplayName", + "paDisplayName", + "piDisplayName", + "faDisplayName", + "plDisplayName", + "psDisplayName", + "ptDisplayName", + "quDisplayName", + "rmDisplayName", + "rnDisplayName", + "roDisplayName", + "ruDisplayName", + "saDisplayName", + "scDisplayName", + "sdDisplayName", + "seDisplayName", + "smDisplayName", + "sgDisplayName", + "srDisplayName", + "gdDisplayName", + "snDisplayName", + "siDisplayName", + "skDisplayName", + "slDisplayName", + "soDisplayName", + "stDisplayName", + "esDisplayName", + "suDisplayName", + "swDisplayName", + "ssDisplayName", + "svDisplayName", + "taDisplayName", + "teDisplayName", + "tgDisplayName", + "thDisplayName", + "tiDisplayName", + "boDisplayName", + "tkDisplayName", + "tlDisplayName", + "tnDisplayName", + "toDisplayName", + "trDisplayName", + "tsDisplayName", + "ttDisplayName", + "twDisplayName", + "tyDisplayName", + "ugDisplayName", + "ukDisplayName", + "urDisplayName", + "uzDisplayName", + "veDisplayName", + "viDisplayName", + "voDisplayName", + "waDisplayName", + "cyDisplayName", + "woDisplayName", + "fyDisplayName", + "xhDisplayName", + "yiDisplayName", + "yoDisplayName", + "zaDisplayName", + "unkDisplayName", + "zuDisplayName", + "hawDisplayName", + "hmnDisplayName", + "multiDisplayName", + "cebDisplayName", + "dzDisplayName", + "iwDisplayName", + "jwDisplayName", + "moDisplayName", + "shDisplayName", + "wwCountryDisplayName", + "afCountryDisplayName", + "axCountryDisplayName", + "alCountryDisplayName", + "dzCountryDisplayName", + "asCountryDisplayName", + "adCountryDisplayName", + "aoCountryDisplayName", + "aiCountryDisplayName", + "agCountryDisplayName", + "arCountryDisplayName", + "amCountryDisplayName", + "awCountryDisplayName", + "acCountryDisplayName", + "auCountryDisplayName", + "atCountryDisplayName", + "azCountryDisplayName", + "bsCountryDisplayName", + "bhCountryDisplayName", + "bdCountryDisplayName", + "bbCountryDisplayName", + "byCountryDisplayName", + "beCountryDisplayName", + "bzCountryDisplayName", + "bjCountryDisplayName", + "bmCountryDisplayName", + "btCountryDisplayName", + "boCountryDisplayName", + "baCountryDisplayName", + "bwCountryDisplayName", + "brCountryDisplayName", + "ioCountryDisplayName", + "vgCountryDisplayName", + "bnCountryDisplayName", + "bgCountryDisplayName", + "bfCountryDisplayName", + "biCountryDisplayName", + "khCountryDisplayName", + "cmCountryDisplayName", + "caCountryDisplayName", + "cvCountryDisplayName", + "bqCountryDisplayName", + "kyCountryDisplayName", + "cfCountryDisplayName", + "tdCountryDisplayName", + "clCountryDisplayName", + "cnCountryDisplayName", + "cxCountryDisplayName", + "ccCountryDisplayName", + "coCountryDisplayName", + "kmCountryDisplayName", + "cdCountryDisplayName", + "cgCountryDisplayName", + "ckCountryDisplayName", + "crCountryDisplayName", + "ciCountryDisplayName", + "hrCountryDisplayName", + "cuCountryDisplayName", + "cwCountryDisplayName", + "cyCountryDisplayName", + "czCountryDisplayName", + "dkCountryDisplayName", + "djCountryDisplayName", + "dmCountryDisplayName", + "doCountryDisplayName", + "tlCountryDisplayName", + "ecCountryDisplayName", + "egCountryDisplayName", + "svCountryDisplayName", + "gqCountryDisplayName", + "erCountryDisplayName", + "eeCountryDisplayName", + "szCountryDisplayName", + "etCountryDisplayName", + "fkCountryDisplayName", + "foCountryDisplayName", + "fjCountryDisplayName", + "fiCountryDisplayName", + "frCountryDisplayName", + "gfCountryDisplayName", + "pfCountryDisplayName", + "gaCountryDisplayName", + "gmCountryDisplayName", + "geCountryDisplayName", + "deCountryDisplayName", + "ghCountryDisplayName", + "giCountryDisplayName", + "grCountryDisplayName", + "glCountryDisplayName", + "gdCountryDisplayName", + "gpCountryDisplayName", + "guCountryDisplayName", + "gtCountryDisplayName", + "ggCountryDisplayName", + "gnCountryDisplayName", + "gwCountryDisplayName", + "gyCountryDisplayName", + "htCountryDisplayName", + "hmCountryDisplayName", + "hnCountryDisplayName", + "hkCountryDisplayName", + "huCountryDisplayName", + "isCountryDisplayName", + "inCountryDisplayName", + "idCountryDisplayName", + "irCountryDisplayName", + "iqCountryDisplayName", + "ieCountryDisplayName", + "imCountryDisplayName", + "ilCountryDisplayName", + "itCountryDisplayName", + "jmCountryDisplayName", + "jpCountryDisplayName", + "jeCountryDisplayName", + "joCountryDisplayName", + "kzCountryDisplayName", + "keCountryDisplayName", + "kiCountryDisplayName", + "xkCountryDisplayName", + "kwCountryDisplayName", + "kgCountryDisplayName", + "laCountryDisplayName", + "lvCountryDisplayName", + "lbCountryDisplayName", + "lsCountryDisplayName", + "lrCountryDisplayName", + "lyCountryDisplayName", + "liCountryDisplayName", + "ltCountryDisplayName", + "luCountryDisplayName", + "moCountryDisplayName", + "mkCountryDisplayName", + "mgCountryDisplayName", + "mwCountryDisplayName", + "myCountryDisplayName", + "mvCountryDisplayName", + "mlCountryDisplayName", + "mtCountryDisplayName", + "mhCountryDisplayName", + "mqCountryDisplayName", + "mrCountryDisplayName", + "muCountryDisplayName", + "ytCountryDisplayName", + "mxCountryDisplayName", + "fmCountryDisplayName", + "mdCountryDisplayName", + "mcCountryDisplayName", + "mnCountryDisplayName", + "meCountryDisplayName", + "msCountryDisplayName", + "maCountryDisplayName", + "mzCountryDisplayName", + "mmCountryDisplayName", + "naCountryDisplayName", + "nrCountryDisplayName", + "npCountryDisplayName", + "nlCountryDisplayName", + "ncCountryDisplayName", + "nzCountryDisplayName", + "niCountryDisplayName", + "neCountryDisplayName", + "ngCountryDisplayName", + "nuCountryDisplayName", + "nfCountryDisplayName", + "kpCountryDisplayName", + "mpCountryDisplayName", + "noCountryDisplayName", + "omCountryDisplayName", + "pkCountryDisplayName", + "pwCountryDisplayName", + "psCountryDisplayName", + "paCountryDisplayName", + "pgCountryDisplayName", + "pyCountryDisplayName", + "peCountryDisplayName", + "phCountryDisplayName", + "plCountryDisplayName", + "ptCountryDisplayName", + "prCountryDisplayName", + "qaCountryDisplayName", + "reCountryDisplayName", + "roCountryDisplayName", + "ruCountryDisplayName", + "rwCountryDisplayName", + "blCountryDisplayName", + "shCountryDisplayName", + "knCountryDisplayName", + "lcCountryDisplayName", + "mfCountryDisplayName", + "pmCountryDisplayName", + "vcCountryDisplayName", + "wsCountryDisplayName", + "smCountryDisplayName", + "stCountryDisplayName", + "saCountryDisplayName", + "snCountryDisplayName", + "rsCountryDisplayName", + "scCountryDisplayName", + "slCountryDisplayName", + "sgCountryDisplayName", + "sxCountryDisplayName", + "skCountryDisplayName", + "siCountryDisplayName", + "sbCountryDisplayName", + "soCountryDisplayName", + "zaCountryDisplayName", + "gsCountryDisplayName", + "krCountryDisplayName", + "ssCountryDisplayName", + "esCountryDisplayName", + "lkCountryDisplayName", + "sdCountryDisplayName", + "srCountryDisplayName", + "sjCountryDisplayName", + "seCountryDisplayName", + "chCountryDisplayName", + "syCountryDisplayName", + "twCountryDisplayName", + "tjCountryDisplayName", + "tzCountryDisplayName", + "thCountryDisplayName", + "tgCountryDisplayName", + "tkCountryDisplayName", + "toCountryDisplayName", + "ttCountryDisplayName", + "tnCountryDisplayName", + "trCountryDisplayName", + "tmCountryDisplayName", + "tcCountryDisplayName", + "tvCountryDisplayName", + "viCountryDisplayName", + "ugCountryDisplayName", + "uaCountryDisplayName", + "aeCountryDisplayName", + "gbCountryDisplayName", + "usCountryDisplayName", + "uyCountryDisplayName", + "uzCountryDisplayName", + "vuCountryDisplayName", + "vaCountryDisplayName", + "veCountryDisplayName", + "vnCountryDisplayName", + "wfCountryDisplayName", + "ehCountryDisplayName", + "yeCountryDisplayName", + "zmCountryDisplayName", + "zwCountryDisplayName", + "pay", + "allPrivateChats", + "unknownPrivateChat", + "copyClassCodeDesc", + "addToClassDesc", + "addToClassOrExchange", + "addToClassOrExchangeDesc", + "invitedToClassOrExchange", + "decline", + "declinedInvitation", + "acceptedInvitation", + "youreInvited", + "studentPermissionsDesc", + "noEligibleSpaces", + "youAddedToSpace", + "youRemovedFromSpace", + "invitedToChat", + "monthlySubscription", + "yearlySubscription", + "defaultSubscription", + "freeTrial", + "grammarAnalytics", + "total", + "noDataFound", + "promoSubscriptionExpirationDesc", + "emptyChatNameWarning", + "emptyClassNameWarning", + "emptyExchangeNameWarning", + "blurMeansTranslateTitle", + "blurMeansTranslateBody", + "someErrorTitle", + "someErrorBody", + "bestCorrectionFeedback", + "distractorFeedback", + "bestAnswerFeedback", + "definitionDefaultPrompt", + "practiceDefaultPrompt", + "correctionDefaultPrompt", + "itStartDefaultPrompt", + "languageLevelWarning", + "lockedChatWarning", + "lockSpace", + "lockChat", + "archiveSpace", + "suggestTo", + "suggestChatDesc", + "suggestExchangeDesc", + "acceptSelection", + "acceptSelectionAnyway", + "makingActivity", + "why", + "definition", + "exampleSentence", + "addToClassTitle", + "reportToTeacher", + "reportMessageTitle", + "reportMessageBody", + "noTeachersFound", + "noAddToSpacePermissions", + "alreadyInSpace", + "yourGlobalUserIdIs", + "noUsersFoundWithQuery", + "searchChatsRooms", + "groupName", + "createGroupAndInviteUsers", + "groupCanBeFoundViaSearch", + "inNoSpaces" + ], + + "uk": [ + "accountInformation", + "addNewFriend", + "alreadyHaveAnAccount", + "classes", + "allCorrect", + "newWayAllGood", + "othersAreBetter", + "holdForInfo", + "greenFeedback", + "yellowFeedback", + "redFeedback", + "customInputFeedbackChoice", + "itInstructionsTitle", + "itInstructionsBody", + "toggleLanguages", + "classWelcomeChat", + "deleteSpace", + "deleteGroup", + "areYouSureDeleteClass", + "areYouSureDeleteGroup", + "cannotBeReversed", + "enterDeletedClassName", + "incorrectClassName", + "oneday", + "oneweek", + "onemonth", + "sixmonth", + "oneyear", + "gaTooltip", + "taTooltip", + "unTooltip", + "interactiveTranslatorSliderHeader", + "interactiveGrammarSliderHeader", + "interactiveTranslatorNotAllowed", + "interactiveTranslatorAllowed", + "interactiveTranslatorRequired", + "interactiveTranslatorNotAllowedDesc", + "interactiveTranslatorAllowedDesc", + "interactiveTranslatorRequiredDesc", + "notYetSet", + "multiLingualClass", + "classAnalytics", + "allClasses", + "myLearning", + "allChatsAndClasses", + "timeOfLastMessage", + "totalMessages", + "waTooltip", + "changeDateRange", + "numberOfStudents", + "classDescription", + "classDescriptionDesc", + "requestToEnroll", + "requestAnExchange", + "findLanguageExchange", + "classAnalyticsDesc", + "addStudents", + "copyClassLink", + "copyClassLinkDesc", + "copyClassCode", + "inviteStudentByUserName", + "classSettings", + "classSettingsDesc", + "selectClassRoomDominantLanguage", + "selectTargetLanguage", + "whatIsYourClassLanguageLevel", + "studentPermissions", + "interactiveTranslator", + "oneToOneChatsWithinClass", + "oneToOneChatsWithinClassDesc", + "createGroupChats", + "createGroupChatsDesc", + "shareVideo", + "shareVideoDesc", + "sharePhotos", + "sharePhotosDesc", + "shareFiles", + "shareFilesDesc", + "shareLocationDesc", + "selectLanguageLevel", + "noIdenticalLanguages", + "iWantALanguagePartnerFrom", + "worldWide", + "noResults", + "searchBy", + "iWantAConversationPartner", + "iWantALanguagePartnerWhoSpeaks", + "iWantALanguagePartnerWhoIsLearning", + "yourBirthdayPlease", + "invalidDob", + "enterYourDob", + "getStarted", + "mustBe13", + "yourBirthdayPleaseShort", + "errorPleaseRefresh", + "joinWithClassCode", + "joinWithClassCodeDesc", + "joinWithClassCodeHint", + "unableToFindClass", + "languageLevelPreA1", + "languageLevelA1", + "languageLevelA2", + "languageLevelB1", + "languageLevelB2", + "languageLevelC1", + "languageLevelC2", + "changeTheNameOfTheClass", + "changeTheNameOfTheChat", + "welcomeToYourNewClass", + "welcomeToClass", + "welcomeToPangea18Plus", + "welcomeToPangeaMinor", + "findALanguagePartner", + "setToPublicSettingsTitle", + "setToPublicSettingsDesc", + "accountSettings", + "unableToFindClassCode", + "askPangeaBot", + "sorryNoResults", + "ignoreInThisText", + "helpMeTranslate", + "needsItShortMessage", + "needsIGCShortMessage", + "needsItMessage", + "needsIgcMessage", + "tokenTranslationTitle", + "spanTranslationDesc", + "spanTranslationTitle", + "l1SpanAndGrammarTitle", + "l1SpanAndGrammarDesc", + "otherTitle", + "otherDesc", + "countryInformation", + "myLanguages", + "targetLanguage", + "sourceLanguage", + "languagesISpeak", + "updateLanguage", + "whatLanguageYouWantToLearn", + "whatIsYourBaseLanguage", + "saveChanges", + "publicProfileTitle", + "publicProfileDesc", + "error502504Title", + "error502504Desc", + "error404Title", + "error404Desc", + "errorDisableIT", + "errorDisableIGC", + "errorDisableLanguageAssistance", + "errorDisableITUserDesc", + "errorDisableIGCUserDesc", + "errorDisableLanguageAssistanceUserDesc", + "errorDisableITClassDesc", + "errorDisableIGCClassDesc", + "errorDisableLanguageAssistanceClassDesc", + "itIsDisabled", + "igcIsDisabled", + "goToLearningSettings", + "error405Title", + "error405Desc", + "loginOrSignup", + "iAgreeToThe", + "termsAndConditions", + "andCertifyIAmAtLeast13YearsOfAge", + "findAClass", + "toggleIT", + "toggleIGC", + "toggleToolSettingsDescription", + "connectedToStaging", + "learningSettings", + "classNameRequired", + "sendVoiceNotes", + "sendVoiceNotesDesc", + "chatTopic", + "chatTopicDesc", + "inviteStudentByUserNameDesc", + "classRoster", + "almostPerfect", + "prettyGood", + "letMeThink", + "clickMessageTitle", + "clickMessageBody", + "understandingMessagesTitle", + "addToClass", + "understandingMessagesBody", + "allDone", + "vocab", + "low", + "medium", + "high", + "unknownProficiency", + "changeView", + "clearAll", + "generateVocabulary", + "generatePrompts", + "subscribe", + "getAccess", + "subscriptionDesc", + "subscriptionManagement", + "currentSubscription", + "changeSubscription", + "cancelSubscription", + "selectYourPlan", + "subsciptionPlatformTooltip", + "subscriptionManagementUnavailable", + "paymentMethod", + "paymentHistory", + "emptyChatDownloadWarning", + "appUpdateAvailable", + "update", + "updateDesc", + "maybeLater", + "mainMenu", + "toggleImmersionMode", + "toggleImmersionModeDesc", + "itToggleDescription", + "igcToggleDescription", + "sendOnEnterDescription", + "alreadyInClass", + "pleaseLoginFirst", + "originalMessage", + "sentMessage", + "useType", + "notAvailable", + "taAndGaTooltip", + "definitionsToolName", + "messageTranslationsToolName", + "definitionsToolDescription", + "translationsToolDescrption", + "welcomeBack", + "classExchanges", + "createNewClass", + "newExchange", + "kickAllStudents", + "kickAllStudentsConfirmation", + "inviteAllStudents", + "inviteAllStudentsConfirmation", + "inviteStudentsFromOtherClasses", + "inviteUsersFromPangea", + "allExchanges", + "redeemPromoCode", + "enterPromoCode", + "downloadTxtFile", + "downloadCSVFile", + "promotionalSubscriptionDesc", + "originalSubscriptionPlatform", + "oneWeekTrial", + "creatingSpacePleaseWait", + "downloadXLSXFile", + "abDisplayName", + "aaDisplayName", + "afDisplayName", + "akDisplayName", + "sqDisplayName", + "amDisplayName", + "arDisplayName", + "anDisplayName", + "hyDisplayName", + "asDisplayName", + "avDisplayName", + "aeDisplayName", + "ayDisplayName", + "azDisplayName", + "bmDisplayName", + "baDisplayName", + "euDisplayName", + "beDisplayName", + "bnDisplayName", + "bhDisplayName", + "biDisplayName", + "bsDisplayName", + "brDisplayName", + "bgDisplayName", + "myDisplayName", + "caDisplayName", + "chDisplayName", + "ceDisplayName", + "nyDisplayName", + "zhDisplayName", + "cvDisplayName", + "kwDisplayName", + "coDisplayName", + "crDisplayName", + "hrDisplayName", + "csDisplayName", + "daDisplayName", + "dvDisplayName", + "nlDisplayName", + "enDisplayName", + "eoDisplayName", + "etDisplayName", + "eeDisplayName", + "foDisplayName", + "fjDisplayName", + "fiDisplayName", + "frDisplayName", + "ffDisplayName", + "glDisplayName", + "kaDisplayName", + "deDisplayName", + "elDisplayName", + "gnDisplayName", + "guDisplayName", + "htDisplayName", + "haDisplayName", + "heDisplayName", + "hzDisplayName", + "hiDisplayName", + "hoDisplayName", + "huDisplayName", + "iaDisplayName", + "idDisplayName", + "ieDisplayName", + "gaDisplayName", + "igDisplayName", + "ikDisplayName", + "ioDisplayName", + "isDisplayName", + "itDisplayName", + "iuDisplayName", + "jaDisplayName", + "jvDisplayName", + "klDisplayName", + "knDisplayName", + "krDisplayName", + "ksDisplayName", + "kkDisplayName", + "kmDisplayName", + "kiDisplayName", + "rwDisplayName", + "kyDisplayName", + "kvDisplayName", + "kgDisplayName", + "koDisplayName", + "kuDisplayName", + "kjDisplayName", + "laDisplayName", + "lbDisplayName", + "lgDisplayName", + "liDisplayName", + "lnDisplayName", + "loDisplayName", + "ltDisplayName", + "luDisplayName", + "lvDisplayName", + "gvDisplayName", + "mkDisplayName", + "mgDisplayName", + "msDisplayName", + "mlDisplayName", + "mtDisplayName", + "miDisplayName", + "mrDisplayName", + "mhDisplayName", + "mnDisplayName", + "naDisplayName", + "nvDisplayName", + "nbDisplayName", + "ndDisplayName", + "neDisplayName", + "ngDisplayName", + "nnDisplayName", + "noDisplayName", + "iiDisplayName", + "nrDisplayName", + "ocDisplayName", + "ojDisplayName", + "cuDisplayName", + "omDisplayName", + "orDisplayName", + "osDisplayName", + "paDisplayName", + "piDisplayName", + "faDisplayName", + "plDisplayName", + "psDisplayName", + "ptDisplayName", + "quDisplayName", + "rmDisplayName", + "rnDisplayName", + "roDisplayName", + "ruDisplayName", + "saDisplayName", + "scDisplayName", + "sdDisplayName", + "seDisplayName", + "smDisplayName", + "sgDisplayName", + "srDisplayName", + "gdDisplayName", + "snDisplayName", + "siDisplayName", + "skDisplayName", + "slDisplayName", + "soDisplayName", + "stDisplayName", + "esDisplayName", + "suDisplayName", + "swDisplayName", + "ssDisplayName", + "svDisplayName", + "taDisplayName", + "teDisplayName", + "tgDisplayName", + "thDisplayName", + "tiDisplayName", + "boDisplayName", + "tkDisplayName", + "tlDisplayName", + "tnDisplayName", + "toDisplayName", + "trDisplayName", + "tsDisplayName", + "ttDisplayName", + "twDisplayName", + "tyDisplayName", + "ugDisplayName", + "ukDisplayName", + "urDisplayName", + "uzDisplayName", + "veDisplayName", + "viDisplayName", + "voDisplayName", + "waDisplayName", + "cyDisplayName", + "woDisplayName", + "fyDisplayName", + "xhDisplayName", + "yiDisplayName", + "yoDisplayName", + "zaDisplayName", + "unkDisplayName", + "zuDisplayName", + "hawDisplayName", + "hmnDisplayName", + "multiDisplayName", + "cebDisplayName", + "dzDisplayName", + "iwDisplayName", + "jwDisplayName", + "moDisplayName", + "shDisplayName", + "wwCountryDisplayName", + "afCountryDisplayName", + "axCountryDisplayName", + "alCountryDisplayName", + "dzCountryDisplayName", + "asCountryDisplayName", + "adCountryDisplayName", + "aoCountryDisplayName", + "aiCountryDisplayName", + "agCountryDisplayName", + "arCountryDisplayName", + "amCountryDisplayName", + "awCountryDisplayName", + "acCountryDisplayName", + "auCountryDisplayName", + "atCountryDisplayName", + "azCountryDisplayName", + "bsCountryDisplayName", + "bhCountryDisplayName", + "bdCountryDisplayName", + "bbCountryDisplayName", + "byCountryDisplayName", + "beCountryDisplayName", + "bzCountryDisplayName", + "bjCountryDisplayName", + "bmCountryDisplayName", + "btCountryDisplayName", + "boCountryDisplayName", + "baCountryDisplayName", + "bwCountryDisplayName", + "brCountryDisplayName", + "ioCountryDisplayName", + "vgCountryDisplayName", + "bnCountryDisplayName", + "bgCountryDisplayName", + "bfCountryDisplayName", + "biCountryDisplayName", + "khCountryDisplayName", + "cmCountryDisplayName", + "caCountryDisplayName", + "cvCountryDisplayName", + "bqCountryDisplayName", + "kyCountryDisplayName", + "cfCountryDisplayName", + "tdCountryDisplayName", + "clCountryDisplayName", + "cnCountryDisplayName", + "cxCountryDisplayName", + "ccCountryDisplayName", + "coCountryDisplayName", + "kmCountryDisplayName", + "cdCountryDisplayName", + "cgCountryDisplayName", + "ckCountryDisplayName", + "crCountryDisplayName", + "ciCountryDisplayName", + "hrCountryDisplayName", + "cuCountryDisplayName", + "cwCountryDisplayName", + "cyCountryDisplayName", + "czCountryDisplayName", + "dkCountryDisplayName", + "djCountryDisplayName", + "dmCountryDisplayName", + "doCountryDisplayName", + "tlCountryDisplayName", + "ecCountryDisplayName", + "egCountryDisplayName", + "svCountryDisplayName", + "gqCountryDisplayName", + "erCountryDisplayName", + "eeCountryDisplayName", + "szCountryDisplayName", + "etCountryDisplayName", + "fkCountryDisplayName", + "foCountryDisplayName", + "fjCountryDisplayName", + "fiCountryDisplayName", + "frCountryDisplayName", + "gfCountryDisplayName", + "pfCountryDisplayName", + "gaCountryDisplayName", + "gmCountryDisplayName", + "geCountryDisplayName", + "deCountryDisplayName", + "ghCountryDisplayName", + "giCountryDisplayName", + "grCountryDisplayName", + "glCountryDisplayName", + "gdCountryDisplayName", + "gpCountryDisplayName", + "guCountryDisplayName", + "gtCountryDisplayName", + "ggCountryDisplayName", + "gnCountryDisplayName", + "gwCountryDisplayName", + "gyCountryDisplayName", + "htCountryDisplayName", + "hmCountryDisplayName", + "hnCountryDisplayName", + "hkCountryDisplayName", + "huCountryDisplayName", + "isCountryDisplayName", + "inCountryDisplayName", + "idCountryDisplayName", + "irCountryDisplayName", + "iqCountryDisplayName", + "ieCountryDisplayName", + "imCountryDisplayName", + "ilCountryDisplayName", + "itCountryDisplayName", + "jmCountryDisplayName", + "jpCountryDisplayName", + "jeCountryDisplayName", + "joCountryDisplayName", + "kzCountryDisplayName", + "keCountryDisplayName", + "kiCountryDisplayName", + "xkCountryDisplayName", + "kwCountryDisplayName", + "kgCountryDisplayName", + "laCountryDisplayName", + "lvCountryDisplayName", + "lbCountryDisplayName", + "lsCountryDisplayName", + "lrCountryDisplayName", + "lyCountryDisplayName", + "liCountryDisplayName", + "ltCountryDisplayName", + "luCountryDisplayName", + "moCountryDisplayName", + "mkCountryDisplayName", + "mgCountryDisplayName", + "mwCountryDisplayName", + "myCountryDisplayName", + "mvCountryDisplayName", + "mlCountryDisplayName", + "mtCountryDisplayName", + "mhCountryDisplayName", + "mqCountryDisplayName", + "mrCountryDisplayName", + "muCountryDisplayName", + "ytCountryDisplayName", + "mxCountryDisplayName", + "fmCountryDisplayName", + "mdCountryDisplayName", + "mcCountryDisplayName", + "mnCountryDisplayName", + "meCountryDisplayName", + "msCountryDisplayName", + "maCountryDisplayName", + "mzCountryDisplayName", + "mmCountryDisplayName", + "naCountryDisplayName", + "nrCountryDisplayName", + "npCountryDisplayName", + "nlCountryDisplayName", + "ncCountryDisplayName", + "nzCountryDisplayName", + "niCountryDisplayName", + "neCountryDisplayName", + "ngCountryDisplayName", + "nuCountryDisplayName", + "nfCountryDisplayName", + "kpCountryDisplayName", + "mpCountryDisplayName", + "noCountryDisplayName", + "omCountryDisplayName", + "pkCountryDisplayName", + "pwCountryDisplayName", + "psCountryDisplayName", + "paCountryDisplayName", + "pgCountryDisplayName", + "pyCountryDisplayName", + "peCountryDisplayName", + "phCountryDisplayName", + "plCountryDisplayName", + "ptCountryDisplayName", + "prCountryDisplayName", + "qaCountryDisplayName", + "reCountryDisplayName", + "roCountryDisplayName", + "ruCountryDisplayName", + "rwCountryDisplayName", + "blCountryDisplayName", + "shCountryDisplayName", + "knCountryDisplayName", + "lcCountryDisplayName", + "mfCountryDisplayName", + "pmCountryDisplayName", + "vcCountryDisplayName", + "wsCountryDisplayName", + "smCountryDisplayName", + "stCountryDisplayName", + "saCountryDisplayName", + "snCountryDisplayName", + "rsCountryDisplayName", + "scCountryDisplayName", + "slCountryDisplayName", + "sgCountryDisplayName", + "sxCountryDisplayName", + "skCountryDisplayName", + "siCountryDisplayName", + "sbCountryDisplayName", + "soCountryDisplayName", + "zaCountryDisplayName", + "gsCountryDisplayName", + "krCountryDisplayName", + "ssCountryDisplayName", + "esCountryDisplayName", + "lkCountryDisplayName", + "sdCountryDisplayName", + "srCountryDisplayName", + "sjCountryDisplayName", + "seCountryDisplayName", + "chCountryDisplayName", + "syCountryDisplayName", + "twCountryDisplayName", + "tjCountryDisplayName", + "tzCountryDisplayName", + "thCountryDisplayName", + "tgCountryDisplayName", + "tkCountryDisplayName", + "toCountryDisplayName", + "ttCountryDisplayName", + "tnCountryDisplayName", + "trCountryDisplayName", + "tmCountryDisplayName", + "tcCountryDisplayName", + "tvCountryDisplayName", + "viCountryDisplayName", + "ugCountryDisplayName", + "uaCountryDisplayName", + "aeCountryDisplayName", + "gbCountryDisplayName", + "usCountryDisplayName", + "uyCountryDisplayName", + "uzCountryDisplayName", + "vuCountryDisplayName", + "vaCountryDisplayName", + "veCountryDisplayName", + "vnCountryDisplayName", + "wfCountryDisplayName", + "ehCountryDisplayName", + "yeCountryDisplayName", + "zmCountryDisplayName", + "zwCountryDisplayName", + "pay", + "allPrivateChats", + "unknownPrivateChat", + "copyClassCodeDesc", + "addToClassDesc", + "addToClassOrExchange", + "addToClassOrExchangeDesc", + "invitedToClassOrExchange", + "decline", + "declinedInvitation", + "acceptedInvitation", + "youreInvited", + "studentPermissionsDesc", + "noEligibleSpaces", + "youAddedToSpace", + "youRemovedFromSpace", + "invitedToChat", + "monthlySubscription", + "yearlySubscription", + "defaultSubscription", + "freeTrial", + "grammarAnalytics", + "total", + "noDataFound", + "promoSubscriptionExpirationDesc", + "emptyChatNameWarning", + "emptyClassNameWarning", + "emptyExchangeNameWarning", + "blurMeansTranslateTitle", + "blurMeansTranslateBody", + "someErrorTitle", + "someErrorBody", + "bestCorrectionFeedback", + "distractorFeedback", + "bestAnswerFeedback", + "definitionDefaultPrompt", + "practiceDefaultPrompt", + "correctionDefaultPrompt", + "itStartDefaultPrompt", + "languageLevelWarning", + "lockedChatWarning", + "lockSpace", + "lockChat", + "archiveSpace", + "suggestTo", + "suggestChatDesc", + "suggestExchangeDesc", + "acceptSelection", + "acceptSelectionAnyway", + "makingActivity", + "why", + "definition", + "exampleSentence", + "addToClassTitle", + "reportToTeacher", + "reportMessageTitle", + "reportMessageBody", + "noTeachersFound", + "noAddToSpacePermissions", + "alreadyInSpace", + "yourGlobalUserIdIs", + "noUsersFoundWithQuery", + "searchChatsRooms", + "groupName", + "createGroupAndInviteUsers", + "groupCanBeFoundViaSearch", + "inNoSpaces" + ], + + "vi": [ + "accountInformation", + "addNewFriend", + "alreadyHaveAnAccount", + "classes", + "editChatPermissions", + "groupDescription", + "groupDescriptionHasBeenChanged", + "allCorrect", + "newWayAllGood", + "othersAreBetter", + "holdForInfo", + "greenFeedback", + "yellowFeedback", + "redFeedback", + "customInputFeedbackChoice", + "itInstructionsTitle", + "itInstructionsBody", + "toggleLanguages", + "classWelcomeChat", + "deleteSpace", + "deleteGroup", + "areYouSureDeleteClass", + "areYouSureDeleteGroup", + "cannotBeReversed", + "enterDeletedClassName", + "incorrectClassName", + "oneday", + "oneweek", + "onemonth", + "sixmonth", + "oneyear", + "gaTooltip", + "taTooltip", + "unTooltip", + "interactiveTranslatorSliderHeader", + "interactiveGrammarSliderHeader", + "interactiveTranslatorNotAllowed", + "interactiveTranslatorAllowed", + "interactiveTranslatorRequired", + "interactiveTranslatorNotAllowedDesc", + "interactiveTranslatorAllowedDesc", + "interactiveTranslatorRequiredDesc", + "notYetSet", + "multiLingualClass", + "classAnalytics", + "allClasses", + "myLearning", + "allChatsAndClasses", + "timeOfLastMessage", + "totalMessages", + "waTooltip", + "changeDateRange", + "numberOfStudents", + "classDescription", + "classDescriptionDesc", + "requestToEnroll", + "requestAnExchange", + "findLanguageExchange", + "classAnalyticsDesc", + "addStudents", + "copyClassLink", + "copyClassLinkDesc", + "copyClassCode", + "inviteStudentByUserName", + "classSettings", + "classSettingsDesc", + "selectClassRoomDominantLanguage", + "selectTargetLanguage", + "whatIsYourClassLanguageLevel", + "studentPermissions", + "interactiveTranslator", + "oneToOneChatsWithinClass", + "oneToOneChatsWithinClassDesc", + "createGroupChats", + "createGroupChatsDesc", + "shareVideo", + "shareVideoDesc", + "sharePhotos", + "sharePhotosDesc", + "shareFiles", + "shareFilesDesc", + "shareLocationDesc", + "selectLanguageLevel", + "noIdenticalLanguages", + "iWantALanguagePartnerFrom", + "worldWide", + "noResults", + "searchBy", + "iWantAConversationPartner", + "iWantALanguagePartnerWhoSpeaks", + "iWantALanguagePartnerWhoIsLearning", + "yourBirthdayPlease", + "invalidDob", + "enterYourDob", + "getStarted", + "mustBe13", + "yourBirthdayPleaseShort", + "errorPleaseRefresh", + "joinWithClassCode", + "joinWithClassCodeDesc", + "joinWithClassCodeHint", + "unableToFindClass", + "languageLevelPreA1", + "languageLevelA1", + "languageLevelA2", + "languageLevelB1", + "languageLevelB2", + "languageLevelC1", + "languageLevelC2", + "changeTheNameOfTheClass", + "changeTheNameOfTheChat", + "welcomeToYourNewClass", + "welcomeToClass", + "welcomeToPangea18Plus", + "welcomeToPangeaMinor", + "findALanguagePartner", + "setToPublicSettingsTitle", + "setToPublicSettingsDesc", + "accountSettings", + "unableToFindClassCode", + "askPangeaBot", + "sorryNoResults", + "ignoreInThisText", + "helpMeTranslate", + "needsItShortMessage", + "needsIGCShortMessage", + "needsItMessage", + "needsIgcMessage", + "tokenTranslationTitle", + "spanTranslationDesc", + "spanTranslationTitle", + "l1SpanAndGrammarTitle", + "l1SpanAndGrammarDesc", + "otherTitle", + "otherDesc", + "countryInformation", + "myLanguages", + "targetLanguage", + "sourceLanguage", + "languagesISpeak", + "updateLanguage", + "whatLanguageYouWantToLearn", + "whatIsYourBaseLanguage", + "saveChanges", + "publicProfileTitle", + "publicProfileDesc", + "error502504Title", + "error502504Desc", + "error404Title", + "error404Desc", + "errorDisableIT", + "errorDisableIGC", + "errorDisableLanguageAssistance", + "errorDisableITUserDesc", + "errorDisableIGCUserDesc", + "errorDisableLanguageAssistanceUserDesc", + "errorDisableITClassDesc", + "errorDisableIGCClassDesc", + "errorDisableLanguageAssistanceClassDesc", + "itIsDisabled", + "igcIsDisabled", + "goToLearningSettings", + "error405Title", + "error405Desc", + "loginOrSignup", + "iAgreeToThe", + "termsAndConditions", + "andCertifyIAmAtLeast13YearsOfAge", + "findAClass", + "toggleIT", + "toggleIGC", + "toggleToolSettingsDescription", + "connectedToStaging", + "learningSettings", + "classNameRequired", + "sendVoiceNotes", + "sendVoiceNotesDesc", + "chatTopic", + "chatTopicDesc", + "inviteStudentByUserNameDesc", + "classRoster", + "almostPerfect", + "prettyGood", + "letMeThink", + "clickMessageTitle", + "clickMessageBody", + "understandingMessagesTitle", + "addToClass", + "understandingMessagesBody", + "allDone", + "vocab", + "low", + "medium", + "high", + "unknownProficiency", + "changeView", + "clearAll", + "generateVocabulary", + "generatePrompts", + "subscribe", + "getAccess", + "subscriptionDesc", + "subscriptionManagement", + "currentSubscription", + "changeSubscription", + "cancelSubscription", + "selectYourPlan", + "subsciptionPlatformTooltip", + "subscriptionManagementUnavailable", + "paymentMethod", + "paymentHistory", + "emptyChatDownloadWarning", + "appUpdateAvailable", + "update", + "updateDesc", + "maybeLater", + "mainMenu", + "toggleImmersionMode", + "toggleImmersionModeDesc", + "itToggleDescription", + "igcToggleDescription", + "sendOnEnterDescription", + "alreadyInClass", + "pleaseLoginFirst", + "originalMessage", + "sentMessage", + "useType", + "notAvailable", + "taAndGaTooltip", + "definitionsToolName", + "messageTranslationsToolName", + "definitionsToolDescription", + "translationsToolDescrption", + "welcomeBack", + "classExchanges", + "createNewClass", + "newExchange", + "kickAllStudents", + "kickAllStudentsConfirmation", + "inviteAllStudents", + "inviteAllStudentsConfirmation", + "inviteStudentsFromOtherClasses", + "inviteUsersFromPangea", + "allExchanges", + "redeemPromoCode", + "enterPromoCode", + "downloadTxtFile", + "downloadCSVFile", + "promotionalSubscriptionDesc", + "originalSubscriptionPlatform", + "oneWeekTrial", + "creatingSpacePleaseWait", + "downloadXLSXFile", + "abDisplayName", + "aaDisplayName", + "afDisplayName", + "akDisplayName", + "sqDisplayName", + "amDisplayName", + "arDisplayName", + "anDisplayName", + "hyDisplayName", + "asDisplayName", + "avDisplayName", + "aeDisplayName", + "ayDisplayName", + "azDisplayName", + "bmDisplayName", + "baDisplayName", + "euDisplayName", + "beDisplayName", + "bnDisplayName", + "bhDisplayName", + "biDisplayName", + "bsDisplayName", + "brDisplayName", + "bgDisplayName", + "myDisplayName", + "caDisplayName", + "chDisplayName", + "ceDisplayName", + "nyDisplayName", + "zhDisplayName", + "cvDisplayName", + "kwDisplayName", + "coDisplayName", + "crDisplayName", + "hrDisplayName", + "csDisplayName", + "daDisplayName", + "dvDisplayName", + "nlDisplayName", + "enDisplayName", + "eoDisplayName", + "etDisplayName", + "eeDisplayName", + "foDisplayName", + "fjDisplayName", + "fiDisplayName", + "frDisplayName", + "ffDisplayName", + "glDisplayName", + "kaDisplayName", + "deDisplayName", + "elDisplayName", + "gnDisplayName", + "guDisplayName", + "htDisplayName", + "haDisplayName", + "heDisplayName", + "hzDisplayName", + "hiDisplayName", + "hoDisplayName", + "huDisplayName", + "iaDisplayName", + "idDisplayName", + "ieDisplayName", + "gaDisplayName", + "igDisplayName", + "ikDisplayName", + "ioDisplayName", + "isDisplayName", + "itDisplayName", + "iuDisplayName", + "jaDisplayName", + "jvDisplayName", + "klDisplayName", + "knDisplayName", + "krDisplayName", + "ksDisplayName", + "kkDisplayName", + "kmDisplayName", + "kiDisplayName", + "rwDisplayName", + "kyDisplayName", + "kvDisplayName", + "kgDisplayName", + "koDisplayName", + "kuDisplayName", + "kjDisplayName", + "laDisplayName", + "lbDisplayName", + "lgDisplayName", + "liDisplayName", + "lnDisplayName", + "loDisplayName", + "ltDisplayName", + "luDisplayName", + "lvDisplayName", + "gvDisplayName", + "mkDisplayName", + "mgDisplayName", + "msDisplayName", + "mlDisplayName", + "mtDisplayName", + "miDisplayName", + "mrDisplayName", + "mhDisplayName", + "mnDisplayName", + "naDisplayName", + "nvDisplayName", + "nbDisplayName", + "ndDisplayName", + "neDisplayName", + "ngDisplayName", + "nnDisplayName", + "noDisplayName", + "iiDisplayName", + "nrDisplayName", + "ocDisplayName", + "ojDisplayName", + "cuDisplayName", + "omDisplayName", + "orDisplayName", + "osDisplayName", + "paDisplayName", + "piDisplayName", + "faDisplayName", + "plDisplayName", + "psDisplayName", + "ptDisplayName", + "quDisplayName", + "rmDisplayName", + "rnDisplayName", + "roDisplayName", + "ruDisplayName", + "saDisplayName", + "scDisplayName", + "sdDisplayName", + "seDisplayName", + "smDisplayName", + "sgDisplayName", + "srDisplayName", + "gdDisplayName", + "snDisplayName", + "siDisplayName", + "skDisplayName", + "slDisplayName", + "soDisplayName", + "stDisplayName", + "esDisplayName", + "suDisplayName", + "swDisplayName", + "ssDisplayName", + "svDisplayName", + "taDisplayName", + "teDisplayName", + "tgDisplayName", + "thDisplayName", + "tiDisplayName", + "boDisplayName", + "tkDisplayName", + "tlDisplayName", + "tnDisplayName", + "toDisplayName", + "trDisplayName", + "tsDisplayName", + "ttDisplayName", + "twDisplayName", + "tyDisplayName", + "ugDisplayName", + "ukDisplayName", + "urDisplayName", + "uzDisplayName", + "veDisplayName", + "viDisplayName", + "voDisplayName", + "waDisplayName", + "cyDisplayName", + "woDisplayName", + "fyDisplayName", + "xhDisplayName", + "yiDisplayName", + "yoDisplayName", + "zaDisplayName", + "unkDisplayName", + "zuDisplayName", + "hawDisplayName", + "hmnDisplayName", + "multiDisplayName", + "cebDisplayName", + "dzDisplayName", + "iwDisplayName", + "jwDisplayName", + "moDisplayName", + "shDisplayName", + "wwCountryDisplayName", + "afCountryDisplayName", + "axCountryDisplayName", + "alCountryDisplayName", + "dzCountryDisplayName", + "asCountryDisplayName", + "adCountryDisplayName", + "aoCountryDisplayName", + "aiCountryDisplayName", + "agCountryDisplayName", + "arCountryDisplayName", + "amCountryDisplayName", + "awCountryDisplayName", + "acCountryDisplayName", + "auCountryDisplayName", + "atCountryDisplayName", + "azCountryDisplayName", + "bsCountryDisplayName", + "bhCountryDisplayName", + "bdCountryDisplayName", + "bbCountryDisplayName", + "byCountryDisplayName", + "beCountryDisplayName", + "bzCountryDisplayName", + "bjCountryDisplayName", + "bmCountryDisplayName", + "btCountryDisplayName", + "boCountryDisplayName", + "baCountryDisplayName", + "bwCountryDisplayName", + "brCountryDisplayName", + "ioCountryDisplayName", + "vgCountryDisplayName", + "bnCountryDisplayName", + "bgCountryDisplayName", + "bfCountryDisplayName", + "biCountryDisplayName", + "khCountryDisplayName", + "cmCountryDisplayName", + "caCountryDisplayName", + "cvCountryDisplayName", + "bqCountryDisplayName", + "kyCountryDisplayName", + "cfCountryDisplayName", + "tdCountryDisplayName", + "clCountryDisplayName", + "cnCountryDisplayName", + "cxCountryDisplayName", + "ccCountryDisplayName", + "coCountryDisplayName", + "kmCountryDisplayName", + "cdCountryDisplayName", + "cgCountryDisplayName", + "ckCountryDisplayName", + "crCountryDisplayName", + "ciCountryDisplayName", + "hrCountryDisplayName", + "cuCountryDisplayName", + "cwCountryDisplayName", + "cyCountryDisplayName", + "czCountryDisplayName", + "dkCountryDisplayName", + "djCountryDisplayName", + "dmCountryDisplayName", + "doCountryDisplayName", + "tlCountryDisplayName", + "ecCountryDisplayName", + "egCountryDisplayName", + "svCountryDisplayName", + "gqCountryDisplayName", + "erCountryDisplayName", + "eeCountryDisplayName", + "szCountryDisplayName", + "etCountryDisplayName", + "fkCountryDisplayName", + "foCountryDisplayName", + "fjCountryDisplayName", + "fiCountryDisplayName", + "frCountryDisplayName", + "gfCountryDisplayName", + "pfCountryDisplayName", + "gaCountryDisplayName", + "gmCountryDisplayName", + "geCountryDisplayName", + "deCountryDisplayName", + "ghCountryDisplayName", + "giCountryDisplayName", + "grCountryDisplayName", + "glCountryDisplayName", + "gdCountryDisplayName", + "gpCountryDisplayName", + "guCountryDisplayName", + "gtCountryDisplayName", + "ggCountryDisplayName", + "gnCountryDisplayName", + "gwCountryDisplayName", + "gyCountryDisplayName", + "htCountryDisplayName", + "hmCountryDisplayName", + "hnCountryDisplayName", + "hkCountryDisplayName", + "huCountryDisplayName", + "isCountryDisplayName", + "inCountryDisplayName", + "idCountryDisplayName", + "irCountryDisplayName", + "iqCountryDisplayName", + "ieCountryDisplayName", + "imCountryDisplayName", + "ilCountryDisplayName", + "itCountryDisplayName", + "jmCountryDisplayName", + "jpCountryDisplayName", + "jeCountryDisplayName", + "joCountryDisplayName", + "kzCountryDisplayName", + "keCountryDisplayName", + "kiCountryDisplayName", + "xkCountryDisplayName", + "kwCountryDisplayName", + "kgCountryDisplayName", + "laCountryDisplayName", + "lvCountryDisplayName", + "lbCountryDisplayName", + "lsCountryDisplayName", + "lrCountryDisplayName", + "lyCountryDisplayName", + "liCountryDisplayName", + "ltCountryDisplayName", + "luCountryDisplayName", + "moCountryDisplayName", + "mkCountryDisplayName", + "mgCountryDisplayName", + "mwCountryDisplayName", + "myCountryDisplayName", + "mvCountryDisplayName", + "mlCountryDisplayName", + "mtCountryDisplayName", + "mhCountryDisplayName", + "mqCountryDisplayName", + "mrCountryDisplayName", + "muCountryDisplayName", + "ytCountryDisplayName", + "mxCountryDisplayName", + "fmCountryDisplayName", + "mdCountryDisplayName", + "mcCountryDisplayName", + "mnCountryDisplayName", + "meCountryDisplayName", + "msCountryDisplayName", + "maCountryDisplayName", + "mzCountryDisplayName", + "mmCountryDisplayName", + "naCountryDisplayName", + "nrCountryDisplayName", + "npCountryDisplayName", + "nlCountryDisplayName", + "ncCountryDisplayName", + "nzCountryDisplayName", + "niCountryDisplayName", + "neCountryDisplayName", + "ngCountryDisplayName", + "nuCountryDisplayName", + "nfCountryDisplayName", + "kpCountryDisplayName", + "mpCountryDisplayName", + "noCountryDisplayName", + "omCountryDisplayName", + "pkCountryDisplayName", + "pwCountryDisplayName", + "psCountryDisplayName", + "paCountryDisplayName", + "pgCountryDisplayName", + "pyCountryDisplayName", + "peCountryDisplayName", + "phCountryDisplayName", + "plCountryDisplayName", + "ptCountryDisplayName", + "prCountryDisplayName", + "qaCountryDisplayName", + "reCountryDisplayName", + "roCountryDisplayName", + "ruCountryDisplayName", + "rwCountryDisplayName", + "blCountryDisplayName", + "shCountryDisplayName", + "knCountryDisplayName", + "lcCountryDisplayName", + "mfCountryDisplayName", + "pmCountryDisplayName", + "vcCountryDisplayName", + "wsCountryDisplayName", + "smCountryDisplayName", + "stCountryDisplayName", + "saCountryDisplayName", + "snCountryDisplayName", + "rsCountryDisplayName", + "scCountryDisplayName", + "slCountryDisplayName", + "sgCountryDisplayName", + "sxCountryDisplayName", + "skCountryDisplayName", + "siCountryDisplayName", + "sbCountryDisplayName", + "soCountryDisplayName", + "zaCountryDisplayName", + "gsCountryDisplayName", + "krCountryDisplayName", + "ssCountryDisplayName", + "esCountryDisplayName", + "lkCountryDisplayName", + "sdCountryDisplayName", + "srCountryDisplayName", + "sjCountryDisplayName", + "seCountryDisplayName", + "chCountryDisplayName", + "syCountryDisplayName", + "twCountryDisplayName", + "tjCountryDisplayName", + "tzCountryDisplayName", + "thCountryDisplayName", + "tgCountryDisplayName", + "tkCountryDisplayName", + "toCountryDisplayName", + "ttCountryDisplayName", + "tnCountryDisplayName", + "trCountryDisplayName", + "tmCountryDisplayName", + "tcCountryDisplayName", + "tvCountryDisplayName", + "viCountryDisplayName", + "ugCountryDisplayName", + "uaCountryDisplayName", + "aeCountryDisplayName", + "gbCountryDisplayName", + "usCountryDisplayName", + "uyCountryDisplayName", + "uzCountryDisplayName", + "vuCountryDisplayName", + "vaCountryDisplayName", + "veCountryDisplayName", + "vnCountryDisplayName", + "wfCountryDisplayName", + "ehCountryDisplayName", + "yeCountryDisplayName", + "zmCountryDisplayName", + "zwCountryDisplayName", + "pay", + "allPrivateChats", + "unknownPrivateChat", + "copyClassCodeDesc", + "addToClassDesc", + "addToClassOrExchange", + "addToClassOrExchangeDesc", + "invitedToClassOrExchange", + "decline", + "declinedInvitation", + "acceptedInvitation", + "youreInvited", + "studentPermissionsDesc", + "noEligibleSpaces", + "youAddedToSpace", + "youRemovedFromSpace", + "invitedToChat", + "monthlySubscription", + "yearlySubscription", + "defaultSubscription", + "freeTrial", + "grammarAnalytics", + "total", + "noDataFound", + "promoSubscriptionExpirationDesc", + "emptyChatNameWarning", + "emptyClassNameWarning", + "emptyExchangeNameWarning", + "blurMeansTranslateTitle", + "blurMeansTranslateBody", + "someErrorTitle", + "someErrorBody", + "bestCorrectionFeedback", + "distractorFeedback", + "bestAnswerFeedback", + "definitionDefaultPrompt", + "practiceDefaultPrompt", + "correctionDefaultPrompt", + "itStartDefaultPrompt", + "languageLevelWarning", + "lockedChatWarning", + "lockSpace", + "lockChat", + "archiveSpace", + "suggestTo", + "suggestChatDesc", + "suggestExchangeDesc", + "acceptSelection", + "acceptSelectionAnyway", + "makingActivity", + "why", + "definition", + "exampleSentence", + "addToClassTitle", + "reportToTeacher", + "reportMessageTitle", + "reportMessageBody", + "noTeachersFound", + "noAddToSpacePermissions", + "alreadyInSpace", + "yourGlobalUserIdIs", + "noUsersFoundWithQuery", + "searchChatsRooms", + "groupName", + "createGroupAndInviteUsers", + "groupCanBeFoundViaSearch", + "inNoSpaces" + ], + + "zh": [ + "accountInformation", + "addNewFriend", + "alreadyHaveAnAccount", + "classes", + "allCorrect", + "newWayAllGood", + "othersAreBetter", + "holdForInfo", + "greenFeedback", + "yellowFeedback", + "redFeedback", + "customInputFeedbackChoice", + "itInstructionsTitle", + "itInstructionsBody", + "toggleLanguages", + "classWelcomeChat", + "deleteSpace", + "deleteGroup", + "areYouSureDeleteClass", + "areYouSureDeleteGroup", + "cannotBeReversed", + "enterDeletedClassName", + "incorrectClassName", + "oneday", + "oneweek", + "onemonth", + "sixmonth", + "oneyear", + "gaTooltip", + "taTooltip", + "unTooltip", + "interactiveTranslatorSliderHeader", + "interactiveGrammarSliderHeader", + "interactiveTranslatorNotAllowed", + "interactiveTranslatorAllowed", + "interactiveTranslatorRequired", + "interactiveTranslatorNotAllowedDesc", + "interactiveTranslatorAllowedDesc", + "interactiveTranslatorRequiredDesc", + "notYetSet", + "multiLingualClass", + "classAnalytics", + "allClasses", + "myLearning", + "allChatsAndClasses", + "timeOfLastMessage", + "totalMessages", + "waTooltip", + "changeDateRange", + "numberOfStudents", + "classDescription", + "classDescriptionDesc", + "requestToEnroll", + "requestAnExchange", + "findLanguageExchange", + "classAnalyticsDesc", + "addStudents", + "copyClassLink", + "copyClassLinkDesc", + "copyClassCode", + "inviteStudentByUserName", + "classSettings", + "classSettingsDesc", + "selectClassRoomDominantLanguage", + "selectTargetLanguage", + "whatIsYourClassLanguageLevel", + "studentPermissions", + "interactiveTranslator", + "oneToOneChatsWithinClass", + "oneToOneChatsWithinClassDesc", + "createGroupChats", + "createGroupChatsDesc", + "shareVideo", + "shareVideoDesc", + "sharePhotos", + "sharePhotosDesc", + "shareFiles", + "shareFilesDesc", + "shareLocationDesc", + "selectLanguageLevel", + "noIdenticalLanguages", + "iWantALanguagePartnerFrom", + "worldWide", + "noResults", + "searchBy", + "iWantAConversationPartner", + "iWantALanguagePartnerWhoSpeaks", + "iWantALanguagePartnerWhoIsLearning", + "yourBirthdayPlease", + "invalidDob", + "enterYourDob", + "getStarted", + "mustBe13", + "yourBirthdayPleaseShort", + "errorPleaseRefresh", + "joinWithClassCode", + "joinWithClassCodeDesc", + "joinWithClassCodeHint", + "unableToFindClass", + "languageLevelPreA1", + "languageLevelA1", + "languageLevelA2", + "languageLevelB1", + "languageLevelB2", + "languageLevelC1", + "languageLevelC2", + "changeTheNameOfTheClass", + "changeTheNameOfTheChat", + "welcomeToYourNewClass", + "welcomeToClass", + "welcomeToPangea18Plus", + "welcomeToPangeaMinor", + "findALanguagePartner", + "setToPublicSettingsTitle", + "setToPublicSettingsDesc", + "accountSettings", + "unableToFindClassCode", + "askPangeaBot", + "sorryNoResults", + "ignoreInThisText", + "helpMeTranslate", + "needsItShortMessage", + "needsIGCShortMessage", + "needsItMessage", + "needsIgcMessage", + "tokenTranslationTitle", + "spanTranslationDesc", + "spanTranslationTitle", + "l1SpanAndGrammarTitle", + "l1SpanAndGrammarDesc", + "otherTitle", + "otherDesc", + "countryInformation", + "myLanguages", + "targetLanguage", + "sourceLanguage", + "languagesISpeak", + "updateLanguage", + "whatLanguageYouWantToLearn", + "whatIsYourBaseLanguage", + "saveChanges", + "publicProfileTitle", + "publicProfileDesc", + "error502504Title", + "error502504Desc", + "error404Title", + "error404Desc", + "errorDisableIT", + "errorDisableIGC", + "errorDisableLanguageAssistance", + "errorDisableITUserDesc", + "errorDisableIGCUserDesc", + "errorDisableLanguageAssistanceUserDesc", + "errorDisableITClassDesc", + "errorDisableIGCClassDesc", + "errorDisableLanguageAssistanceClassDesc", + "itIsDisabled", + "igcIsDisabled", + "goToLearningSettings", + "error405Title", + "error405Desc", + "loginOrSignup", + "iAgreeToThe", + "termsAndConditions", + "andCertifyIAmAtLeast13YearsOfAge", + "findAClass", + "toggleIT", + "toggleIGC", + "toggleToolSettingsDescription", + "connectedToStaging", + "learningSettings", + "classNameRequired", + "sendVoiceNotes", + "sendVoiceNotesDesc", + "chatTopic", + "chatTopicDesc", + "inviteStudentByUserNameDesc", + "classRoster", + "almostPerfect", + "prettyGood", + "letMeThink", + "clickMessageTitle", + "clickMessageBody", + "understandingMessagesTitle", + "addToClass", + "understandingMessagesBody", + "allDone", + "vocab", + "low", + "medium", + "high", + "unknownProficiency", + "changeView", + "clearAll", + "generateVocabulary", + "generatePrompts", + "subscribe", + "getAccess", + "subscriptionDesc", + "subscriptionManagement", + "currentSubscription", + "changeSubscription", + "cancelSubscription", + "selectYourPlan", + "subsciptionPlatformTooltip", + "subscriptionManagementUnavailable", + "paymentMethod", + "paymentHistory", + "emptyChatDownloadWarning", + "appUpdateAvailable", + "update", + "updateDesc", + "maybeLater", + "mainMenu", + "toggleImmersionMode", + "toggleImmersionModeDesc", + "itToggleDescription", + "igcToggleDescription", + "sendOnEnterDescription", + "alreadyInClass", + "pleaseLoginFirst", + "originalMessage", + "sentMessage", + "useType", + "notAvailable", + "taAndGaTooltip", + "definitionsToolName", + "messageTranslationsToolName", + "definitionsToolDescription", + "translationsToolDescrption", + "welcomeBack", + "classExchanges", + "createNewClass", + "newExchange", + "kickAllStudents", + "kickAllStudentsConfirmation", + "inviteAllStudents", + "inviteAllStudentsConfirmation", + "inviteStudentsFromOtherClasses", + "inviteUsersFromPangea", + "allExchanges", + "redeemPromoCode", + "enterPromoCode", + "downloadTxtFile", + "downloadCSVFile", + "promotionalSubscriptionDesc", + "originalSubscriptionPlatform", + "oneWeekTrial", + "creatingSpacePleaseWait", + "downloadXLSXFile", + "abDisplayName", + "aaDisplayName", + "afDisplayName", + "akDisplayName", + "sqDisplayName", + "amDisplayName", + "arDisplayName", + "anDisplayName", + "hyDisplayName", + "asDisplayName", + "avDisplayName", + "aeDisplayName", + "ayDisplayName", + "azDisplayName", + "bmDisplayName", + "baDisplayName", + "euDisplayName", + "beDisplayName", + "bnDisplayName", + "bhDisplayName", + "biDisplayName", + "bsDisplayName", + "brDisplayName", + "bgDisplayName", + "myDisplayName", + "caDisplayName", + "chDisplayName", + "ceDisplayName", + "nyDisplayName", + "zhDisplayName", + "cvDisplayName", + "kwDisplayName", + "coDisplayName", + "crDisplayName", + "hrDisplayName", + "csDisplayName", + "daDisplayName", + "dvDisplayName", + "nlDisplayName", + "enDisplayName", + "eoDisplayName", + "etDisplayName", + "eeDisplayName", + "foDisplayName", + "fjDisplayName", + "fiDisplayName", + "frDisplayName", + "ffDisplayName", + "glDisplayName", + "kaDisplayName", + "deDisplayName", + "elDisplayName", + "gnDisplayName", + "guDisplayName", + "htDisplayName", + "haDisplayName", + "heDisplayName", + "hzDisplayName", + "hiDisplayName", + "hoDisplayName", + "huDisplayName", + "iaDisplayName", + "idDisplayName", + "ieDisplayName", + "gaDisplayName", + "igDisplayName", + "ikDisplayName", + "ioDisplayName", + "isDisplayName", + "itDisplayName", + "iuDisplayName", + "jaDisplayName", + "jvDisplayName", + "klDisplayName", + "knDisplayName", + "krDisplayName", + "ksDisplayName", + "kkDisplayName", + "kmDisplayName", + "kiDisplayName", + "rwDisplayName", + "kyDisplayName", + "kvDisplayName", + "kgDisplayName", + "koDisplayName", + "kuDisplayName", + "kjDisplayName", + "laDisplayName", + "lbDisplayName", + "lgDisplayName", + "liDisplayName", + "lnDisplayName", + "loDisplayName", + "ltDisplayName", + "luDisplayName", + "lvDisplayName", + "gvDisplayName", + "mkDisplayName", + "mgDisplayName", + "msDisplayName", + "mlDisplayName", + "mtDisplayName", + "miDisplayName", + "mrDisplayName", + "mhDisplayName", + "mnDisplayName", + "naDisplayName", + "nvDisplayName", + "nbDisplayName", + "ndDisplayName", + "neDisplayName", + "ngDisplayName", + "nnDisplayName", + "noDisplayName", + "iiDisplayName", + "nrDisplayName", + "ocDisplayName", + "ojDisplayName", + "cuDisplayName", + "omDisplayName", + "orDisplayName", + "osDisplayName", + "paDisplayName", + "piDisplayName", + "faDisplayName", + "plDisplayName", + "psDisplayName", + "ptDisplayName", + "quDisplayName", + "rmDisplayName", + "rnDisplayName", + "roDisplayName", + "ruDisplayName", + "saDisplayName", + "scDisplayName", + "sdDisplayName", + "seDisplayName", + "smDisplayName", + "sgDisplayName", + "srDisplayName", + "gdDisplayName", + "snDisplayName", + "siDisplayName", + "skDisplayName", + "slDisplayName", + "soDisplayName", + "stDisplayName", + "esDisplayName", + "suDisplayName", + "swDisplayName", + "ssDisplayName", + "svDisplayName", + "taDisplayName", + "teDisplayName", + "tgDisplayName", + "thDisplayName", + "tiDisplayName", + "boDisplayName", + "tkDisplayName", + "tlDisplayName", + "tnDisplayName", + "toDisplayName", + "trDisplayName", + "tsDisplayName", + "ttDisplayName", + "twDisplayName", + "tyDisplayName", + "ugDisplayName", + "ukDisplayName", + "urDisplayName", + "uzDisplayName", + "veDisplayName", + "viDisplayName", + "voDisplayName", + "waDisplayName", + "cyDisplayName", + "woDisplayName", + "fyDisplayName", + "xhDisplayName", + "yiDisplayName", + "yoDisplayName", + "zaDisplayName", + "unkDisplayName", + "zuDisplayName", + "hawDisplayName", + "hmnDisplayName", + "multiDisplayName", + "cebDisplayName", + "dzDisplayName", + "iwDisplayName", + "jwDisplayName", + "moDisplayName", + "shDisplayName", + "wwCountryDisplayName", + "afCountryDisplayName", + "axCountryDisplayName", + "alCountryDisplayName", + "dzCountryDisplayName", + "asCountryDisplayName", + "adCountryDisplayName", + "aoCountryDisplayName", + "aiCountryDisplayName", + "agCountryDisplayName", + "arCountryDisplayName", + "amCountryDisplayName", + "awCountryDisplayName", + "acCountryDisplayName", + "auCountryDisplayName", + "atCountryDisplayName", + "azCountryDisplayName", + "bsCountryDisplayName", + "bhCountryDisplayName", + "bdCountryDisplayName", + "bbCountryDisplayName", + "byCountryDisplayName", + "beCountryDisplayName", + "bzCountryDisplayName", + "bjCountryDisplayName", + "bmCountryDisplayName", + "btCountryDisplayName", + "boCountryDisplayName", + "baCountryDisplayName", + "bwCountryDisplayName", + "brCountryDisplayName", + "ioCountryDisplayName", + "vgCountryDisplayName", + "bnCountryDisplayName", + "bgCountryDisplayName", + "bfCountryDisplayName", + "biCountryDisplayName", + "khCountryDisplayName", + "cmCountryDisplayName", + "caCountryDisplayName", + "cvCountryDisplayName", + "bqCountryDisplayName", + "kyCountryDisplayName", + "cfCountryDisplayName", + "tdCountryDisplayName", + "clCountryDisplayName", + "cnCountryDisplayName", + "cxCountryDisplayName", + "ccCountryDisplayName", + "coCountryDisplayName", + "kmCountryDisplayName", + "cdCountryDisplayName", + "cgCountryDisplayName", + "ckCountryDisplayName", + "crCountryDisplayName", + "ciCountryDisplayName", + "hrCountryDisplayName", + "cuCountryDisplayName", + "cwCountryDisplayName", + "cyCountryDisplayName", + "czCountryDisplayName", + "dkCountryDisplayName", + "djCountryDisplayName", + "dmCountryDisplayName", + "doCountryDisplayName", + "tlCountryDisplayName", + "ecCountryDisplayName", + "egCountryDisplayName", + "svCountryDisplayName", + "gqCountryDisplayName", + "erCountryDisplayName", + "eeCountryDisplayName", + "szCountryDisplayName", + "etCountryDisplayName", + "fkCountryDisplayName", + "foCountryDisplayName", + "fjCountryDisplayName", + "fiCountryDisplayName", + "frCountryDisplayName", + "gfCountryDisplayName", + "pfCountryDisplayName", + "gaCountryDisplayName", + "gmCountryDisplayName", + "geCountryDisplayName", + "deCountryDisplayName", + "ghCountryDisplayName", + "giCountryDisplayName", + "grCountryDisplayName", + "glCountryDisplayName", + "gdCountryDisplayName", + "gpCountryDisplayName", + "guCountryDisplayName", + "gtCountryDisplayName", + "ggCountryDisplayName", + "gnCountryDisplayName", + "gwCountryDisplayName", + "gyCountryDisplayName", + "htCountryDisplayName", + "hmCountryDisplayName", + "hnCountryDisplayName", + "hkCountryDisplayName", + "huCountryDisplayName", + "isCountryDisplayName", + "inCountryDisplayName", + "idCountryDisplayName", + "irCountryDisplayName", + "iqCountryDisplayName", + "ieCountryDisplayName", + "imCountryDisplayName", + "ilCountryDisplayName", + "itCountryDisplayName", + "jmCountryDisplayName", + "jpCountryDisplayName", + "jeCountryDisplayName", + "joCountryDisplayName", + "kzCountryDisplayName", + "keCountryDisplayName", + "kiCountryDisplayName", + "xkCountryDisplayName", + "kwCountryDisplayName", + "kgCountryDisplayName", + "laCountryDisplayName", + "lvCountryDisplayName", + "lbCountryDisplayName", + "lsCountryDisplayName", + "lrCountryDisplayName", + "lyCountryDisplayName", + "liCountryDisplayName", + "ltCountryDisplayName", + "luCountryDisplayName", + "moCountryDisplayName", + "mkCountryDisplayName", + "mgCountryDisplayName", + "mwCountryDisplayName", + "myCountryDisplayName", + "mvCountryDisplayName", + "mlCountryDisplayName", + "mtCountryDisplayName", + "mhCountryDisplayName", + "mqCountryDisplayName", + "mrCountryDisplayName", + "muCountryDisplayName", + "ytCountryDisplayName", + "mxCountryDisplayName", + "fmCountryDisplayName", + "mdCountryDisplayName", + "mcCountryDisplayName", + "mnCountryDisplayName", + "meCountryDisplayName", + "msCountryDisplayName", + "maCountryDisplayName", + "mzCountryDisplayName", + "mmCountryDisplayName", + "naCountryDisplayName", + "nrCountryDisplayName", + "npCountryDisplayName", + "nlCountryDisplayName", + "ncCountryDisplayName", + "nzCountryDisplayName", + "niCountryDisplayName", + "neCountryDisplayName", + "ngCountryDisplayName", + "nuCountryDisplayName", + "nfCountryDisplayName", + "kpCountryDisplayName", + "mpCountryDisplayName", + "noCountryDisplayName", + "omCountryDisplayName", + "pkCountryDisplayName", + "pwCountryDisplayName", + "psCountryDisplayName", + "paCountryDisplayName", + "pgCountryDisplayName", + "pyCountryDisplayName", + "peCountryDisplayName", + "phCountryDisplayName", + "plCountryDisplayName", + "ptCountryDisplayName", + "prCountryDisplayName", + "qaCountryDisplayName", + "reCountryDisplayName", + "roCountryDisplayName", + "ruCountryDisplayName", + "rwCountryDisplayName", + "blCountryDisplayName", + "shCountryDisplayName", + "knCountryDisplayName", + "lcCountryDisplayName", + "mfCountryDisplayName", + "pmCountryDisplayName", + "vcCountryDisplayName", + "wsCountryDisplayName", + "smCountryDisplayName", + "stCountryDisplayName", + "saCountryDisplayName", + "snCountryDisplayName", + "rsCountryDisplayName", + "scCountryDisplayName", + "slCountryDisplayName", + "sgCountryDisplayName", + "sxCountryDisplayName", + "skCountryDisplayName", + "siCountryDisplayName", + "sbCountryDisplayName", + "soCountryDisplayName", + "zaCountryDisplayName", + "gsCountryDisplayName", + "krCountryDisplayName", + "ssCountryDisplayName", + "esCountryDisplayName", + "lkCountryDisplayName", + "sdCountryDisplayName", + "srCountryDisplayName", + "sjCountryDisplayName", + "seCountryDisplayName", + "chCountryDisplayName", + "syCountryDisplayName", + "twCountryDisplayName", + "tjCountryDisplayName", + "tzCountryDisplayName", + "thCountryDisplayName", + "tgCountryDisplayName", + "tkCountryDisplayName", + "toCountryDisplayName", + "ttCountryDisplayName", + "tnCountryDisplayName", + "trCountryDisplayName", + "tmCountryDisplayName", + "tcCountryDisplayName", + "tvCountryDisplayName", + "viCountryDisplayName", + "ugCountryDisplayName", + "uaCountryDisplayName", + "aeCountryDisplayName", + "gbCountryDisplayName", + "usCountryDisplayName", + "uyCountryDisplayName", + "uzCountryDisplayName", + "vuCountryDisplayName", + "vaCountryDisplayName", + "veCountryDisplayName", + "vnCountryDisplayName", + "wfCountryDisplayName", + "ehCountryDisplayName", + "yeCountryDisplayName", + "zmCountryDisplayName", + "zwCountryDisplayName", + "pay", + "allPrivateChats", + "unknownPrivateChat", + "copyClassCodeDesc", + "addToClassDesc", + "addToClassOrExchange", + "addToClassOrExchangeDesc", + "invitedToClassOrExchange", + "decline", + "declinedInvitation", + "acceptedInvitation", + "youreInvited", + "studentPermissionsDesc", + "noEligibleSpaces", + "youAddedToSpace", + "youRemovedFromSpace", + "invitedToChat", + "monthlySubscription", + "yearlySubscription", + "defaultSubscription", + "freeTrial", + "grammarAnalytics", + "total", + "noDataFound", + "promoSubscriptionExpirationDesc", + "emptyChatNameWarning", + "emptyClassNameWarning", + "emptyExchangeNameWarning", + "blurMeansTranslateTitle", + "blurMeansTranslateBody", + "someErrorTitle", + "someErrorBody", + "bestCorrectionFeedback", + "distractorFeedback", + "bestAnswerFeedback", + "definitionDefaultPrompt", + "practiceDefaultPrompt", + "correctionDefaultPrompt", + "itStartDefaultPrompt", + "languageLevelWarning", + "lockedChatWarning", + "lockSpace", + "lockChat", + "archiveSpace", + "suggestTo", + "suggestChatDesc", + "suggestExchangeDesc", + "acceptSelection", + "acceptSelectionAnyway", + "makingActivity", + "why", + "definition", + "exampleSentence", + "addToClassTitle", + "reportToTeacher", + "reportMessageTitle", + "reportMessageBody", + "noTeachersFound", + "noAddToSpacePermissions", + "alreadyInSpace", + "yourGlobalUserIdIs", + "noUsersFoundWithQuery", + "searchChatsRooms", + "groupName", + "createGroupAndInviteUsers", + "groupCanBeFoundViaSearch", + "inNoSpaces" + ], + + "zh_Hant": [ + "accountInformation", + "addNewFriend", + "alreadyHaveAnAccount", + "classes", + "allCorrect", + "newWayAllGood", + "othersAreBetter", + "holdForInfo", + "greenFeedback", + "yellowFeedback", + "redFeedback", + "customInputFeedbackChoice", + "itInstructionsTitle", + "itInstructionsBody", + "toggleLanguages", + "classWelcomeChat", + "deleteSpace", + "deleteGroup", + "areYouSureDeleteClass", + "areYouSureDeleteGroup", + "cannotBeReversed", + "enterDeletedClassName", + "incorrectClassName", + "oneday", + "oneweek", + "onemonth", + "sixmonth", + "oneyear", + "gaTooltip", + "taTooltip", + "unTooltip", + "interactiveTranslatorSliderHeader", + "interactiveGrammarSliderHeader", + "interactiveTranslatorNotAllowed", + "interactiveTranslatorAllowed", + "interactiveTranslatorRequired", + "interactiveTranslatorNotAllowedDesc", + "interactiveTranslatorAllowedDesc", + "interactiveTranslatorRequiredDesc", + "notYetSet", + "multiLingualClass", + "classAnalytics", + "allClasses", + "myLearning", + "allChatsAndClasses", + "timeOfLastMessage", + "totalMessages", + "waTooltip", + "changeDateRange", + "numberOfStudents", + "classDescription", + "classDescriptionDesc", + "requestToEnroll", + "requestAnExchange", + "findLanguageExchange", + "classAnalyticsDesc", + "addStudents", + "copyClassLink", + "copyClassLinkDesc", + "copyClassCode", + "inviteStudentByUserName", + "classSettings", + "classSettingsDesc", + "selectClassRoomDominantLanguage", + "selectTargetLanguage", + "whatIsYourClassLanguageLevel", + "studentPermissions", + "interactiveTranslator", + "oneToOneChatsWithinClass", + "oneToOneChatsWithinClassDesc", + "createGroupChats", + "createGroupChatsDesc", + "shareVideo", + "shareVideoDesc", + "sharePhotos", + "sharePhotosDesc", + "shareFiles", + "shareFilesDesc", + "shareLocationDesc", + "selectLanguageLevel", + "noIdenticalLanguages", + "iWantALanguagePartnerFrom", + "worldWide", + "noResults", + "searchBy", + "iWantAConversationPartner", + "iWantALanguagePartnerWhoSpeaks", + "iWantALanguagePartnerWhoIsLearning", + "yourBirthdayPlease", + "invalidDob", + "enterYourDob", + "getStarted", + "mustBe13", + "yourBirthdayPleaseShort", + "errorPleaseRefresh", + "joinWithClassCode", + "joinWithClassCodeDesc", + "joinWithClassCodeHint", + "unableToFindClass", + "languageLevelPreA1", + "languageLevelA1", + "languageLevelA2", + "languageLevelB1", + "languageLevelB2", + "languageLevelC1", + "languageLevelC2", + "changeTheNameOfTheClass", + "changeTheNameOfTheChat", + "welcomeToYourNewClass", + "welcomeToClass", + "welcomeToPangea18Plus", + "welcomeToPangeaMinor", + "findALanguagePartner", + "setToPublicSettingsTitle", + "setToPublicSettingsDesc", + "accountSettings", + "unableToFindClassCode", + "askPangeaBot", + "sorryNoResults", + "ignoreInThisText", + "helpMeTranslate", + "needsItShortMessage", + "needsIGCShortMessage", + "needsItMessage", + "needsIgcMessage", + "tokenTranslationTitle", + "spanTranslationDesc", + "spanTranslationTitle", + "l1SpanAndGrammarTitle", + "l1SpanAndGrammarDesc", + "otherTitle", + "otherDesc", + "countryInformation", + "myLanguages", + "targetLanguage", + "sourceLanguage", + "languagesISpeak", + "updateLanguage", + "whatLanguageYouWantToLearn", + "whatIsYourBaseLanguage", + "saveChanges", + "publicProfileTitle", + "publicProfileDesc", + "error502504Title", + "error502504Desc", + "error404Title", + "error404Desc", + "errorDisableIT", + "errorDisableIGC", + "errorDisableLanguageAssistance", + "errorDisableITUserDesc", + "errorDisableIGCUserDesc", + "errorDisableLanguageAssistanceUserDesc", + "errorDisableITClassDesc", + "errorDisableIGCClassDesc", + "errorDisableLanguageAssistanceClassDesc", + "itIsDisabled", + "igcIsDisabled", + "goToLearningSettings", + "error405Title", + "error405Desc", + "loginOrSignup", + "iAgreeToThe", + "termsAndConditions", + "andCertifyIAmAtLeast13YearsOfAge", + "findAClass", + "toggleIT", + "toggleIGC", + "toggleToolSettingsDescription", + "connectedToStaging", + "learningSettings", + "classNameRequired", + "sendVoiceNotes", + "sendVoiceNotesDesc", + "chatTopic", + "chatTopicDesc", + "inviteStudentByUserNameDesc", + "classRoster", + "almostPerfect", + "prettyGood", + "letMeThink", + "clickMessageTitle", + "clickMessageBody", + "understandingMessagesTitle", + "addToClass", + "understandingMessagesBody", + "allDone", + "vocab", + "low", + "medium", + "high", + "unknownProficiency", + "changeView", + "clearAll", + "generateVocabulary", + "generatePrompts", + "subscribe", + "getAccess", + "subscriptionDesc", + "subscriptionManagement", + "currentSubscription", + "changeSubscription", + "cancelSubscription", + "selectYourPlan", + "subsciptionPlatformTooltip", + "subscriptionManagementUnavailable", + "paymentMethod", + "paymentHistory", + "emptyChatDownloadWarning", + "appUpdateAvailable", + "update", + "updateDesc", + "maybeLater", + "mainMenu", + "toggleImmersionMode", + "toggleImmersionModeDesc", + "itToggleDescription", + "igcToggleDescription", + "sendOnEnterDescription", + "alreadyInClass", + "pleaseLoginFirst", + "originalMessage", + "sentMessage", + "useType", + "notAvailable", + "taAndGaTooltip", + "definitionsToolName", + "messageTranslationsToolName", + "definitionsToolDescription", + "translationsToolDescrption", + "welcomeBack", + "classExchanges", + "createNewClass", + "newExchange", + "kickAllStudents", + "kickAllStudentsConfirmation", + "inviteAllStudents", + "inviteAllStudentsConfirmation", + "inviteStudentsFromOtherClasses", + "inviteUsersFromPangea", + "allExchanges", + "redeemPromoCode", + "enterPromoCode", + "downloadTxtFile", + "downloadCSVFile", + "promotionalSubscriptionDesc", + "originalSubscriptionPlatform", + "oneWeekTrial", + "creatingSpacePleaseWait", + "downloadXLSXFile", + "abDisplayName", + "aaDisplayName", + "afDisplayName", + "akDisplayName", + "sqDisplayName", + "amDisplayName", + "arDisplayName", + "anDisplayName", + "hyDisplayName", + "asDisplayName", + "avDisplayName", + "aeDisplayName", + "ayDisplayName", + "azDisplayName", + "bmDisplayName", + "baDisplayName", + "euDisplayName", + "beDisplayName", + "bnDisplayName", + "bhDisplayName", + "biDisplayName", + "bsDisplayName", + "brDisplayName", + "bgDisplayName", + "myDisplayName", + "caDisplayName", + "chDisplayName", + "ceDisplayName", + "nyDisplayName", + "zhDisplayName", + "cvDisplayName", + "kwDisplayName", + "coDisplayName", + "crDisplayName", + "hrDisplayName", + "csDisplayName", + "daDisplayName", + "dvDisplayName", + "nlDisplayName", + "enDisplayName", + "eoDisplayName", + "etDisplayName", + "eeDisplayName", + "foDisplayName", + "fjDisplayName", + "fiDisplayName", + "frDisplayName", + "ffDisplayName", + "glDisplayName", + "kaDisplayName", + "deDisplayName", + "elDisplayName", + "gnDisplayName", + "guDisplayName", + "htDisplayName", + "haDisplayName", + "heDisplayName", + "hzDisplayName", + "hiDisplayName", + "hoDisplayName", + "huDisplayName", + "iaDisplayName", + "idDisplayName", + "ieDisplayName", + "gaDisplayName", + "igDisplayName", + "ikDisplayName", + "ioDisplayName", + "isDisplayName", + "itDisplayName", + "iuDisplayName", + "jaDisplayName", + "jvDisplayName", + "klDisplayName", + "knDisplayName", + "krDisplayName", + "ksDisplayName", + "kkDisplayName", + "kmDisplayName", + "kiDisplayName", + "rwDisplayName", + "kyDisplayName", + "kvDisplayName", + "kgDisplayName", + "koDisplayName", + "kuDisplayName", + "kjDisplayName", + "laDisplayName", + "lbDisplayName", + "lgDisplayName", + "liDisplayName", + "lnDisplayName", + "loDisplayName", + "ltDisplayName", + "luDisplayName", + "lvDisplayName", + "gvDisplayName", + "mkDisplayName", + "mgDisplayName", + "msDisplayName", + "mlDisplayName", + "mtDisplayName", + "miDisplayName", + "mrDisplayName", + "mhDisplayName", + "mnDisplayName", + "naDisplayName", + "nvDisplayName", + "nbDisplayName", + "ndDisplayName", + "neDisplayName", + "ngDisplayName", + "nnDisplayName", + "noDisplayName", + "iiDisplayName", + "nrDisplayName", + "ocDisplayName", + "ojDisplayName", + "cuDisplayName", + "omDisplayName", + "orDisplayName", + "osDisplayName", + "paDisplayName", + "piDisplayName", + "faDisplayName", + "plDisplayName", + "psDisplayName", + "ptDisplayName", + "quDisplayName", + "rmDisplayName", + "rnDisplayName", + "roDisplayName", + "ruDisplayName", + "saDisplayName", + "scDisplayName", + "sdDisplayName", + "seDisplayName", + "smDisplayName", + "sgDisplayName", + "srDisplayName", + "gdDisplayName", + "snDisplayName", + "siDisplayName", + "skDisplayName", + "slDisplayName", + "soDisplayName", + "stDisplayName", + "esDisplayName", + "suDisplayName", + "swDisplayName", + "ssDisplayName", + "svDisplayName", + "taDisplayName", + "teDisplayName", + "tgDisplayName", + "thDisplayName", + "tiDisplayName", + "boDisplayName", + "tkDisplayName", + "tlDisplayName", + "tnDisplayName", + "toDisplayName", + "trDisplayName", + "tsDisplayName", + "ttDisplayName", + "twDisplayName", + "tyDisplayName", + "ugDisplayName", + "ukDisplayName", + "urDisplayName", + "uzDisplayName", + "veDisplayName", + "viDisplayName", + "voDisplayName", + "waDisplayName", + "cyDisplayName", + "woDisplayName", + "fyDisplayName", + "xhDisplayName", + "yiDisplayName", + "yoDisplayName", + "zaDisplayName", + "unkDisplayName", + "zuDisplayName", + "hawDisplayName", + "hmnDisplayName", + "multiDisplayName", + "cebDisplayName", + "dzDisplayName", + "iwDisplayName", + "jwDisplayName", + "moDisplayName", + "shDisplayName", + "wwCountryDisplayName", + "afCountryDisplayName", + "axCountryDisplayName", + "alCountryDisplayName", + "dzCountryDisplayName", + "asCountryDisplayName", + "adCountryDisplayName", + "aoCountryDisplayName", + "aiCountryDisplayName", + "agCountryDisplayName", + "arCountryDisplayName", + "amCountryDisplayName", + "awCountryDisplayName", + "acCountryDisplayName", + "auCountryDisplayName", + "atCountryDisplayName", + "azCountryDisplayName", + "bsCountryDisplayName", + "bhCountryDisplayName", + "bdCountryDisplayName", + "bbCountryDisplayName", + "byCountryDisplayName", + "beCountryDisplayName", + "bzCountryDisplayName", + "bjCountryDisplayName", + "bmCountryDisplayName", + "btCountryDisplayName", + "boCountryDisplayName", + "baCountryDisplayName", + "bwCountryDisplayName", + "brCountryDisplayName", + "ioCountryDisplayName", + "vgCountryDisplayName", + "bnCountryDisplayName", + "bgCountryDisplayName", + "bfCountryDisplayName", + "biCountryDisplayName", + "khCountryDisplayName", + "cmCountryDisplayName", + "caCountryDisplayName", + "cvCountryDisplayName", + "bqCountryDisplayName", + "kyCountryDisplayName", + "cfCountryDisplayName", + "tdCountryDisplayName", + "clCountryDisplayName", + "cnCountryDisplayName", + "cxCountryDisplayName", + "ccCountryDisplayName", + "coCountryDisplayName", + "kmCountryDisplayName", + "cdCountryDisplayName", + "cgCountryDisplayName", + "ckCountryDisplayName", + "crCountryDisplayName", + "ciCountryDisplayName", + "hrCountryDisplayName", + "cuCountryDisplayName", + "cwCountryDisplayName", + "cyCountryDisplayName", + "czCountryDisplayName", + "dkCountryDisplayName", + "djCountryDisplayName", + "dmCountryDisplayName", + "doCountryDisplayName", + "tlCountryDisplayName", + "ecCountryDisplayName", + "egCountryDisplayName", + "svCountryDisplayName", + "gqCountryDisplayName", + "erCountryDisplayName", + "eeCountryDisplayName", + "szCountryDisplayName", + "etCountryDisplayName", + "fkCountryDisplayName", + "foCountryDisplayName", + "fjCountryDisplayName", + "fiCountryDisplayName", + "frCountryDisplayName", + "gfCountryDisplayName", + "pfCountryDisplayName", + "gaCountryDisplayName", + "gmCountryDisplayName", + "geCountryDisplayName", + "deCountryDisplayName", + "ghCountryDisplayName", + "giCountryDisplayName", + "grCountryDisplayName", + "glCountryDisplayName", + "gdCountryDisplayName", + "gpCountryDisplayName", + "guCountryDisplayName", + "gtCountryDisplayName", + "ggCountryDisplayName", + "gnCountryDisplayName", + "gwCountryDisplayName", + "gyCountryDisplayName", + "htCountryDisplayName", + "hmCountryDisplayName", + "hnCountryDisplayName", + "hkCountryDisplayName", + "huCountryDisplayName", + "isCountryDisplayName", + "inCountryDisplayName", + "idCountryDisplayName", + "irCountryDisplayName", + "iqCountryDisplayName", + "ieCountryDisplayName", + "imCountryDisplayName", + "ilCountryDisplayName", + "itCountryDisplayName", + "jmCountryDisplayName", + "jpCountryDisplayName", + "jeCountryDisplayName", + "joCountryDisplayName", + "kzCountryDisplayName", + "keCountryDisplayName", + "kiCountryDisplayName", + "xkCountryDisplayName", + "kwCountryDisplayName", + "kgCountryDisplayName", + "laCountryDisplayName", + "lvCountryDisplayName", + "lbCountryDisplayName", + "lsCountryDisplayName", + "lrCountryDisplayName", + "lyCountryDisplayName", + "liCountryDisplayName", + "ltCountryDisplayName", + "luCountryDisplayName", + "moCountryDisplayName", + "mkCountryDisplayName", + "mgCountryDisplayName", + "mwCountryDisplayName", + "myCountryDisplayName", + "mvCountryDisplayName", + "mlCountryDisplayName", + "mtCountryDisplayName", + "mhCountryDisplayName", + "mqCountryDisplayName", + "mrCountryDisplayName", + "muCountryDisplayName", + "ytCountryDisplayName", + "mxCountryDisplayName", + "fmCountryDisplayName", + "mdCountryDisplayName", + "mcCountryDisplayName", + "mnCountryDisplayName", + "meCountryDisplayName", + "msCountryDisplayName", + "maCountryDisplayName", + "mzCountryDisplayName", + "mmCountryDisplayName", + "naCountryDisplayName", + "nrCountryDisplayName", + "npCountryDisplayName", + "nlCountryDisplayName", + "ncCountryDisplayName", + "nzCountryDisplayName", + "niCountryDisplayName", + "neCountryDisplayName", + "ngCountryDisplayName", + "nuCountryDisplayName", + "nfCountryDisplayName", + "kpCountryDisplayName", + "mpCountryDisplayName", + "noCountryDisplayName", + "omCountryDisplayName", + "pkCountryDisplayName", + "pwCountryDisplayName", + "psCountryDisplayName", + "paCountryDisplayName", + "pgCountryDisplayName", + "pyCountryDisplayName", + "peCountryDisplayName", + "phCountryDisplayName", + "plCountryDisplayName", + "ptCountryDisplayName", + "prCountryDisplayName", + "qaCountryDisplayName", + "reCountryDisplayName", + "roCountryDisplayName", + "ruCountryDisplayName", + "rwCountryDisplayName", + "blCountryDisplayName", + "shCountryDisplayName", + "knCountryDisplayName", + "lcCountryDisplayName", + "mfCountryDisplayName", + "pmCountryDisplayName", + "vcCountryDisplayName", + "wsCountryDisplayName", + "smCountryDisplayName", + "stCountryDisplayName", + "saCountryDisplayName", + "snCountryDisplayName", + "rsCountryDisplayName", + "scCountryDisplayName", + "slCountryDisplayName", + "sgCountryDisplayName", + "sxCountryDisplayName", + "skCountryDisplayName", + "siCountryDisplayName", + "sbCountryDisplayName", + "soCountryDisplayName", + "zaCountryDisplayName", + "gsCountryDisplayName", + "krCountryDisplayName", + "ssCountryDisplayName", + "esCountryDisplayName", + "lkCountryDisplayName", + "sdCountryDisplayName", + "srCountryDisplayName", + "sjCountryDisplayName", + "seCountryDisplayName", + "chCountryDisplayName", + "syCountryDisplayName", + "twCountryDisplayName", + "tjCountryDisplayName", + "tzCountryDisplayName", + "thCountryDisplayName", + "tgCountryDisplayName", + "tkCountryDisplayName", + "toCountryDisplayName", + "ttCountryDisplayName", + "tnCountryDisplayName", + "trCountryDisplayName", + "tmCountryDisplayName", + "tcCountryDisplayName", + "tvCountryDisplayName", + "viCountryDisplayName", + "ugCountryDisplayName", + "uaCountryDisplayName", + "aeCountryDisplayName", + "gbCountryDisplayName", + "usCountryDisplayName", + "uyCountryDisplayName", + "uzCountryDisplayName", + "vuCountryDisplayName", + "vaCountryDisplayName", + "veCountryDisplayName", + "vnCountryDisplayName", + "wfCountryDisplayName", + "ehCountryDisplayName", + "yeCountryDisplayName", + "zmCountryDisplayName", + "zwCountryDisplayName", + "pay", + "allPrivateChats", + "unknownPrivateChat", + "copyClassCodeDesc", + "addToClassDesc", + "addToClassOrExchange", + "addToClassOrExchangeDesc", + "invitedToClassOrExchange", + "decline", + "declinedInvitation", + "acceptedInvitation", + "youreInvited", + "studentPermissionsDesc", + "noEligibleSpaces", + "youAddedToSpace", + "youRemovedFromSpace", + "invitedToChat", + "monthlySubscription", + "yearlySubscription", + "defaultSubscription", + "freeTrial", + "grammarAnalytics", + "total", + "noDataFound", + "promoSubscriptionExpirationDesc", + "emptyChatNameWarning", + "emptyClassNameWarning", + "emptyExchangeNameWarning", + "blurMeansTranslateTitle", + "blurMeansTranslateBody", + "someErrorTitle", + "someErrorBody", + "bestCorrectionFeedback", + "distractorFeedback", + "bestAnswerFeedback", + "definitionDefaultPrompt", + "practiceDefaultPrompt", + "correctionDefaultPrompt", + "itStartDefaultPrompt", + "languageLevelWarning", + "lockedChatWarning", + "lockSpace", + "lockChat", + "archiveSpace", + "suggestTo", + "suggestChatDesc", + "suggestExchangeDesc", + "acceptSelection", + "acceptSelectionAnyway", + "makingActivity", + "why", + "definition", + "exampleSentence", + "addToClassTitle", + "reportToTeacher", + "reportMessageTitle", + "reportMessageBody", + "noTeachersFound", + "noAddToSpacePermissions", + "alreadyInSpace", + "yourGlobalUserIdIs", + "noUsersFoundWithQuery", + "searchChatsRooms", + "groupName", + "createGroupAndInviteUsers", + "groupCanBeFoundViaSearch", + "inNoSpaces" + ] +} diff --git a/pangea_packages/fcm_shared_isolate/CHANGELOG.md b/pangea_packages/fcm_shared_isolate/CHANGELOG.md new file mode 100644 index 000000000..e53776993 --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/CHANGELOG.md @@ -0,0 +1,3 @@ +## 0.1.0 + +- Initial release \ No newline at end of file diff --git a/pangea_packages/fcm_shared_isolate/LICENSE b/pangea_packages/fcm_shared_isolate/LICENSE new file mode 100644 index 000000000..be3f7b28e --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/LICENSE @@ -0,0 +1,661 @@ + GNU AFFERO GENERAL PUBLIC LICENSE + Version 3, 19 November 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU Affero General Public License is a free, copyleft license for +software and other kinds of works, specifically designed to ensure +cooperation with the community in the case of network server software. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +our General Public Licenses are intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + Developers that use our General Public Licenses protect your rights +with two steps: (1) assert copyright on the software, and (2) offer +you this License which gives you legal permission to copy, distribute +and/or modify the software. + + A secondary benefit of defending all users' freedom is that +improvements made in alternate versions of the program, if they +receive widespread use, become available for other developers to +incorporate. Many developers of free software are heartened and +encouraged by the resulting cooperation. However, in the case of +software used on network servers, this result may fail to come about. +The GNU General Public License permits making a modified version and +letting the public access it on a server without ever releasing its +source code to the public. + + The GNU Affero General Public License is designed specifically to +ensure that, in such cases, the modified source code becomes available +to the community. It requires the operator of a network server to +provide the source code of the modified version running there to the +users of that server. Therefore, public use of a modified version, on +a publicly accessible server, gives the public access to the source +code of the modified version. + + An older license, called the Affero General Public License and +published by Affero, was designed to accomplish similar goals. This is +a different license, not a version of the Affero GPL, but Affero has +released a new version of the Affero GPL which permits relicensing under +this license. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU Affero General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Remote Network Interaction; Use with the GNU General Public License. + + Notwithstanding any other provision of this License, if you modify the +Program, your modified version must prominently offer all users +interacting with it remotely through a computer network (if your version +supports such interaction) an opportunity to receive the Corresponding +Source of your version by providing access to the Corresponding Source +from a network server at no charge, through some standard or customary +means of facilitating copying of software. This Corresponding Source +shall include the Corresponding Source for any work covered by version 3 +of the GNU General Public License that is incorporated pursuant to the +following paragraph. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the work with which it is combined will remain governed by version +3 of the GNU General Public License. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU Affero General Public License from time to time. Such new versions +will be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU Affero General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU Affero General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU Affero General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If your software can interact with users remotely through a computer +network, you should also make sure that it provides a way for users to +get its source. For example, if your program is a web application, its +interface could display a "Source" link that leads users to an archive +of the code. There are many ways you could offer source, and different +solutions will be better for different programs; see section 13 for the +specific requirements. + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU AGPL, see +. diff --git a/pangea_packages/fcm_shared_isolate/README.md b/pangea_packages/fcm_shared_isolate/README.md new file mode 100644 index 000000000..73f89d4db --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/README.md @@ -0,0 +1,122 @@ +# fcm_shared_isolate + +Firebase Messaging Plugin for Flutter supporting shared isolate + +## Installing the library +After adding the library to your `pubspec.yaml` do the following things: + +1. Modify the main activity on the android side of your app to look like the following + (typically in `android/app/src/main/kotlin/your/app/id/MainActivity.kt`): + +```kotlin +package your.app.id + +import io.flutter.embedding.android.FlutterActivity +import io.flutter.embedding.engine.FlutterEngine + +import android.content.Context +import android.os.Bundle +import android.util.Log +import android.view.WindowManager + +class MainActivity : FlutterActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + }; + + override fun provideFlutterEngine(context: Context): FlutterEngine? { + return provideEngine(this) + } + + override fun configureFlutterEngine(flutterEngine: FlutterEngine) { + // do nothing, because the engine was been configured in provideEngine + } + + companion object { + var engine: FlutterEngine? = null + fun provideEngine(context: Context): FlutterEngine { + var eng = engine ?: FlutterEngine(context, emptyArray(), true, false) + engine = eng + return eng + } + } +``` + +2. Add an `FcmPushService` (typically in `android/app/src/main/kotlin/your/app/id/FcmPushService.kt`) + +```kotlin +package your.app.id + +import com.famedly.fcm_shared_isolate.FcmSharedIsolateService + +import your.app.id.MainActivity + +import io.flutter.embedding.android.FlutterActivity +import io.flutter.embedding.engine.FlutterEngine +import io.flutter.view.FlutterMain +import io.flutter.embedding.engine.dart.DartExecutor.DartEntrypoint + +import android.content.Context +import android.os.Bundle +import android.util.Log +import android.view.WindowManager + +class FcmPushService : FcmSharedIsolateService() { + override fun getEngine(): FlutterEngine { + return provideEngine(getApplicationContext()) + } + + companion object { + fun provideEngine(context: Context): FlutterEngine { + var engine = MainActivity.engine + if (engine == null) { + engine = MainActivity.provideEngine(context) + engine.getLocalizationPlugin().sendLocalesToFlutter( + context.getResources().getConfiguration()) + engine.getDartExecutor().executeDartEntrypoint( + DartEntrypoint.createDefault()) + } + return engine + } + } +} + +``` + +3. Add the intent filters to your `AndroidManifest.xml` (typically in `android/app/src/main/AndroidManifest.xml`): + +```xml + + + + + +``` + +Note that the `.FcmPushService` has to match the class name defined in the file above + +## Usage + +```dart +// Create the instance +final fcm = FcmSharedIsolate(); + +// Only for iOS you need to request permissions: +if (Platform.isIOS) { + await fcm.requestPermission(); +} + +// Get the push token: +await fcm.getToken(); + +// Set the listeners +fcm.setListeners( + onMessage: onMessage, + onNewToken: onNewToken, +); + +Future onMessage(Map message) async { + print('Got a new message from firebase cloud messaging: $message'); +} +``` \ No newline at end of file diff --git a/pangea_packages/fcm_shared_isolate/analysis_options.yaml b/pangea_packages/fcm_shared_isolate/analysis_options.yaml new file mode 100644 index 000000000..0996667b3 --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/analysis_options.yaml @@ -0,0 +1,9 @@ +include: package:pedantic/analysis_options.yaml + +linter: + rules: + - camel_case_types + - avoid_print + - constant_identifier_names + - prefer_final_locals + - prefer_final_in_for_each diff --git a/pangea_packages/fcm_shared_isolate/android/.gradle/6.7.1/executionHistory/executionHistory.lock b/pangea_packages/fcm_shared_isolate/android/.gradle/6.7.1/executionHistory/executionHistory.lock new file mode 100644 index 000000000..ec3fe34fd Binary files /dev/null and b/pangea_packages/fcm_shared_isolate/android/.gradle/6.7.1/executionHistory/executionHistory.lock differ diff --git a/pangea_packages/fcm_shared_isolate/android/.gradle/6.7.1/fileChanges/last-build.bin b/pangea_packages/fcm_shared_isolate/android/.gradle/6.7.1/fileChanges/last-build.bin new file mode 100644 index 000000000..f76dd238a Binary files /dev/null and b/pangea_packages/fcm_shared_isolate/android/.gradle/6.7.1/fileChanges/last-build.bin differ diff --git a/pangea_packages/fcm_shared_isolate/android/.gradle/6.7.1/fileHashes/fileHashes.bin b/pangea_packages/fcm_shared_isolate/android/.gradle/6.7.1/fileHashes/fileHashes.bin new file mode 100644 index 000000000..5dfd940b6 Binary files /dev/null and b/pangea_packages/fcm_shared_isolate/android/.gradle/6.7.1/fileHashes/fileHashes.bin differ diff --git a/pangea_packages/fcm_shared_isolate/android/.gradle/6.7.1/fileHashes/fileHashes.lock b/pangea_packages/fcm_shared_isolate/android/.gradle/6.7.1/fileHashes/fileHashes.lock new file mode 100644 index 000000000..7cb52b3f8 Binary files /dev/null and b/pangea_packages/fcm_shared_isolate/android/.gradle/6.7.1/fileHashes/fileHashes.lock differ diff --git a/pangea_packages/fcm_shared_isolate/android/.gradle/6.7.1/gc.properties b/pangea_packages/fcm_shared_isolate/android/.gradle/6.7.1/gc.properties new file mode 100644 index 000000000..e69de29bb diff --git a/pangea_packages/fcm_shared_isolate/android/.gradle/6.8.3/fileChanges/last-build.bin b/pangea_packages/fcm_shared_isolate/android/.gradle/6.8.3/fileChanges/last-build.bin new file mode 100644 index 000000000..f76dd238a Binary files /dev/null and b/pangea_packages/fcm_shared_isolate/android/.gradle/6.8.3/fileChanges/last-build.bin differ diff --git a/pangea_packages/fcm_shared_isolate/android/.gradle/6.8.3/fileHashes/fileHashes.lock b/pangea_packages/fcm_shared_isolate/android/.gradle/6.8.3/fileHashes/fileHashes.lock new file mode 100644 index 000000000..6eb41fd25 Binary files /dev/null and b/pangea_packages/fcm_shared_isolate/android/.gradle/6.8.3/fileHashes/fileHashes.lock differ diff --git a/pangea_packages/fcm_shared_isolate/android/.gradle/6.8.3/gc.properties b/pangea_packages/fcm_shared_isolate/android/.gradle/6.8.3/gc.properties new file mode 100644 index 000000000..e69de29bb diff --git a/pangea_packages/fcm_shared_isolate/android/.gradle/7.3.3/checksums/checksums.lock b/pangea_packages/fcm_shared_isolate/android/.gradle/7.3.3/checksums/checksums.lock new file mode 100644 index 000000000..9b9a81fae Binary files /dev/null and b/pangea_packages/fcm_shared_isolate/android/.gradle/7.3.3/checksums/checksums.lock differ diff --git a/pangea_packages/fcm_shared_isolate/android/.gradle/7.3.3/dependencies-accessors/dependencies-accessors.lock b/pangea_packages/fcm_shared_isolate/android/.gradle/7.3.3/dependencies-accessors/dependencies-accessors.lock new file mode 100644 index 000000000..166e91e36 Binary files /dev/null and b/pangea_packages/fcm_shared_isolate/android/.gradle/7.3.3/dependencies-accessors/dependencies-accessors.lock differ diff --git a/pangea_packages/fcm_shared_isolate/android/.gradle/7.3.3/dependencies-accessors/gc.properties b/pangea_packages/fcm_shared_isolate/android/.gradle/7.3.3/dependencies-accessors/gc.properties new file mode 100644 index 000000000..e69de29bb diff --git a/pangea_packages/fcm_shared_isolate/android/.gradle/7.3.3/fileChanges/last-build.bin b/pangea_packages/fcm_shared_isolate/android/.gradle/7.3.3/fileChanges/last-build.bin new file mode 100644 index 000000000..f76dd238a Binary files /dev/null and b/pangea_packages/fcm_shared_isolate/android/.gradle/7.3.3/fileChanges/last-build.bin differ diff --git a/pangea_packages/fcm_shared_isolate/android/.gradle/7.3.3/fileHashes/fileHashes.lock b/pangea_packages/fcm_shared_isolate/android/.gradle/7.3.3/fileHashes/fileHashes.lock new file mode 100644 index 000000000..d6084472c Binary files /dev/null and b/pangea_packages/fcm_shared_isolate/android/.gradle/7.3.3/fileHashes/fileHashes.lock differ diff --git a/pangea_packages/fcm_shared_isolate/android/.gradle/7.3.3/gc.properties b/pangea_packages/fcm_shared_isolate/android/.gradle/7.3.3/gc.properties new file mode 100644 index 000000000..e69de29bb diff --git a/pangea_packages/fcm_shared_isolate/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/pangea_packages/fcm_shared_isolate/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock new file mode 100644 index 000000000..487a88833 Binary files /dev/null and b/pangea_packages/fcm_shared_isolate/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock differ diff --git a/pangea_packages/fcm_shared_isolate/android/.gradle/buildOutputCleanup/cache.properties b/pangea_packages/fcm_shared_isolate/android/.gradle/buildOutputCleanup/cache.properties new file mode 100644 index 000000000..889a37ac8 --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/android/.gradle/buildOutputCleanup/cache.properties @@ -0,0 +1,2 @@ +#Tue Jan 17 18:47:16 PKT 2023 +gradle.version=6.7.1 diff --git a/pangea_packages/fcm_shared_isolate/android/.gradle/checksums/checksums.lock b/pangea_packages/fcm_shared_isolate/android/.gradle/checksums/checksums.lock new file mode 100644 index 000000000..b99989c33 Binary files /dev/null and b/pangea_packages/fcm_shared_isolate/android/.gradle/checksums/checksums.lock differ diff --git a/pangea_packages/fcm_shared_isolate/android/.gradle/checksums/md5-checksums.bin b/pangea_packages/fcm_shared_isolate/android/.gradle/checksums/md5-checksums.bin new file mode 100644 index 000000000..6f9cbd72b Binary files /dev/null and b/pangea_packages/fcm_shared_isolate/android/.gradle/checksums/md5-checksums.bin differ diff --git a/pangea_packages/fcm_shared_isolate/android/.gradle/checksums/sha1-checksums.bin b/pangea_packages/fcm_shared_isolate/android/.gradle/checksums/sha1-checksums.bin new file mode 100644 index 000000000..9391a9b33 Binary files /dev/null and b/pangea_packages/fcm_shared_isolate/android/.gradle/checksums/sha1-checksums.bin differ diff --git a/pangea_packages/fcm_shared_isolate/android/.gradle/configuration-cache/gc.properties b/pangea_packages/fcm_shared_isolate/android/.gradle/configuration-cache/gc.properties new file mode 100644 index 000000000..e69de29bb diff --git a/pangea_packages/fcm_shared_isolate/android/.gradle/vcs-1/gc.properties b/pangea_packages/fcm_shared_isolate/android/.gradle/vcs-1/gc.properties new file mode 100644 index 000000000..e69de29bb diff --git a/pangea_packages/fcm_shared_isolate/android/build.gradle b/pangea_packages/fcm_shared_isolate/android/build.gradle new file mode 100644 index 000000000..59f00010c --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/android/build.gradle @@ -0,0 +1,62 @@ +group 'com.famedly.fcm_shared_isolate' +version '1.0-SNAPSHOT' + +buildscript { + ext.kotlin_version = '1.4.32' + repositories { + google() + mavenCentral() + } + + dependencies { + classpath 'com.android.tools.build:gradle:4.2.1' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + } +} + +rootProject.allprojects { + repositories { + google() + mavenCentral() + } +} + +apply plugin: 'com.android.library' +apply plugin: 'kotlin-android' + +def firebaseCoreProject = findProject(':firebase_core') +if (firebaseCoreProject == null) { + + throw GradleException('Could not find the firebase_core FlutterFire plugin, have you added it as a dependency in your pubspec?') +} else if (!firebaseCoreProject.properties['FirebaseSDKVersion']) { + throw GradleException('A newer version of the firebase_core FlutterFire plugin is required, please update your firebase_core pubspec dependency.') +} + +def getRootProjectExtOrCoreProperty(name, firebaseCoreProject) { + if (!rootProject.ext.has('FlutterFire')) return firebaseCoreProject.properties[name] + if (!rootProject.ext.get('FlutterFire')[name]) return firebaseCoreProject.properties[name] + return rootProject.ext.get('FlutterFire').get(name) +} + +android { + compileSdkVersion 30 + + sourceSets { + main.java.srcDirs += 'src/main/kotlin' + } + defaultConfig { + minSdkVersion 16 + } + lintOptions { + disable 'InvalidPackage' + } + dependencies { + api firebaseCoreProject + implementation platform("com.google.firebase:firebase-bom:${getRootProjectExtOrCoreProperty("FirebaseSDKVersion", firebaseCoreProject)}") + } +} + +dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" + implementation 'com.google.firebase:firebase-messaging-ktx:23.0.2' +} diff --git a/pangea_packages/fcm_shared_isolate/android/gradle.properties b/pangea_packages/fcm_shared_isolate/android/gradle.properties new file mode 100644 index 000000000..94adc3a3f --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/android/gradle.properties @@ -0,0 +1,3 @@ +org.gradle.jvmargs=-Xmx1536M +android.useAndroidX=true +android.enableJetifier=true diff --git a/pangea_packages/fcm_shared_isolate/android/gradle/wrapper/gradle-wrapper.properties b/pangea_packages/fcm_shared_isolate/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000..9fe8d05db --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-all.zip diff --git a/pangea_packages/fcm_shared_isolate/android/local.properties b/pangea_packages/fcm_shared_isolate/android/local.properties new file mode 100644 index 000000000..5ca26ae66 --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/android/local.properties @@ -0,0 +1,8 @@ +## This file must *NOT* be checked into Version Control Systems, +# as it contains information specific to your local configuration. +# +# Location of the SDK. This is only used by Gradle. +# For customization when using a Version Control System, please read the +# header note. +#Tue Jan 17 02:51:21 PKT 2023 +sdk.dir=/Users/lalaiqbalkhokhar/Library/Android/sdk diff --git a/pangea_packages/fcm_shared_isolate/android/settings.gradle b/pangea_packages/fcm_shared_isolate/android/settings.gradle new file mode 100644 index 000000000..12cfbc0b0 --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/android/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'fcm_shared_isolate' diff --git a/pangea_packages/fcm_shared_isolate/android/src/main/AndroidManifest.xml b/pangea_packages/fcm_shared_isolate/android/src/main/AndroidManifest.xml new file mode 100644 index 000000000..9ec46a345 --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/android/src/main/AndroidManifest.xml @@ -0,0 +1,3 @@ + + diff --git a/pangea_packages/fcm_shared_isolate/android/src/main/kotlin/com/famedly/fcm_shared_isolate/FcmSharedIsolatePlugin.kt b/pangea_packages/fcm_shared_isolate/android/src/main/kotlin/com/famedly/fcm_shared_isolate/FcmSharedIsolatePlugin.kt new file mode 100644 index 000000000..fe0f85af3 --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/android/src/main/kotlin/com/famedly/fcm_shared_isolate/FcmSharedIsolatePlugin.kt @@ -0,0 +1,48 @@ + +package com.famedly.fcm_shared_isolate + +import androidx.annotation.NonNull +import com.google.firebase.messaging.FirebaseMessaging +import io.flutter.embedding.engine.plugins.FlutterPlugin +import io.flutter.plugin.common.MethodCall +import io.flutter.plugin.common.MethodChannel +import io.flutter.plugin.common.MethodChannel.MethodCallHandler +import io.flutter.plugin.common.MethodChannel.Result + +class FcmSharedIsolatePlugin : FlutterPlugin, MethodCallHandler { + private lateinit var channel: MethodChannel + + private val fcm = FirebaseMessaging.getInstance() + + override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) { + channel = MethodChannel(flutterPluginBinding.binaryMessenger, "fcm_shared_isolate") + channel.setMethodCallHandler(this) + } + + override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) { + if (fcm == null) { + result.error("fcm_unavailable", null, null) + return + } + + if (call.method == "getToken") { + val getToken = FirebaseMessaging.getInstance().getToken() + getToken.addOnSuccessListener { result.success(it) } + getToken.addOnFailureListener { result.error("unknown", null, null) } + } else { + result.notImplemented() + } + } + + override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) { + channel.setMethodCallHandler(null) + } + + fun message(@NonNull data: Map) { + channel.invokeMethod("message", data) + } + + fun token(@NonNull str: String) { + channel.invokeMethod("token", str) + } +} diff --git a/pangea_packages/fcm_shared_isolate/android/src/main/kotlin/com/famedly/fcm_shared_isolate/FcmSharedIsolateService.kt b/pangea_packages/fcm_shared_isolate/android/src/main/kotlin/com/famedly/fcm_shared_isolate/FcmSharedIsolateService.kt new file mode 100644 index 000000000..7446d6939 --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/android/src/main/kotlin/com/famedly/fcm_shared_isolate/FcmSharedIsolateService.kt @@ -0,0 +1,34 @@ +package com.famedly.fcm_shared_isolate + +import android.os.Handler +import com.google.firebase.messaging.FirebaseMessagingService +import com.google.firebase.messaging.RemoteMessage +import io.flutter.embedding.engine.FlutterEngine + +abstract class FcmSharedIsolateService : FirebaseMessagingService() { + abstract fun getEngine(): FlutterEngine + + private val handler = Handler() + + private fun getPlugin(): FcmSharedIsolatePlugin { + val registry = getEngine().getPlugins() + var plugin = registry.get(FcmSharedIsolatePlugin::class.java) as? FcmSharedIsolatePlugin + if (plugin == null) { + plugin = FcmSharedIsolatePlugin() + registry.add(plugin) + } + return plugin + } + + override fun onMessageReceived(message: RemoteMessage) { + handler.post { + getPlugin().message(message.getData()) + } + } + + override fun onNewToken(token: String) { + handler.post { + getPlugin().token(token) + } + } +} diff --git a/pangea_packages/fcm_shared_isolate/build/test_cache/build/c075001b96339384a97db4862b8ab8db.cache.dill.track.dill b/pangea_packages/fcm_shared_isolate/build/test_cache/build/c075001b96339384a97db4862b8ab8db.cache.dill.track.dill new file mode 100644 index 000000000..4c868dc8b Binary files /dev/null and b/pangea_packages/fcm_shared_isolate/build/test_cache/build/c075001b96339384a97db4862b8ab8db.cache.dill.track.dill differ diff --git a/pangea_packages/fcm_shared_isolate/build/unit_test_assets/AssetManifest.json b/pangea_packages/fcm_shared_isolate/build/unit_test_assets/AssetManifest.json new file mode 100644 index 000000000..9e26dfeeb --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/build/unit_test_assets/AssetManifest.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/pangea_packages/fcm_shared_isolate/build/unit_test_assets/FontManifest.json b/pangea_packages/fcm_shared_isolate/build/unit_test_assets/FontManifest.json new file mode 100644 index 000000000..0637a088a --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/build/unit_test_assets/FontManifest.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/pangea_packages/fcm_shared_isolate/build/unit_test_assets/NOTICES.Z b/pangea_packages/fcm_shared_isolate/build/unit_test_assets/NOTICES.Z new file mode 100644 index 000000000..2b6801c84 Binary files /dev/null and b/pangea_packages/fcm_shared_isolate/build/unit_test_assets/NOTICES.Z differ diff --git a/pangea_packages/fcm_shared_isolate/build/unit_test_assets/shaders/ink_sparkle.frag b/pangea_packages/fcm_shared_isolate/build/unit_test_assets/shaders/ink_sparkle.frag new file mode 100644 index 000000000..ead18b083 Binary files /dev/null and b/pangea_packages/fcm_shared_isolate/build/unit_test_assets/shaders/ink_sparkle.frag differ diff --git a/pangea_packages/fcm_shared_isolate/ios/Classes/FcmSharedIsolatePlugin.swift b/pangea_packages/fcm_shared_isolate/ios/Classes/FcmSharedIsolatePlugin.swift new file mode 100644 index 000000000..50a89f127 --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/ios/Classes/FcmSharedIsolatePlugin.swift @@ -0,0 +1,92 @@ +import Flutter +import FirebaseCore +import FirebaseMessaging + +@objc public class FcmSharedIsolatePlugin: NSObject, FlutterPlugin, MessagingDelegate { + internal init(channel: FlutterMethodChannel) { + self.channel = channel + } + + public static func register(with registrar: FlutterPluginRegistrar) { + let channel = FlutterMethodChannel(name: "fcm_shared_isolate", binaryMessenger: registrar.messenger()) + let instance = FcmSharedIsolatePlugin(channel: channel) + registrar.addApplicationDelegate(instance) + registrar.addMethodCallDelegate(instance, channel: channel) + } + + let channel: FlutterMethodChannel + + public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { + switch call.method { + case "getToken": + Messaging.messaging().delegate = self + Messaging.messaging().token { token, error in + if let error = error { + result(FlutterError(code: "unknown", message: nil, details: error.localizedDescription)) + } else if let token = token { + print("Some ok") + result(String(token)) + } + } + case "requestPermission": + let arguments = call.arguments as! NSDictionary; + if #available(iOS 10.0, *) { + var authOptions: UNAuthorizationOptions = [] + if arguments["sound"] as! Bool { + authOptions.insert(.sound) + } + if arguments["alert"] as! Bool { + authOptions.insert(.alert) + } + if arguments["badge"] as! Bool { + authOptions.insert(.badge) + } + if arguments["provisional"] as! Bool { + if #available(iOS 12.0, *) { + authOptions.insert(.provisional) + } + } + + UNUserNotificationCenter.current().requestAuthorization( + options: authOptions, + completionHandler: { [] granted, error in + if let error = error { + result(FlutterError(code: "perm", message: nil, details: error.localizedDescription)) + return + } + + result(granted) + } + ) + + UIApplication.shared.registerForRemoteNotifications() + } else { + var notificationTypes: UIUserNotificationType = [] + if arguments["sound"] as! Bool { + notificationTypes.insert(.sound) + } + if arguments["alert"] as! Bool { + notificationTypes.insert(.alert) + } + if arguments["badge"] as! Bool { + notificationTypes.insert(.badge) + } + + let settings = UIUserNotificationSettings(types: notificationTypes, categories: nil) + UIApplication.shared.registerUserNotificationSettings(settings) + + UIApplication.shared.registerForRemoteNotifications() + + result(true) + } + default: + assertionFailure(call.method) + result(FlutterMethodNotImplemented) + } + } + + public func messaging(_ messaging: Messaging, didReceiveRegistrationToken token: String?) { + + channel.invokeMethod("token", arguments: [token]) + } +} diff --git a/pangea_packages/fcm_shared_isolate/ios/fcm_shared_isolate.podspec b/pangea_packages/fcm_shared_isolate/ios/fcm_shared_isolate.podspec new file mode 100644 index 000000000..9e2fb06ed --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/ios/fcm_shared_isolate.podspec @@ -0,0 +1,18 @@ +Pod::Spec.new do |s| + s.name = 'fcm_shared_isolate' + s.version = '0.0.1' + s.summary = 'fixme' + s.homepage = 'https://gitlab.com/famedly/libraries/fcm_shared_isolate' + s.license = { :file => '../LICENSE' } + s.author = { 'Famedly' => 'info@famedly.de' } + s.source = { :path => '.' } + s.source_files = 'Classes/**/*' + s.public_header_files = 'Classes/**/*.h' + s.dependency 'Flutter' + s.dependency 'FirebaseCore' + s.dependency 'FirebaseMessaging' + s.swift_version = '5.2' + s.ios.deployment_target = '11.0' + s.static_framework = true + +end diff --git a/pangea_packages/fcm_shared_isolate/lib/fcm_shared_isolate.dart b/pangea_packages/fcm_shared_isolate/lib/fcm_shared_isolate.dart new file mode 100644 index 000000000..843716626 --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/lib/fcm_shared_isolate.dart @@ -0,0 +1,70 @@ +import 'dart:async'; +import 'dart:io'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/services.dart'; + +class FcmSharedIsolate { + final _channel = MethodChannel('fcm_shared_isolate'); + final _msg = >[]; + void Function(Map)? _onMessage; + void Function(String)? _onNewToken; + + FcmSharedIsolate() { + _channel.setMethodCallHandler(handle); + } + + Future handle(MethodCall call) async { + if (call.method == 'message') { + final Map data = call.arguments; + final onMessage = _onMessage; + if (onMessage != null) { + onMessage(data); + } else { + _msg.add(data); + } + } else if (call.method == 'token') { + final String newToken = call.arguments; + _onNewToken?.call(newToken); + } + return null; + } + + Future getToken() async { + // if (Platform.isAndroid) { + // await Firebase.initializeApp(); + // return (await FirebaseMessaging.instance.getToken())!; + // } + return await _channel.invokeMethod('getToken'); + } + + void setListeners({ + void Function(Map)? onMessage, + void Function(String)? onNewToken, + }) { + _onMessage = onMessage; + _onNewToken = onNewToken; + if (onMessage != null) { + _msg.forEach(onMessage); + _msg.clear(); + } + } + + Future requestPermission( + {bool sound = true, + bool alert = true, + bool badge = true, + bool provisional = false}) async { + if (kIsWeb || !Platform.isIOS) { + return true; + } + + final bool result = await _channel.invokeMethod('requestPermission', { + 'sound': sound, + 'alert': alert, + 'badge': badge, + 'provisional': provisional, + }); + return result; + } +} diff --git a/pangea_packages/fcm_shared_isolate/pubspec.lock b/pangea_packages/fcm_shared_isolate/pubspec.lock new file mode 100644 index 000000000..41db938bc --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/pubspec.lock @@ -0,0 +1,242 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + _flutterfire_internals: + dependency: transitive + description: + name: _flutterfire_internals + sha256: "3ff770dfff04a67b0863dff205a0936784de1b87a5e99b11c693fc10e66a9ce3" + url: "https://pub.dev" + source: hosted + version: "1.0.12" + async: + dependency: transitive + description: + name: async + sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" + url: "https://pub.dev" + source: hosted + version: "2.11.0" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + characters: + dependency: transitive + description: + name: characters + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" + url: "https://pub.dev" + source: hosted + version: "1.3.0" + clock: + dependency: transitive + description: + name: clock + sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + url: "https://pub.dev" + source: hosted + version: "1.1.1" + collection: + dependency: transitive + description: + name: collection + sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c" + url: "https://pub.dev" + source: hosted + version: "1.17.1" + fake_async: + dependency: transitive + description: + name: fake_async + sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" + url: "https://pub.dev" + source: hosted + version: "1.3.1" + firebase_core: + dependency: "direct main" + description: + name: firebase_core + sha256: c129209ba55f3d4272c89fb4a4994c15bea77fb6de63a82d45fb6bc5c94e4355 + url: "https://pub.dev" + source: hosted + version: "2.4.1" + firebase_core_platform_interface: + dependency: transitive + description: + name: firebase_core_platform_interface + sha256: "5fab93f5b354648efa62e7cc829c90efb68c8796eecf87e0888cae2d5f3accd4" + url: "https://pub.dev" + source: hosted + version: "4.5.2" + firebase_core_web: + dependency: transitive + description: + name: firebase_core_web + sha256: "18b35ce111b0a4266abf723c825bcf9d4e2519d13638cc7f06f2a8dd960c75bc" + url: "https://pub.dev" + source: hosted + version: "2.1.0" + firebase_messaging: + dependency: "direct main" + description: + name: firebase_messaging + sha256: dc010a6436333029fba858415fe65887c3fe44d8f6e6ea162bb8d3dd764fbcb6 + url: "https://pub.dev" + source: hosted + version: "14.2.1" + firebase_messaging_platform_interface: + dependency: transitive + description: + name: firebase_messaging_platform_interface + sha256: abda2d766486096eb1c568c7b20aef46180596c8b0708190b929133ff03e0a8d + url: "https://pub.dev" + source: hosted + version: "4.2.10" + firebase_messaging_web: + dependency: transitive + description: + name: firebase_messaging_web + sha256: "7a0ce957bd2210e8636325152234728874dad039f1c7271ba1be5c752fdc5888" + url: "https://pub.dev" + source: hosted + version: "3.2.11" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + flutter_web_plugins: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + js: + dependency: transitive + description: + name: js + sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 + url: "https://pub.dev" + source: hosted + version: "0.6.7" + matcher: + dependency: transitive + description: + name: matcher + sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb" + url: "https://pub.dev" + source: hosted + version: "0.12.15" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 + url: "https://pub.dev" + source: hosted + version: "0.2.0" + meta: + dependency: transitive + description: + name: meta + sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" + url: "https://pub.dev" + source: hosted + version: "1.9.1" + path: + dependency: transitive + description: + name: path + sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + url: "https://pub.dev" + source: hosted + version: "1.8.3" + pedantic: + dependency: "direct dev" + description: + name: pedantic + sha256: "67fc27ed9639506c856c840ccce7594d0bdcd91bc8d53d6e52359449a1d50602" + url: "https://pub.dev" + source: hosted + version: "1.11.1" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + sha256: dbf0f707c78beedc9200146ad3cb0ab4d5da13c246336987be6940f026500d3a + url: "https://pub.dev" + source: hosted + version: "2.1.3" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.99" + source_span: + dependency: transitive + description: + name: source_span + sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 + url: "https://pub.dev" + source: hosted + version: "1.9.1" + stack_trace: + dependency: transitive + description: + name: stack_trace + sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 + url: "https://pub.dev" + source: hosted + version: "1.11.0" + stream_channel: + dependency: transitive + description: + name: stream_channel + sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + string_scanner: + dependency: transitive + description: + name: string_scanner + sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + url: "https://pub.dev" + source: hosted + version: "1.2.0" + term_glyph: + dependency: transitive + description: + name: term_glyph + sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 + url: "https://pub.dev" + source: hosted + version: "1.2.1" + test_api: + dependency: transitive + description: + name: test_api + sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb + url: "https://pub.dev" + source: hosted + version: "0.5.1" + vector_math: + dependency: transitive + description: + name: vector_math + sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" + url: "https://pub.dev" + source: hosted + version: "2.1.4" +sdks: + dart: ">=3.0.0-0 <4.0.0" + flutter: ">=1.20.0" diff --git a/pangea_packages/fcm_shared_isolate/pubspec.yaml b/pangea_packages/fcm_shared_isolate/pubspec.yaml new file mode 100644 index 000000000..d43abe16c --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/pubspec.yaml @@ -0,0 +1,30 @@ +name: fcm_shared_isolate +description: Firebase Messaging Plugin for Flutter supporting shared isolate +homepage: https://famedly.com +version: 0.1.0 +repository: https://gitlab.com/famedly/libraries/fcm_shared_isolate +issue_tracker: https://gitlab.com/famedly/libraries/fcm_shared_isolate/issues + +environment: + sdk: ">=2.12.0 <3.0.0" + flutter: ">=1.20.0" + +dependencies: + firebase_core: ^2.4.1 + firebase_messaging: ^14.2.1 + flutter: + sdk: flutter + +dev_dependencies: + pedantic: ^1.11.0 + flutter_test: + sdk: flutter + +flutter: + plugin: + platforms: + android: + package: com.famedly.fcm_shared_isolate + pluginClass: FcmSharedIsolatePlugin + ios: + pluginClass: FcmSharedIsolatePlugin diff --git a/pangea_packages/fcm_shared_isolate/test/fcm_shared_isolate_test.dart b/pangea_packages/fcm_shared_isolate/test/fcm_shared_isolate_test.dart new file mode 100644 index 000000000..ca85293d8 --- /dev/null +++ b/pangea_packages/fcm_shared_isolate/test/fcm_shared_isolate_test.dart @@ -0,0 +1,19 @@ +import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + const channel = MethodChannel('fcm_shared_isolate'); + TestWidgetsFlutterBinding.ensureInitialized(); + + setUp(() { + channel.setMockMethodCallHandler((MethodCall methodCall) async { + return '42'; + }); + }); + + tearDown(() { + channel.setMockMethodCallHandler(null); + }); + + test('create', () async {}); +} diff --git a/pubspec.lock b/pubspec.lock index 7155d6332..cd036d373 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -9,14 +9,22 @@ packages: url: "https://pub.dev" source: hosted version: "61.0.0" + _flutterfire_internals: + dependency: transitive + description: + name: _flutterfire_internals + sha256: dd68ecea9f1e3556d385521bd21c7bafd6311a8c1e11abe2595ca27974f468ee + url: "https://pub.dev" + source: hosted + version: "1.3.13" adaptive_dialog: dependency: "direct main" description: name: adaptive_dialog - sha256: "3b8abc7d1ba0834061759ee0be8e623eff5bffbcd1e6df5608a11983cfad6b2b" + sha256: "910debe8766eff4b378ed5164bb470debb87c53a3bdf6adee03c79f64fbf7348" url: "https://pub.dev" source: hosted - version: "1.9.0" + version: "1.10.1" analyzer: dependency: transitive description: @@ -37,26 +45,34 @@ packages: dependency: "direct main" description: name: animations - sha256: fe8a6bdca435f718bb1dc8a11661b2c22504c6da40ef934cee8327ed77934164 + sha256: ef57563eed3620bd5d75ad96189846aca1e033c0c45fc9a7d26e80ab02b88a70 url: "https://pub.dev" source: hosted - version: "2.0.7" + version: "2.0.8" ansicolor: dependency: transitive description: name: ansicolor - sha256: "607f8fa9786f392043f169898923e6c59b4518242b68b8862eb8a8b7d9c30b4a" + sha256: "8bf17a8ff6ea17499e40a2d2542c2f481cd7615760c6d34065cb22bfd22e6880" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "2.0.2" + appkit_ui_element_colors: + dependency: transitive + description: + name: appkit_ui_element_colors + sha256: c3e50f900aae314d339de489535736238627071457c4a4a2dbbb1545b4f04f22 + url: "https://pub.dev" + source: hosted + version: "1.0.0" archive: dependency: "direct main" description: name: archive - sha256: e0902a06f0e00414e4e3438a084580161279f137aeb862274710f29ec10cf01e + sha256: "7b875fd4a20b165a3084bd2d210439b22ebc653f21cea4842729c0c30c82596b" url: "https://pub.dev" source: hosted - version: "3.3.9" + version: "3.4.9" args: dependency: transitive description: @@ -66,7 +82,7 @@ packages: source: hosted version: "2.4.2" async: - dependency: transitive + dependency: "direct main" description: name: async sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" @@ -77,18 +93,18 @@ packages: dependency: transitive description: name: audio_session - sha256: "8a2bc5e30520e18f3fb0e366793d78057fb64cd5287862c76af0c8771f2a52ad" + sha256: "768eadc8174b366b8b1b0b75e0518eea2bbd463d47a7938c54a2a0e6aa06946d" url: "https://pub.dev" source: hosted - version: "0.1.16" + version: "0.1.17" badges: dependency: "direct main" description: name: badges - sha256: "6e7f3ec561ec08f47f912cfe349d4a1707afdc8dda271e17b046aa6d42c89e77" + sha256: a7b6bbd60dce418df0db3058b53f9d083c22cdb5132a052145dc267494df0b84 url: "https://pub.dev" source: hosted - version: "3.1.1" + version: "3.1.2" base58check: dependency: transitive description: @@ -113,6 +129,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.1" + build_config: + dependency: transitive + description: + name: build_config + sha256: bf80fcfb46a29945b423bd9aad884590fb1dc69b330a4d4700cac476af1708d1 + url: "https://pub.dev" + source: hosted + version: "1.1.1" callkeep: dependency: "direct main" description: @@ -145,14 +169,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.1" + checked_yaml: + dependency: transitive + description: + name: checked_yaml + sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff + url: "https://pub.dev" + source: hosted + version: "2.0.3" chewie: dependency: "direct main" description: name: chewie - sha256: "60701da1f22ed20cd2d40e856fd1f2249dacf5b629d9fa50676443a18a4857b8" + sha256: ccfce3350ae9fd419cd336cdf3380f77a08e45171e1e3cb3d499d204de5e7ea8 url: "https://pub.dev" source: hosted - version: "1.7.0" + version: "1.7.1" cli_util: dependency: transitive description: @@ -173,10 +205,26 @@ packages: dependency: "direct main" description: name: collection - sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687 + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a url: "https://pub.dev" source: hosted - version: "1.17.2" + version: "1.18.0" + connectivity_plus: + dependency: "direct main" + description: + name: connectivity_plus + sha256: b74247fad72c171381dbe700ca17da24deac637ab6d43c343b42867acb95c991 + url: "https://pub.dev" + source: hosted + version: "3.0.6" + connectivity_plus_platform_interface: + dependency: transitive + description: + name: connectivity_plus_platform_interface + sha256: cf1d1c28f4416f8c654d7dc3cd638ec586076255d407cef3ddbdaf178272a71a + url: "https://pub.dev" + source: hosted + version: "1.2.4" console: dependency: transitive description: @@ -193,14 +241,22 @@ packages: url: "https://pub.dev" source: hosted version: "3.1.1" + country_picker: + dependency: "direct main" + description: + name: country_picker + sha256: "931454ceb75c7e1230ac5620bfe601a5a293b4436d8de8bf7fea776a05a9568c" + url: "https://pub.dev" + source: hosted + version: "2.0.22" cross_file: dependency: transitive description: name: cross_file - sha256: "0b0036e8cccbfbe0555fd83c1d31a6f30b77a96b598b35a5d36dd41f718695e9" + sha256: "445db18de832dba8d851e287aff8ccf169bed30d2e94243cb54c7d2f1ed2142c" url: "https://pub.dev" source: hosted - version: "0.3.3+4" + version: "0.3.3+6" crypto: dependency: transitive description: @@ -217,14 +273,22 @@ packages: url: "https://pub.dev" source: hosted version: "0.17.3" + csv: + dependency: "direct main" + description: + name: csv + sha256: "63ed2871dd6471193dffc52c0e6c76fb86269c00244d244297abbb355c84a86e" + url: "https://pub.dev" + source: hosted + version: "5.1.1" cupertino_icons: dependency: "direct main" description: name: cupertino_icons - sha256: e35129dc44c9118cee2a5603506d823bab99c68393879edb440e0090d07586be + sha256: d57953e10f9f8327ce64a508a355f0b1ec902193f66288e8cb5070e7c47eeb2d url: "https://pub.dev" source: hosted - version: "1.0.5" + version: "1.0.6" dart_code_metrics: dependency: "direct dev" description: @@ -253,10 +317,10 @@ packages: dependency: transitive description: name: dart_webrtc - sha256: dfe42714abe3eb83eefec407c9da7f8e341a899aa1b8ac2484af298cdfeb74a3 + sha256: "5897a3bdd6c7fded07e80e250260ca4c9cd61f9080911aa308b516e1206745a9" url: "https://pub.dev" source: hosted - version: "1.1.2" + version: "1.1.3" dbus: dependency: transitive description: @@ -265,14 +329,22 @@ packages: url: "https://pub.dev" source: hosted version: "0.7.8" + dependency_validator: + dependency: transitive + description: + name: dependency_validator + sha256: f727a5627aa405965fab4aef4f468e50a9b632ba0737fd2f98c932fec6d712b9 + url: "https://pub.dev" + source: hosted + version: "3.2.3" desktop_drop: dependency: "direct main" description: name: desktop_drop - sha256: "4ca4d960f4b11c032e9adfd2a0a8ac615bc3fddb4cbe73dcf840dd8077582186" + sha256: d55a010fe46c8e8fcff4ea4b451a9ff84a162217bdb3b2a0aa1479776205e15d url: "https://pub.dev" source: hosted - version: "0.4.1" + version: "0.4.4" desktop_lifecycle: dependency: "direct main" description: @@ -293,10 +365,10 @@ packages: dependency: "direct main" description: name: device_info_plus - sha256: "86add5ef97215562d2e090535b0a16f197902b10c369c558a100e74ea06e8659" + sha256: "7035152271ff67b072a211152846e9f1259cf1be41e34cd3e0b5463d2d6b8419" url: "https://pub.dev" source: hosted - version: "9.0.3" + version: "9.1.0" device_info_plus_platform_interface: dependency: transitive description: @@ -309,18 +381,18 @@ packages: dependency: "direct main" description: name: dynamic_color - sha256: de4798a7069121aee12d5895315680258415de9b00e717723a1bd73d58f0126d + sha256: "8b8bd1d798bd393e11eddeaa8ae95b12ff028bf7d5998fc5d003488cd5f4ce2f" url: "https://pub.dev" source: hosted - version: "1.6.6" + version: "1.6.8" emoji_picker_flutter: dependency: "direct main" description: name: emoji_picker_flutter - sha256: "1ca31245cc1f7ab5304c68ccda8039f52b9f2372aa4d10803117160fad3faf12" + sha256: "009c51efc763d5a6ba05a5628b8b2184c327cd117d66ea9c3e7edf2ff269c423" url: "https://pub.dev" source: hosted - version: "1.6.1" + version: "1.6.3" emoji_proposal: dependency: "direct main" description: @@ -345,6 +417,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.2.4" + equatable: + dependency: transitive + description: + name: equatable + sha256: c2b87cb7756efdf69892005af546c56c0b5037f54d2a88269b4f347a505e3ca2 + url: "https://pub.dev" + source: hosted + version: "2.0.5" fake_async: dependency: transitive description: @@ -353,6 +433,13 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.1" + fcm_shared_isolate: + dependency: "direct main" + description: + path: "pangea_packages/fcm_shared_isolate" + relative: true + source: path + version: "0.1.0" ffi: dependency: transitive description: @@ -373,42 +460,122 @@ packages: dependency: "direct main" description: name: file_picker - sha256: "21145c9c268d54b1f771d8380c195d2d6f655e0567dc1ca2f9c134c02c819e0a" + sha256: "4e42aacde3b993c5947467ab640882c56947d9d27342a5b6f2895b23956954a6" url: "https://pub.dev" source: hosted - version: "5.3.3" + version: "6.1.1" file_selector_linux: dependency: transitive description: name: file_selector_linux - sha256: "770eb1ab057b5ae4326d1c24cc57710758b9a46026349d021d6311bd27580046" + sha256: "045d372bf19b02aeb69cacf8b4009555fb5f6f0b7ad8016e5f46dd1387ddd492" url: "https://pub.dev" source: hosted - version: "0.9.2" + version: "0.9.2+1" file_selector_macos: dependency: transitive description: name: file_selector_macos - sha256: "4ada532862917bf16e3adb3891fe3a5917a58bae03293e497082203a80909412" + sha256: b15c3da8bd4908b9918111fa486903f5808e388b8d1c559949f584725a6594d6 url: "https://pub.dev" source: hosted - version: "0.9.3+1" + version: "0.9.3+3" file_selector_platform_interface: dependency: transitive description: name: file_selector_platform_interface - sha256: "412705a646a0ae90f33f37acfae6a0f7cbc02222d6cd34e479421c3e74d3853c" + sha256: "0aa47a725c346825a2bd396343ce63ac00bda6eff2fbc43eabe99737dede8262" url: "https://pub.dev" source: hosted - version: "2.6.0" + version: "2.6.1" file_selector_windows: dependency: transitive description: name: file_selector_windows - sha256: "1372760c6b389842b77156203308940558a2817360154084368608413835fc26" + sha256: d3547240c20cabf205c7c7f01a50ecdbc413755814d6677f3cb366f04abcead0 url: "https://pub.dev" source: hosted - version: "0.9.3" + version: "0.9.3+1" + firebase_analytics: + dependency: "direct main" + description: + name: firebase_analytics + sha256: de3d73b5c5618bf31004308b017b4067b7d9156b96e97b62d59ae5eab71081ec + url: "https://pub.dev" + source: hosted + version: "10.7.1" + firebase_analytics_platform_interface: + dependency: transitive + description: + name: firebase_analytics_platform_interface + sha256: ffc59c0b00a572cd1fbf915a1d50cb4ccdc61e429614aa6ae9a598ee5723b96a + url: "https://pub.dev" + source: hosted + version: "3.8.1" + firebase_analytics_web: + dependency: transitive + description: + name: firebase_analytics_web + sha256: "0e725a7dcdeb0a59e44d93d1d45dfec94efe54329ac9d6aa145e24d31429100c" + url: "https://pub.dev" + source: hosted + version: "0.5.5+8" + firebase_core: + dependency: "direct main" + description: + name: firebase_core + sha256: "471b46ea6a9af503184d4de691566887daedd312aec5baac5baa42d819f56446" + url: "https://pub.dev" + source: hosted + version: "2.23.0" + firebase_core_platform_interface: + dependency: transitive + description: + name: firebase_core_platform_interface + sha256: c437ae5d17e6b5cc7981cf6fd458a5db4d12979905f9aafd1fea930428a9fe63 + url: "https://pub.dev" + source: hosted + version: "5.0.0" + firebase_core_web: + dependency: transitive + description: + name: firebase_core_web + sha256: "0631a2ec971dbc540275e2fa00c3a8a2676f0a7adbc3c197d6fba569db689d97" + url: "https://pub.dev" + source: hosted + version: "2.8.1" + firebase_messaging: + dependency: "direct main" + description: + name: firebase_messaging + sha256: f4576000e749c906d44649feadb2449ada39eab9777650319bdd6fa69a3044f5 + url: "https://pub.dev" + source: hosted + version: "14.7.5" + firebase_messaging_platform_interface: + dependency: transitive + description: + name: firebase_messaging_platform_interface + sha256: dcf065ecb9518ddc671477f9b8592274df7ccf74c6aaa15f02fc92b1f2b9c8a8 + url: "https://pub.dev" + source: hosted + version: "4.5.14" + firebase_messaging_web: + dependency: transitive + description: + name: firebase_messaging_web + sha256: "11b7920273367ce2cb272d29153bb7aaae93577eba1eba423c7af61d7f2a3eb2" + url: "https://pub.dev" + source: hosted + version: "3.5.14" + fl_chart: + dependency: "direct main" + description: + name: fl_chart + sha256: e97c5b850ad056e9b3a85d3afeb44c239a83aa994a90723940dac82234f2efaf + url: "https://pub.dev" + source: hosted + version: "0.61.0" flutter: dependency: "direct main" description: flutter @@ -422,13 +589,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.5.0" + flutter_app_lock: + dependency: "direct main" + description: + name: flutter_app_lock + sha256: "98890a2a2bc507b2f85165515189750e134921f8f4022ec10bd223033633a3ba" + url: "https://pub.dev" + source: hosted + version: "3.0.0" flutter_blurhash: dependency: "direct main" description: - name: flutter_blurhash - sha256: "05001537bd3fac7644fa6558b09ec8c0a3f2eba78c0765f88912882b1331a5c6" - url: "https://pub.dev" - source: hosted + path: "." + ref: eb9565f9d5731d4729bd7605510cec0f9e172e5f + resolved-ref: eb9565f9d5731d4729bd7605510cec0f9e172e5f + url: "https://github.com/Craftplacer/flutter_blurhash.git" + source: git version: "0.7.0" flutter_cache_manager: dependency: "direct main" @@ -438,6 +614,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.3.1" + flutter_dotenv: + dependency: "direct main" + description: + name: flutter_dotenv + sha256: "9357883bdd153ab78cbf9ffa07656e336b8bbb2b5a3ca596b0b27e119f7c7d77" + url: "https://pub.dev" + source: hosted + version: "5.1.0" flutter_driver: dependency: transitive description: flutter @@ -527,10 +711,10 @@ packages: dependency: transitive description: name: flutter_layout_grid - sha256: "3c03d28f884d816d6f483bdd64dd79663abfb00eea7cb27ffe98380e8357af95" + sha256: "3529b7aa7ed2cb9861a0bbaa5c14d4be2beaf5a070ce0176077159f80c5de094" url: "https://pub.dev" source: hosted - version: "2.0.4" + version: "2.0.5" flutter_linkify: dependency: "direct main" description: @@ -543,18 +727,18 @@ packages: dependency: "direct dev" description: name: flutter_lints - sha256: "2118df84ef0c3ca93f96123a616ae8540879991b8b57af2f81b76a7ada49b2a4" + sha256: e2a421b7e59244faef694ba7b30562e489c2b489866e505074eb005cd7060db7 url: "https://pub.dev" source: hosted - version: "2.0.2" + version: "3.0.1" flutter_local_notifications: dependency: "direct main" description: name: flutter_local_notifications - sha256: "3cc40fe8c50ab8383f3e053a499f00f975636622ecdc8e20a77418ece3b1e975" + sha256: "6d11ea777496061e583623aaf31923f93a9409ef8fcaeeefdd6cd78bf4fe5bb3" url: "https://pub.dev" source: hosted - version: "15.1.0+1" + version: "16.1.0" flutter_local_notifications_linux: dependency: transitive description: @@ -587,27 +771,28 @@ packages: flutter_math_fork: dependency: "direct main" description: - name: flutter_math_fork - sha256: a143a3a89131b578043ecbdb5e759c1033a1b3e9174f5cd1b979d93f4a7fb41c - url: "https://pub.dev" - source: hosted + path: "." + ref: "3442b36a436880ce1c023e25c868d6f4004c4c24" + resolved-ref: "3442b36a436880ce1c023e25c868d6f4004c4c24" + url: "https://github.com/The-Redhat/flutter_math_fork.git" + source: git version: "0.7.1" flutter_native_splash: dependency: "direct dev" description: name: flutter_native_splash - sha256: ecff62b3b893f2f665de7e4ad3de89f738941fcfcaaba8ee601e749efafa4698 + sha256: d93394f22f73e810bda59e11ebe83329c5511d6460b6b7509c4e1f3c92d6d625 url: "https://pub.dev" source: hosted - version: "2.3.2" + version: "2.3.5" flutter_olm: dependency: "direct main" description: name: flutter_olm - sha256: fef0c9476d02c0df25ef0a66680bc23ac529a36b4911505910bcd8711b449c81 + sha256: "69aaac45d854e74d17d04dac8a0ca3f548266d271a0f0fa7600e006e81432417" url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.3.2" flutter_openssl_crypto: dependency: "direct main" description: @@ -620,10 +805,10 @@ packages: dependency: transitive description: name: flutter_plugin_android_lifecycle - sha256: "950e77c2bbe1692bc0874fc7fb491b96a4dc340457f4ea1641443d0a6c1ea360" + sha256: b068ffc46f82a55844acfa4fdbb61fad72fa2aef0905548419d97f0f95c456da url: "https://pub.dev" source: hosted - version: "2.0.15" + version: "2.0.17" flutter_ringtone_player: dependency: "direct main" description: @@ -636,12 +821,12 @@ packages: dependency: "direct main" description: name: flutter_secure_storage - sha256: "98352186ee7ad3639ccc77ad7924b773ff6883076ab952437d20f18a61f0a7c5" + sha256: ffdbb60130e4665d2af814a0267c481bcf522c41ae2e43caf69fa0146876d685 url: "https://pub.dev" source: hosted - version: "8.0.0" + version: "9.0.0" flutter_secure_storage_linux: - dependency: transitive + dependency: "direct overridden" description: name: flutter_secure_storage_linux sha256: "0912ae29a572230ad52d8a4697e5518d7f0f429052fd51df7e5a7952c7efe2a3" @@ -652,42 +837,42 @@ packages: dependency: transitive description: name: flutter_secure_storage_macos - sha256: "083add01847fc1c80a07a08e1ed6927e9acd9618a35e330239d4422cd2a58c50" + sha256: bd33935b4b628abd0b86c8ca20655c5b36275c3a3f5194769a7b3f37c905369c url: "https://pub.dev" source: hosted - version: "3.0.0" + version: "3.0.1" flutter_secure_storage_platform_interface: dependency: transitive description: name: flutter_secure_storage_platform_interface - sha256: b3773190e385a3c8a382007893d678ae95462b3c2279e987b55d140d3b0cb81b + sha256: "0d4d3a5dd4db28c96ae414d7ba3b8422fd735a8255642774803b2532c9a61d7e" url: "https://pub.dev" source: hosted - version: "1.0.1" + version: "1.0.2" flutter_secure_storage_web: dependency: transitive description: name: flutter_secure_storage_web - sha256: "42938e70d4b872e856e678c423cc0e9065d7d294f45bc41fc1981a4eb4beaffe" + sha256: "30f84f102df9dcdaa2241866a958c2ec976902ebdaa8883fbfe525f1f2f3cf20" url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.1.2" flutter_secure_storage_windows: dependency: transitive description: name: flutter_secure_storage_windows - sha256: fc2910ec9b28d60598216c29ea763b3a96c401f0ce1d13cdf69ccb0e5c93c3ee + sha256: "5809c66f9dd3b4b93b0a6e2e8561539405322ee767ac2f64d084e2ab5429d108" url: "https://pub.dev" source: hosted - version: "2.0.0" + version: "3.0.0" flutter_svg: - dependency: transitive + dependency: "direct main" description: name: flutter_svg - sha256: "8c5d68a82add3ca76d792f058b186a0599414f279f00ece4830b9b231b570338" + sha256: d39e7f95621fc84376bc0f7d504f05c3a41488c562f4a8ad410569127507402c url: "https://pub.dev" source: hosted - version: "2.0.7" + version: "2.0.9" flutter_test: dependency: "direct dev" description: flutter @@ -697,26 +882,26 @@ packages: dependency: "direct main" description: name: flutter_typeahead - sha256: a3539f7a90246b152f569029dedcf0b842532d3f2a440701b520e0bf2acbcf42 + sha256: b9942bd5b7611a6ec3f0730c477146cffa4cd4b051077983ba67ddfc9e7ee818 url: "https://pub.dev" source: hosted - version: "4.6.2" + version: "4.8.0" flutter_web_auth_2: dependency: "direct main" description: name: flutter_web_auth_2 - sha256: "70e4df72940183b8e269c4163f78dd5bf9102ba3329bfe00c0f2373f30fb32d0" + sha256: "75613aa4d8e43df3de0fc3d93df36ae5b4ba2e94070384c5a9baeda99f5a235f" url: "https://pub.dev" source: hosted - version: "2.1.5" + version: "3.0.3" flutter_web_auth_2_platform_interface: dependency: transitive description: name: flutter_web_auth_2_platform_interface - sha256: f6fa7059ff3428c19cd756c02fef8eb0147131c7e64591f9060c90b5ab84f094 + sha256: "9124824cbd21e12680bf58190e27b77f251c897e80ec81cd557ec1fde9aecabf" url: "https://pub.dev" source: hosted - version: "2.1.4" + version: "3.0.0" flutter_web_plugins: dependency: transitive description: flutter @@ -726,10 +911,18 @@ packages: dependency: "direct main" description: name: flutter_webrtc - sha256: "770c6f8babfdc4907539dc57bf9e98b89132eaa4486bac774c537dd25c2d5362" + sha256: "8522e9f347aed9f03ec591d05fc286a698c1b11a1a6d3e994e92727d24c6f352" url: "https://pub.dev" source: hosted - version: "0.9.40" + version: "0.9.46" + freezed_annotation: + dependency: transitive + description: + name: freezed_annotation + sha256: c3fd9336eb55a38cc1bbd79ab17573113a8deccd0ecbbf926cca3c62803b5c2d + url: "https://pub.dev" + source: hosted + version: "2.4.1" fuchsia_remote_debug_protocol: dependency: transitive description: flutter @@ -739,10 +932,10 @@ packages: dependency: "direct main" description: name: future_loading_dialog - sha256: "6227dddb32ad5c7d233a54668f862acb4beb5a5e0dde072de372347cc0799e63" + sha256: "2718b1a308db452da32ab9bca9ad496ff92b683e217add9e92cf50520f90537e" url: "https://pub.dev" source: hosted - version: "0.2.4" + version: "0.3.0" geolocator: dependency: "direct main" description: @@ -783,14 +976,30 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.6" + get: + dependency: transitive + description: + name: get + sha256: e4e7335ede17452b391ed3b2ede016545706c01a02292a6c97619705e7d2a85e + url: "https://pub.dev" + source: hosted + version: "4.6.6" get_it: dependency: transitive description: name: get_it - sha256: "529de303c739fca98cd7ece5fca500d8ff89649f1bb4b4e94fb20954abcd7468" + sha256: f79870884de16d689cf9a7d15eedf31ed61d750e813c538a6efb92660fea83c3 url: "https://pub.dev" source: hosted - version: "7.6.0" + version: "7.6.4" + get_storage: + dependency: "direct main" + description: + name: get_storage + sha256: "39db1fffe779d0c22b3a744376e86febe4ade43bf65e06eab5af707dc84185a2" + url: "https://pub.dev" + source: hosted + version: "2.1.1" glob: dependency: transitive description: @@ -803,10 +1012,18 @@ packages: dependency: "direct main" description: name: go_router - sha256: "2aa884667eeda3a1c461f31e72af1f77984ab0f29450d8fb12ec1f7bc53eea14" + sha256: c247a4f76071c3b97bb5ae8912968870d5565644801c5e09f3bc961b4d874895 url: "https://pub.dev" source: hosted - version: "10.1.0" + version: "12.1.1" + gradient_borders: + dependency: transitive + description: + name: gradient_borders + sha256: "69eeaff519d145a4c6c213ada1abae386bcc8981a4970d923e478ce7ba19e309" + url: "https://pub.dev" + source: hosted + version: "1.0.0" highlighter: dependency: transitive description: @@ -867,74 +1084,74 @@ packages: dependency: transitive description: name: image - sha256: a72242c9a0ffb65d03de1b7113bc4e189686fc07c7147b8b41811d0dd0e0d9bf + sha256: "028f61960d56f26414eb616b48b04eb37d700cbe477b7fb09bf1d7ce57fd9271" url: "https://pub.dev" source: hosted - version: "4.0.17" + version: "4.1.3" image_picker: dependency: "direct main" description: name: image_picker - sha256: "841837258e0b42c80946c43443054fc726f5e8aa84a97f363eb9ef0d45b33c14" + sha256: "7d7f2768df2a8b0a3cefa5ef4f84636121987d403130e70b17ef7e2cf650ba84" url: "https://pub.dev" source: hosted - version: "1.0.2" + version: "1.0.4" image_picker_android: dependency: transitive description: name: image_picker_android - sha256: "8179b54039b50eee561676232304f487602e2950ffb3e8995ed9034d6505ca34" + sha256: d6a6e78821086b0b737009b09363018309bbc6de3fd88cc5c26bc2bb44a4957f url: "https://pub.dev" source: hosted - version: "0.8.7+4" + version: "0.8.8+2" image_picker_for_web: dependency: transitive description: name: image_picker_for_web - sha256: "8b6c160cdbe572199103a091c783685b236110e4a0fd7a4947f32ff5b7da8765" + sha256: "50bc9ae6a77eea3a8b11af5eb6c661eeb858fdd2f734c2a4fd17086922347ef7" url: "https://pub.dev" source: hosted - version: "3.0.0" + version: "3.0.1" image_picker_ios: dependency: transitive description: name: image_picker_ios - sha256: b3e2f21feb28b24dd73a35d7ad6e83f568337c70afab5eabac876e23803f264b + sha256: "76ec722aeea419d03aa915c2c96bf5b47214b053899088c9abb4086ceecf97a7" url: "https://pub.dev" source: hosted - version: "0.8.8" + version: "0.8.8+4" image_picker_linux: dependency: transitive description: name: image_picker_linux - sha256: "02cbc21fe1706b97942b575966e5fbbeaac535e76deef70d3a242e4afb857831" + sha256: "4ed1d9bb36f7cd60aa6e6cd479779cc56a4cb4e4de8f49d487b1aaad831300fa" url: "https://pub.dev" source: hosted - version: "0.2.1" + version: "0.2.1+1" image_picker_macos: dependency: transitive description: name: image_picker_macos - sha256: cee2aa86c56780c13af2c77b5f2f72973464db204569e1ba2dd744459a065af4 + sha256: "3f5ad1e8112a9a6111c46d0b57a7be2286a9a07fc6e1976fdf5be2bd31d4ff62" url: "https://pub.dev" source: hosted - version: "0.2.1" + version: "0.2.1+1" image_picker_platform_interface: dependency: transitive description: name: image_picker_platform_interface - sha256: c1134543ae2187e85299996d21c526b2f403854994026d575ae4cf30d7bb2a32 + sha256: ed9b00e63977c93b0d2d2b343685bed9c324534ba5abafbb3dfbd6a780b1b514 url: "https://pub.dev" source: hosted - version: "2.9.0" + version: "2.9.1" image_picker_windows: dependency: transitive description: name: image_picker_windows - sha256: c3066601ea42113922232c7b7b3330a2d86f029f685bba99d82c30e799914952 + sha256: "6ad07afc4eb1bc25f3a01084d28520496c4a3bb0cb13685435838167c9dcedeb" url: "https://pub.dev" source: hosted - version: "0.2.1" + version: "0.2.1+1" import_sorter: dependency: "direct dev" description: @@ -943,6 +1160,38 @@ packages: url: "https://pub.dev" source: hosted version: "4.6.0" + in_app_purchase: + dependency: "direct main" + description: + name: in_app_purchase + sha256: bdda02b5b11b56d5e29c7f0c57c433db3452b0c8ce1c37cbfcf1de52946efd9f + url: "https://pub.dev" + source: hosted + version: "3.1.11" + in_app_purchase_android: + dependency: transitive + description: + name: in_app_purchase_android + sha256: c4b84caa4e2c7ffebda444c5033fd8423cc3a45a6e1066929bbbcd4daf665db5 + url: "https://pub.dev" + source: hosted + version: "0.3.0+15" + in_app_purchase_platform_interface: + dependency: transitive + description: + name: in_app_purchase_platform_interface + sha256: "5168afbc54f406f741252b66d41872c1193a0066a6edcb587176290b92e2d537" + url: "https://pub.dev" + source: hosted + version: "1.3.6" + in_app_purchase_storekit: + dependency: transitive + description: + name: in_app_purchase_storekit + sha256: "29526f5ce85bd908b4cacdadb2e8ef299bccbb516b90d2881805343f868502ab" + url: "https://pub.dev" + source: hosted + version: "0.3.7" integration_test: dependency: "direct dev" description: flutter @@ -964,6 +1213,22 @@ packages: url: "https://pub.dev" source: hosted version: "0.18.1" + io: + dependency: transitive + description: + name: io + sha256: "2ec25704aba361659e10e3e5f5d672068d332fc8ac516421d483a11e5cbd061e" + url: "https://pub.dev" + source: hosted + version: "1.0.4" + jiffy: + dependency: transitive + description: + name: jiffy + sha256: cc1d4b75016a9156c29b5d61f0c9176c3e0fb0580cc5a0e0422b5d2cab3fbfff + url: "https://pub.dev" + source: hosted + version: "6.2.1" js: dependency: transitive description: @@ -984,26 +1249,34 @@ packages: dependency: "direct main" description: name: just_audio - sha256: "890cd0fc41a1a4530c171e375a2a3fb6a09d84e9d508c5195f40bcff54330327" + sha256: b607cd1a43bac03d85c3aaee00448ff4a589ef2a77104e3d409889ff079bf823 url: "https://pub.dev" source: hosted - version: "0.9.34" + version: "0.9.36" just_audio_platform_interface: dependency: transitive description: name: just_audio_platform_interface - sha256: d8409da198bbc59426cd45d4c92fca522a2ec269b576ce29459d6d6fcaeb44df + sha256: c3dee0014248c97c91fe6299edb73dc4d6c6930a2f4f713579cd692d9e47f4a1 url: "https://pub.dev" source: hosted - version: "4.2.1" + version: "4.2.2" just_audio_web: dependency: transitive description: name: just_audio_web - sha256: ff62f733f437b25a0ff590f0e295fa5441dcb465f1edbdb33b3dea264705bc13 + sha256: "134356b0fe3d898293102b33b5fd618831ffdc72bb7a1b726140abdf22772b70" url: "https://pub.dev" source: hosted - version: "0.4.8" + version: "0.4.9" + jwt_decode: + dependency: "direct main" + description: + name: jwt_decode + sha256: d2e9f68c052b2225130977429d30f187aa1981d789c76ad104a32243cfdebfbb + url: "https://pub.dev" + source: hosted + version: "0.3.1" keyboard_shortcuts: dependency: "direct main" description: @@ -1013,6 +1286,14 @@ packages: url: "https://github.com/TheOneWithTheBraid/keyboard_shortcuts.git" source: git version: "0.1.4" + language_tool: + dependency: "direct main" + description: + name: language_tool + sha256: "90ceb6f0a0b57fb3a5b88be82ffd676c90639cd06d622d25f76add30d5a2acd6" + url: "https://pub.dev" + source: hosted + version: "2.1.1" latlong2: dependency: "direct main" description: @@ -1033,10 +1314,10 @@ packages: dependency: transitive description: name: lints - sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452" + sha256: cbf8d4b858bb0134ef3ef87841abdf8d63bfc255c266b7bf6b39daa1085c4290 url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "3.0.0" list_counter: dependency: transitive description: @@ -1065,26 +1346,26 @@ packages: dependency: transitive description: name: macos_ui - sha256: b739149b812c47e5ff10a00c9fdf7315f22ac5cd1fdbd447a6b7ffee31472717 + sha256: cc499122655c61728185561e9006af4b239f9526f98d7b2cbf42124e9044a0ff url: "https://pub.dev" source: hosted - version: "2.0.0" + version: "2.0.2" macos_window_utils: dependency: transitive description: name: macos_window_utils - sha256: "43a90473f8786f00f07203e6819dab67e032f8896dafa4a6f85fbc71fba32c0b" + sha256: b3dfd47bbc605f0e315af684b50370a8f84932267aaa542098063fa384d593bd url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.4.0" markdown: dependency: transitive description: name: markdown - sha256: "01512006c8429f604eb10f9848717baeaedf99e991d14a50d540d9beff08e5c6" + sha256: acf35edccc0463a9d7384e437c015a3535772e09714cf60e07eeef3a15870dcd url: "https://pub.dev" source: hosted - version: "4.0.1" + version: "7.1.1" matcher: dependency: transitive description: @@ -1105,18 +1386,18 @@ packages: dependency: "direct main" description: name: matrix - sha256: "10389562a4562db6150291b538e025a9a1b7a79998a71d38cb5c78a34ca6b007" + sha256: b01a8a7141a586853a4f9b2e98b3c9912ff74bbceadc16b2bf3630bf055a830a url: "https://pub.dev" source: hosted - version: "0.22.3" + version: "0.22.7" matrix_api_lite: dependency: transitive description: name: matrix_api_lite - sha256: e5304b33b16d60863533836717be808845bf94cd0e3a339ef146d9321e6b59b7 + sha256: "62bdd1dffb956e956863ba21e52109157502342b749e4728f4105f0c6d73a254" url: "https://pub.dev" source: hosted - version: "1.7.1" + version: "1.7.2" matrix_homeserver_recommendations: dependency: "direct main" description: @@ -1129,10 +1410,10 @@ packages: dependency: transitive description: name: meta - sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" + sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.10.0" mgrs_dart: dependency: transitive description: @@ -1153,18 +1434,18 @@ packages: dependency: "direct dev" description: name: msix - sha256: "76c87b8207323803169626a55afd78bbb8413c984df349a76598b9fbf9224677" + sha256: "957d04eee260e4bd15bec1fdb988dfc73718285e201cf89d97ef01ef38e66d4c" url: "https://pub.dev" source: hosted - version: "3.16.1" + version: "3.16.6" native_imaging: dependency: "direct main" description: name: native_imaging - sha256: "9f96eafb6d84ec934262caf36b60e236d1c4507ed6555a1effc117d463ef5932" + sha256: "182ccd8e0815a8a2158500ef66c828c030f6b9e05783e41e22f33bbcfd46a3d5" url: "https://pub.dev" source: hosted - version: "0.1.0" + version: "0.1.1" nested: dependency: transitive description: @@ -1173,6 +1454,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.0" + new_version_plus: + dependency: "direct main" + description: + name: new_version_plus + sha256: "136cd6368ef96eae5ee3efb59f284c6ff61a06c3c08fb6a49f451ac5fa635e1d" + url: "https://pub.dev" + source: hosted + version: "0.0.10" + nm: + dependency: transitive + description: + name: nm + sha256: "2c9aae4127bdc8993206464fcc063611e0e36e72018696cd9631023a31b24254" + url: "https://pub.dev" + source: hosted + version: "0.5.0" olm: dependency: transitive description: @@ -1181,6 +1478,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.3" + open_file: + dependency: "direct main" + description: + name: open_file + sha256: a5a32d44acb7c899987d0999e1e3cbb0a0f1adebbf41ac813ec6d2d8faa0af20 + url: "https://pub.dev" + source: hosted + version: "3.3.2" package_config: dependency: transitive description: @@ -1193,10 +1498,10 @@ packages: dependency: "direct main" description: name: package_info_plus - sha256: "6ff267fcd9d48cb61c8df74a82680e8b82e940231bb5f68356672fde0397334a" + sha256: "7e76fad405b3e4016cd39d08f455a4eb5199723cf594cd1b8916d47140d93017" url: "https://pub.dev" source: hosted - version: "4.1.0" + version: "4.2.0" package_info_plus_platform_interface: dependency: transitive description: @@ -1233,66 +1538,66 @@ packages: dependency: "direct main" description: name: path_provider - sha256: "909b84830485dbcd0308edf6f7368bc8fd76afa26a270420f34cabea2a6467a0" + sha256: a1aa8aaa2542a6bc57e381f132af822420216c80d4781f7aa085ca3229208aaa url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.1.1" path_provider_android: dependency: transitive description: name: path_provider_android - sha256: "5d44fc3314d969b84816b569070d7ace0f1dea04bd94a83f74c4829615d22ad8" + sha256: e595b98692943b4881b219f0a9e3945118d3c16bd7e2813f98ec6e532d905f72 url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.2.1" path_provider_foundation: dependency: transitive description: name: path_provider_foundation - sha256: "1b744d3d774e5a879bb76d6cd1ecee2ba2c6960c03b1020cd35212f6aa267ac5" + sha256: "19314d595120f82aca0ba62787d58dde2cc6b5df7d2f0daf72489e38d1b57f2d" url: "https://pub.dev" source: hosted - version: "2.3.0" + version: "2.3.1" path_provider_linux: dependency: transitive description: name: path_provider_linux - sha256: ba2b77f0c52a33db09fc8caf85b12df691bf28d983e84cf87ff6d693cfa007b3 + sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279 url: "https://pub.dev" source: hosted - version: "2.2.0" + version: "2.2.1" path_provider_platform_interface: dependency: transitive description: name: path_provider_platform_interface - sha256: bced5679c7df11190e1ddc35f3222c858f328fff85c3942e46e7f5589bf9eb84 + sha256: "94b1e0dd80970c1ce43d5d4e050a9918fce4f4a775e6142424c30a29a363265c" url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.1.1" path_provider_windows: dependency: transitive description: name: path_provider_windows - sha256: ee0e0d164516b90ae1f970bdf29f726f1aa730d7cfc449ecc74c495378b705da + sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170" url: "https://pub.dev" source: hosted - version: "2.2.0" + version: "2.2.1" permission_handler: dependency: "direct main" description: name: permission_handler - sha256: "63e5216aae014a72fe9579ccd027323395ce7a98271d9defa9d57320d001af81" + sha256: "284a66179cabdf942f838543e10413246f06424d960c92ba95c84439154fcac8" url: "https://pub.dev" source: hosted - version: "10.4.3" + version: "11.0.1" permission_handler_android: dependency: transitive description: name: permission_handler_android - sha256: "2ffaf52a21f64ac9b35fe7369bb9533edbd4f698e5604db8645b1064ff4cf221" + sha256: f9fddd3b46109bd69ff3f9efa5006d2d309b7aec0f3c1c5637a60a2d5659e76e url: "https://pub.dev" source: hosted - version: "10.3.3" + version: "11.1.0" permission_handler_apple: dependency: transitive description: @@ -1305,10 +1610,10 @@ packages: dependency: transitive description: name: permission_handler_platform_interface - sha256: "7c6b1500385dd1d2ca61bb89e2488ca178e274a69144d26bbd65e33eae7c02a9" + sha256: "6760eb5ef34589224771010805bea6054ad28453906936f843a8cc4d3a55c4a4" url: "https://pub.dev" source: hosted - version: "3.11.3" + version: "3.12.0" permission_handler_windows: dependency: transitive description: @@ -1329,34 +1634,34 @@ packages: dependency: transitive description: name: platform - sha256: "4a451831508d7d6ca779f7ac6e212b4023dd5a7d08a27a63da33756410e32b76" + sha256: ae68c7bfcd7383af3629daafb32fb4e8681c7154428da4febcff06200585f102 url: "https://pub.dev" source: hosted - version: "3.1.0" + version: "3.1.2" platform_detect: dependency: transitive description: name: platform_detect - sha256: "14afcb6ffcd93745e39a288db53d1d6522ea25d71f7993c13a367a86c437b54d" + sha256: "08f4ee79c0e1c4858d37e06b22352a3ebdef5466b613749a3adb03e703d4f5b0" url: "https://pub.dev" source: hosted - version: "2.0.7" + version: "2.0.11" plugin_platform_interface: dependency: transitive description: name: plugin_platform_interface - sha256: "43798d895c929056255600343db8f049921cbec94d31ec87f1dc5c16c01935dd" + sha256: da3fdfeccc4d4ff2da8f8c556704c08f912542c5fb3cf2233ed75372384a034d url: "https://pub.dev" source: hosted - version: "2.1.5" + version: "2.1.6" pointer_interceptor: dependency: transitive description: name: pointer_interceptor - sha256: "6aa680b30d96dccef496933d00208ad25f07e047f644dc98ce03ec6141633a9a" + sha256: adf7a637f97c077041d36801b43be08559fd4322d2127b3f20bb7be1b9eebc22 url: "https://pub.dev" source: hosted - version: "0.9.3+4" + version: "0.9.3+7" pointycastle: dependency: transitive description: @@ -1393,10 +1698,10 @@ packages: dependency: "direct main" description: name: provider - sha256: cdbe7530b12ecd9eb455bdaa2fcb8d4dad22e80b8afb4798b41479d5ce26847f + sha256: "9a96a0a19b594dbc5bf0f1f27d2bc67d5f95957359b461cd9feb44ed6ae75096" url: "https://pub.dev" source: hosted - version: "6.0.5" + version: "6.1.1" pub_semver: dependency: transitive description: @@ -1413,6 +1718,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.3.0" + pubspec_parse: + dependency: transitive + description: + name: pubspec_parse + sha256: c63b2876e58e194e4b0828fcb080ad0e06d051cb607a6be51a9e084f47cb9367 + url: "https://pub.dev" + source: hosted + version: "1.2.3" punycode: dependency: "direct main" description: @@ -1421,6 +1734,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.0" + purchases_flutter: + dependency: "direct main" + description: + name: purchases_flutter + sha256: "3e1444a87a11b82322ec2bd0f1af3eb0d3431717f1a93cbd4f823e192b5c891f" + url: "https://pub.dev" + source: hosted + version: "5.8.0" qr: dependency: transitive description: @@ -1521,10 +1842,10 @@ packages: dependency: transitive description: name: remove_emoji - sha256: d75024ae134328c38871c0fe73ada15ebeb635fca8903d039f5090a3e902c2b2 + sha256: ed9e8463e8c9ca05b86fcddd4c0dbd2c2605a50d267f4ffa05496607924809e3 url: "https://pub.dev" source: hosted - version: "0.0.9" + version: "0.0.10" rxdart: dependency: transitive description: @@ -1557,78 +1878,94 @@ packages: url: "https://pub.dev" source: hosted version: "0.0.5" + sentry: + dependency: transitive + description: + name: sentry + sha256: e7ded42974bac5f69e4ca4ddc57d30499dd79381838f24b7e8fd9aa4139e7b79 + url: "https://pub.dev" + source: hosted + version: "7.13.2" + sentry_flutter: + dependency: "direct main" + description: + name: sentry_flutter + sha256: d6f55ec7a1f681784165021f749007712a72ff57eadf91e963331b6ae326f089 + url: "https://pub.dev" + source: hosted + version: "7.13.2" share_plus: dependency: "direct main" description: name: share_plus - sha256: "6cec740fa0943a826951223e76218df002804adb588235a8910dc3d6b0654e11" + sha256: f74fc3f1cbd99f39760182e176802f693fa0ec9625c045561cfad54681ea93dd url: "https://pub.dev" source: hosted - version: "7.1.0" + version: "7.2.1" share_plus_platform_interface: dependency: transitive description: name: share_plus_platform_interface - sha256: "357412af4178d8e11d14f41723f80f12caea54cf0d5cd29af9dcdab85d58aea7" + sha256: df08bc3a07d01f5ea47b45d03ffcba1fa9cd5370fb44b3f38c70e42cced0f956 url: "https://pub.dev" source: hosted - version: "3.3.0" + version: "3.3.1" shared_preferences: dependency: "direct main" description: name: shared_preferences - sha256: "0344316c947ffeb3a529eac929e1978fcd37c26be4e8468628bac399365a3ca1" + sha256: "81429e4481e1ccfb51ede496e916348668fd0921627779233bd24cc3ff6abd02" url: "https://pub.dev" source: hosted - version: "2.2.0" + version: "2.2.2" shared_preferences_android: dependency: transitive description: name: shared_preferences_android - sha256: fe8401ec5b6dcd739a0fe9588802069e608c3fdbfd3c3c93e546cf2f90438076 + sha256: "8568a389334b6e83415b6aae55378e158fbc2314e074983362d20c562780fb06" url: "https://pub.dev" source: hosted - version: "2.2.0" + version: "2.2.1" shared_preferences_foundation: dependency: transitive description: name: shared_preferences_foundation - sha256: d29753996d8eb8f7619a1f13df6ce65e34bc107bef6330739ed76f18b22310ef + sha256: "7bf53a9f2d007329ee6f3df7268fd498f8373602f943c975598bbb34649b62a7" url: "https://pub.dev" source: hosted - version: "2.3.3" + version: "2.3.4" shared_preferences_linux: dependency: transitive description: name: shared_preferences_linux - sha256: "71d6806d1449b0a9d4e85e0c7a917771e672a3d5dc61149cc9fac871115018e1" + sha256: "9f2cbcf46d4270ea8be39fa156d86379077c8a5228d9dfdb1164ae0bb93f1faa" url: "https://pub.dev" source: hosted - version: "2.3.0" + version: "2.3.2" shared_preferences_platform_interface: dependency: transitive description: name: shared_preferences_platform_interface - sha256: "23b052f17a25b90ff2b61aad4cc962154da76fb62848a9ce088efe30d7c50ab1" + sha256: d4ec5fc9ebb2f2e056c617112aa75dcf92fc2e4faaf2ae999caa297473f75d8a url: "https://pub.dev" source: hosted - version: "2.3.0" + version: "2.3.1" shared_preferences_web: dependency: transitive description: name: shared_preferences_web - sha256: "7347b194fb0bbeb4058e6a4e87ee70350b6b2b90f8ac5f8bd5b3a01548f6d33a" + sha256: d762709c2bbe80626ecc819143013cc820fa49ca5e363620ee20a8b15a3e3daf url: "https://pub.dev" source: hosted - version: "2.2.0" + version: "2.2.1" shared_preferences_windows: dependency: transitive description: name: shared_preferences_windows - sha256: f95e6a43162bce43c9c3405f3eb6f39e5b5d11f65fab19196cf8225e2777624d + sha256: "841ad54f3c8381c480d0c9b508b89a34036f512482c407e6df7a9c4aa2ef8f59" url: "https://pub.dev" source: hosted - version: "2.3.0" + version: "2.3.2" sky_engine: dependency: transitive description: flutter @@ -1662,26 +1999,26 @@ packages: dependency: transitive description: name: sqflite_common - sha256: "1b92f368f44b0dee2425bb861cfa17b6f6cf3961f762ff6f941d20b33355660a" + sha256: bb4738f15b23352822f4c42a531677e5c6f522e079461fd240ead29d8d8a54a6 url: "https://pub.dev" source: hosted - version: "2.5.0" + version: "2.5.0+2" stack_trace: dependency: transitive description: name: stack_trace - sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 + sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" url: "https://pub.dev" source: hosted - version: "1.11.0" + version: "1.11.1" stream_channel: dependency: transitive description: name: stream_channel - sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" + sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" string_scanner: dependency: transitive description: @@ -1706,6 +2043,30 @@ packages: url: "https://pub.dev" source: hosted version: "0.3.1" + syncfusion_flutter_core: + dependency: transitive + description: + name: syncfusion_flutter_core + sha256: "9f0a4593f7642b2f106e329734d0e5fc746baf8d0a59495eec586cd0d9ba7d02" + url: "https://pub.dev" + source: hosted + version: "22.2.12" + syncfusion_flutter_xlsio: + dependency: "direct main" + description: + name: syncfusion_flutter_xlsio + sha256: "66b009fce91e10cfa5d9b3cdf2c4aa3fdf7430dab159626f4c67297638da2caf" + url: "https://pub.dev" + source: hosted + version: "22.2.12" + syncfusion_officecore: + dependency: transitive + description: + name: syncfusion_officecore + sha256: "66d0a0faba40f043bba4ef102474213d3145ffeca2b3f2351a98c0cc10079c27" + url: "https://pub.dev" + source: hosted + version: "22.2.12" synchronized: dependency: transitive description: @@ -1726,10 +2087,10 @@ packages: dependency: transitive description: name: test_api - sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8" + sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" url: "https://pub.dev" source: hosted - version: "0.6.0" + version: "0.6.1" timezone: dependency: transitive description: @@ -1814,34 +2175,34 @@ packages: dependency: "direct main" description: name: unifiedpush - sha256: "083863337eae48a3d5e30b41964c7c025a6e0e77c3f9c74340d5ff7bfa4e8c85" + sha256: ef7f3ae6139d27169604e3844379ef7929af573a2be21d9e82187f44ab7b9a32 url: "https://pub.dev" source: hosted - version: "5.0.0" + version: "5.0.1" unifiedpush_android: dependency: transitive description: name: unifiedpush_android - sha256: "559124eb1d6bcc5d8f422c8b9a942e52cc704858e6f0afad4c449feef654f1a3" + sha256: "19fcdd2671c46bd074efbb80c43cedd0bcddd1fc0cfd3e2f74aec03fb0659d58" url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.2.0" unifiedpush_platform_interface: dependency: transitive description: name: unifiedpush_platform_interface - sha256: b973137572f84b67656b18032f5047d327cffc5ab77ec4230d2459b1144ccf84 + sha256: "7782b18a15d22bb184fa766ef1e0c675eef862055ff815453df7041dfd026146" url: "https://pub.dev" source: hosted - version: "2.0.0" + version: "2.0.1" universal_html: dependency: "direct main" description: name: universal_html - sha256: a5cc5a84188e5d3e58f3ed77fe3dd4575dc1f68aa7c89e51b5b4105b9aab3b9d + sha256: "56536254004e24d9d8cfdb7dbbf09b74cf8df96729f38a2f5c238163e3d58971" url: "https://pub.dev" source: hosted - version: "2.2.3" + version: "2.2.4" universal_io: dependency: transitive description: @@ -1862,66 +2223,66 @@ packages: dependency: "direct main" description: name: url_launcher - sha256: "781bd58a1eb16069412365c98597726cd8810ae27435f04b3b4d3a470bacd61e" + sha256: b1c9e98774adf8820c96fbc7ae3601231d324a7d5ebd8babe27b6dfac91357ba url: "https://pub.dev" source: hosted - version: "6.1.12" + version: "6.2.1" url_launcher_android: dependency: transitive description: name: url_launcher_android - sha256: "3dd2388cc0c42912eee04434531a26a82512b9cb1827e0214430c9bcbddfe025" + sha256: "31222ffb0063171b526d3e569079cf1f8b294075ba323443fdc690842bfd4def" url: "https://pub.dev" source: hosted - version: "6.0.38" + version: "6.2.0" url_launcher_ios: dependency: transitive description: name: url_launcher_ios - sha256: "9af7ea73259886b92199f9e42c116072f05ff9bea2dcb339ab935dfc957392c2" + sha256: "4ac97281cf60e2e8c5cc703b2b28528f9b50c8f7cebc71df6bdf0845f647268a" url: "https://pub.dev" source: hosted - version: "6.1.4" + version: "6.2.0" url_launcher_linux: dependency: transitive description: name: url_launcher_linux - sha256: "207f4ddda99b95b4d4868320a352d374b0b7e05eefad95a4a26f57da413443f5" + sha256: "9f2d390e096fdbe1e6e6256f97851e51afc2d9c423d3432f1d6a02a8a9a8b9fd" url: "https://pub.dev" source: hosted - version: "3.0.5" + version: "3.1.0" url_launcher_macos: dependency: transitive description: name: url_launcher_macos - sha256: "1c4fdc0bfea61a70792ce97157e5cc17260f61abbe4f39354513f39ec6fd73b1" + sha256: b7244901ea3cf489c5335bdacda07264a6e960b1c1b1a9f91e4bc371d9e68234 url: "https://pub.dev" source: hosted - version: "3.0.6" + version: "3.1.0" url_launcher_platform_interface: dependency: transitive description: name: url_launcher_platform_interface - sha256: bfdfa402f1f3298637d71ca8ecfe840b4696698213d5346e9d12d4ab647ee2ea + sha256: "980e8d9af422f477be6948bdfb68df8433be71f5743a188968b0c1b887807e50" url: "https://pub.dev" source: hosted - version: "2.1.3" + version: "2.2.0" url_launcher_web: dependency: transitive description: name: url_launcher_web - sha256: cc26720eefe98c1b71d85f9dc7ef0cada5132617046369d9dc296b3ecaa5cbb4 + sha256: "7fd2f55fe86cea2897b963e864dc01a7eb0719ecc65fcef4c1cc3d686d718bb2" url: "https://pub.dev" source: hosted - version: "2.0.18" + version: "2.2.0" url_launcher_windows: dependency: transitive description: name: url_launcher_windows - sha256: "7967065dd2b5fccc18c653b97958fdf839c5478c28e767c61ee879f4e7882422" + sha256: "7754a1ad30ee896b265f8d14078b0513a4dba28d358eabb9d5f339886f4a1adc" url: "https://pub.dev" source: hosted - version: "3.0.7" + version: "3.1.0" uuid: dependency: transitive description: @@ -1934,26 +2295,26 @@ packages: dependency: transitive description: name: vector_graphics - sha256: "670f6e07aca990b4a2bcdc08a784193c4ccdd1932620244c3a86bb72a0eac67f" + sha256: "0f0c746dd2d6254a0057218ff980fc7f5670fd0fcf5e4db38a490d31eed4ad43" url: "https://pub.dev" source: hosted - version: "1.1.7" + version: "1.1.9+1" vector_graphics_codec: dependency: transitive description: name: vector_graphics_codec - sha256: "7451721781d967db9933b63f5733b1c4533022c0ba373a01bdd79d1a5457f69f" + sha256: "0edf6d630d1bfd5589114138ed8fada3234deacc37966bec033d3047c29248b7" url: "https://pub.dev" source: hosted - version: "1.1.7" + version: "1.1.9+1" vector_graphics_compiler: dependency: transitive description: name: vector_graphics_compiler - sha256: "80a13c613c8bde758b1464a1755a7b3a8f2b6cec61fbf0f5a53c94c30f03ba2e" + sha256: d24333727332d9bd20990f1483af4e09abdb9b1fc7c3db940b56ab5c42790c26 url: "https://pub.dev" source: hosted - version: "1.1.7" + version: "1.1.9+1" vector_math: dependency: transitive description: @@ -1966,10 +2327,10 @@ packages: dependency: "direct main" description: name: vibration - sha256: d81f665bcb201f586c295a21f3fe8f1cb6dc32c81a213a99e9c714ec8e811ce5 + sha256: "63d4f6b03e38d106599da18e786d5edcd02354433a4ed478fccbbcfc347193ab" url: "https://pub.dev" source: hosted - version: "1.8.1" + version: "1.8.3" video_compress: dependency: "direct main" description: @@ -1982,42 +2343,42 @@ packages: dependency: "direct main" description: name: video_player - sha256: "3fd106c74da32f336dc7feb65021da9b0207cb3124392935f1552834f7cce822" + sha256: e16f0a83601a78d165dabc17e4dac50997604eb9e4cc76e10fa219046b70cef3 url: "https://pub.dev" source: hosted - version: "2.7.0" + version: "2.8.1" video_player_android: dependency: transitive description: name: video_player_android - sha256: f338a5a396c845f4632959511cad3542cdf3167e1b2a1a948ef07f7123c03608 + sha256: "3fe89ab07fdbce786e7eb25b58532d6eaf189ceddc091cb66cba712f8d9e8e55" url: "https://pub.dev" source: hosted - version: "2.4.9" + version: "2.4.10" video_player_avfoundation: dependency: transitive description: name: video_player_avfoundation - sha256: f5f5b7fe8c865be8a57fe80c2dca130772e1db775b7af4e5c5aa1905069cfc6c + sha256: fe73d636f82286a3739f5e644f95f09442cacdc436ebbe5436521dc915f3ecac url: "https://pub.dev" source: hosted - version: "2.4.9" + version: "2.5.1" video_player_platform_interface: dependency: transitive description: name: video_player_platform_interface - sha256: "1ca9acd7a0fb15fb1a990cb554e6f004465c6f37c99d2285766f08a4b2802988" + sha256: be72301bf2c0150ab35a8c34d66e5a99de525f6de1e8d27c0672b836fe48f73a url: "https://pub.dev" source: hosted - version: "6.2.0" + version: "6.2.1" video_player_web: dependency: transitive description: name: video_player_web - sha256: "44ce41424d104dfb7cf6982cc6b84af2b007a24d126406025bf40de5d481c74c" + sha256: ab7a462b07d9ca80bed579e30fb3bce372468f1b78642e0911b10600f2c5cb5b url: "https://pub.dev" source: hosted - version: "2.0.16" + version: "2.1.2" visibility_detector: dependency: transitive description: @@ -2030,10 +2391,10 @@ packages: dependency: transitive description: name: vm_service - sha256: c620a6f783fa22436da68e42db7ebbf18b8c44b9a46ab911f666ff09ffd9153f + sha256: c538be99af830f478718b51630ec1b6bee5e74e52c8a802d328d9e71d35d2583 url: "https://pub.dev" source: hosted - version: "11.7.1" + version: "11.10.0" wakelock_platform_interface: dependency: transitive description: @@ -2046,10 +2407,10 @@ packages: dependency: "direct main" description: name: wakelock_plus - sha256: aac3f3258f01781ec9212df94eecef1eb9ba9350e106728def405baa096ba413 + sha256: f45a6c03aa3f8322e0a9d7f4a0482721c8789cb41d555407367650b8f9c26018 url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.1.3" wakelock_plus_platform_interface: dependency: transitive description: @@ -2079,10 +2440,10 @@ packages: dependency: transitive description: name: web - sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10 + sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152 url: "https://pub.dev" source: hosted - version: "0.1.4-beta" + version: "0.3.0" webdriver: dependency: transitive description: @@ -2095,26 +2456,26 @@ packages: dependency: "direct main" description: name: webrtc_interface - sha256: faec2b578f7cd588766843a8c59d4a0137c44de10b83341ce7bec05e104614d7 + sha256: "2efbd3e4e5ebeb2914253bcc51dafd3053c4b87b43f3076c74835a9deecbae3a" url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.1.2" win32: dependency: transitive description: name: win32 - sha256: f2add6fa510d3ae152903412227bda57d0d5a8da61d2c39c1fb022c9429a41c0 + sha256: "7c99c0e1e2fa190b48d25c81ca5e42036d5cac81430ef249027d97b0935c553f" url: "https://pub.dev" source: hosted - version: "5.0.6" + version: "5.1.0" win32_registry: dependency: transitive description: name: win32_registry - sha256: e4506d60b7244251bc59df15656a3093501c37fb5af02105a944d73eb95be4c9 + sha256: "41fd8a189940d8696b1b810efb9abcf60827b6cbfab90b0c43e8439e3a39d85a" url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.1.2" window_to_front: dependency: transitive description: @@ -2135,10 +2496,10 @@ packages: dependency: transitive description: name: xdg_directories - sha256: f0c26453a2d47aa4c2570c6a033246a3fc62da2fe23c7ffdd0a7495086dc0247 + sha256: "589ada45ba9e39405c198fe34eb0f607cddb2108527e658136120892beac46d2" url: "https://pub.dev" source: hosted - version: "1.0.2" + version: "1.0.3" xml: dependency: transitive description: @@ -2156,5 +2517,5 @@ packages: source: hosted version: "3.1.2" sdks: - dart: ">=3.1.0-185.0.dev <4.0.0" - flutter: ">=3.10.0" + dart: ">=3.2.0-194.0.dev <4.0.0" + flutter: ">=3.13.0" diff --git a/pubspec.yaml b/pubspec.yaml index 2c4f3f9fe..f0275779f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,98 +1,119 @@ name: fluffychat -description: Chat with your friends. +description: Learn a language while texting your friends. publish_to: none -# On version bump also increase the build number for F-Droid -version: 1.14.5+3520 +version: 1.11.2+3453 environment: sdk: ">=3.0.0 <4.0.0" dependencies: - adaptive_dialog: ^1.9.0-x-macos-beta.1 - animations: ^2.0.7 - archive: ^3.3.9 - badges: ^3.1.1 - blurhash_dart: ^1.1.0 + adaptive_dialog: ^1.10.0 + animations: ^2.0.8 + archive: ^3.4.9 + async: ^2.11.0 + badges: ^3.1.2 + blurhash_dart: ^1.2.1 callkeep: ^0.3.2 - chewie: ^1.3.6 - collection: ^1.16.0 + chewie: ^1.7.1 + collection: ^1.17.2 + connectivity_plus: ^3.0.2 + country_picker: ^2.0.20 + csv: ^5.0.2 cupertino_icons: any - desktop_drop: ^0.4.0 + desktop_drop: ^0.4.4 desktop_lifecycle: ^0.1.0 desktop_notifications: ^0.6.3 - device_info_plus: ^9.0.2 - dynamic_color: ^1.6.0 - emoji_picker_flutter: ^1.5.1 + device_info_plus: ^9.1.0 + dynamic_color: ^1.6.8 + emoji_picker_flutter: ^1.6.3 emoji_proposal: ^0.0.1 emojis: ^0.9.9 #fcm_shared_isolate: ^0.1.0 - file_picker: ^5.3.0 + file_picker: ^6.1.1 + fl_chart: ^0.61.0 + firebase_analytics: ^10.2.1 + firebase_core: ^2.10.0 + firebase_messaging: ^14.4.1 flutter: sdk: flutter flutter_app_badger: ^1.5.0 + flutter_app_lock: ^3.0.0 flutter_blurhash: ^0.7.0 flutter_cache_manager: ^3.3.0 + flutter_dotenv: ^5.0.2 + fcm_shared_isolate: + path: pangea_packages/fcm_shared_isolate flutter_foreground_task: ^6.0.0+1 flutter_highlighter: ^0.1.1 flutter_html: ^3.0.0-beta.2 flutter_html_table: ^3.0.0-beta.2 flutter_linkify: ^6.0.0 - flutter_local_notifications: ^15.1.0+1 + flutter_local_notifications: ^16.1.0 flutter_localizations: sdk: flutter flutter_map: ^4.0.0 flutter_math_fork: ^0.7.1 - flutter_olm: ^1.2.0 + flutter_olm: 1.3.2 # Keep in sync with scripts/prepare-web.sh ! 1.4.0 does currently not build on Android flutter_openssl_crypto: ^0.1.0 flutter_ringtone_player: ^3.1.1 - flutter_secure_storage: ^8.0.0 - flutter_typeahead: ^4.3.2 - flutter_web_auth_2: ^2.1.1 - flutter_webrtc: ^0.9.37 - future_loading_dialog: ^0.2.3 + flutter_secure_storage: ^9.0.0 + flutter_svg: ^2.0.0+1 + flutter_typeahead: ^4.8.0 + flutter_web_auth_2: ^3.0.3 + flutter_webrtc: ^0.9.46 + future_loading_dialog: ^0.3.0 geolocator: ^7.6.2 - go_router: ^10.0.0 + get_storage: ^2.1.1 + go_router: ^12.1.1 hive: ^2.2.3 hive_flutter: ^1.1.0 http: ^0.13.4 image_picker: ^1.0.0 + in_app_purchase: ^3.1.5 intl: any just_audio: ^0.9.30 + jwt_decode: ^0.3.1 keyboard_shortcuts: ^0.1.4 + language_tool: ^2.1.1 latlong2: ^0.8.1 linkify: ^5.0.0 - matrix: ^0.22.3 + matrix: ^0.22.6 matrix_homeserver_recommendations: ^0.3.0 native_imaging: ^0.1.0 + new_version_plus: ^0.0.10 + open_file: ^3.3.2 package_info_plus: ^4.0.0 pasteboard: ^0.2.0 path_provider: ^2.0.9 - permission_handler: ^10.0.0 + permission_handler: ^11.0.1 provider: ^6.0.2 punycode: ^1.0.0 + purchases_flutter: ^5.6.0 qr_code_scanner: ^1.0.0 qr_flutter: ^4.0.0 receive_sharing_intent: ^1.4.5 - record: ^4.4.4 + record: 4.4.4 # Upgrade to 5 currently breaks playing on iOS scroll_to_index: ^3.0.1 - share_plus: ^7.0.0 + sentry_flutter: ^7.4.0 + share_plus: ^7.2.1 shared_preferences: ^2.2.0 # Pinned because https://github.com/flutter/flutter/issues/118401 slugify: ^2.0.0 swipe_to_action: ^0.2.0 + syncfusion_flutter_xlsio: ^22.2.9 tor_detector_web: ^1.1.0 uni_links: ^0.5.1 - unifiedpush: ^5.0.0 - universal_html: ^2.0.8 - url_launcher: ^6.0.20 - vibration: ^1.7.4-nullsafety.0 + unifiedpush: ^5.0.1 + universal_html: ^2.2.4 + url_launcher: ^6.2.1 + vibration: ^1.8.3 video_compress: ^3.1.1 - video_player: ^2.2.18 - wakelock_plus: ^1.1.1 + video_player: ^2.8.1 + wakelock_plus: ^1.1.3 webrtc_interface: ^1.0.13 dev_dependencies: dart_code_metrics: ^5.7.5 - flutter_lints: ^2.0.1 + flutter_lints: ^3.0.0 flutter_native_splash: ^2.0.3+1 flutter_test: sdk: flutter @@ -111,7 +132,10 @@ flutter: generate: true uses-material-design: true assets: + - .env - assets/ + - assets/pangea/ + - assets/pangea/bot_faces/ - assets/sounds/ - assets/js/ - assets/js/package/ @@ -130,12 +154,21 @@ flutter: - family: NotoEmoji fonts: - asset: fonts/NotoEmoji/NotoColorEmoji.ttf + # Pangea + - family: Inconsolata + fonts: + - asset: fonts/Inconsolata/Inconsolata-Regular.ttf + - asset: fonts/Inconsolata/Inconsolata-Light.ttf + style: italic + - asset: fonts/Inconsolata/Inconsolata-Bold.ttf + weight: 700 + # Pangea msix_config: display_name: FluffyChat publisher_display_name: FluffyChat publisher: CN=FluffyChat, O=Head of bad integration tests, L=Matrix, S=Internet, C=EU - identity_name: chat.fluffy.fluffychat + identity_name: com.talktolearn.chat logo_path: assets\logo.png capabilities: internetClient, location, microphone, webcam protocol_activation: https @@ -145,6 +178,18 @@ msix_config: install_certificate: false dependency_overrides: + # https://github.com/fluttercommunity/flutter_blurhash/pull/58 + flutter_blurhash: + git: + url: https://github.com/Craftplacer/flutter_blurhash.git + ref: eb9565f9d5731d4729bd7605510cec0f9e172e5f + # https://github.com/simpleclub-extended/flutter_math_fork/pull/87 + flutter_math_fork: + git: + url: https://github.com/The-Redhat/flutter_math_fork.git + ref: 3442b36a436880ce1c023e25c868d6f4004c4c24 + # Until https://github.com/mogol/flutter_secure_storage/issues/616 is fixed + flutter_secure_storage_linux: 1.1.3 geolocator_android: hosted: name: geolocator_android diff --git a/scripts/.credentials b/scripts/.credentials new file mode 100644 index 000000000..2adef4ff8 --- /dev/null +++ b/scripts/.credentials @@ -0,0 +1 @@ +DEEPL_AUTH_KEY=3e0060e0-a0c5-008f-ca16-fd92d80bec5d \ No newline at end of file diff --git a/scripts/build-android-apk.sh b/scripts/build-android-apk.sh new file mode 100644 index 000000000..4b1b641be --- /dev/null +++ b/scripts/build-android-apk.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash +flutter pub get +flutter build apk --release +mkdir -p build/android +cp build/app/outputs/apk/release/app-release.apk build/android/ diff --git a/scripts/build-android-debug.sh b/scripts/build-android-debug.sh new file mode 100644 index 000000000..5c2744a4c --- /dev/null +++ b/scripts/build-android-debug.sh @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +flutter build apk --debug diff --git a/scripts/build-ios.sh b/scripts/build-ios.sh old mode 100755 new mode 100644 diff --git a/scripts/build-linux.sh b/scripts/build-linux.sh new file mode 100644 index 000000000..e1df0e603 --- /dev/null +++ b/scripts/build-linux.sh @@ -0,0 +1,5 @@ +#!/bin/sh -ve +flutter config --enable-linux-desktop +flutter clean +flutter pub get +flutter build linux --release -v diff --git a/scripts/build-macos.sh b/scripts/build-macos.sh old mode 100755 new mode 100644 diff --git a/scripts/build-olm-windows.sh b/scripts/build-olm-windows.sh old mode 100755 new mode 100644 diff --git a/scripts/build-web.sh b/scripts/build-web.sh new file mode 100755 index 000000000..603a84301 --- /dev/null +++ b/scripts/build-web.sh @@ -0,0 +1,6 @@ +#!/bin/sh -ve +flutter config --enable-web +flutter clean +flutter pub get +flutter build web --dart-define=FLUTTER_WEB_CANVASKIT_URL=canvaskit/ --source-maps --base-href "/client/" +# flutter build web --release --verbose --source-maps --dart-define=SENTRY_RELEASE=$CI_COMMIT_SHA diff --git a/scripts/code_analyze.sh b/scripts/code_analyze.sh new file mode 100644 index 000000000..c0249a7c5 --- /dev/null +++ b/scripts/code_analyze.sh @@ -0,0 +1,8 @@ +#!/bin/sh -ve +flutter pub get +flutter pub run import_sorter:main --no-comments --exit-if-changed +flutter format lib/ test/ --set-exit-if-changed +git apply ./scripts/enable-android-google-services.patch +flutter pub get +flutter analyze +flutter pub run dart_code_metrics:metrics lib -r gitlab > code-quality-report.json || true \ No newline at end of file diff --git a/scripts/create_fdroid_repos.sh b/scripts/create_fdroid_repos.sh old mode 100755 new mode 100644 diff --git a/scripts/download-web-stable.sh b/scripts/download-web-stable.sh new file mode 100644 index 000000000..8467d1bf0 --- /dev/null +++ b/scripts/download-web-stable.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +GITLAB_PROJECT_ID="16112282" + +PIPELINE="$(curl https://gitlab.com/api/v4/projects/${GITLAB_PROJECT_ID}/pipelines\?scope=tags\&status=success\&order_by=updated_at | jq '.[].id' | head -n1)" +JOB="$(curl https://gitlab.com/api/v4/projects/${GITLAB_PROJECT_ID}/pipelines/${PIPELINE}/jobs | jq -r '.[] | select(.name == "build_web").id')" + +wget --output-document web.zip https://gitlab.com/api/v4/projects/${GITLAB_PROJECT_ID}/jobs/${JOB}/artifacts + +unzip web.zip + +mv build/web stable diff --git a/scripts/enable-android-google-services.patch b/scripts/enable-android-google-services.patch index ab4ec8a6a..95dfaa1ff 100644 --- a/scripts/enable-android-google-services.patch +++ b/scripts/enable-android-google-services.patch @@ -2,7 +2,7 @@ diff --git a/android/app/build.gradle b/android/app/build.gradle index 001fbd72..339b35af 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle -@@ -68,6 +68,10 @@ android { +@@ -70,6 +70,10 @@ } release { signingConfig signingConfigs.release @@ -12,7 +12,7 @@ index 001fbd72..339b35af 100644 + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } - } + // https://stackoverflow.com/a/77494454/8222484 @@ -78,8 +82,11 @@ flutter { dependencies { @@ -123,11 +123,11 @@ index 85aa8647..3b7e09e7 100644 } diff --git a/lib/utils/background_push.dart b/lib/utils/background_push.dart -index cd79b0ab..c2db0f1e 100644 +index 8e67ae92..da4da5c3 100644 --- a/lib/utils/background_push.dart +++ b/lib/utils/background_push.dart @@ -39,7 +39,7 @@ import '../config/setting_keys.dart'; - import 'famedlysdk_store.dart'; + import '../widgets/matrix.dart'; import 'platform_infos.dart'; -//import 'package:fcm_shared_isolate/fcm_shared_isolate.dart'; @@ -135,7 +135,7 @@ index cd79b0ab..c2db0f1e 100644 class NoTokenException implements Exception { String get cause => 'Cannot get firebase token'; -@@ -65,7 +65,7 @@ class BackgroundPush { +@@ -64,7 +64,7 @@ class BackgroundPush { final pendingTests = >{}; @@ -149,11 +149,11 @@ index 6999d0b8..b2c9144f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -26,7 +26,7 @@ dependencies: - emoji_picker_flutter: ^1.5.1 + emoji_picker_flutter: ^1.6.3 emoji_proposal: ^0.0.1 emojis: ^0.9.9 - #fcm_shared_isolate: ^0.1.0 + fcm_shared_isolate: ^0.1.0 - file_picker: ^5.3.0 + file_picker: ^6.1.1 flutter: sdk: flutter diff --git a/scripts/generate_command_hints_glue.sh b/scripts/generate_command_hints_glue.sh old mode 100755 new mode 100644 diff --git a/scripts/integration-check-release-build.sh b/scripts/integration-check-release-build.sh old mode 100755 new mode 100644 diff --git a/scripts/integration-create-environment-variables.sh b/scripts/integration-create-environment-variables.sh old mode 100755 new mode 100644 diff --git a/scripts/integration-prepare-alpine.sh b/scripts/integration-prepare-alpine.sh new file mode 100644 index 000000000..f4a57b6d5 --- /dev/null +++ b/scripts/integration-prepare-alpine.sh @@ -0,0 +1,2 @@ +#!/usr/bin/env bash +apk update && apk add docker drill grep \ No newline at end of file diff --git a/scripts/integration-prepare-homeserver.sh b/scripts/integration-prepare-homeserver.sh old mode 100755 new mode 100644 diff --git a/scripts/integration-prepare-host.sh b/scripts/integration-prepare-host.sh old mode 100755 new mode 100644 diff --git a/scripts/integration-server-conduit.sh b/scripts/integration-server-conduit.sh old mode 100755 new mode 100644 diff --git a/scripts/integration-server-dendrite.sh b/scripts/integration-server-dendrite.sh old mode 100755 new mode 100644 diff --git a/scripts/integration-server-synapse.sh b/scripts/integration-server-synapse.sh old mode 100755 new mode 100644 diff --git a/scripts/integration-start-avd.sh b/scripts/integration-start-avd.sh old mode 100755 new mode 100644 diff --git a/scripts/open-mr.sh b/scripts/open-mr.sh new file mode 100644 index 000000000..4af2c7128 --- /dev/null +++ b/scripts/open-mr.sh @@ -0,0 +1,37 @@ +#!/bin/bash -ve + +# source: https://about.gitlab.com/blog/2017/09/05/how-to-automatically-create-a-new-mr-on-gitlab-with-gitlab-ci/ + +# Extract the host where the server is running, and add the URL to the APIs +[[ $HOST =~ ^https?://[^/]+ ]] && HOST="${BASH_REMATCH[0]}/api/v4/projects/" + +# Look which is the default branch +TARGET_BRANCH=`curl --silent "${HOST}${CI_PROJECT_ID}" --header "PRIVATE-TOKEN:${PRIVATE_TOKEN}" | python3 -c "import sys, json; print(json.load(sys.stdin)['default_branch'])"`; + +# The description of our new MR, we want to remove the branch after the MR has +# been closed +BODY="{ + \"id\": ${CI_PROJECT_ID}, + \"source_branch\": \"${UPDATE_BRANCH}\", + \"target_branch\": \"${TARGET_BRANCH}\", + \"remove_source_branch\": true, + \"title\": \"chore: automated dependency update\" +}"; + +# Require a list of all the merge request and take a look if there is already +# one with the same source branch +LISTMR=`curl --silent "${HOST}${CI_PROJECT_ID}/merge_requests?state=opened" --header "PRIVATE-TOKEN:${PRIVATE_TOKEN}"`; +COUNTBRANCHES=`echo ${LISTMR} | grep -o "\"source_branch\":\"${UPDATE_BRANCH}\"" | wc -l`; + +# No MR found, let's create a new one +if [ ${COUNTBRANCHES} -eq "0" ]; then + curl -X POST "${HOST}${CI_PROJECT_ID}/merge_requests" \ + --header "PRIVATE-TOKEN:${PRIVATE_TOKEN}" \ + --header "Content-Type: application/json" \ + --data "${BODY}"; + + echo "Opened a new dependency update MR." + exit; +fi + +echo "No new merge request opened."; diff --git a/scripts/prepare-fdroid.sh b/scripts/prepare-fdroid.sh old mode 100755 new mode 100644 diff --git a/scripts/prepare-macos.sh b/scripts/prepare-macos.sh old mode 100755 new mode 100644 diff --git a/scripts/prepare-web.sh b/scripts/prepare-web.sh index 0c4283e69..798bbe37f 100755 --- a/scripts/prepare-web.sh +++ b/scripts/prepare-web.sh @@ -1,6 +1,10 @@ #!/bin/sh -ve rm -r assets/js/package -cd assets/js/ && curl -L $(curl -s 'https://api.github.com/repos/famedly/olm/releases' | jq -r '.[0] | .assets | .[0] | .browser_download_url') > olm.zip && cd ../../ + +OLM_VERSION=$(cat pubspec.yaml | yq .dependencies.flutter_olm) +DOWNLOAD_PATH="https://github.com/famedly/olm/releases/download/v$OLM_VERSION/olm.zip" + +cd assets/js/ && curl -L $DOWNLOAD_PATH > olm.zip && cd ../../ cd assets/js/ && unzip olm.zip && cd ../../ cd assets/js/ && rm olm.zip && cd ../../ -cd assets/js/ && mv javascript package && cd ../../ +cd assets/js/ && mv javascript package && cd ../../ \ No newline at end of file diff --git a/scripts/release-ios-testflight.sh b/scripts/release-ios-testflight.sh old mode 100755 new mode 100644 index a30d3e5a4..e3f1a109a --- a/scripts/release-ios-testflight.sh +++ b/scripts/release-ios-testflight.sh @@ -1,5 +1,7 @@ #!/bin/sh -ve git apply ./scripts/enable-android-google-services.patch +rm -rf fonts/NotoEmoji +yq -i 'del( .flutter.fonts[] | select(.family == "NotoEmoji") )' pubspec.yaml flutter clean flutter pub get cd ios diff --git a/scripts/release-playstore-beta.sh b/scripts/release-playstore-beta.sh new file mode 100644 index 000000000..7d4dcd4b0 --- /dev/null +++ b/scripts/release-playstore-beta.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash +flutter pub get +flutter build appbundle --target-platform android-arm,android-arm64,android-x64 +mkdir -p build/android +cp build/app/outputs/bundle/release/app-release.aab build/android/ +cd android +bundle install +bundle update fastlane +bundle exec fastlane deploy_internal_test +cd .. diff --git a/scripts/release-playstore.sh b/scripts/release-playstore.sh new file mode 100644 index 000000000..f78d38cb5 --- /dev/null +++ b/scripts/release-playstore.sh @@ -0,0 +1,9 @@ +#!/bin/sh -ve +RELEASE_TYPE=$(echo $CI_COMMIT_TAG | grep -oE "[a-z]+") +cd android +if [ "$RELEASE_TYPE" = "rc" ]; then + bundle exec fastlane deploy_candidate +else + bundle exec fastlane deploy_release +fi +cd .. diff --git a/scripts/temp.49243.json b/scripts/temp.49243.json new file mode 100644 index 000000000..e69de29bb diff --git a/scripts/translate.sh b/scripts/translate.sh new file mode 100644 index 000000000..425d95352 --- /dev/null +++ b/scripts/translate.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +# 1. Define DeepL credentials +DEEPL_AUTH_KEY=$(awk -F "=" '/DEEPL_AUTH_KEY/ {print $2}' ./.credentials) +DEEPL_API_URL="https://api.deepl.com/v2/translate" +TARGET_LANG="es" + +# 2. Extract missing translation keys +MISSING_KEYS=$(jq -r '.es[]' ../needed-translations.txt) + +# 3. Get English copy for missing keys and translate them +for key in $MISSING_KEYS; do + EN_COPY=$(jq -r ".[\"$key\"]" ../assets/l10n/intl_en.arb) + + # 4. Call DeepL for the translations + TRANSLATED_TEXT=$(curl -s -X POST "${DEEPL_API_URL}" \ + -H "Authorization: DeepL-Auth-Key ${DEEPL_AUTH_KEY}" \ + -d "text=${EN_COPY}" \ + -d "target_lang=${TARGET_LANG}" | jq -r '.translations[0].text') + + # 5. Save them to the Spanish translation file + jq ".[\"$key\"] = \"$TRANSLATED_TEXT\"" ../assets/l10n/intl_es.arb > temp.json && mv temp.json ../assets/l10n/intl_$TARGET_LANG.arb + echo "Translated $key: $TRANSLATED_TEXT" +done + +echo "Translations saved to ../assets/l10n/intl_$TARGET_LANG.arb" \ No newline at end of file diff --git a/scripts/update-dependencies.sh b/scripts/update-dependencies.sh old mode 100755 new mode 100644 diff --git a/scripts/upload-sentry.sh b/scripts/upload-sentry.sh new file mode 100755 index 000000000..569d1aad5 --- /dev/null +++ b/scripts/upload-sentry.sh @@ -0,0 +1,22 @@ +#!/bin/sh -ve + +# Build a release version of the app for a platform and upload symbols +OUTPUT_FOLDER_WEB=./build/web/ +SENTRY_RELEASE=$CI_COMMIT_SHA +SENTRY_PROJECT="client" +SENTRY_ORG="pangea-chat" + +echo "[run] Uploading sourcemaps for $SENTRY_RELEASE" +sentry-cli releases new $SENTRY_RELEASE +sentry-cli releases set-commits $CI_COMMIT_SHA --auto +sentry-cli releases files $SENTRY_RELEASE upload-sourcemaps . \ + --ext dart \ + --rewrite + +(cd $OUTPUT_FOLDER_WEB +sentry-cli releases files $SENTRY_RELEASE upload-sourcemaps . \ + --ext map \ + --ext js \ + --rewrite) + +sentry-cli releases finalize $SENTRY_RELEASE diff --git a/snap/gui/fluffychat.desktop b/snap/gui/fluffychat.desktop deleted file mode 100755 index 886148753..000000000 --- a/snap/gui/fluffychat.desktop +++ /dev/null @@ -1,9 +0,0 @@ -[Desktop Entry] -Name=FluffyChat -GenericName=Matrix Client -Comment=Chat with your friends -Exec=fluffychat -Icon=${SNAP}/meta/gui/fluffychat.png -Terminal=false -Type=Application -Categories=Network;Chat;InstantMessaging; diff --git a/snap/gui/fluffychat.png b/snap/gui/fluffychat.png deleted file mode 100644 index e00764939..000000000 Binary files a/snap/gui/fluffychat.png and /dev/null differ diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml deleted file mode 100644 index 45399c3a2..000000000 --- a/snap/snapcraft.yaml +++ /dev/null @@ -1,111 +0,0 @@ -name: fluffychat -title: FluffyChat -base: core22 -version: git -license: AGPL-3.0 -summary: The cutest messenger in the Matrix network -description: | - FluffyChat is an open source, nonprofit and cute matrix messenger app. The app is easy to use but secure and decentralized. - - - ## Features - - - Send all kinds of messages, images and files - - Voice messages - - Location sharing - - Push notifications - - Unlimited private and public group chats - - Public channels with thousands of participants - - Feature rich group moderation including all matrix features - - Discover and join public groups - - Dark mode - - Hides complexity of Matrix IDs behind simple QR codes - - Custom emotes and stickers - - Video calls via sharing links to Jitsi - - Spaces - - Compatible with Element, Nheko, NeoChat and all other Matrix apps - - End to end encryption - - Emoji verification & cross signing - - And much more... - - - ## FluffyChat comes with a dream - - Imagine a world where everyone can choose the messenger they like and is still able to chat with all of their friends. - - A world where there are no companies spying on you when you send selfies to friends and lovers. - - And a world where apps are made for fluffyness and not for profit. ♥ - - Join the community: https://matrix.to/#/#fluffychat:matrix.org - Website: http://fluffychat.im - Microblog: https://mastodon.art/@krille - -grade: stable -confinement: strict - -architectures: - - build-on: amd64 - - build-on: arm64 - -parts: - olm: - plugin: cmake - cmake-parameters: - - -DCMAKE_INSTALL_PREFIX=/usr - source: https://gitlab.matrix.org/matrix-org/olm.git - source-type: git - source-tag: '3.2.14' - build-packages: - - g++ - - zenity-integration: - plugin: nil - stage-snaps: - - zenity-integration - - fluffychat: - plugin: flutter - source: . - override-build: | - # Workaround for Flutter build error: - rm -rf build - craftctl default - build-packages: - - libjsoncpp-dev - - curl - stage-packages: - - libsecret-1-dev - - libjsoncpp-dev - -slots: - dbus-svc: - interface: dbus - bus: session - name: chat.fluffy.fluffychat - -apps: - fluffychat: - command: fluffychat - extensions: [gnome] - plugs: - - audio-playback - - desktop - - desktop-legacy - - home - - network - - network-manager - - network-manager-observe - - opengl - - removable-media - - browser-support - - password-manager-service - slots: - - dbus-svc - # Workaround for: - # https://github.com/flutter-webrtc/flutter-webrtc/issues/1212#issuecomment-1611899344 - environment: - XDG_DATA_HOME: $SNAP_USER_DATA - XDG_DATA_DIRS: $SNAP/usr/share - GDK_GL: gles - LD_LIBRARY_PATH: "$LD_LIBRARY_PATH:$SNAP/lib:$SNAP/usr/lib/$SNAPCRAFT_ARCH_TRIPLET" \ No newline at end of file diff --git a/test/choreographer_test.dart b/test/choreographer_test.dart new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/test/choreographer_test.dart @@ -0,0 +1 @@ + diff --git a/test_driver/integration_test.dart b/test_driver/integration_test.dart new file mode 100644 index 000000000..b38629cca --- /dev/null +++ b/test_driver/integration_test.dart @@ -0,0 +1,3 @@ +import 'package:integration_test/integration_test_driver.dart'; + +Future main() => integrationDriver(); diff --git a/web/favicon.png b/web/favicon.png index e062b83e7..9583e5e97 100644 Binary files a/web/favicon.png and b/web/favicon.png differ diff --git a/web/index.html b/web/index.html index 7ebfd6128..4e6f28e70 100644 --- a/web/index.html +++ b/web/index.html @@ -24,13 +24,20 @@ - + + + + - FluffyChat + + + Pangea Chat + + @@ -48,6 +55,9 @@ window.addEventListener('load', function (ev) { // Download main.dart.js _flutter.loader.loadEntrypoint({ + // #Pangea + entrypointUrl: "main.dart.js?v=" + serviceWorkerVersion, + // Pangea# serviceWorker: { serviceWorkerVersion: serviceWorkerVersion, }, @@ -60,13 +70,21 @@ }); - + +
+
+ +
+
+
+
diff --git a/web/splash/img/dark-1x.png b/web/splash/img/dark-1x.png index f4c0bdb92..66574aed8 100644 Binary files a/web/splash/img/dark-1x.png and b/web/splash/img/dark-1x.png differ diff --git a/web/splash/img/dark-2x.png b/web/splash/img/dark-2x.png index dafa3b707..5064d226c 100644 Binary files a/web/splash/img/dark-2x.png and b/web/splash/img/dark-2x.png differ diff --git a/web/splash/img/dark-3x.png b/web/splash/img/dark-3x.png index b627f5280..a66b9f972 100644 Binary files a/web/splash/img/dark-3x.png and b/web/splash/img/dark-3x.png differ diff --git a/web/splash/img/dark-4x.png b/web/splash/img/dark-4x.png index 0d1d2a74d..0c04404bb 100644 Binary files a/web/splash/img/dark-4x.png and b/web/splash/img/dark-4x.png differ diff --git a/web/splash/img/light-1x.png b/web/splash/img/light-1x.png index f4c0bdb92..66574aed8 100644 Binary files a/web/splash/img/light-1x.png and b/web/splash/img/light-1x.png differ diff --git a/web/splash/img/light-2x.png b/web/splash/img/light-2x.png index dafa3b707..5064d226c 100644 Binary files a/web/splash/img/light-2x.png and b/web/splash/img/light-2x.png differ diff --git a/web/splash/img/light-3x.png b/web/splash/img/light-3x.png index b627f5280..a66b9f972 100644 Binary files a/web/splash/img/light-3x.png and b/web/splash/img/light-3x.png differ diff --git a/web/splash/img/light-4x.png b/web/splash/img/light-4x.png index 0d1d2a74d..0c04404bb 100644 Binary files a/web/splash/img/light-4x.png and b/web/splash/img/light-4x.png differ diff --git a/web/splash/splash.js b/web/splash/splash.js new file mode 100644 index 000000000..898c454fb --- /dev/null +++ b/web/splash/splash.js @@ -0,0 +1,7 @@ +function removeSplashFromWeb() { + const elem = document.getElementById("splash"); + if (elem) { + elem.remove(); + } + document.body.style.background = "transparent"; +} diff --git a/web/splash/style.css b/web/splash/style.css index 455b79370..edfcec032 100644 --- a/web/splash/style.css +++ b/web/splash/style.css @@ -1,6 +1,7 @@ -body, html { - margin:0; - height:100%; +body, +html { + margin: 0; + height: 100%; background: #ffffff; background-image: url("img/light-background.png"); background-size: 100% 100%; @@ -16,22 +17,26 @@ body, html { } .contain { - display:block; - width:100%; height:100%; + display: block; + width: 100%; + height: 100%; object-fit: contain; } .stretch { - display:block; - width:100%; height:100%; + display: block; + width: 100%; + height: 100%; } .cover { - display:block; - width:100%; height:100%; + display: block; + width: 100%; + height: 100%; object-fit: cover; } +/* #Pangea @media (prefers-color-scheme: dark) { body { margin:0; @@ -41,3 +46,45 @@ body, html { background-size: 100% 100%; } } +*/ + +@media (prefers-color-scheme: dark) { + body { + margin: 0; + height: 100%; + background: #000000; + background-size: 100% 100%; + } +} + +.image { + width: 100%; +} + +.custom-loader { + --d: 88px; + width: 3px; + height: 3px; + position: absolute; + top: 85px; + left: 85px; + border-radius: 100%; + color: #8C5EE8; + box-shadow: + calc(1*var(--d)) calc(0*var(--d)) 0 0, + calc(0.707*var(--d)) calc(0.707*var(--d)) 0 2px, + calc(0*var(--d)) calc(1*var(--d)) 0 4px, + calc(-0.707*var(--d)) calc(0.707*var(--d)) 0 6px, + calc(-1*var(--d)) calc(0*var(--d)) 0 8px, + calc(-0.707*var(--d)) calc(-0.707*var(--d))0 10px, + calc(0*var(--d)) calc(-1*var(--d)) 0 12px; + animation: s7 1s infinite steps(8); +} + +@keyframes s7 { + 100% { + transform: rotate(1turn) + } +} + +/* Pangea# */ \ No newline at end of file diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index c56ef092b..3f7add542 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -6,21 +6,26 @@ #include "generated_plugin_registrant.h" +#include #include #include #include #include #include +#include #include #include #include #include #include +#include #include #include #include void RegisterPlugins(flutter::PluginRegistry* registry) { + ConnectivityPlusWindowsPluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("ConnectivityPlusWindowsPlugin")); DesktopDropPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("DesktopDropPlugin")); DesktopLifecyclePluginRegisterWithRegistrar( @@ -31,6 +36,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) { registry->GetRegistrarForPlugin("EmojiPickerFlutterPluginCApi")); FileSelectorWindowsRegisterWithRegistrar( registry->GetRegistrarForPlugin("FileSelectorWindows")); + FirebaseCorePluginCApiRegisterWithRegistrar( + registry->GetRegistrarForPlugin("FirebaseCorePluginCApi")); FlutterSecureStorageWindowsPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("FlutterSecureStorageWindowsPlugin")); FlutterWebRTCPluginRegisterWithRegistrar( @@ -41,6 +48,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) { registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin")); RecordWindowsPluginCApiRegisterWithRegistrar( registry->GetRegistrarForPlugin("RecordWindowsPluginCApi")); + SentryFlutterPluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("SentryFlutterPlugin")); SharePlusWindowsPluginCApiRegisterWithRegistrar( registry->GetRegistrarForPlugin("SharePlusWindowsPluginCApi")); UrlLauncherWindowsRegisterWithRegistrar( diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index 27cc5bc0d..f0c310aec 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -3,16 +3,19 @@ # list(APPEND FLUTTER_PLUGIN_LIST + connectivity_plus desktop_drop desktop_lifecycle dynamic_color emoji_picker_flutter file_selector_windows + firebase_core flutter_secure_storage_windows flutter_webrtc pasteboard permission_handler_windows record_windows + sentry_flutter share_plus url_launcher_windows window_to_front