diff --git a/.github/workflows/auto_pull_request.yaml b/.github/workflows/auto_pull_request.yaml new file mode 100644 index 0000000000..cf6bb228c3 --- /dev/null +++ b/.github/workflows/auto_pull_request.yaml @@ -0,0 +1,41 @@ +name: Auto Pull Request + +#on: +# schedule: +# - cron: '0 0 * * 0' # Run at midnight (00:00) every Sunday + +on: + push: + branches: + - auto-pr # Change this to match your main branch name + +jobs: + auto_pull_request: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Test + run: echo ${{ github.head_ref }}.${{ github.sha }} + + - name: Pull changes from FluffyChat + run: | + git config --global user.email "${{ vars.CI_EMAIL }}" + git config --global user.name "${{ vars.CI_USERNAME }}" + git remote add fluffychat https://github.com/krille-chan/fluffychat + git fetch fluffychat main + git merge --no-edit fluffychat/main --allow-unrelated-histories + + - name: Push changes + run: | + git push origin HEAD:main-update-fluffy-automatic + + - name: Create Pull Request + uses: peter-evans/create-pull-request@v3 + with: + token: ${{ secrets.GH_TOKEN }} + title: Updated fork with new fluffy changes + body: | + This is an automatic PR created by GitHub Actions. + branch: main diff --git a/.github/workflows/integrate.yaml b/.github/workflows/integrate.yaml index bc0db0caea..784736a4d0 100644 --- a/.github/workflows/integrate.yaml +++ b/.github/workflows/integrate.yaml @@ -19,22 +19,23 @@ jobs: run: dart format lib/ test/ --set-exit-if-changed - name: Check import formatting run: dart run import_sorter:main --no-comments --exit-if-changed + - name: Check license compliance + run: dart run license_checker check-licenses -c licenses.yaml --problematic - run: flutter analyze - name: Apply google services patch run: git apply ./scripts/enable-android-google-services.patch - run: flutter analyze - run: flutter test - - name: Check for unused localization strings - run: flutter pub run translations_cleaner list-unused-terms -a build_debug_apk: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: cat .github/workflows/versions.env >> $GITHUB_ENV - - uses: actions/setup-java@v1 + - uses: actions/setup-java@v4 with: java-version: ${{ env.JAVA_VERSION }} + distribution: "zulu" - uses: subosito/flutter-action@v2 with: flutter-version: ${{ env.FLUTTER_VERSION }} @@ -66,7 +67,7 @@ jobs: flutter-version: ${{ env.FLUTTER_VERSION }} cache: true - name: Install dependencies - run: sudo apt-get update && sudo apt-get install curl clang cmake ninja-build pkg-config libgtk-3-dev libblkid-dev liblzma-dev libjsoncpp-dev cmake-data libsecret-1-dev libsecret-1-0 librhash0 -y + run: sudo apt-get update && sudo apt-get install curl clang cmake ninja-build pkg-config libgtk-3-dev libblkid-dev liblzma-dev libjsoncpp-dev cmake-data libsecret-1-dev libsecret-1-0 librhash0 libssl-dev -y - run: flutter pub get - run: flutter build linux --target-platform linux-x64 @@ -80,6 +81,9 @@ jobs: flutter-version: ${{ env.FLUTTER_VERSION }} cache: true - name: Setup Xcode version - uses: maxim-lobanov/setup-xcode@v1.5.1 + uses: maxim-lobanov/setup-xcode@v1.6.0 + with: + xcode-version: latest + - run: brew install sqlcipher - run: flutter pub get - run: flutter build ios --no-codesign diff --git a/.github/workflows/main_deploy.yaml b/.github/workflows/main_deploy.yaml index 6aea98c3e4..bb3bdf93d1 100644 --- a/.github/workflows/main_deploy.yaml +++ b/.github/workflows/main_deploy.yaml @@ -19,6 +19,10 @@ jobs: - uses: subosito/flutter-action@v2 with: flutter-version: ${{ env.FLUTTER_VERSION }} + - 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 web run: ./scripts/prepare-web.sh diff --git a/.github/workflows/process_tags.yaml b/.github/workflows/process_tags.yaml deleted file mode 100644 index 0aba2538f8..0000000000 --- a/.github/workflows/process_tags.yaml +++ /dev/null @@ -1,28 +0,0 @@ -on: - push: - tags: - - "v*" - - "rc*" - -name: Process Tags - -jobs: - build: - name: Create Release - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - 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 a78ec2574a..8bea1bf252 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -9,6 +9,10 @@ concurrency: group: release_workflow cancel-in-progress: true +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + jobs: build_web: runs-on: ubuntu-latest @@ -22,6 +26,10 @@ jobs: cache: true - name: Install dependencies run: sudo apt-get update && sudo apt-get install nodejs -y + - 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 web run: ./scripts/prepare-web.sh @@ -55,9 +63,10 @@ jobs: steps: - uses: actions/checkout@v2 - run: cat .github/workflows/versions.env >> $GITHUB_ENV - - uses: actions/setup-java@v1 + - uses: actions/setup-java@v4 with: java-version: ${{ env.JAVA_VERSION }} + distribution: 'zulu' - uses: subosito/flutter-action@v2 with: flutter-version: ${{ env.FLUTTER_VERSION }} @@ -97,7 +106,7 @@ jobs: flutter-version: ${{ env.FLUTTER_VERSION }} cache: true - name: Install dependencies - run: sudo apt-get update && sudo apt-get install curl clang cmake ninja-build pkg-config libgtk-3-dev libblkid-dev liblzma-dev libjsoncpp-dev cmake-data libsecret-1-dev libsecret-1-0 librhash0 -y + run: sudo apt-get update && sudo apt-get install curl clang cmake ninja-build pkg-config libgtk-3-dev libblkid-dev liblzma-dev libjsoncpp-dev cmake-data libsecret-1-dev libsecret-1-0 librhash0 libssl-dev -y - run: flutter pub get - run: flutter build linux --release --target-platform linux-x64 - name: Create archive @@ -118,9 +127,10 @@ jobs: steps: - uses: actions/checkout@v2 - run: cat .github/workflows/versions.env >> $GITHUB_ENV - - uses: actions/setup-java@v1 + - uses: actions/setup-java@v4 with: java-version: ${{ env.JAVA_VERSION }} + distribution: 'zulu' - uses: subosito/flutter-action@v2 with: flutter-version: ${{ env.FLUTTER_VERSION }} @@ -128,7 +138,7 @@ jobs: - name: Set up Ruby uses: ruby/setup-ruby@v1 with: - ruby-version: 2.7 + ruby-version: '3.3' - name: Install Fastlane run: gem install fastlane -NV - name: Apply Google Services Patch diff --git a/.github/workflows/versions.env b/.github/workflows/versions.env index ed14bbc6c3..a5bf6f315b 100644 --- a/.github/workflows/versions.env +++ b/.github/workflows/versions.env @@ -1,2 +1,2 @@ -FLUTTER_VERSION=3.16.7 -JAVA_VERSION=17 \ No newline at end of file +FLUTTER_VERSION=3.19.5 +JAVA_VERSION=17 diff --git a/.metadata b/.metadata index 9b76059518..572440b8e7 100644 --- a/.metadata +++ b/.metadata @@ -4,7 +4,7 @@ # This file should be version controlled. version: - revision: "efbf63d9c66b9f6ec30e9ad4611189aa80003d31" + revision: "abb292a07e20d696c4568099f918f6c5f330e6b0" channel: "stable" project_type: app @@ -13,26 +13,11 @@ project_type: app migration: platforms: - platform: root - create_revision: efbf63d9c66b9f6ec30e9ad4611189aa80003d31 - base_revision: efbf63d9c66b9f6ec30e9ad4611189aa80003d31 - - platform: android - create_revision: efbf63d9c66b9f6ec30e9ad4611189aa80003d31 - base_revision: efbf63d9c66b9f6ec30e9ad4611189aa80003d31 - - platform: ios - create_revision: efbf63d9c66b9f6ec30e9ad4611189aa80003d31 - base_revision: efbf63d9c66b9f6ec30e9ad4611189aa80003d31 + create_revision: abb292a07e20d696c4568099f918f6c5f330e6b0 + base_revision: abb292a07e20d696c4568099f918f6c5f330e6b0 - 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 + create_revision: abb292a07e20d696c4568099f918f6c5f330e6b0 + base_revision: abb292a07e20d696c4568099f918f6c5f330e6b0 # User provided section diff --git a/CHANGELOG.md b/CHANGELOG.md index 21ab86f3cb..7f3199c007 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,135 @@ +## v1.19.1 +Minor bugfix release for login with SSO on web. + +- feat: Show/hide third column in chat view (krille-chan) +- design: Adjust some colors in inputbar (krille-chan) +- fix: Login with SSO on web (krille-chan) +- fix: Make chat permission settings null and type safe (krille-chan) +- chore: do not use static openssl (ShootingStarDragons) +- refactor: Move room headers into appbar bottom field (krille-chan) +- refactor: new flutter only typing animation (krille-chan) + +## v1.19.0 +FluffyChat v1.19.0 features an improved design for message bubbles and a lot of fixes under the hood. + +- build: Update matrix dart sdk (Krille) +- build: Update to flutter 3.19.5 (krille-chan) +- chore: Add missing command hints (krille-chan) +- chore: Add pagekey to custom page builder (Krille) +- chore: Adjust design of typing indicator (Krille) +- chore: Adjust ticker of notifications for Android (Krille) +- chore: Calc blurhash in other thread (Krille) +- chore: Mark muted unread rooms with bold text (krille-chan) +- chore: More minimal matrix pill (Krille) +- chore: Try out CupertinoPage instead of custom transition in router (krille-chan) +- ci: add a license compliance check (lauren n. liberda) +- design: Connect bubbles from same sender (krille-chan) +- design: Display images in correct ratio in timeline (krille-chan) +- design: Make appbar in material you design for mobile mode (krille-chan) +- design: New sticker picker next to emoji picker (krille-chan) +- design: Nicer QR Code design (krille-chan) +- design: Nicer reactions design with size animations (Krille) +- feat: Add insert content via gboard (krille-chan) +- feat: Reply with one button in desktop (krille-chan) +- fix: Do not sync in background mode (krille-chan) +- fix: FluffyChat should assume m.change_password capabilitiy is supported if not present per spec (krille-chan) +- fix: never use root navigator for bottom sheets (The one with the braid) +- fix: Remove pantalaimon message with normal error message (krille-chan) +- fix: Search in spaces view (krille-chan) +- fix: Set read marker on web (Krille) +- fix: Point to correct path for auth.html so completing sso login flow no longer 404s (Gavin Mogan) +- refactor: Better logic for removing outdated notifications (Krille) +- refactor: Enhance logic when to mark room as read (krille-chan) +- refactor: Remove old aliases workaround (Krille) +- refactor: Sticker widget code (Krille) +- refactor: Use dart blurhash (Krille) +- Translated using Weblate (Basque) (xabirequejo) +- Translated using Weblate (Interlingua) (Software In Interlingua) + +## v1.18.0 +- feat: Add speed button for audioplayer (krille-chan) +- feat: enhanced send video functionality by adding toggle send original (Mubeen Rizvi) +- feat: add dialog to hide presence list with long-press (Marcus Hoffmann) +- feat: Add notification shortcuts to android (krille-chan) +- feat: make showing user presence info optional (Marcus Hoffmann) +- feat: Open chat on shortcut click on android (krille-chan) +- fix: BuildContext crash when joining room (krille-chan) +- fix: Export session (krille-chan) +- fix: Notifications open sometimes automatically on android (krille-chan) +- fix: Open room after join (krille-chan) +- fix: Open room by notification happened multiple times (krille-chan) +- fix: Open room links with event id (krille-chan) +- fix: properly initialize hideUnimportantStateEvents setting (Marcus Hoffmann) +- fix: Remove status msg not changeable from old cache (krille-chan) +- fix: use correct icons for chat pin/unpin (Marcus Hoffmann) +- fix: use correct icons for mark read/unread action (Marcus Hoffmann) +- build: Update Linux build files (krille-chan) +- build: Update to Flutter 3.19.1 (Krille) +- chore: Add more information to Person object in android notifications (krille-chan) +- chore: Thumbnail follow up for notifications (Krille) +- refactor: Better download UX with file picker for android and iOS (krille-chan) +- refactor: Use hashcode instead of string to id workaround for notifications (Krille) +- Added translation using Weblate (Belarusian) (kopatych) +- Added translation using Weblate (Interlingua) (Software In Interlingua) +- Translated using Weblate (Arabic) (Rex_sa) +- Translated using Weblate (Basque) (xabirequejo) +- Translated using Weblate (Chinese (Simplified)) (Poesty Li) +- Translated using Weblate (Chinese (Simplified)) (大王叫我来巡山) +- Translated using Weblate (Estonian) (Priit Jõerüüt) +- Translated using Weblate (Galician) (josé m) +- Translated using Weblate (German) (Benjamin Wagner) +- Translated using Weblate (Greek) (Benjamin Wagner) +- Translated using Weblate (Russian) (Benjamin Wagner) +- Translated using Weblate (Russian) (v1s7) +- Translated using Weblate (Ukrainian) (Ihor Hordiichuk) +- Translated using Weblate (Ukrainian) (Сергій) + +## v1.17.3 +- feat: New account data based wallpaper feature (Krille) +- build: Update dependencies (Krille) +- build: Update flutter to 3.16.9 (Krille) +- build: Update matrix dart sdk to 0.25.7 (Krille) +- build: Update minor versions (Krille) +- chore: Adjust status msg design (krille-chan) +- chore: Improved error handling for recovery key (Krille) +- chore: Make stickers smaller (Krille) +- chore: Wait for device keys before ask bootstrap (Krille) +- fix: Missing null check in public room bottom sheet (Krille) +- fix: onDragDone crashes when no files found (Krille) +- fix: Render tg-forward html tags (Krille) +- fix: Use HapticFeedback.selectionClick() for long press on message (Krille) +- fix: whitespaces sometimes encoded in html message (Krille) +- fix: Share invite links of public rooms (Krille) + +## v1.17.2 +Another minor bugfix release which also implements private read receipts. + +- feat: Implement private read receipts (krille-chan) +- feat: Join room by alias by tpying alias in searchbar (krille-chan) +- fix: Add cancel button to key request dialog (Krille) +- fix: Encode component for links correctly (Krille) +- fix: Forward arbitrary message content (krille-chan) +- fix: Open publicroombottomsheet by alias (krille-chan) +- docs: Add noto animated emojis link (krille-chan) +- docs: New website (krille-chan) +- build: Do not load emojis at initial start on web (krille-chan) +- build: Update flutter to 3.16.8 (krille-chan) +- build: Update sdk to 0.25.6 (Krille) +- chore: Add more explaining text for key verification (krille-chan) +- chore: Resort settings and add more description text (krille-chan) +- refactor: Dialog BuildContext (krille-chan) +- refactor: Use popupmenudivider instead of workaround (krille-chan) +- Translated using Weblate (Arabic) (Rex_sa) +- Translated using Weblate (Basque) (xabirequejo) +- Translated using Weblate (Chinese (Simplified)) (Poesty Li) +- Translated using Weblate (Estonian) (Priit Jõerüüt) +- Translated using Weblate (Galician) (josé m) +- Translated using Weblate (German) (nautilusx) +- Translated using Weblate (Russian) (v1s7) +- Translated using Weblate (Swedish) (Flat) +- Translated using Weblate (Ukrainian) (Ihor Hordiichuk) +- Translated using Weblate (Ukrainian) (Сергій) + ## v1.17.1 Minor bugfix release. diff --git a/assets/l10n/intl_ar.arb b/assets/l10n/intl_ar.arb index ab51372360..fb3ca0383c 100644 --- a/assets/l10n/intl_ar.arb +++ b/assets/l10n/intl_ar.arb @@ -1,2457 +1,2604 @@ { - "@@locale": "ar", - "@@last_modified": "2021-08-14 12:41:10.156221", - "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": {} - } - }, - "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": {} - } - }, - "banFromChat": "حظر من المحادثة", - "@banFromChat": { - "type": "text", - "placeholders": {} - }, - "banned": "محظور", - "@banned": { - "type": "text", - "placeholders": {} - }, - "bannedUser": "{username} حظر {targetName}", - "@bannedUser": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "blockDevice": "أُحظر الجهاز", - "@blockDevice": { - "type": "text", - "placeholders": {} - }, - "cancel": "ألغِ", - "@cancel": { - "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": {} - } - }, - "changeTheHomeserver": "غيّر الخادم", - "@changeTheHomeserver": { - "type": "text", - "placeholders": {} - }, - "changeTheme": "غيّر أسلوبك", - "@changeTheme": { - "type": "text", - "placeholders": {} - }, - "changeTheNameOfTheGroup": "غيِّر اسم المجموعة", - "@changeTheNameOfTheGroup": { - "type": "text", - "placeholders": {} - }, - "channelCorruptedDecryptError": "فسُد التشفير", - "@channelCorruptedDecryptError": { - "type": "text", - "placeholders": {} - }, - "chat": "محادثة", - "@chat": { - "type": "text", - "placeholders": {} - }, - "chatDetails": "تفاصيل المحادثة", - "@chatDetails": { - "type": "text", - "placeholders": {} - }, - "chooseAStrongPassword": "اختر كلمة سر قوية", - "@chooseAStrongPassword": { - "type": "text", - "placeholders": {} - }, - "close": "اغلق", - "@close": { - "type": "text", - "placeholders": {} - }, - "compareEmojiMatch": "يرجى مقارنة الرموز التعبيرية", - "@compareEmojiMatch": { - "type": "text", - "placeholders": {} - }, - "compareNumbersMatch": "الرجاء مقارنة الأرقام", - "@compareNumbersMatch": { - "type": "text", - "placeholders": {} - }, - "confirm": "أكّد", - "@confirm": { - "type": "text", - "placeholders": {} - }, - "connect": "اتصل", - "@connect": { - "type": "text", - "placeholders": {} - }, - "contactHasBeenInvitedToTheGroup": "دعيَ المراسل للمجموعة", - "@contactHasBeenInvitedToTheGroup": { - "type": "text", - "placeholders": {} - }, - "copiedToClipboard": "نُسخ للحافظة", - "@copiedToClipboard": { - "type": "text", - "placeholders": {} - }, - "copy": "انسخ", - "@copy": { - "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": {} - } - }, - "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": "{day}/{month}/{year}", - "@dateWithYear": { - "type": "text", - "placeholders": { - "year": {}, - "month": {}, - "day": {} - } - }, - "deactivateAccountWarning": "لا مجال للعودة، أتأكد تعطيل حسابك؟", - "@deactivateAccountWarning": { - "type": "text", - "placeholders": {} - }, - "delete": "احذف", - "@delete": { - "type": "text", - "placeholders": {} - }, - "deleteAccount": "احذف الحساب", - "@deleteAccount": { - "type": "text", - "placeholders": {} - }, - "deleteMessage": "حذف الرسالة", - "@deleteMessage": { - "type": "text", - "placeholders": {} - }, - "device": "جهاز", - "@device": { - "type": "text", - "placeholders": {} - }, - "devices": "الأجهزة", - "@devices": { - "type": "text", - "placeholders": {} - }, - "displaynameHasBeenChanged": "غُيِّر الاسم العلني", - "@displaynameHasBeenChanged": { - "type": "text", - "placeholders": {} - }, - "downloadFile": "نزِّل الملف", - "@downloadFile": { - "type": "text", - "placeholders": {} - }, - "editDisplayname": "حرر الاسم العلني", - "@editDisplayname": { - "type": "text", - "placeholders": {} - }, - "emoteExists": "الانفعالة موجودة مسبقا!", - "@emoteExists": { - "type": "text", - "placeholders": {} - }, - "emoteInvalid": "رمز الانفعالة غير صالح!", - "@emoteInvalid": { - "type": "text", - "placeholders": {} - }, - "emoteSettings": "اعدادات الانفعالات", - "@emoteSettings": { - "type": "text", - "placeholders": {} - }, - "emoteShortcode": "رمز الانفعالة", - "@emoteShortcode": { - "type": "text", - "placeholders": {} - }, - "emoteWarnNeedToPick": "اختر صورة ورمزا للانفعالة!", - "@emoteWarnNeedToPick": { - "type": "text", - "placeholders": {} - }, - "emptyChat": "محادثة فارغة", - "@emptyChat": { - "type": "text", - "placeholders": {} - }, - "enableEncryptionWarning": "لن يمكنك تعطيل التشفير أبدا، أمتأكد؟", - "@enableEncryptionWarning": { - "type": "text", - "placeholders": {} - }, - "encryption": "التشفير", - "@encryption": { - "type": "text", - "placeholders": {} - }, - "encryptionNotEnabled": "التشفير معطل", - "@encryptionNotEnabled": { - "type": "text", - "placeholders": {} - }, - "endedTheCall": "أنهى {senderName} المكالمة", - "@endedTheCall": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "enterYourHomeserver": "أدخل الخادم", - "@enterYourHomeserver": { - "type": "text", - "placeholders": {} - }, - "fileName": "اسم الملف", - "@fileName": { - "type": "text", - "placeholders": {} - }, - "fluffychat": "فلافي-شات", - "@fluffychat": { - "type": "text", - "placeholders": {} - }, - "forward": "أعد التوجيه", - "@forward": { - "type": "text", - "placeholders": {} - }, - "fromJoining": "من بعد الانضمام", - "@fromJoining": { - "type": "text", - "placeholders": {} - }, - "fromTheInvitation": "من بعد الدعوة", - "@fromTheInvitation": { - "type": "text", - "placeholders": {} - }, - "group": "المجموعة", - "@group": { - "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": {} - }, - "hasWithdrawnTheInvitationFor": "سحب {username} دعوة {targetName}", - "@hasWithdrawnTheInvitationFor": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "help": "المساعدة", - "@help": { - "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": {} - }, - "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": {} - }, - "inviteText": "دعاك {username} إلى FluffyChat.\n1. قم بزيارة موقع fluffychat.im وقم بتثبيت التطبيق\n2. قم بإنشاءحساب أو تسجيل الدخول\n3. افتح رابط الدعوة:\n {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": {} - } - }, - "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": {} - }, - "moderator": "مشرف", - "@moderator": { - "type": "text", - "placeholders": {} - }, - "muteChat": "أكتم الماحدثة", - "@muteChat": { - "type": "text", - "placeholders": {} - }, - "needPantalaimonWarning": "اعلم أننا نستخدم بانتاليمون للتشفير طرفا لطرف.", - "@needPantalaimonWarning": { - "type": "text", - "placeholders": {} - }, - "newMessageInFluffyChat": "💬 رسالة جديدة في FluffyChat", - "@newMessageInFluffyChat": { - "type": "text", - "placeholders": {} - }, - "newVerificationRequest": "طلب تحقق جديد!", - "@newVerificationRequest": { - "type": "text", - "placeholders": {} - }, - "no": "لا", - "@no": { - "type": "text", - "placeholders": {} - }, - "noEmotesFound": "لم يُعثر على انفعالة. 😕", - "@noEmotesFound": { - "type": "text", - "placeholders": {} - }, - "noGoogleServicesWarning": "يبدو أن خدمة Firebase Cloud Messaging غير متاحة على جهازك. لمواصلة تلقي الإشعارات، نوصي بتثبيت ntfy. باستخدام ntfy أو أي مزود خدمة Unified Push آخر، يمكنك تلقي إشعارات الدفع بطريقة آمنة للبيانات. يمكنك تنزيل ntfy من PlayStore أو من F-Droid.", - "@noGoogleServicesWarning": { - "type": "text", - "placeholders": {} - }, - "none": "بدون", - "@none": { - "type": "text", - "placeholders": {} - }, - "noPermission": "بدون اذن", - "@noPermission": { - "type": "text", - "placeholders": {} - }, - "noRoomsFound": "لم يُعثر على غرف…", - "@noRoomsFound": { - "type": "text", - "placeholders": {} - }, - "ok": "موافق", - "@ok": { - "type": "text", - "placeholders": {} - }, - "onlineKeyBackupEnabled": "تم تفعيل النسخ الاحتياطي للمفاتيح عبر الإنترنت", - "@onlineKeyBackupEnabled": { - "type": "text", - "placeholders": {} - }, - "oopsSomethingWentWrong": "عذراً، هناك خطأ ما…", - "@oopsSomethingWentWrong": { - "type": "text", - "placeholders": {} - }, - "openAppToReadMessages": "افتح التطبيق لقراءة الرسائل", - "@openAppToReadMessages": { - "type": "text", - "placeholders": {} - }, - "openCamera": "افتح الكميرا", - "@openCamera": { - "type": "text", - "placeholders": {} - }, - "passphraseOrKey": "عبارة المرور أو مفتاح الاستعادة", - "@passphraseOrKey": { - "type": "text", - "placeholders": {} - }, - "password": "كلمة السر", - "@password": { - "type": "text", - "placeholders": {} - }, - "passwordHasBeenChanged": "غُيّرت كلمة السر", - "@passwordHasBeenChanged": { - "type": "text", - "placeholders": {} - }, - "pickImage": "اختر صورة", - "@pickImage": { - "type": "text", - "placeholders": {} - }, - "pin": "ثبِّت", - "@pin": { - "type": "text", - "placeholders": {} - }, - "play": "شغّل {fileName}", - "@play": { - "type": "text", - "placeholders": { - "fileName": {} - } - }, - "pleaseEnterYourPassword": "أدخل كلمة السر", - "@pleaseEnterYourPassword": { - "type": "text", - "placeholders": {} - }, - "pleaseEnterYourUsername": "أدخل اسم المستخدم", - "@pleaseEnterYourUsername": { - "type": "text", - "placeholders": {} - }, - "privacy": "الخصوصية", - "@privacy": { - "type": "text", - "placeholders": {} - }, - "publicRooms": "الغرف العامة", - "@publicRooms": { - "type": "text", - "placeholders": {} - }, - "recording": "يسجل", - "@recording": { - "type": "text", - "placeholders": {} - }, - "redactedAnEvent": "حذف {username} حدثًا", - "@redactedAnEvent": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "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": {} - }, - "reply": "ردّ", - "@reply": { - "type": "text", - "placeholders": {} - }, - "requestPermission": "أطلب إذنا", - "@requestPermission": { - "type": "text", - "placeholders": {} - }, - "roomHasBeenUpgraded": "رُقيّت الغرفة", - "@roomHasBeenUpgraded": { - "type": "text", - "placeholders": {} - }, - "seenByUser": "رآه {username}", - "@seenByUser": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "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": {} - }, - "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": {} - } - }, - "setInvitationLink": "عيّن رابط الدعوة", - "@setInvitationLink": { - "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": {} - } - }, - "skip": "تخط", - "@skip": { - "type": "text", - "placeholders": {} - }, - "sourceCode": "الشفرة المصدرية", - "@sourceCode": { - "type": "text", - "placeholders": {} - }, - "startedACall": "بدأ {senderName} مكالمة", - "@startedACall": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "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": "فلافي-شات", - "@title": { - "description": "Title for the application", - "type": "text", - "placeholders": {} - }, - "tryToSendAgain": "حاول إعادة الارسال", - "@tryToSendAgain": { - "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 محادثة غير مقروءة} 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": {} - } - }, - "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": {} - }, - "whoIsAllowedToJoinThisGroup": "من يسمح له الانضمام للمجموعة", - "@whoIsAllowedToJoinThisGroup": { - "type": "text", - "placeholders": {} - }, - "writeAMessage": "اكتب رسالة…", - "@writeAMessage": { - "type": "text", - "placeholders": {} - }, - "yes": "نعم", - "@yes": { - "type": "text", - "placeholders": {} - }, - "you": "انت", - "@you": { - "type": "text", - "placeholders": {} - }, - "youAreNoLongerParticipatingInThisChat": "لم تعد منتسبا لهذه المحادثة", - "@youAreNoLongerParticipatingInThisChat": { - "type": "text", - "placeholders": {} - }, - "youHaveBeenBannedFromThisChat": "حُظرت من هذه المحادثة", - "@youHaveBeenBannedFromThisChat": { - "type": "text", - "placeholders": {} - }, - "people": "أشخاص", - "@people": { - "type": "text", - "placeholders": {} - }, - "scanQrCode": "امسح رمز الاستجابة السريعة", - "@scanQrCode": {}, - "noMatrixServer": "{server1} ليس خادم ماتريكس، بدلًا منه أتريد استخدام {server2}؟", - "@noMatrixServer": { - "type": "text", - "placeholders": { - "server1": {}, - "server2": {} - } - }, - "noConnectionToTheServer": "انقطع الاتصال بالخادم", - "@noConnectionToTheServer": { - "type": "text", - "placeholders": {} - }, - "next": "التالي", - "@next": { - "type": "text", - "placeholders": {} - }, - "newChat": "محادثة جديدة", - "@newChat": { - "type": "text", - "placeholders": {} - }, - "messages": "الرسائل", - "@messages": { - "type": "text", - "placeholders": {} - }, - "mention": "اذكر", - "@mention": { - "type": "text", - "placeholders": {} - }, - "memberChanges": "تغييرات تخص الأعضاء", - "@memberChanges": { - "type": "text", - "placeholders": {} - }, - "inoffensive": "غير مسيء", - "@inoffensive": { - "type": "text", - "placeholders": {} - }, - "iHaveClickedOnLink": "نقرت على الرابط", - "@iHaveClickedOnLink": { - "type": "text", - "placeholders": {} - }, - "ignore": "تجاهل", - "@ignore": { - "type": "text", - "placeholders": {} - }, - "howOffensiveIsThisContent": "ما مدى سوء هذا المحتوى؟", - "@howOffensiveIsThisContent": { - "type": "text", - "placeholders": {} - }, - "hideUnknownEvents": "اخف الأحداث المجهولة", - "@hideUnknownEvents": { - "type": "text", - "placeholders": {} - }, - "groups": "المجموعات", - "@groups": { - "type": "text", - "placeholders": {} - }, - "goToTheNewRoom": "انتقل للغرفة الجديدة", - "@goToTheNewRoom": { - "type": "text", - "placeholders": {} - }, - "fontSize": "حجم الخط", - "@fontSize": { - "type": "text", - "placeholders": {} - }, - "extremeOffensive": "مسيئة للغاية", - "@extremeOffensive": { - "type": "text", - "placeholders": {} - }, - "everythingReady": "كل شيء جاهز!", - "@everythingReady": { - "type": "text", - "placeholders": {} - }, - "homeserver": "الخادم", - "@homeserver": {}, - "enterAnEmailAddress": "أدخل عنوان بريد إلكتروني", - "@enterAnEmailAddress": { - "type": "text", - "placeholders": {} - }, - "encrypted": "مشفر", - "@encrypted": { - "type": "text", - "placeholders": {} - }, - "enableEncryption": "فعّل التشفير", - "@enableEncryption": { - "type": "text", - "placeholders": {} - }, - "emotePacks": "حزمة الوجوه التعبيرية للغرفة", - "@emotePacks": { - "type": "text", - "placeholders": {} - }, - "editRoomAvatar": "عدّل الصورة الرمزية للغرفة", - "@editRoomAvatar": { - "type": "text", - "placeholders": {} - }, - "editBlockedServers": "عدّل الخوادم المحجوبة", - "@editBlockedServers": { - "type": "text", - "placeholders": {} - }, - "edit": "عدّل", - "@edit": { - "type": "text", - "placeholders": {} - }, - "directChats": "محادثات مباشرة", - "@directChats": { - "type": "text", - "placeholders": {} - }, - "deviceId": "معرّف الجهاز", - "@deviceId": { - "type": "text", - "placeholders": {} - }, - "createNewSpace": "فضاء جديد", - "@createNewSpace": { - "type": "text", - "placeholders": {} - }, - "copyToClipboard": "انسخ الى الحافظة", - "@copyToClipboard": { - "type": "text", - "placeholders": {} - }, - "contentHasBeenReported": "أّرسل الابلاغ الى مدير الخادم", - "@contentHasBeenReported": { - "type": "text", - "placeholders": {} - }, - "containsUserName": "يحوي اسم المستخدم", - "@containsUserName": { - "type": "text", - "placeholders": {} - }, - "containsDisplayName": "يحوي الاسم العلني", - "@containsDisplayName": { - "type": "text", - "placeholders": {} - }, - "commandMissing": "{command} ليس بأمر.", - "@commandMissing": { - "type": "text", - "placeholders": { - "command": {} - }, - "description": "State that {command} is not a valid /command." - }, - "commandInvalid": "أمر غير صالح", - "@commandInvalid": { - "type": "text" - }, - "commandHint_unban": "فك الحظر عن المستخدم المذكور في هذه الغرفة", - "@commandHint_unban": { - "type": "text", - "description": "Usage hint for the command /unban" - }, - "commandHint_send": "أرسل نصًا", - "@commandHint_send": { - "type": "text", - "description": "Usage hint for the command /send" - }, - "commandHint_react": "أرسل ردًا كتفاعل", - "@commandHint_react": { - "type": "text", - "description": "Usage hint for the command /react" - }, - "commandHint_plain": "أرسل نصًا غير منسق", - "@commandHint_plain": { - "type": "text", - "description": "Usage hint for the command /plain" - }, - "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_me": "صف نفسك", - "@commandHint_me": { - "type": "text", - "description": "Usage hint for the command /me" - }, - "commandHint_leave": "تغادر هذه الغرفة", - "@commandHint_leave": { - "type": "text", - "description": "Usage hint for the command /leave" - }, - "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" - }, - "commandHint_invite": "يدعو المستخدم المذكور الى الغرفة", - "@commandHint_invite": { - "type": "text", - "description": "Usage hint for the command /invite" - }, - "commandHint_html": "أرسل نصًا بتنسيق HTML", - "@commandHint_html": { - "type": "text", - "description": "Usage hint for the command /html" - }, - "commandHint_ban": "يحظر المستخدم المذكور من هذه الغرفة", - "@commandHint_ban": { - "type": "text", - "description": "Usage hint for the command /ban" - }, - "clearArchive": "امسح الأرشيف", - "@clearArchive": {}, - "chats": "المحادثات", - "@chats": { - "type": "text", - "placeholders": {} - }, - "chatHasBeenAddedToThisSpace": "أُضيفت المحادثة الى هذا المساحة", - "@chatHasBeenAddedToThisSpace": {}, - "chatBackup": "النسخ الاحتياطي للمحادثات", - "@chatBackup": { - "type": "text", - "placeholders": {} - }, - "changeYourAvatar": "غيّر الصورة الرمزية", - "@changeYourAvatar": { - "type": "text", - "placeholders": {} - }, - "changePassword": "غيّر كلمة السر", - "@changePassword": { - "type": "text", - "placeholders": {} - }, - "changeDeviceName": "غيّر اسم الجهاز", - "@changeDeviceName": { - "type": "text", - "placeholders": {} - }, - "cantOpenUri": "تعذر فتح المسار {uri}", - "@cantOpenUri": { - "type": "text", - "placeholders": { - "uri": {} - } - }, - "blocked": "محجوب", - "@blocked": { - "type": "text", - "placeholders": {} - }, - "sendOnEnter": "أرسل عند الدخول", - "@sendOnEnter": {}, - "autoplayImages": "شغِّل الملصقات والوجوه المتحركة تلقائيا", - "@autoplayImages": { - "type": "text", - "placeholder": {} - }, - "areYouSureYouWantToLogout": "أمتأكد من الخروج؟", - "@areYouSureYouWantToLogout": { - "type": "text", - "placeholders": {} - }, - "appLock": "قفل التطبيق", - "@appLock": { - "type": "text", - "placeholders": {} - }, - "allChats": "كل المحادثات", - "@allChats": { - "type": "text", - "placeholders": {} - }, - "all": "الكل", - "@all": { - "type": "text", - "placeholders": {} - }, - "addToSpace": "أضف إلى المساحة", - "@addToSpace": {}, - "addEmail": "أضف بريدًا إلكترونيًا", - "@addEmail": { - "type": "text", - "placeholders": {} - }, - "noPasswordRecoveryDescription": "لم تضف أي طريقة لاستعادة كلمة السر.", - "@noPasswordRecoveryDescription": { - "type": "text", - "placeholders": {} - }, - "notifications": "الإشعارات", - "@notifications": { - "type": "text", - "placeholders": {} - }, - "reason": "السبب", - "@reason": { - "type": "text", - "placeholders": {} - }, - "search": "ابحث", - "@search": { - "type": "text", - "placeholders": {} - }, - "locationDisabledNotice": "خدمات الموقع معطلة. مكنها لتتمكن من مشاركة موقعك.", - "@locationDisabledNotice": { - "type": "text", - "placeholders": {} - }, - "errorObtainingLocation": "خطأ أثناء الحصول على الموقع: {error}", - "@errorObtainingLocation": { - "type": "text", - "placeholders": { - "error": {} - } - }, - "editRoomAliases": "عدّل الاسم المميز للغرفة", - "@editRoomAliases": { - "type": "text", - "placeholders": {} - }, - "configureChat": "ضبط المحادثة", - "@configureChat": { - "type": "text", - "placeholders": {} - }, - "chatBackupDescription": "يتم تأمين رسائلك القديمة باستخدام مفتاح الاسترداد. يرجى التأكد من أنك لا تضيعه.", - "@chatBackupDescription": { - "type": "text", - "placeholders": {} - }, - "shareLocation": "شارك الموقع", - "@shareLocation": { - "type": "text", - "placeholders": {} - }, - "pleaseChooseAPasscode": "اختر رمز المرور", - "@pleaseChooseAPasscode": { - "type": "text", - "placeholders": {} - }, - "pleaseChoose": "اختر رجاء", - "@pleaseChoose": { - "type": "text", - "placeholders": {} - }, - "passwordRecovery": "استعادة كلمة السر", - "@passwordRecovery": { - "type": "text", - "placeholders": {} - }, - "passwordForgotten": "نسيتَ كلمة السر", - "@passwordForgotten": { - "type": "text", - "placeholders": {} - }, - "participant": "منتسب", - "@participant": { - "type": "text", - "placeholders": {} - }, - "or": "أو", - "@or": { - "type": "text", - "placeholders": {} - }, - "serverRequiresEmail": "يتطلب هذا الخادم التحقق من بريدك الإلكتروني.", - "@serverRequiresEmail": {}, - "link": "رابط", - "@link": {}, - "openInMaps": "افتح في الخريطة", - "@openInMaps": { - "type": "text", - "placeholders": {} - }, - "enableMultiAccounts": "(ميزة تجربية) فعّل تعدد الحسابات", - "@enableMultiAccounts": {}, - "bundleName": "اسم الحزمة", - "@bundleName": {}, - "removeFromBundle": "أزله من الحزمة", - "@removeFromBundle": {}, - "addToBundle": "أضفه الى حزمة", - "@addToBundle": {}, - "editBundlesForAccount": "عدّل حزم هذا الحساب", - "@editBundlesForAccount": {}, - "addAccount": "أضف حسابًا", - "@addAccount": {}, - "online": "متصل", - "@online": { - "type": "text", - "placeholders": {} - }, - "offline": "غير متصل", - "@offline": { - "type": "text", - "placeholders": {} - }, - "numUsersTyping": "{count} يكتبون…", - "@numUsersTyping": { - "type": "text", - "placeholders": { - "count": {} - } - }, - "notificationsEnabledForThisAccount": "الإشعارات مفعلة لهذا الحساب", - "@notificationsEnabledForThisAccount": { - "type": "text", - "placeholders": {} - }, - "spaceIsPublic": "عام في المساحة", - "@spaceIsPublic": { - "type": "text", - "placeholders": {} - }, - "toggleFavorite": "بدّل حالة التفضيل", - "@toggleFavorite": { - "type": "text", - "placeholders": {} - }, - "toggleUnread": "علّمه كمقروء/غير مقروء", - "@toggleUnread": { - "type": "text", - "placeholders": {} - }, - "unavailable": "غير متوفر", - "@unavailable": { - "type": "text", - "placeholders": {} - }, - "whyDoYouWantToReportThis": "لماذا تريد الإبلاغ عنه؟", - "@whyDoYouWantToReportThis": { - "type": "text", - "placeholders": {} - }, - "withTheseAddressesRecoveryDescription": "يمكنك استعادة كلمة السر بهذه العناوين.", - "@withTheseAddressesRecoveryDescription": { - "type": "text", - "placeholders": {} - }, - "singlesignon": "تسجيل دخول أحادي", - "@singlesignon": { - "type": "text", - "placeholders": {} - }, - "toggleMuted": "بدّل حالة الكتم", - "@toggleMuted": { - "type": "text", - "placeholders": {} - }, - "showPassword": "أظهر كلمة السر", - "@showPassword": { - "type": "text", - "placeholders": {} - }, - "verified": "موثّق", - "@verified": { - "type": "text", - "placeholders": {} - }, - "spaceName": "اسم المساحة", - "@spaceName": { - "type": "text", - "placeholders": {} - }, - "synchronizingPleaseWait": "يُزامن… يرجى الانتظار.", - "@synchronizingPleaseWait": { - "type": "text", - "placeholders": {} - }, - "tooManyRequestsWarning": "طابات كثيرة. حاول مجددًا لاحقًا!", - "@tooManyRequestsWarning": { - "type": "text", - "placeholders": {} - }, - "weSentYouAnEmail": "أرسلنا لك رسالة بالبريد الإلكتروني", - "@weSentYouAnEmail": { - "type": "text", - "placeholders": {} - }, - "yourPublicKey": "مفتاحك العمومي", - "@yourPublicKey": { - "type": "text", - "placeholders": {} - }, - "status": "الحالة", - "@status": { - "type": "text", - "placeholders": {} - }, - "transferFromAnotherDevice": "أنقله من جهاز آخر", - "@transferFromAnotherDevice": { - "type": "text", - "placeholders": {} - }, - "wipeChatBackup": "مسح نسخة الدردشة الاحتياطية لإنشاء مفتاح استرداد جديد؟", - "@wipeChatBackup": { - "type": "text", - "placeholders": {} - }, - "saveFile": "احفظ الملف", - "@saveFile": { - "type": "text", - "placeholders": {} - }, - "security": "الأمان", - "@security": { - "type": "text", - "placeholders": {} - }, - "removeYourAvatar": "أزل الصورة الرمزية", - "@removeYourAvatar": { - "type": "text", - "placeholders": {} - }, - "botMessages": "رسائل البوت", - "@botMessages": { - "type": "text", - "placeholders": {} - }, - "sendAsText": "أرسل نصًا", - "@sendAsText": { - "type": "text" - }, - "sendMessages": "إرسال رسائل", - "@sendMessages": { - "type": "text", - "placeholders": {} - }, - "inviteForMe": "دعوات لي", - "@inviteForMe": { - "type": "text", - "placeholders": {} - }, - "replaceRoomWithNewerVersion": "استبدل الغرفة باصدار أحدث", - "@replaceRoomWithNewerVersion": { - "type": "text", - "placeholders": {} - }, - "register": "سجّل", - "@register": { - "type": "text", - "placeholders": {} - }, - "obtainingLocation": "يحصل على الموقع…", - "@obtainingLocation": { - "type": "text", - "placeholders": {} - }, - "sendSticker": "أرسل ملصقًا", - "@sendSticker": { - "type": "text", - "placeholders": {} - }, - "defaultPermissionLevel": "مستوى الأذونات الإفتراضي", - "@defaultPermissionLevel": { - "type": "text", - "placeholders": {} - }, - "setPermissionsLevel": "تعيين مستوى الأذونات", - "@setPermissionsLevel": { - "type": "text", - "placeholders": {} - }, - "setCustomEmotes": "عيّن وجوهًا تعبيرية مخصصة", - "@setCustomEmotes": { - "type": "text", - "placeholders": {} - }, - "oneClientLoggedOut": "أُ خرج أحد العملاء الذي تسختدمها", - "@oneClientLoggedOut": {}, - "pleaseEnter4Digits": "أدخل 4 أرقام أو أتركه فارغ لتعطيل القفل.", - "@pleaseEnter4Digits": { - "type": "text", - "placeholders": {} - }, - "redactMessage": "احذف رسالة", - "@redactMessage": { - "type": "text", - "placeholders": {} - }, - "reportMessage": "أبلغ عن الرسالة", - "@reportMessage": { - "type": "text", - "placeholders": {} - }, - "roomVersion": "إصدار الغرفة", - "@roomVersion": { - "type": "text", - "placeholders": {} - }, - "repeatPassword": "كرّر كلمة السر", - "@repeatPassword": {}, - "removeFromSpace": "أزل من المساحة", - "@removeFromSpace": {}, - "unverified": "غير مؤكد", - "@unverified": {}, - "whoCanPerformWhichAction": "من يستطيع القيام بأي عمل", - "@whoCanPerformWhichAction": { - "type": "text", - "placeholders": {} - }, - "messageInfo": "معلومات الرسالة", - "@messageInfo": {}, - "messageType": "نوع الرسالة", - "@messageType": {}, - "sender": "المرسل", - "@sender": {}, - "openGallery": "افتخ المعرض", - "@openGallery": {}, - "time": "الوقت", - "@time": {}, - "badServerLoginTypesException": "يدعم الخادم المستخدم أنواع تسجيل الدخول التالية:\n{serverVersions}\nلكن هذا التطبيق يدعم فقط:\n{supportedVersions}", - "@badServerLoginTypesException": { - "type": "text", - "placeholders": { - "serverVersions": {}, - "supportedVersions": {} - } - }, - "commandHint_clearcache": "مسح الذاكرة المؤقتة", - "@commandHint_clearcache": { - "type": "text", - "description": "Usage hint for the command /clearcache" - }, - "enableEmotesGlobally": "تفعيل حزمة التعبيرات بشكل عام", - "@enableEmotesGlobally": { - "type": "text", - "placeholders": {} - }, - "hideRedactedEvents": "إخفاء الأحداث المنقحة", - "@hideRedactedEvents": { - "type": "text", - "placeholders": {} - }, - "commandHint_discardsession": "إنهاء الجلسة", - "@commandHint_discardsession": { - "type": "text", - "description": "Usage hint for the command /discardsession" - }, - "locationPermissionDeniedNotice": "تم رفض إذن الموقع. الرجاء منح الإذن للقدرة على مشاركة موقعك.", - "@locationPermissionDeniedNotice": { - "type": "text", - "placeholders": {} - }, - "badServerVersionsException": "يدعم الخادم الرئيسي المستخدم إصدارات المواصفات:\n{serverVersions}\nلكن هذا التطبيق يدعم فقط:\n{supportedVersions}", - "@badServerVersionsException": { - "type": "text", - "placeholders": { - "serverVersions": {}, - "supportedVersions": {} - } - }, - "offensive": "عدواني", - "@offensive": { - "type": "text", - "placeholders": {} - }, - "yourChatBackupHasBeenSetUp": "تم إعداد النسخ الاحتياطي لمحادثاتك.", - "@yourChatBackupHasBeenSetUp": {}, - "noEncryptionForPublicRooms": "يمكنك فقط تفعيل التشفير عندما تصبح الغرفة غير متاحة للعامة.", - "@noEncryptionForPublicRooms": { - "type": "text", - "placeholders": {} - }, - "emojis": "إيموجي", - "@emojis": {}, - "voiceCall": "مكالمة صوتية", - "@voiceCall": {}, - "unsupportedAndroidVersion": "نسخة أندرويد غير مدعومة", - "@unsupportedAndroidVersion": {}, - "unsupportedAndroidVersionLong": "تتطلب هذه الميزة إصدار Android أحدث. يرجى التحقق من وجود تحديثات أو دعم Lineage OS.", - "@unsupportedAndroidVersionLong": {}, - "experimentalVideoCalls": "مكالمات الفيديو التجريبية", - "@experimentalVideoCalls": {}, - "commandHint_create": "أنشأ محادثة جماعية فارغة\nاستخدم --لا-تشفير لتعطيل التشفير", - "@commandHint_create": { - "type": "text", - "description": "Usage hint for the command /create" - }, - "commandHint_dm": "إبدأ محادثة مباشرة\nاستخدم --لا-تشفير لتعطيل التشفير", - "@commandHint_dm": { - "type": "text", - "description": "Usage hint for the command /dm" - }, - "oopsPushError": "عذراً! للأسف، حدث خطأ أثناء إعداد الإشعارات.", - "@oopsPushError": { - "type": "text", - "placeholders": {} - }, - "pleaseFollowInstructionsOnWeb": "يرجى اتباع التعليمات الموجودة على الموقع والنقر على التالي.", - "@pleaseFollowInstructionsOnWeb": { - "type": "text", - "placeholders": {} - }, - "commandHint_myroomavatar": "حدد صورتك لهذه الغرفة (عن طريق mxc-uri)", - "@commandHint_myroomavatar": { - "type": "text", - "description": "Usage hint for the command /myroomavatar" - }, - "videoCallsBetaWarning": "يرجى ملاحظة أن مكالمات الفيديو حالياً في مرحلة تجريبية. قد لا تعمل كما هو متوقع أو تعمل على الإطلاق على جميع المنصات.", - "@videoCallsBetaWarning": {}, - "placeCall": "إجراء مكالمة", - "@placeCall": {}, - "videoWithSize": "فيديو ({size})", - "@videoWithSize": { - "type": "text", - "placeholders": { - "size": {} - } - }, - "emailOrUsername": "البريد الإلكتروني أو اسم المستخدم", - "@emailOrUsername": {}, - "dismiss": "رفض", - "@dismiss": {}, - "setAsCanonicalAlias": "تعيين كاسم مستعار رئيسي", - "@setAsCanonicalAlias": { - "type": "text", - "placeholders": {} - }, - "pleaseClickOnLink": "يرجى النقر على الرابط الموجود في البريد الإلكتروني ثم المتابعة.", - "@pleaseClickOnLink": { - "type": "text", - "placeholders": {} - }, - "pleaseEnterYourPin": "الرجاء إدخال رقم التعريف الشخصي الخاص بك", - "@pleaseEnterYourPin": { - "type": "text", - "placeholders": {} - }, - "pushRules": "قواعد الإشعارات", - "@pushRules": { - "type": "text", - "placeholders": {} - }, - "reactedWith": "{sender} تفاعل ب {reaction}", - "@reactedWith": { - "type": "text", - "placeholders": { - "sender": {}, - "reaction": {} - } - }, - "markAsRead": "حدد كمقروء", - "@markAsRead": {}, - "openVideoCamera": "افتح الكاميرا لمقطع فيديو", - "@openVideoCamera": { - "type": "text", - "placeholders": {} - }, - "start": "إبدأ", - "@start": {}, - "publish": "انشر", - "@publish": {}, - "addToSpaceDescription": "إختر فضاء لإضافة هذه المحادثة إليه.", - "@addToSpaceDescription": {}, - "reportUser": "التبيلغ عن المستخدم", - "@reportUser": {}, - "openChat": "فتح المحادثة", - "@openChat": {}, - "pinMessage": "تثبيت في الغرفة", - "@pinMessage": {}, - "confirmEventUnpin": "هل أنت متأكد من إلغاء تثبيت الحدث بشكل دائم؟", - "@confirmEventUnpin": {}, - "fileHasBeenSavedAt": "تم حفظ الملف في {path}", - "@fileHasBeenSavedAt": { - "type": "text", - "placeholders": { - "path": {} - } - }, - "user": "مستخدم", - "@user": {}, - "custom": "مُخصّص", - "@custom": {}, - "googlyEyesContent": "{senderName} يرسل لك عيون googly", - "@googlyEyesContent": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "widgetVideo": "فيديو", - "@widgetVideo": {}, - "recoveryKeyLost": "هل فقدت مفتاح الاسترداد؟", - "@recoveryKeyLost": {}, - "pleaseEnterRecoveryKeyDescription": "لإلغاء قفل رسائلك القديمة ، يرجى إدخال مفتاح الاسترداد الذي تم إنشاؤه في جلسة سابقة. مفتاح الاسترداد ليس كلمة المرور الخاصة بك.", - "@pleaseEnterRecoveryKeyDescription": {}, - "confirmMatrixId": "يرجى تأكيد معرف Matrix الخاص بك من أجل حذف حسابك.", - "@confirmMatrixId": {}, - "supposedMxid": "يجب أن يكون هذا {mxid}", - "@supposedMxid": { - "type": "text", - "placeholders": { - "mxid": {} - } - }, - "hydrateTor": "مستخدمو تور: استيراد تصدير الجلسة", - "@hydrateTor": {}, - "commandHint_googly": "أرسل بعض عيون googly", - "@commandHint_googly": {}, - "commandHint_cuddle": "أرسل عناق", - "@commandHint_cuddle": {}, - "commandHint_hug": "إرسال حضن", - "@commandHint_hug": {}, - "cuddleContent": "{senderName} يحتضنك", - "@cuddleContent": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "unlockOldMessages": "إلغاء قفل الرسائل القديمة", - "@unlockOldMessages": {}, - "commandHint_markasdm": "وضع علامة على أنها غرفة رسائل مباشرة لمعرف المصفوفة", - "@commandHint_markasdm": {}, - "allRooms": "جميع الدردشات الجماعية", - "@allRooms": { - "type": "text", - "placeholders": {} - }, - "dehydrate": "تصدير الجلسة ومسح الجهاز", - "@dehydrate": {}, - "dehydrateWarning": "لا يمكن التراجع عن هذا الإجراء. تأكد من تخزين ملف النسخ الاحتياطي بأمان.", - "@dehydrateWarning": {}, - "dehydrateTorLong": "بالنسبة لمستخدمي تور ، يوصى بتصدير الجلسة قبل إغلاق النافذة.", - "@dehydrateTorLong": {}, - "dehydrateTor": "مستخدمو تور: تصدير الجلسة", - "@dehydrateTor": {}, - "hydrate": "استعادة من ملف النسخ الاحتياطي", - "@hydrate": {}, - "pleaseEnterRecoveryKey": "الرجاء إدخال مفتاح الاسترداد:", - "@pleaseEnterRecoveryKey": {}, - "recoveryKey": "مفتاح الاسترداد", - "@recoveryKey": {}, - "startFirstChat": "ابدأ محادثتك الأولى", - "@startFirstChat": {}, - "widgetCustom": "مُخصّص", - "@widgetCustom": {}, - "widgetNameError": "يرجى تقديم اسم العرض.", - "@widgetNameError": {}, - "errorAddingWidget": "خطأ في إضافة الأداة.", - "@errorAddingWidget": {}, - "youRejectedTheInvitation": "لقد رفضت الدعوة", - "@youRejectedTheInvitation": {}, - "youJoinedTheChat": "لقد انضممت إلى الدردشة", - "@youJoinedTheChat": {}, - "youAcceptedTheInvitation": "👍 لقد قبلت الدعوة", - "@youAcceptedTheInvitation": {}, - "youBannedUser": "لقد حظرت {user}", - "@youBannedUser": { - "placeholders": { - "user": {} - } - }, - "youHaveWithdrawnTheInvitationFor": "لقد سحبت الدعوة لـ {user}", - "@youHaveWithdrawnTheInvitationFor": { - "placeholders": { - "user": {} - } - }, - "youInvitedBy": "📩 لقد تمت دعوتك من قبل {user}", - "@youInvitedBy": { - "placeholders": { - "user": {} - } - }, - "storeInAndroidKeystore": "تخزين في سجل مفاتيح اندرويد", - "@storeInAndroidKeystore": {}, - "storeInAppleKeyChain": "تخزين في سلسلة مفاتيح ابل", - "@storeInAppleKeyChain": {}, - "storeSecurlyOnThisDevice": "احفظه بأمان على هذا الجهاز", - "@storeSecurlyOnThisDevice": {}, - "countFiles": "ملفات {count}", - "@countFiles": { - "placeholders": { - "count": {} - } - }, - "foregroundServiceRunning": "يظهر هذا الإشعار عند تشغيل الخدمة الأمامية.", - "@foregroundServiceRunning": {}, - "screenSharingTitle": "مشاركة الشاشة", - "@screenSharingTitle": {}, - "appearOnTop": "يظهر في الأعلى", - "@appearOnTop": {}, - "otherCallingPermissions": "الميكروفون والكاميرا وأذونات FluffyChat الأخرى", - "@otherCallingPermissions": {}, - "enterSpace": "أدخل المساحة", - "@enterSpace": {}, - "enterRoom": "أدخل الغرفة", - "@enterRoom": {}, - "deviceKeys": "مفاتيح الجهاز:", - "@deviceKeys": {}, - "whyIsThisMessageEncrypted": "لماذا هذه الرسالة غير قابلة للقراءة؟", - "@whyIsThisMessageEncrypted": {}, - "nextAccount": "الحساب التالي", - "@nextAccount": {}, - "previousAccount": "الحساب السابق", - "@previousAccount": {}, - "encryptThisChat": "تشفير هذه الدردشة", - "@encryptThisChat": {}, - "screenSharingDetail": "أنت تشارك شاشتك في FuffyChat", - "@screenSharingDetail": {}, - "hideUnimportantStateEvents": "إخفاء أحداث الحالة غير المهمة", - "@hideUnimportantStateEvents": {}, - "newGroup": "مجموعة جديدة", - "@newGroup": {}, - "youKicked": "👞 لقد ركلت {user}", - "@youKicked": { - "placeholders": { - "user": {} - } - }, - "newSpace": "مساحة جديدة", - "@newSpace": {}, - "commandHint_markasgroup": "وضع علامة كمجموعة", - "@commandHint_markasgroup": {}, - "separateChatTypes": "الدردشات المباشرة والمجموعات المنفصلة", - "@separateChatTypes": { - "type": "text", - "placeholders": {} - }, - "hugContent": "{senderName} يعانقك", - "@hugContent": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "hydrateTorLong": "هل قمت بتصدير جلستك الأخيرة على تور؟ قم باستيراده بسرعة واستمر في الدردشة.", - "@hydrateTorLong": {}, - "widgetUrlError": "هذا ليس عنوان URL صالحًا.", - "@widgetUrlError": {}, - "indexedDbErrorTitle": "مشاكل الوضع الخاص", - "@indexedDbErrorTitle": {}, - "indexedDbErrorLong": "للأسف ، لم يتم تمكين تخزين الرسائل في الوضع الخاص افتراضيا.\nيرجى زيارة\n - حول:التكوين\n - تعيين dom.indexedDB.privateBrowsing.enabled إلى true\nخلاف ذلك ، لا يمكن تشغيل FluffyChat.", - "@indexedDbErrorLong": {}, - "switchToAccount": "التبديل إلى الحساب {number}", - "@switchToAccount": { - "type": "number", - "placeholders": { - "number": {} - } - }, - "addWidget": "إضافة اداة", - "@addWidget": {}, - "widgetEtherpad": "ملاحظة نصية", - "@widgetEtherpad": {}, - "youKickedAndBanned": "🙅 لقد ركلت وحظرت {user}", - "@youKickedAndBanned": { - "placeholders": { - "user": {} - } - }, - "youUnbannedUser": "قمت بإلغاء الحظر {user}", - "@youUnbannedUser": { - "placeholders": { - "user": {} - } - }, - "saveKeyManuallyDescription": "احفظ هذا المفتاح يدويا عن طريق تشغيل مربع حوار مشاركة النظام أو الحافظة.", - "@saveKeyManuallyDescription": {}, - "widgetJitsi": "اجتماعات جيتسي", - "@widgetJitsi": {}, - "youInvitedUser": "📩 قمت بدعوة {user}", - "@youInvitedUser": { - "placeholders": { - "user": {} - } - }, - "storeInSecureStorageDescription": "قم بتخزين مفتاح الاسترداد في التخزين الآمن لهذا الجهاز.", - "@storeInSecureStorageDescription": {}, - "widgetName": "الاسم", - "@widgetName": {}, - "users": "المستخدمون", - "@users": {}, - "callingPermissions": "أذونات الاتصال", - "@callingPermissions": {}, - "callingAccount": "الاتصال بالحساب", - "@callingAccount": {}, - "callingAccountDetails": "يسمح لـ FluffyChat باستخدام تطبيق android Dialer الأصلي.", - "@callingAccountDetails": {}, - "appearOnTopDetails": "يسمح للتطبيق بالظهور في الأعلى (ليست هناك حاجة إذا قمت بالفعل بإعداد Fluffychat كحساب اتصال)", - "@appearOnTopDetails": {}, - "numChats": "{number} الدردشات", - "@numChats": { - "type": "number", - "placeholders": { - "number": {} - } - }, - "jump": "قفز", - "@jump": {}, - "report": "التقرير", - "@report": {}, - "noKeyForThisMessage": "يمكن أن يحدث هذا إذا تم إرسال الرسالة قبل تسجيل الدخول إلى حسابك على هذا الجهاز.\n\nمن الممكن أيضا أن يكون المرسل قد حظر جهازك أو حدث خطأ ما في الاتصال بالإنترنت.\n\nهل يمكنك قراءة الرسالة في جلسة أخرى؟ ثم يمكنك نقل الرسالة منه! انتقل إلى الإعدادات > الأجهزة وتأكد من أن أجهزتك قد تحققت من بعضها البعض. عندما تفتح الغرفة في المرة التالية وتكون كلتا الجلستين في المقدمة ، سيتم إرسال المفاتيح تلقائيا.\n\nألا تريد أن تفقد المفاتيح عند تسجيل الخروج أو تبديل الأجهزة؟ تأكد من تمكين النسخ الاحتياطي للدردشة في الإعدادات.", - "@noKeyForThisMessage": {}, - "allSpaces": "كل المساحات", - "@allSpaces": {}, - "doNotShowAgain": "لا تظهر مرة أخرى", - "@doNotShowAgain": {}, - "wasDirectChatDisplayName": "محادثة فارغة (كانت {oldDisplayName})", - "@wasDirectChatDisplayName": { - "type": "text", - "placeholders": { - "oldDisplayName": {} - } - }, - "disableEncryptionWarning": "لأسباب أمنية ، لا يمكنك تعطيل التشفير في الدردشة ، حيث تم تمكينه من قبل.", - "@disableEncryptionWarning": {}, - "reportErrorDescription": "اوه لا. حدث خطأ ما. يرجى إعادة المحاولة لاحقا. إذا كنت ترغب في ذلك ، يمكنك الإبلاغ عن الخطأ للمطورين.", - "@reportErrorDescription": {}, - "newSpaceDescription": "يسمح لك تطبيق المساحات بتوحيد دردشاتك وبناء مجتمعات خاصة أو عامة.", - "@newSpaceDescription": {}, - "sorryThatsNotPossible": "معذرة... هذا غير ممكن", - "@sorryThatsNotPossible": {}, - "openLinkInBrowser": "فتح الرابط في المتصفح", - "@openLinkInBrowser": {}, - "reopenChat": "إعادة فتح الدردشة", - "@reopenChat": {}, - "noBackupWarning": "تحذير! بدون تمكين النسخ الاحتياطي للدردشة ، ستفقد الوصول إلى رسائلك المشفرة. يوصى بشدة بتمكين النسخ الاحتياطي للدردشة أولاً قبل تسجيل الخروج.", - "@noBackupWarning": {}, - "noOtherDevicesFound": "لم يتم العثور على أجهزة أخرى", - "@noOtherDevicesFound": {}, - "fileIsTooBigForServer": "أبلغ الخادم أن الملف كبير جدًا بحيث لا يمكن إرساله.", - "@fileIsTooBigForServer": {}, - "jumpToLastReadMessage": "الانتقال إلى آخر رسالة مقروءة", - "@jumpToLastReadMessage": {}, - "readUpToHere": "اقرأ حتى هنا", - "@readUpToHere": {}, - "signInWithPassword": "سجل الدخول بكلمة السر", - "@signInWithPassword": {}, - "pleaseTryAgainLaterOrChooseDifferentServer": "رجاء حاول مجددا أو اختر خادما مختلفا.", - "@pleaseTryAgainLaterOrChooseDifferentServer": {}, - "signInWith": "تسجيل الدخول باستخدام {provider}", - "@signInWith": { - "type": "text", - "placeholders": { - "provider": {} - } - }, - "importNow": "استيراد الآن", - "@importNow": {}, - "importEmojis": "استيراد الرموز التعبيرية", - "@importEmojis": {}, - "exportEmotePack": "تصدير حزمة الرموز التعبيرية بتنسيق zip", - "@exportEmotePack": {}, - "notAnImage": "ليس ملف صورة.", - "@notAnImage": {}, - "importFromZipFile": "الاستيراد من ملف .zip", - "@importFromZipFile": {}, - "replace": "استبدال", - "@replace": {}, - "sendTypingNotifications": "إرسال إشعارات الكتابة", - "@sendTypingNotifications": {}, - "createGroup": "إنشاء مجموعة", - "@createGroup": {}, - "messagesStyle": "الرسائل:", - "@messagesStyle": {}, - "shareInviteLink": "شارك رابط الدعوة", - "@shareInviteLink": {}, - "profileNotFound": "لا يمكن العثور على المستخدم على الخادم. ربما هناك مشكلة في الاتصال أو المستخدم غير موجود.", - "@profileNotFound": {}, - "setTheme": "تعيين السمة:", - "@setTheme": {}, - "setColorTheme": "تعيين لون السمة:", - "@setColorTheme": {}, - "inviteContactToGroupQuestion": "هل تريد دعوة {contact} إلى المحادثة \"{groupName}\"؟?", - "@inviteContactToGroupQuestion": {}, - "tryAgain": "أعد المحاولة", - "@tryAgain": {}, - "redactMessageDescription": "سيتم تنقيح الرسالة لجميع المشاركين في هذه المحادثة. هذا لا يمكن التراجع عنها.", - "@redactMessageDescription": {}, - "optionalRedactReason": "(اختياري) سبب تنقيح هذه الرسالة ...", - "@optionalRedactReason": {}, - "redactedBy": "منقح بواسطة {username}", - "@redactedBy": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "redactedByBecause": "تم حجبه بواسطة {username} بسبب: \"{reason}\"", - "@redactedByBecause": { - "type": "text", - "placeholders": { - "username": {}, - "reason": {} - } - }, - "invite": "دعوة", - "@invite": {}, - "addChatDescription": "أضف وصفًا للدردشة...", - "@addChatDescription": {}, - "chatPermissions": "صلاحيات المحادثة", - "@chatPermissions": {}, - "chatDescription": "وصف الدردشة", - "@chatDescription": {}, - "chatDescriptionHasBeenChanged": "تغير وصف المجموعة", - "@chatDescriptionHasBeenChanged": {}, - "noChatDescriptionYet": "لم يتم إنشاء وصف للمحادثة حتى الآن.", - "@noChatDescriptionYet": {}, - "invalidServerName": "اسم الخادم غير متاح", - "@invalidServerName": {}, - "setChatDescription": "تعيين وصفًا للدردشة", - "@setChatDescription": {}, - "directChat": "محادثة مباشرة", - "@directChat": {}, - "inviteGroupChat": "📨 دعوة الدردشة الجماعية", - "@inviteGroupChat": {}, - "invitePrivateChat": "📨 دعوة دردشة خاصة", - "@invitePrivateChat": {}, - "emoteKeyboardNoRecents": "التعبيرات المستخدمة مؤخرًا ستظهر هنا ...", - "@emoteKeyboardNoRecents": { - "type": "text", - "placeholders": {} - }, - "invalidInput": "مدخل غير صالح!", - "@invalidInput": {}, - "wrongPinEntered": "تم إدخال رمز خاطئ! حاول مرة أخرى خلال {seconds} ثانية...", - "@wrongPinEntered": { - "type": "text", - "placeholders": { - "seconds": {} - } - }, - "hasKnocked": "لقد طرق {user}", - "@hasKnocked": { - "placeholders": { - "user": {} - } - }, - "pleaseEnterANumber": "الرجاء إدخال رقم أكبر من 0", - "@pleaseEnterANumber": {}, - "banUserDescription": "سيتم حظر المستخدم من الدردشة ولن يتمكن من الدخول إلى الدردشة مرة أخرى حتى يتم رفع الحظر عنه.", - "@banUserDescription": {}, - "removeDevicesDescription": "سيتم تسجيل خروجك من هذا الجهاز ولن تتمكن بعد ذلك من تلقي الرسائل.", - "@removeDevicesDescription": {}, - "unbanUserDescription": "سيتمكن المستخدم من الدخول إلى الدردشة مرة أخرى إذا حاول.", - "@unbanUserDescription": {}, - "pushNotificationsNotAvailable": "دفع الإخطارات غير متوفرة", - "@pushNotificationsNotAvailable": {}, - "makeAdminDescription": "بمجرد تعيين هذا المستخدم كمسؤول، قد لا تتمكن من التراجع عن هذا لأنه سيكون لديه نفس الأذونات التي تتمتع بها.", - "@makeAdminDescription": {}, - "archiveRoomDescription": "سيتم نقل الدردشة إلى الأرشيف. سيتمكن المستخدمون الآخرون من رؤية أنك غادرت الدردشة.", - "@archiveRoomDescription": {}, - "learnMore": "تعلم المزيد", - "@learnMore": {}, - "roomUpgradeDescription": "سيتم بعد ذلك إعادة إنشاء الدردشة باستخدام إصدار الغرفة الجديد. سيتم إخطار جميع المشاركين بأنهم بحاجة إلى التبديل إلى الدردشة الجديدة. يمكنك معرفة المزيد حول إصدارات الغرف على https://spec.matrix.org/latest/rooms/", - "@roomUpgradeDescription": {}, - "kickUserDescription": "يتم طرد المستخدم من الدردشة ولكن لا يتم حظره. في الدردشات العامة، يمكن للمستخدم الانضمام مرة أخرى في أي وقت.", - "@kickUserDescription": {}, - "createGroupAndInviteUsers": "إنشاء مجموعة ودعوة المستخدمين", - "@createGroupAndInviteUsers": {}, - "groupCanBeFoundViaSearch": "يمكن العثور على المجموعة عبر البحث", - "@groupCanBeFoundViaSearch": {}, - "noUsersFoundWithQuery": "لسوء الحظ، لا يمكن العثور على مستخدم لديه \"{query}\". يرجى التحقق مما إذا كنت قد ارتكبت خطأ كتابي.", - "@noUsersFoundWithQuery": { - "type": "text", - "placeholders": { - "query": {} - } - }, - "yourGlobalUserIdIs": "معرف المستخدم العمومي الخاص بك هو: ", - "@yourGlobalUserIdIs": {}, - "groupName": "أسم المجموعة", - "@groupName": {}, - "searchChatsRooms": "ابحث عن #الدردشات، @المستخدمين...", - "@searchChatsRooms": {}, - "startConversation": "بدء محادثة", - "@startConversation": {}, - "commandHint_sendraw": "إرسال جيسون الخام", - "@commandHint_sendraw": {}, - "wrongRecoveryKey": "عذرًا... لا يبدو أن هذا هو مفتاح الاسترداد الصحيح.", - "@wrongRecoveryKey": {}, - "blockListDescription": "يمكنك حظر المستخدمين الذين يزعجونك. لن تتمكن من تلقي أي رسائل أو دعوات للغرفة من المستخدمين الموجودين في قائمة الحظر الشخصية الخاصة بك.", - "@blockListDescription": {}, - "blockedUsers": "المستخدمون المحظورون", - "@blockedUsers": {}, - "block": "حظر", - "@block": {}, - "blockUsername": "تجاهل اسم المستخدم", - "@blockUsername": {}, - "databaseMigrationTitle": "تم تحسين قاعدة البيانات", - "@databaseMigrationTitle": {}, - "databaseMigrationBody": "انتظر من فضلك. قد يستغرق ذلك بعض الوقت.", - "@databaseMigrationBody": {} -} \ No newline at end of file + "@@locale": "ar", + "@@last_modified": "2021-08-14 12:41:10.156221", + "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": {} + } + }, + "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": {} + } + }, + "banFromChat": "حظر من المحادثة", + "@banFromChat": { + "type": "text", + "placeholders": {} + }, + "banned": "محظور", + "@banned": { + "type": "text", + "placeholders": {} + }, + "bannedUser": "{username} حظر {targetName}", + "@bannedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "blockDevice": "أُحظر الجهاز", + "@blockDevice": { + "type": "text", + "placeholders": {} + }, + "cancel": "ألغِ", + "@cancel": { + "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": {} + } + }, + "changeTheHomeserver": "غيّر الخادم", + "@changeTheHomeserver": { + "type": "text", + "placeholders": {} + }, + "changeTheme": "غيّر أسلوبك", + "@changeTheme": { + "type": "text", + "placeholders": {} + }, + "changeTheNameOfTheGroup": "غيِّر اسم المجموعة", + "@changeTheNameOfTheGroup": { + "type": "text", + "placeholders": {} + }, + "channelCorruptedDecryptError": "فسُد التشفير", + "@channelCorruptedDecryptError": { + "type": "text", + "placeholders": {} + }, + "chat": "محادثة", + "@chat": { + "type": "text", + "placeholders": {} + }, + "chatDetails": "تفاصيل المحادثة", + "@chatDetails": { + "type": "text", + "placeholders": {} + }, + "chooseAStrongPassword": "اختر كلمة سر قوية", + "@chooseAStrongPassword": { + "type": "text", + "placeholders": {} + }, + "close": "اغلق", + "@close": { + "type": "text", + "placeholders": {} + }, + "compareEmojiMatch": "يرجى مقارنة الرموز التعبيرية", + "@compareEmojiMatch": { + "type": "text", + "placeholders": {} + }, + "compareNumbersMatch": "الرجاء مقارنة الأرقام", + "@compareNumbersMatch": { + "type": "text", + "placeholders": {} + }, + "confirm": "أكّد", + "@confirm": { + "type": "text", + "placeholders": {} + }, + "connect": "اتصل", + "@connect": { + "type": "text", + "placeholders": {} + }, + "contactHasBeenInvitedToTheGroup": "دعيَ المراسل للمجموعة", + "@contactHasBeenInvitedToTheGroup": { + "type": "text", + "placeholders": {} + }, + "copiedToClipboard": "نُسخ للحافظة", + "@copiedToClipboard": { + "type": "text", + "placeholders": {} + }, + "copy": "انسخ", + "@copy": { + "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": {} + } + }, + "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": "{day}/{month}/{year}", + "@dateWithYear": { + "type": "text", + "placeholders": { + "year": {}, + "month": {}, + "day": {} + } + }, + "deactivateAccountWarning": "لا مجال للعودة، أتأكد تعطيل حسابك؟", + "@deactivateAccountWarning": { + "type": "text", + "placeholders": {} + }, + "delete": "احذف", + "@delete": { + "type": "text", + "placeholders": {} + }, + "deleteAccount": "احذف الحساب", + "@deleteAccount": { + "type": "text", + "placeholders": {} + }, + "deleteMessage": "حذف الرسالة", + "@deleteMessage": { + "type": "text", + "placeholders": {} + }, + "device": "جهاز", + "@device": { + "type": "text", + "placeholders": {} + }, + "devices": "الأجهزة", + "@devices": { + "type": "text", + "placeholders": {} + }, + "displaynameHasBeenChanged": "غُيِّر الاسم العلني", + "@displaynameHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "downloadFile": "نزِّل الملف", + "@downloadFile": { + "type": "text", + "placeholders": {} + }, + "editDisplayname": "حرر الاسم العلني", + "@editDisplayname": { + "type": "text", + "placeholders": {} + }, + "emoteExists": "الانفعالة موجودة مسبقا!", + "@emoteExists": { + "type": "text", + "placeholders": {} + }, + "emoteInvalid": "رمز الانفعالة غير صالح!", + "@emoteInvalid": { + "type": "text", + "placeholders": {} + }, + "emoteSettings": "اعدادات الانفعالات", + "@emoteSettings": { + "type": "text", + "placeholders": {} + }, + "emoteShortcode": "رمز الانفعالة", + "@emoteShortcode": { + "type": "text", + "placeholders": {} + }, + "emoteWarnNeedToPick": "اختر صورة ورمزا للانفعالة!", + "@emoteWarnNeedToPick": { + "type": "text", + "placeholders": {} + }, + "emptyChat": "محادثة فارغة", + "@emptyChat": { + "type": "text", + "placeholders": {} + }, + "enableEncryptionWarning": "لن يمكنك تعطيل التشفير أبدا، أمتأكد؟", + "@enableEncryptionWarning": { + "type": "text", + "placeholders": {} + }, + "encryption": "التشفير", + "@encryption": { + "type": "text", + "placeholders": {} + }, + "encryptionNotEnabled": "التشفير معطل", + "@encryptionNotEnabled": { + "type": "text", + "placeholders": {} + }, + "endedTheCall": "أنهى {senderName} المكالمة", + "@endedTheCall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "enterYourHomeserver": "أدخل الخادم", + "@enterYourHomeserver": { + "type": "text", + "placeholders": {} + }, + "fileName": "اسم الملف", + "@fileName": { + "type": "text", + "placeholders": {} + }, + "fluffychat": "فلافي-شات", + "@fluffychat": { + "type": "text", + "placeholders": {} + }, + "forward": "أعد التوجيه", + "@forward": { + "type": "text", + "placeholders": {} + }, + "fromJoining": "من بعد الانضمام", + "@fromJoining": { + "type": "text", + "placeholders": {} + }, + "fromTheInvitation": "من بعد الدعوة", + "@fromTheInvitation": { + "type": "text", + "placeholders": {} + }, + "group": "المجموعة", + "@group": { + "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": {} + }, + "hasWithdrawnTheInvitationFor": "سحب {username} دعوة {targetName}", + "@hasWithdrawnTheInvitationFor": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "help": "المساعدة", + "@help": { + "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": {} + }, + "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": {} + }, + "inviteText": "دعاك {username} إلى FluffyChat.\n1. قم بزيارة موقع fluffychat.im وقم بتثبيت التطبيق\n2. قم بإنشاءحساب أو تسجيل الدخول\n3. افتح رابط الدعوة:\n {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": {} + } + }, + "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": {} + }, + "moderator": "مشرف", + "@moderator": { + "type": "text", + "placeholders": {} + }, + "muteChat": "أكتم الماحدثة", + "@muteChat": { + "type": "text", + "placeholders": {} + }, + "needPantalaimonWarning": "اعلم أننا نستخدم بانتاليمون للتشفير طرفا لطرف.", + "@needPantalaimonWarning": { + "type": "text", + "placeholders": {} + }, + "newMessageInFluffyChat": "💬 رسالة جديدة في FluffyChat", + "@newMessageInFluffyChat": { + "type": "text", + "placeholders": {} + }, + "newVerificationRequest": "طلب تحقق جديد!", + "@newVerificationRequest": { + "type": "text", + "placeholders": {} + }, + "no": "لا", + "@no": { + "type": "text", + "placeholders": {} + }, + "noEmotesFound": "لم يُعثر على انفعالة. 😕", + "@noEmotesFound": { + "type": "text", + "placeholders": {} + }, + "noGoogleServicesWarning": "يبدو أن خدمة Firebase Cloud Messaging غير متاحة على جهازك. لمواصلة تلقي الإشعارات، نوصي بتثبيت ntfy. باستخدام ntfy أو أي مزود خدمة Unified Push آخر، يمكنك تلقي إشعارات الدفع بطريقة آمنة للبيانات. يمكنك تنزيل ntfy من PlayStore أو من F-Droid.", + "@noGoogleServicesWarning": { + "type": "text", + "placeholders": {} + }, + "none": "بدون", + "@none": { + "type": "text", + "placeholders": {} + }, + "noPermission": "بدون اذن", + "@noPermission": { + "type": "text", + "placeholders": {} + }, + "noRoomsFound": "لم يُعثر على غرف…", + "@noRoomsFound": { + "type": "text", + "placeholders": {} + }, + "ok": "موافق", + "@ok": { + "type": "text", + "placeholders": {} + }, + "onlineKeyBackupEnabled": "تم تفعيل النسخ الاحتياطي للمفاتيح عبر الإنترنت", + "@onlineKeyBackupEnabled": { + "type": "text", + "placeholders": {} + }, + "oopsSomethingWentWrong": "عذراً، هناك خطأ ما…", + "@oopsSomethingWentWrong": { + "type": "text", + "placeholders": {} + }, + "openAppToReadMessages": "افتح التطبيق لقراءة الرسائل", + "@openAppToReadMessages": { + "type": "text", + "placeholders": {} + }, + "openCamera": "افتح الكميرا", + "@openCamera": { + "type": "text", + "placeholders": {} + }, + "passphraseOrKey": "عبارة المرور أو مفتاح الاستعادة", + "@passphraseOrKey": { + "type": "text", + "placeholders": {} + }, + "password": "كلمة السر", + "@password": { + "type": "text", + "placeholders": {} + }, + "passwordHasBeenChanged": "غُيّرت كلمة السر", + "@passwordHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "pickImage": "اختر صورة", + "@pickImage": { + "type": "text", + "placeholders": {} + }, + "pin": "ثبِّت", + "@pin": { + "type": "text", + "placeholders": {} + }, + "play": "شغّل {fileName}", + "@play": { + "type": "text", + "placeholders": { + "fileName": {} + } + }, + "pleaseEnterYourPassword": "أدخل كلمة السر", + "@pleaseEnterYourPassword": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourUsername": "أدخل اسم المستخدم", + "@pleaseEnterYourUsername": { + "type": "text", + "placeholders": {} + }, + "privacy": "الخصوصية", + "@privacy": { + "type": "text", + "placeholders": {} + }, + "publicRooms": "الغرف العامة", + "@publicRooms": { + "type": "text", + "placeholders": {} + }, + "recording": "يسجل", + "@recording": { + "type": "text", + "placeholders": {} + }, + "redactedAnEvent": "حذف {username} حدثًا", + "@redactedAnEvent": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "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": {} + }, + "reply": "ردّ", + "@reply": { + "type": "text", + "placeholders": {} + }, + "requestPermission": "أطلب إذنا", + "@requestPermission": { + "type": "text", + "placeholders": {} + }, + "roomHasBeenUpgraded": "رُقيّت الغرفة", + "@roomHasBeenUpgraded": { + "type": "text", + "placeholders": {} + }, + "seenByUser": "رآه {username}", + "@seenByUser": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "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": {} + }, + "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": {} + } + }, + "setInvitationLink": "عيّن رابط الدعوة", + "@setInvitationLink": { + "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": {} + } + }, + "skip": "تخط", + "@skip": { + "type": "text", + "placeholders": {} + }, + "sourceCode": "الشفرة المصدرية", + "@sourceCode": { + "type": "text", + "placeholders": {} + }, + "startedACall": "بدأ {senderName} مكالمة", + "@startedACall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "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": "فلافي-شات", + "@title": { + "description": "Title for the application", + "type": "text", + "placeholders": {} + }, + "tryToSendAgain": "حاول إعادة الارسال", + "@tryToSendAgain": { + "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 محادثة غير مقروءة} 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": {} + } + }, + "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": {} + }, + "whoIsAllowedToJoinThisGroup": "من يسمح له الانضمام للمجموعة", + "@whoIsAllowedToJoinThisGroup": { + "type": "text", + "placeholders": {} + }, + "writeAMessage": "اكتب رسالة…", + "@writeAMessage": { + "type": "text", + "placeholders": {} + }, + "yes": "نعم", + "@yes": { + "type": "text", + "placeholders": {} + }, + "you": "انت", + "@you": { + "type": "text", + "placeholders": {} + }, + "youAreNoLongerParticipatingInThisChat": "لم تعد منتسبا لهذه المحادثة", + "@youAreNoLongerParticipatingInThisChat": { + "type": "text", + "placeholders": {} + }, + "youHaveBeenBannedFromThisChat": "حُظرت من هذه المحادثة", + "@youHaveBeenBannedFromThisChat": { + "type": "text", + "placeholders": {} + }, + "people": "أشخاص", + "@people": { + "type": "text", + "placeholders": {} + }, + "scanQrCode": "امسح رمز الاستجابة السريعة", + "@scanQrCode": {}, + "noMatrixServer": "{server1} ليس خادم ماتريكس، بدلًا منه أتريد استخدام {server2}؟", + "@noMatrixServer": { + "type": "text", + "placeholders": { + "server1": {}, + "server2": {} + } + }, + "noConnectionToTheServer": "انقطع الاتصال بالخادم", + "@noConnectionToTheServer": { + "type": "text", + "placeholders": {} + }, + "next": "التالي", + "@next": { + "type": "text", + "placeholders": {} + }, + "newChat": "محادثة جديدة", + "@newChat": { + "type": "text", + "placeholders": {} + }, + "messages": "الرسائل", + "@messages": { + "type": "text", + "placeholders": {} + }, + "mention": "اذكر", + "@mention": { + "type": "text", + "placeholders": {} + }, + "memberChanges": "تغييرات تخص الأعضاء", + "@memberChanges": { + "type": "text", + "placeholders": {} + }, + "inoffensive": "غير مسيء", + "@inoffensive": { + "type": "text", + "placeholders": {} + }, + "iHaveClickedOnLink": "نقرت على الرابط", + "@iHaveClickedOnLink": { + "type": "text", + "placeholders": {} + }, + "ignore": "تجاهل", + "@ignore": { + "type": "text", + "placeholders": {} + }, + "howOffensiveIsThisContent": "ما مدى سوء هذا المحتوى؟", + "@howOffensiveIsThisContent": { + "type": "text", + "placeholders": {} + }, + "hideUnknownEvents": "اخف الأحداث المجهولة", + "@hideUnknownEvents": { + "type": "text", + "placeholders": {} + }, + "groups": "المجموعات", + "@groups": { + "type": "text", + "placeholders": {} + }, + "goToTheNewRoom": "انتقل للغرفة الجديدة", + "@goToTheNewRoom": { + "type": "text", + "placeholders": {} + }, + "fontSize": "حجم الخط", + "@fontSize": { + "type": "text", + "placeholders": {} + }, + "extremeOffensive": "مسيئة للغاية", + "@extremeOffensive": { + "type": "text", + "placeholders": {} + }, + "everythingReady": "كل شيء جاهز!", + "@everythingReady": { + "type": "text", + "placeholders": {} + }, + "homeserver": "الخادم", + "@homeserver": {}, + "enterAnEmailAddress": "أدخل عنوان بريد إلكتروني", + "@enterAnEmailAddress": { + "type": "text", + "placeholders": {} + }, + "encrypted": "مشفر", + "@encrypted": { + "type": "text", + "placeholders": {} + }, + "enableEncryption": "فعّل التشفير", + "@enableEncryption": { + "type": "text", + "placeholders": {} + }, + "emotePacks": "حزمة الوجوه التعبيرية للغرفة", + "@emotePacks": { + "type": "text", + "placeholders": {} + }, + "editRoomAvatar": "عدّل الصورة الرمزية للغرفة", + "@editRoomAvatar": { + "type": "text", + "placeholders": {} + }, + "editBlockedServers": "عدّل الخوادم المحجوبة", + "@editBlockedServers": { + "type": "text", + "placeholders": {} + }, + "edit": "عدّل", + "@edit": { + "type": "text", + "placeholders": {} + }, + "directChats": "محادثات مباشرة", + "@directChats": { + "type": "text", + "placeholders": {} + }, + "deviceId": "معرّف الجهاز", + "@deviceId": { + "type": "text", + "placeholders": {} + }, + "createNewSpace": "مساحة جديدة", + "@createNewSpace": { + "type": "text", + "placeholders": {} + }, + "copyToClipboard": "انسخ الى الحافظة", + "@copyToClipboard": { + "type": "text", + "placeholders": {} + }, + "contentHasBeenReported": "أّرسل الابلاغ الى مدير الخادم", + "@contentHasBeenReported": { + "type": "text", + "placeholders": {} + }, + "containsUserName": "يحوي اسم المستخدم", + "@containsUserName": { + "type": "text", + "placeholders": {} + }, + "containsDisplayName": "يحوي الاسم العلني", + "@containsDisplayName": { + "type": "text", + "placeholders": {} + }, + "commandMissing": "{command} ليس بأمر.", + "@commandMissing": { + "type": "text", + "placeholders": { + "command": {} + }, + "description": "State that {command} is not a valid /command." + }, + "commandInvalid": "أمر غير صالح", + "@commandInvalid": { + "type": "text" + }, + "commandHint_unban": "فك الحظر عن المستخدم المذكور في هذه الغرفة", + "@commandHint_unban": { + "type": "text", + "description": "Usage hint for the command /unban" + }, + "commandHint_send": "أرسل نصًا", + "@commandHint_send": { + "type": "text", + "description": "Usage hint for the command /send" + }, + "commandHint_react": "أرسل ردًا كتفاعل", + "@commandHint_react": { + "type": "text", + "description": "Usage hint for the command /react" + }, + "commandHint_plain": "أرسل نصًا غير منسق", + "@commandHint_plain": { + "type": "text", + "description": "Usage hint for the command /plain" + }, + "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_me": "صف نفسك", + "@commandHint_me": { + "type": "text", + "description": "Usage hint for the command /me" + }, + "commandHint_leave": "تغادر هذه الغرفة", + "@commandHint_leave": { + "type": "text", + "description": "Usage hint for the command /leave" + }, + "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" + }, + "commandHint_invite": "يدعو المستخدم المذكور الى الغرفة", + "@commandHint_invite": { + "type": "text", + "description": "Usage hint for the command /invite" + }, + "commandHint_html": "أرسل نصًا بتنسيق HTML", + "@commandHint_html": { + "type": "text", + "description": "Usage hint for the command /html" + }, + "commandHint_ban": "يحظر المستخدم المذكور من هذه الغرفة", + "@commandHint_ban": { + "type": "text", + "description": "Usage hint for the command /ban" + }, + "clearArchive": "امسح الأرشيف", + "@clearArchive": {}, + "chats": "المحادثات", + "@chats": { + "type": "text", + "placeholders": {} + }, + "chatHasBeenAddedToThisSpace": "أُضيفت المحادثة الى هذا المساحة", + "@chatHasBeenAddedToThisSpace": {}, + "chatBackup": "النسخ الاحتياطي للمحادثات", + "@chatBackup": { + "type": "text", + "placeholders": {} + }, + "changeYourAvatar": "غيّر الصورة الرمزية", + "@changeYourAvatar": { + "type": "text", + "placeholders": {} + }, + "changePassword": "غيّر كلمة السر", + "@changePassword": { + "type": "text", + "placeholders": {} + }, + "changeDeviceName": "غيّر اسم الجهاز", + "@changeDeviceName": { + "type": "text", + "placeholders": {} + }, + "cantOpenUri": "تعذر فتح المسار {uri}", + "@cantOpenUri": { + "type": "text", + "placeholders": { + "uri": {} + } + }, + "blocked": "محجوب", + "@blocked": { + "type": "text", + "placeholders": {} + }, + "sendOnEnter": "أرسل عند الدخول", + "@sendOnEnter": {}, + "autoplayImages": "شغِّل الملصقات والوجوه المتحركة تلقائيا", + "@autoplayImages": { + "type": "text", + "placeholder": {} + }, + "areYouSureYouWantToLogout": "أمتأكد من الخروج؟", + "@areYouSureYouWantToLogout": { + "type": "text", + "placeholders": {} + }, + "appLock": "قفل التطبيق", + "@appLock": { + "type": "text", + "placeholders": {} + }, + "allChats": "كل المحادثات", + "@allChats": { + "type": "text", + "placeholders": {} + }, + "all": "الكل", + "@all": { + "type": "text", + "placeholders": {} + }, + "addToSpace": "أضف إلى المساحة", + "@addToSpace": {}, + "addEmail": "أضف بريدًا إلكترونيًا", + "@addEmail": { + "type": "text", + "placeholders": {} + }, + "noPasswordRecoveryDescription": "لم تضف أي طريقة لاستعادة كلمة السر.", + "@noPasswordRecoveryDescription": { + "type": "text", + "placeholders": {} + }, + "notifications": "الإشعارات", + "@notifications": { + "type": "text", + "placeholders": {} + }, + "reason": "السبب", + "@reason": { + "type": "text", + "placeholders": {} + }, + "search": "ابحث", + "@search": { + "type": "text", + "placeholders": {} + }, + "locationDisabledNotice": "خدمات الموقع معطلة. مكنها لتتمكن من مشاركة موقعك.", + "@locationDisabledNotice": { + "type": "text", + "placeholders": {} + }, + "errorObtainingLocation": "خطأ أثناء الحصول على الموقع: {error}", + "@errorObtainingLocation": { + "type": "text", + "placeholders": { + "error": {} + } + }, + "editRoomAliases": "عدّل الاسم المميز للغرفة", + "@editRoomAliases": { + "type": "text", + "placeholders": {} + }, + "configureChat": "ضبط المحادثة", + "@configureChat": { + "type": "text", + "placeholders": {} + }, + "chatBackupDescription": "يتم تأمين رسائلك القديمة باستخدام مفتاح الاسترداد. يرجى التأكد من أنك لا تضيعه.", + "@chatBackupDescription": { + "type": "text", + "placeholders": {} + }, + "shareLocation": "شارك الموقع", + "@shareLocation": { + "type": "text", + "placeholders": {} + }, + "pleaseChooseAPasscode": "اختر رمز المرور", + "@pleaseChooseAPasscode": { + "type": "text", + "placeholders": {} + }, + "pleaseChoose": "اختر رجاء", + "@pleaseChoose": { + "type": "text", + "placeholders": {} + }, + "passwordRecovery": "استعادة كلمة السر", + "@passwordRecovery": { + "type": "text", + "placeholders": {} + }, + "passwordForgotten": "نسيتَ كلمة السر", + "@passwordForgotten": { + "type": "text", + "placeholders": {} + }, + "participant": "منتسب", + "@participant": { + "type": "text", + "placeholders": {} + }, + "or": "أو", + "@or": { + "type": "text", + "placeholders": {} + }, + "serverRequiresEmail": "يتطلب هذا الخادم التحقق من بريدك الإلكتروني.", + "@serverRequiresEmail": {}, + "link": "رابط", + "@link": {}, + "openInMaps": "افتح في الخريطة", + "@openInMaps": { + "type": "text", + "placeholders": {} + }, + "enableMultiAccounts": "(ميزة تجربية) فعّل تعدد الحسابات", + "@enableMultiAccounts": {}, + "bundleName": "اسم الحزمة", + "@bundleName": {}, + "removeFromBundle": "أزله من الحزمة", + "@removeFromBundle": {}, + "addToBundle": "أضفه الى حزمة", + "@addToBundle": {}, + "editBundlesForAccount": "عدّل حزم هذا الحساب", + "@editBundlesForAccount": {}, + "addAccount": "أضف حسابًا", + "@addAccount": {}, + "online": "متصل", + "@online": { + "type": "text", + "placeholders": {} + }, + "offline": "غير متصل", + "@offline": { + "type": "text", + "placeholders": {} + }, + "numUsersTyping": "{count} يكتبون…", + "@numUsersTyping": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "notificationsEnabledForThisAccount": "الإشعارات مفعلة لهذا الحساب", + "@notificationsEnabledForThisAccount": { + "type": "text", + "placeholders": {} + }, + "spaceIsPublic": "عام في المساحة", + "@spaceIsPublic": { + "type": "text", + "placeholders": {} + }, + "toggleFavorite": "بدّل حالة التفضيل", + "@toggleFavorite": { + "type": "text", + "placeholders": {} + }, + "toggleUnread": "علّمه كمقروء/غير مقروء", + "@toggleUnread": { + "type": "text", + "placeholders": {} + }, + "unavailable": "غير متوفر", + "@unavailable": { + "type": "text", + "placeholders": {} + }, + "whyDoYouWantToReportThis": "لماذا تريد الإبلاغ عنه؟", + "@whyDoYouWantToReportThis": { + "type": "text", + "placeholders": {} + }, + "withTheseAddressesRecoveryDescription": "يمكنك استعادة كلمة السر بهذه العناوين.", + "@withTheseAddressesRecoveryDescription": { + "type": "text", + "placeholders": {} + }, + "singlesignon": "تسجيل دخول أحادي", + "@singlesignon": { + "type": "text", + "placeholders": {} + }, + "toggleMuted": "بدّل حالة الكتم", + "@toggleMuted": { + "type": "text", + "placeholders": {} + }, + "showPassword": "أظهر كلمة السر", + "@showPassword": { + "type": "text", + "placeholders": {} + }, + "verified": "موثّق", + "@verified": { + "type": "text", + "placeholders": {} + }, + "spaceName": "اسم المساحة", + "@spaceName": { + "type": "text", + "placeholders": {} + }, + "synchronizingPleaseWait": "يُزامن… يرجى الانتظار.", + "@synchronizingPleaseWait": { + "type": "text", + "placeholders": {} + }, + "tooManyRequestsWarning": "طابات كثيرة. حاول مجددًا لاحقًا!", + "@tooManyRequestsWarning": { + "type": "text", + "placeholders": {} + }, + "weSentYouAnEmail": "أرسلنا لك رسالة بالبريد الإلكتروني", + "@weSentYouAnEmail": { + "type": "text", + "placeholders": {} + }, + "yourPublicKey": "مفتاحك العمومي", + "@yourPublicKey": { + "type": "text", + "placeholders": {} + }, + "status": "الحالة", + "@status": { + "type": "text", + "placeholders": {} + }, + "transferFromAnotherDevice": "أنقله من جهاز آخر", + "@transferFromAnotherDevice": { + "type": "text", + "placeholders": {} + }, + "wipeChatBackup": "مسح نسخة الدردشة الاحتياطية لإنشاء مفتاح استرداد جديد؟", + "@wipeChatBackup": { + "type": "text", + "placeholders": {} + }, + "saveFile": "احفظ الملف", + "@saveFile": { + "type": "text", + "placeholders": {} + }, + "security": "الأمان", + "@security": { + "type": "text", + "placeholders": {} + }, + "removeYourAvatar": "أزل الصورة الرمزية", + "@removeYourAvatar": { + "type": "text", + "placeholders": {} + }, + "botMessages": "رسائل البوت", + "@botMessages": { + "type": "text", + "placeholders": {} + }, + "sendAsText": "أرسل نصًا", + "@sendAsText": { + "type": "text" + }, + "sendMessages": "إرسال رسائل", + "@sendMessages": { + "type": "text", + "placeholders": {} + }, + "inviteForMe": "دعوات لي", + "@inviteForMe": { + "type": "text", + "placeholders": {} + }, + "replaceRoomWithNewerVersion": "استبدل الغرفة باصدار أحدث", + "@replaceRoomWithNewerVersion": { + "type": "text", + "placeholders": {} + }, + "register": "سجّل", + "@register": { + "type": "text", + "placeholders": {} + }, + "obtainingLocation": "يحصل على الموقع…", + "@obtainingLocation": { + "type": "text", + "placeholders": {} + }, + "sendSticker": "أرسل ملصقًا", + "@sendSticker": { + "type": "text", + "placeholders": {} + }, + "defaultPermissionLevel": "مستوى الأذونات الإفتراضي", + "@defaultPermissionLevel": { + "type": "text", + "placeholders": {} + }, + "setPermissionsLevel": "تعيين مستوى الأذونات", + "@setPermissionsLevel": { + "type": "text", + "placeholders": {} + }, + "setCustomEmotes": "عيّن وجوهًا تعبيرية مخصصة", + "@setCustomEmotes": { + "type": "text", + "placeholders": {} + }, + "oneClientLoggedOut": "أُ خرج أحد العملاء الذي تسختدمها", + "@oneClientLoggedOut": {}, + "pleaseEnter4Digits": "أدخل 4 أرقام أو أتركه فارغ لتعطيل القفل.", + "@pleaseEnter4Digits": { + "type": "text", + "placeholders": {} + }, + "redactMessage": "احذف رسالة", + "@redactMessage": { + "type": "text", + "placeholders": {} + }, + "reportMessage": "أبلغ عن الرسالة", + "@reportMessage": { + "type": "text", + "placeholders": {} + }, + "roomVersion": "إصدار الغرفة", + "@roomVersion": { + "type": "text", + "placeholders": {} + }, + "repeatPassword": "كرّر كلمة السر", + "@repeatPassword": {}, + "removeFromSpace": "أزل من المساحة", + "@removeFromSpace": {}, + "unverified": "غير مؤكد", + "@unverified": {}, + "whoCanPerformWhichAction": "من يستطيع القيام بأي عمل", + "@whoCanPerformWhichAction": { + "type": "text", + "placeholders": {} + }, + "messageInfo": "معلومات الرسالة", + "@messageInfo": {}, + "messageType": "نوع الرسالة", + "@messageType": {}, + "sender": "المرسل", + "@sender": {}, + "openGallery": "افتخ المعرض", + "@openGallery": {}, + "time": "الوقت", + "@time": {}, + "badServerLoginTypesException": "يدعم الخادم المستخدم أنواع تسجيل الدخول التالية:\n{serverVersions}\nلكن هذا التطبيق يدعم فقط:\n{supportedVersions}", + "@badServerLoginTypesException": { + "type": "text", + "placeholders": { + "serverVersions": {}, + "supportedVersions": {} + } + }, + "commandHint_clearcache": "مسح الذاكرة المؤقتة", + "@commandHint_clearcache": { + "type": "text", + "description": "Usage hint for the command /clearcache" + }, + "enableEmotesGlobally": "تفعيل حزمة التعبيرات بشكل عام", + "@enableEmotesGlobally": { + "type": "text", + "placeholders": {} + }, + "hideRedactedEvents": "إخفاء الأحداث المنقحة", + "@hideRedactedEvents": { + "type": "text", + "placeholders": {} + }, + "commandHint_discardsession": "إنهاء الجلسة", + "@commandHint_discardsession": { + "type": "text", + "description": "Usage hint for the command /discardsession" + }, + "locationPermissionDeniedNotice": "تم رفض إذن الموقع. الرجاء منح الإذن للقدرة على مشاركة موقعك.", + "@locationPermissionDeniedNotice": { + "type": "text", + "placeholders": {} + }, + "badServerVersionsException": "يدعم الخادم الرئيسي المستخدم إصدارات المواصفات:\n{serverVersions}\nلكن هذا التطبيق يدعم فقط:\n{supportedVersions}", + "@badServerVersionsException": { + "type": "text", + "placeholders": { + "serverVersions": {}, + "supportedVersions": {} + } + }, + "offensive": "عدواني", + "@offensive": { + "type": "text", + "placeholders": {} + }, + "yourChatBackupHasBeenSetUp": "تم إعداد النسخ الاحتياطي لمحادثاتك.", + "@yourChatBackupHasBeenSetUp": {}, + "noEncryptionForPublicRooms": "يمكنك فقط تفعيل التشفير عندما تصبح الغرفة غير متاحة للعامة.", + "@noEncryptionForPublicRooms": { + "type": "text", + "placeholders": {} + }, + "emojis": "إيموجي", + "@emojis": {}, + "voiceCall": "مكالمة صوتية", + "@voiceCall": {}, + "unsupportedAndroidVersion": "نسخة أندرويد غير مدعومة", + "@unsupportedAndroidVersion": {}, + "unsupportedAndroidVersionLong": "تتطلب هذه الميزة إصدار Android أحدث. يرجى التحقق من وجود تحديثات أو دعم Lineage OS.", + "@unsupportedAndroidVersionLong": {}, + "experimentalVideoCalls": "مكالمات الفيديو التجريبية", + "@experimentalVideoCalls": {}, + "commandHint_create": "أنشأ محادثة جماعية فارغة\nاستخدم --لا-تشفير لتعطيل التشفير", + "@commandHint_create": { + "type": "text", + "description": "Usage hint for the command /create" + }, + "commandHint_dm": "إبدأ محادثة مباشرة\nاستخدم --لا-تشفير لتعطيل التشفير", + "@commandHint_dm": { + "type": "text", + "description": "Usage hint for the command /dm" + }, + "oopsPushError": "عذراً! للأسف، حدث خطأ أثناء إعداد الإشعارات.", + "@oopsPushError": { + "type": "text", + "placeholders": {} + }, + "pleaseFollowInstructionsOnWeb": "يرجى اتباع التعليمات الموجودة على الموقع والنقر على التالي.", + "@pleaseFollowInstructionsOnWeb": { + "type": "text", + "placeholders": {} + }, + "commandHint_myroomavatar": "حدد صورتك لهذه الغرفة (عن طريق mxc-uri)", + "@commandHint_myroomavatar": { + "type": "text", + "description": "Usage hint for the command /myroomavatar" + }, + "videoCallsBetaWarning": "يرجى ملاحظة أن مكالمات الفيديو حالياً في مرحلة تجريبية. قد لا تعمل كما هو متوقع أو تعمل على الإطلاق على جميع المنصات.", + "@videoCallsBetaWarning": {}, + "placeCall": "إجراء مكالمة", + "@placeCall": {}, + "videoWithSize": "فيديو ({size})", + "@videoWithSize": { + "type": "text", + "placeholders": { + "size": {} + } + }, + "emailOrUsername": "البريد الإلكتروني أو اسم المستخدم", + "@emailOrUsername": {}, + "dismiss": "رفض", + "@dismiss": {}, + "setAsCanonicalAlias": "تعيين كاسم مستعار رئيسي", + "@setAsCanonicalAlias": { + "type": "text", + "placeholders": {} + }, + "pleaseClickOnLink": "يرجى النقر على الرابط الموجود في البريد الإلكتروني ثم المتابعة.", + "@pleaseClickOnLink": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourPin": "الرجاء إدخال رقم التعريف الشخصي الخاص بك", + "@pleaseEnterYourPin": { + "type": "text", + "placeholders": {} + }, + "pushRules": "قواعد الإشعارات", + "@pushRules": { + "type": "text", + "placeholders": {} + }, + "reactedWith": "{sender} تفاعل ب {reaction}", + "@reactedWith": { + "type": "text", + "placeholders": { + "sender": {}, + "reaction": {} + } + }, + "markAsRead": "حدد كمقروء", + "@markAsRead": {}, + "openVideoCamera": "افتح الكاميرا لمقطع فيديو", + "@openVideoCamera": { + "type": "text", + "placeholders": {} + }, + "start": "إبدأ", + "@start": {}, + "publish": "انشر", + "@publish": {}, + "addToSpaceDescription": "إختر مساحة لإضافة هذه المحادثة إليها.", + "@addToSpaceDescription": {}, + "reportUser": "التبيلغ عن المستخدم", + "@reportUser": {}, + "openChat": "فتح المحادثة", + "@openChat": {}, + "pinMessage": "تثبيت في الغرفة", + "@pinMessage": {}, + "confirmEventUnpin": "هل أنت متأكد من إلغاء تثبيت الحدث بشكل دائم؟", + "@confirmEventUnpin": {}, + "fileHasBeenSavedAt": "تم حفظ الملف في {path}", + "@fileHasBeenSavedAt": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "user": "مستخدم", + "@user": {}, + "custom": "مُخصّص", + "@custom": {}, + "googlyEyesContent": "{senderName} يرسل لك عيون googly", + "@googlyEyesContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "widgetVideo": "فيديو", + "@widgetVideo": {}, + "recoveryKeyLost": "هل فقدت مفتاح الاسترداد؟", + "@recoveryKeyLost": {}, + "pleaseEnterRecoveryKeyDescription": "لإلغاء قفل رسائلك القديمة ، يرجى إدخال مفتاح الاسترداد الذي تم إنشاؤه في جلسة سابقة. مفتاح الاسترداد ليس كلمة المرور الخاصة بك.", + "@pleaseEnterRecoveryKeyDescription": {}, + "confirmMatrixId": "يرجى تأكيد معرف Matrix الخاص بك من أجل حذف حسابك.", + "@confirmMatrixId": {}, + "supposedMxid": "يجب أن يكون هذا {mxid}", + "@supposedMxid": { + "type": "text", + "placeholders": { + "mxid": {} + } + }, + "hydrateTor": "مستخدمو تور: استيراد تصدير الجلسة", + "@hydrateTor": {}, + "commandHint_googly": "أرسل بعض عيون googly", + "@commandHint_googly": {}, + "commandHint_cuddle": "أرسل عناق", + "@commandHint_cuddle": {}, + "commandHint_hug": "إرسال حضن", + "@commandHint_hug": {}, + "cuddleContent": "{senderName} يحتضنك", + "@cuddleContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "unlockOldMessages": "إلغاء قفل الرسائل القديمة", + "@unlockOldMessages": {}, + "commandHint_markasdm": "وضع علامة على أنها غرفة رسائل مباشرة لمعرف المصفوفة", + "@commandHint_markasdm": {}, + "allRooms": "جميع الدردشات الجماعية", + "@allRooms": { + "type": "text", + "placeholders": {} + }, + "dehydrate": "تصدير الجلسة ومسح الجهاز", + "@dehydrate": {}, + "dehydrateWarning": "لا يمكن التراجع عن هذا الإجراء. تأكد من تخزين ملف النسخ الاحتياطي بأمان.", + "@dehydrateWarning": {}, + "dehydrateTorLong": "بالنسبة لمستخدمي تور ، يوصى بتصدير الجلسة قبل إغلاق النافذة.", + "@dehydrateTorLong": {}, + "dehydrateTor": "مستخدمو تور: تصدير الجلسة", + "@dehydrateTor": {}, + "hydrate": "استعادة من ملف النسخ الاحتياطي", + "@hydrate": {}, + "pleaseEnterRecoveryKey": "الرجاء إدخال مفتاح الاسترداد:", + "@pleaseEnterRecoveryKey": {}, + "recoveryKey": "مفتاح الاسترداد", + "@recoveryKey": {}, + "startFirstChat": "ابدأ محادثتك الأولى", + "@startFirstChat": {}, + "widgetCustom": "مُخصّص", + "@widgetCustom": {}, + "widgetNameError": "يرجى تقديم اسم العرض.", + "@widgetNameError": {}, + "errorAddingWidget": "خطأ في إضافة الأداة.", + "@errorAddingWidget": {}, + "youRejectedTheInvitation": "لقد رفضت الدعوة", + "@youRejectedTheInvitation": {}, + "youJoinedTheChat": "لقد انضممت إلى الدردشة", + "@youJoinedTheChat": {}, + "youAcceptedTheInvitation": "👍 لقد قبلت الدعوة", + "@youAcceptedTheInvitation": {}, + "youBannedUser": "لقد حظرت {user}", + "@youBannedUser": { + "placeholders": { + "user": {} + } + }, + "youHaveWithdrawnTheInvitationFor": "لقد سحبت الدعوة لـ {user}", + "@youHaveWithdrawnTheInvitationFor": { + "placeholders": { + "user": {} + } + }, + "youInvitedBy": "📩 لقد تمت دعوتك من قبل {user}", + "@youInvitedBy": { + "placeholders": { + "user": {} + } + }, + "storeInAndroidKeystore": "تخزين في سجل مفاتيح اندرويد", + "@storeInAndroidKeystore": {}, + "storeInAppleKeyChain": "تخزين في سلسلة مفاتيح ابل", + "@storeInAppleKeyChain": {}, + "storeSecurlyOnThisDevice": "احفظه بأمان على هذا الجهاز", + "@storeSecurlyOnThisDevice": {}, + "countFiles": "ملفات {count}", + "@countFiles": { + "placeholders": { + "count": {} + } + }, + "foregroundServiceRunning": "يظهر هذا الإشعار عند تشغيل الخدمة الأمامية.", + "@foregroundServiceRunning": {}, + "screenSharingTitle": "مشاركة الشاشة", + "@screenSharingTitle": {}, + "appearOnTop": "يظهر في الأعلى", + "@appearOnTop": {}, + "otherCallingPermissions": "الميكروفون والكاميرا وأذونات FluffyChat الأخرى", + "@otherCallingPermissions": {}, + "enterSpace": "أدخل المساحة", + "@enterSpace": {}, + "enterRoom": "أدخل الغرفة", + "@enterRoom": {}, + "deviceKeys": "مفاتيح الجهاز:", + "@deviceKeys": {}, + "whyIsThisMessageEncrypted": "لماذا هذه الرسالة غير قابلة للقراءة؟", + "@whyIsThisMessageEncrypted": {}, + "nextAccount": "الحساب التالي", + "@nextAccount": {}, + "previousAccount": "الحساب السابق", + "@previousAccount": {}, + "encryptThisChat": "تشفير هذه الدردشة", + "@encryptThisChat": {}, + "screenSharingDetail": "أنت تشارك شاشتك في FuffyChat", + "@screenSharingDetail": {}, + "hideUnimportantStateEvents": "إخفاء أحداث الحالة غير المهمة", + "@hideUnimportantStateEvents": {}, + "newGroup": "مجموعة جديدة", + "@newGroup": {}, + "youKicked": "👞 لقد ركلت {user}", + "@youKicked": { + "placeholders": { + "user": {} + } + }, + "newSpace": "مساحة جديدة", + "@newSpace": {}, + "commandHint_markasgroup": "وضع علامة كمجموعة", + "@commandHint_markasgroup": {}, + "separateChatTypes": "الدردشات المباشرة والمجموعات المنفصلة", + "@separateChatTypes": { + "type": "text", + "placeholders": {} + }, + "hugContent": "{senderName} يعانقك", + "@hugContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "hydrateTorLong": "هل قمت بتصدير جلستك الأخيرة على تور؟ قم باستيراده بسرعة واستمر في الدردشة.", + "@hydrateTorLong": {}, + "widgetUrlError": "هذا ليس عنوان URL صالحًا.", + "@widgetUrlError": {}, + "indexedDbErrorTitle": "مشاكل الوضع الخاص", + "@indexedDbErrorTitle": {}, + "indexedDbErrorLong": "للأسف ، لم يتم تمكين تخزين الرسائل في الوضع الخاص افتراضيا.\nيرجى زيارة\n - حول:التكوين\n - تعيين dom.indexedDB.privateBrowsing.enabled إلى true\nخلاف ذلك ، لا يمكن تشغيل FluffyChat.", + "@indexedDbErrorLong": {}, + "switchToAccount": "التبديل إلى الحساب {number}", + "@switchToAccount": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "addWidget": "إضافة اداة", + "@addWidget": {}, + "widgetEtherpad": "ملاحظة نصية", + "@widgetEtherpad": {}, + "youKickedAndBanned": "🙅 لقد ركلت وحظرت {user}", + "@youKickedAndBanned": { + "placeholders": { + "user": {} + } + }, + "youUnbannedUser": "قمت بإلغاء الحظر {user}", + "@youUnbannedUser": { + "placeholders": { + "user": {} + } + }, + "saveKeyManuallyDescription": "احفظ هذا المفتاح يدويا عن طريق تشغيل مربع حوار مشاركة النظام أو الحافظة.", + "@saveKeyManuallyDescription": {}, + "widgetJitsi": "اجتماعات جيتسي", + "@widgetJitsi": {}, + "youInvitedUser": "📩 قمت بدعوة {user}", + "@youInvitedUser": { + "placeholders": { + "user": {} + } + }, + "storeInSecureStorageDescription": "قم بتخزين مفتاح الاسترداد في التخزين الآمن لهذا الجهاز.", + "@storeInSecureStorageDescription": {}, + "widgetName": "الاسم", + "@widgetName": {}, + "users": "المستخدمون", + "@users": {}, + "callingPermissions": "أذونات الاتصال", + "@callingPermissions": {}, + "callingAccount": "الاتصال بالحساب", + "@callingAccount": {}, + "callingAccountDetails": "يسمح لـ FluffyChat باستخدام تطبيق android Dialer الأصلي.", + "@callingAccountDetails": {}, + "appearOnTopDetails": "يسمح للتطبيق بالظهور في الأعلى (ليست هناك حاجة إذا قمت بالفعل بإعداد Fluffychat كحساب اتصال)", + "@appearOnTopDetails": {}, + "numChats": "{number} الدردشات", + "@numChats": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "jump": "قفز", + "@jump": {}, + "report": "التقرير", + "@report": {}, + "noKeyForThisMessage": "يمكن أن يحدث هذا إذا تم إرسال الرسالة قبل تسجيل الدخول إلى حسابك على هذا الجهاز.\n\nمن الممكن أيضا أن يكون المرسل قد حظر جهازك أو حدث خطأ ما في الاتصال بالإنترنت.\n\nهل يمكنك قراءة الرسالة في جلسة أخرى؟ ثم يمكنك نقل الرسالة منه! انتقل إلى الإعدادات > الأجهزة وتأكد من أن أجهزتك قد تحققت من بعضها البعض. عندما تفتح الغرفة في المرة التالية وتكون كلتا الجلستين في المقدمة ، سيتم إرسال المفاتيح تلقائيا.\n\nألا تريد أن تفقد المفاتيح عند تسجيل الخروج أو تبديل الأجهزة؟ تأكد من تمكين النسخ الاحتياطي للدردشة في الإعدادات.", + "@noKeyForThisMessage": {}, + "allSpaces": "كل المساحات", + "@allSpaces": {}, + "doNotShowAgain": "لا تظهر مرة أخرى", + "@doNotShowAgain": {}, + "wasDirectChatDisplayName": "محادثة فارغة (كانت {oldDisplayName})", + "@wasDirectChatDisplayName": { + "type": "text", + "placeholders": { + "oldDisplayName": {} + } + }, + "disableEncryptionWarning": "لأسباب أمنية ، لا يمكنك تعطيل التشفير في الدردشة ، حيث تم تمكينه من قبل.", + "@disableEncryptionWarning": {}, + "reportErrorDescription": "😭 أوه لا. هناك خطأ ما. إذا كنت تريد، يمكنك الإبلاغ عن هذا الخطأ إلى المطورين.", + "@reportErrorDescription": {}, + "newSpaceDescription": "يسمح لك تطبيق المساحات بتوحيد دردشاتك وبناء مجتمعات خاصة أو عامة.", + "@newSpaceDescription": {}, + "sorryThatsNotPossible": "معذرة... هذا غير ممكن", + "@sorryThatsNotPossible": {}, + "openLinkInBrowser": "فتح الرابط في المتصفح", + "@openLinkInBrowser": {}, + "reopenChat": "إعادة فتح الدردشة", + "@reopenChat": {}, + "noBackupWarning": "تحذير! بدون تمكين النسخ الاحتياطي للدردشة ، ستفقد الوصول إلى رسائلك المشفرة. يوصى بشدة بتمكين النسخ الاحتياطي للدردشة أولاً قبل تسجيل الخروج.", + "@noBackupWarning": {}, + "noOtherDevicesFound": "لم يتم العثور على أجهزة أخرى", + "@noOtherDevicesFound": {}, + "fileIsTooBigForServer": "أبلغ الخادم أن الملف كبير جدًا بحيث لا يمكن إرساله.", + "@fileIsTooBigForServer": {}, + "jumpToLastReadMessage": "الانتقال إلى آخر رسالة مقروءة", + "@jumpToLastReadMessage": {}, + "readUpToHere": "اقرأ حتى هنا", + "@readUpToHere": {}, + "signInWithPassword": "سجل الدخول بكلمة السر", + "@signInWithPassword": {}, + "pleaseTryAgainLaterOrChooseDifferentServer": "رجاء حاول مجددا أو اختر خادما مختلفا.", + "@pleaseTryAgainLaterOrChooseDifferentServer": {}, + "signInWith": "تسجيل الدخول باستخدام {provider}", + "@signInWith": { + "type": "text", + "placeholders": { + "provider": {} + } + }, + "importNow": "استيراد الآن", + "@importNow": {}, + "importEmojis": "استيراد الرموز التعبيرية", + "@importEmojis": {}, + "exportEmotePack": "تصدير حزمة الرموز التعبيرية بتنسيق zip", + "@exportEmotePack": {}, + "notAnImage": "ليس ملف صورة.", + "@notAnImage": {}, + "importFromZipFile": "الاستيراد من ملف .zip", + "@importFromZipFile": {}, + "replace": "استبدال", + "@replace": {}, + "sendTypingNotifications": "إرسال إشعارات الكتابة", + "@sendTypingNotifications": {}, + "createGroup": "إنشاء مجموعة", + "@createGroup": {}, + "messagesStyle": "الرسائل:", + "@messagesStyle": {}, + "shareInviteLink": "شارك رابط الدعوة", + "@shareInviteLink": {}, + "profileNotFound": "لا يمكن العثور على المستخدم على الخادم. ربما هناك مشكلة في الاتصال أو المستخدم غير موجود.", + "@profileNotFound": {}, + "setTheme": "تعيين السمة:", + "@setTheme": {}, + "setColorTheme": "تعيين لون السمة:", + "@setColorTheme": {}, + "inviteContactToGroupQuestion": "هل تريد دعوة {contact} إلى المحادثة \"{groupName}\"؟?", + "@inviteContactToGroupQuestion": {}, + "tryAgain": "أعد المحاولة", + "@tryAgain": {}, + "redactMessageDescription": "سيتم تنقيح الرسالة لجميع المشاركين في هذه المحادثة. هذا لا يمكن التراجع عنها.", + "@redactMessageDescription": {}, + "optionalRedactReason": "(اختياري) سبب تنقيح هذه الرسالة ...", + "@optionalRedactReason": {}, + "redactedBy": "منقح بواسطة {username}", + "@redactedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "redactedByBecause": "تم حجبه بواسطة {username} بسبب: \"{reason}\"", + "@redactedByBecause": { + "type": "text", + "placeholders": { + "username": {}, + "reason": {} + } + }, + "invite": "دعوة", + "@invite": {}, + "addChatDescription": "أضف وصفًا للدردشة...", + "@addChatDescription": {}, + "chatPermissions": "صلاحيات المحادثة", + "@chatPermissions": {}, + "chatDescription": "وصف الدردشة", + "@chatDescription": {}, + "chatDescriptionHasBeenChanged": "تغير وصف المجموعة", + "@chatDescriptionHasBeenChanged": {}, + "noChatDescriptionYet": "لم يتم إنشاء وصف للمحادثة حتى الآن.", + "@noChatDescriptionYet": {}, + "invalidServerName": "اسم الخادم غير متاح", + "@invalidServerName": {}, + "setChatDescription": "تعيين وصفًا للدردشة", + "@setChatDescription": {}, + "directChat": "محادثة مباشرة", + "@directChat": {}, + "inviteGroupChat": "📨 دعوة الدردشة الجماعية", + "@inviteGroupChat": {}, + "invitePrivateChat": "📨 دعوة دردشة خاصة", + "@invitePrivateChat": {}, + "emoteKeyboardNoRecents": "التعبيرات المستخدمة مؤخرًا ستظهر هنا ...", + "@emoteKeyboardNoRecents": { + "type": "text", + "placeholders": {} + }, + "invalidInput": "مدخل غير صالح!", + "@invalidInput": {}, + "wrongPinEntered": "تم إدخال رمز خاطئ! حاول مرة أخرى خلال {seconds} ثانية...", + "@wrongPinEntered": { + "type": "text", + "placeholders": { + "seconds": {} + } + }, + "hasKnocked": "لقد طرق {user}", + "@hasKnocked": { + "placeholders": { + "user": {} + } + }, + "pleaseEnterANumber": "الرجاء إدخال رقم أكبر من 0", + "@pleaseEnterANumber": {}, + "banUserDescription": "سيتم حظر المستخدم من الدردشة ولن يتمكن من الدخول إلى الدردشة مرة أخرى حتى يتم رفع الحظر عنه.", + "@banUserDescription": {}, + "removeDevicesDescription": "سيتم تسجيل خروجك من هذا الجهاز ولن تتمكن بعد ذلك من تلقي الرسائل.", + "@removeDevicesDescription": {}, + "unbanUserDescription": "سيتمكن المستخدم من الدخول إلى الدردشة مرة أخرى إذا حاول.", + "@unbanUserDescription": {}, + "pushNotificationsNotAvailable": "دفع الإخطارات غير متوفرة", + "@pushNotificationsNotAvailable": {}, + "makeAdminDescription": "بمجرد تعيين هذا المستخدم كمسؤول، قد لا تتمكن من التراجع عن هذا لأنه سيكون لديه نفس الأذونات التي تتمتع بها.", + "@makeAdminDescription": {}, + "archiveRoomDescription": "سيتم نقل الدردشة إلى الأرشيف. سيتمكن المستخدمون الآخرون من رؤية أنك غادرت الدردشة.", + "@archiveRoomDescription": {}, + "learnMore": "تعلم المزيد", + "@learnMore": {}, + "roomUpgradeDescription": "سيتم بعد ذلك إعادة إنشاء الدردشة باستخدام إصدار الغرفة الجديد. سيتم إخطار جميع المشاركين بأنهم بحاجة إلى التبديل إلى الدردشة الجديدة. يمكنك معرفة المزيد حول إصدارات الغرف على https://spec.matrix.org/latest/rooms/", + "@roomUpgradeDescription": {}, + "kickUserDescription": "يتم طرد المستخدم من الدردشة ولكن لا يتم حظره. في الدردشات العامة، يمكن للمستخدم الانضمام مرة أخرى في أي وقت.", + "@kickUserDescription": {}, + "createGroupAndInviteUsers": "إنشاء مجموعة ودعوة المستخدمين", + "@createGroupAndInviteUsers": {}, + "groupCanBeFoundViaSearch": "يمكن العثور على المجموعة عبر البحث", + "@groupCanBeFoundViaSearch": {}, + "noUsersFoundWithQuery": "لسوء الحظ، لا يمكن العثور على مستخدم لديه \"{query}\". يرجى التحقق مما إذا كنت قد ارتكبت خطأ كتابي.", + "@noUsersFoundWithQuery": { + "type": "text", + "placeholders": { + "query": {} + } + }, + "yourGlobalUserIdIs": "معرف المستخدم العمومي الخاص بك هو: ", + "@yourGlobalUserIdIs": {}, + "groupName": "أسم المجموعة", + "@groupName": {}, + "searchChatsRooms": "ابحث عن #الدردشات، @المستخدمين...", + "@searchChatsRooms": {}, + "startConversation": "بدء محادثة", + "@startConversation": {}, + "commandHint_sendraw": "إرسال جيسون الخام", + "@commandHint_sendraw": {}, + "wrongRecoveryKey": "عذرًا... لا يبدو أن هذا هو مفتاح الاسترداد الصحيح.", + "@wrongRecoveryKey": {}, + "blockListDescription": "يمكنك حظر المستخدمين الذين يزعجونك. لن تتمكن من تلقي أي رسائل أو دعوات للغرفة من المستخدمين الموجودين في قائمة الحظر الشخصية الخاصة بك.", + "@blockListDescription": {}, + "blockedUsers": "المستخدمون المحظورون", + "@blockedUsers": {}, + "block": "حظر", + "@block": {}, + "blockUsername": "تجاهل اسم المستخدم", + "@blockUsername": {}, + "databaseMigrationTitle": "تم تحسين قاعدة البيانات", + "@databaseMigrationTitle": {}, + "databaseMigrationBody": "انتظر من فضلك. قد يستغرق ذلك بعض الوقت.", + "@databaseMigrationBody": {}, + "thisDevice": "هذا الجهاز:", + "@thisDevice": {}, + "publicSpaces": "مساحة عامة", + "@publicSpaces": {}, + "passwordIsWrong": "كلمة السر للدخول خاطئة", + "@passwordIsWrong": {}, + "pleaseEnterYourCurrentPassword": "من فضلك أدخل كلمة السر الحالية", + "@pleaseEnterYourCurrentPassword": {}, + "publicLink": "رابط عام", + "@publicLink": {}, + "nothingFound": "لم نجد شيئاً.", + "@nothingFound": {}, + "decline": "رفض", + "@decline": {}, + "newPassword": "كلمة المرور الجديدة", + "@newPassword": {}, + "passwordsDoNotMatch": "كلمات المرور لا تتطابق", + "@passwordsDoNotMatch": {}, + "subspace": "مساحة فرعية", + "@subspace": {}, + "select": "اختر", + "@select": {}, + "pleaseChooseAStrongPassword": "الرجاء اختيار كلمة مرور قوية", + "@pleaseChooseAStrongPassword": {}, + "addChatOrSubSpace": "إضافة دردشة أو مساحة فرعية", + "@addChatOrSubSpace": {}, + "leaveEmptyToClearStatus": "اتركه فارغًا لمسح حالتك.", + "@leaveEmptyToClearStatus": {}, + "joinSpace": "انضم إلى المساحة", + "@joinSpace": {}, + "searchForUsers": "ابحث عن @users...", + "@searchForUsers": {}, + "databaseBuildErrorBody": "غير قادر على بناء قاعدة بيانات SQlite. يحاول التطبيق استخدام قاعدة بيانات قديمة في الوقت الحالي. الرجاء الإبلاغ عن هذا الخطأ للمطورين على {url}. رسالة الخطأ هي: {error}", + "@databaseBuildErrorBody": { + "type": "text", + "placeholders": { + "url": {}, + "error": {} + } + }, + "initAppError": "حدث خطأ بداخل التطبيق", + "@initAppError": {}, + "sessionLostBody": "جلستك مفقودة يرجى إبلاغ المطورين بهذا الخطأ في {url}. رسالة الخطأ هي: {error}", + "@sessionLostBody": { + "type": "text", + "placeholders": { + "url": {}, + "error": {} + } + }, + "restoreSessionBody": "يحاول التطبيق الآن استعادة جلستك من النسخة الاحتياطية. الرجاء الإبلاغ عن هذا الخطأ للمطورين على {url}. رسالة الخطأ هي:{error}", + "@restoreSessionBody": { + "type": "text", + "placeholders": { + "url": {}, + "error": {} + } + }, + "completedKeyVerification": "أكمل {sender} عملية التحقق من المفتاح", + "@completedKeyVerification": { + "type": "text", + "placeholders": { + "sender": {} + } + }, + "requestedKeyVerification": "طلب {sender} التحقق من المفتاح", + "@requestedKeyVerification": { + "type": "text", + "placeholders": { + "sender": {} + } + }, + "transparent": "شفّاف", + "@transparent": {}, + "youInvitedToBy": "📩 تمت دعوتك عبر الرابط إلى:\n{alias}", + "@youInvitedToBy": { + "placeholders": { + "alias": {} + } + }, + "formattedMessagesDescription": "عرض محتوى الرسالة الغنية مثل النص الغامق باستخدام الماركداون.", + "@formattedMessagesDescription": {}, + "verifyOtherUserDescription": "إذا قمت بالتحقق من مستخدم آخر، فيمكنك التأكد من أنك تعرف من تكتب إليه حقًا. 💪\n\nعند بدء عملية التحقق، سترى أنت والمستخدم الآخر نافذة منبثقة في التطبيق. هناك سترى بعد ذلك سلسلة من الرموز التعبيرية أو الأرقام التي يتعين عليك مقارنتها مع بعضها البعض.\n\nأفضل طريقة للقيام بذلك هي الالتقاء أو بدء مكالمة فيديو. 👭", + "@verifyOtherUserDescription": {}, + "verifyOtherDeviceDescription": "عند التحقق من جهاز آخر، يمكن لهذه الأجهزة تبادل المفاتيح، مما يزيد من أمانك بشكل عام. 💪 عند بدء عملية التحقق، ستظهر نافذة منبثقة في التطبيق على كلا الجهازين. هناك سترى بعد ذلك سلسلة من الرموز التعبيرية أو الأرقام التي يتعين عليك مقارنتها مع بعضها البعض. من الأفضل أن يكون كلا الجهازين في متناول يديك قبل بدء عملية التحقق. 🤳", + "@verifyOtherDeviceDescription": {}, + "formattedMessages": "رسائل منسقة", + "@formattedMessages": {}, + "sendReadReceipts": "إرسال بالقراءة", + "@sendReadReceipts": {}, + "verifyOtherDevice": "🔐 التحقق من الجهاز الآخر", + "@verifyOtherDevice": {}, + "forwardMessageTo": "هل تريد إعادة توجيه الرسالة إلى {roomName}؟", + "@forwardMessageTo": { + "type": "text", + "placeholders": { + "roomName": {} + } + }, + "sendTypingNotificationsDescription": "يستطيع المشاركون الآخرون في الدردشة رؤيتك عند كتابة رسالة جديدة.", + "@sendTypingNotificationsDescription": {}, + "sendReadReceiptsDescription": "يمكن للمشاركين الآخرين في الدردشة معرفة متى قرأت رسالة.", + "@sendReadReceiptsDescription": {}, + "verifyOtherUser": "🔐 التحقق من المستخدم الآخر", + "@verifyOtherUser": {}, + "acceptedKeyVerification": "وافق {sender} على التحقق من المفتاح", + "@acceptedKeyVerification": { + "type": "text", + "placeholders": { + "sender": {} + } + }, + "canceledKeyVerification": "قام {sender} بإلغاء التحقق من المفتاح", + "@canceledKeyVerification": { + "type": "text", + "placeholders": { + "sender": {} + } + }, + "isReadyForKeyVerification": "{sender} جاهز للتحقق من المفتاح", + "@isReadyForKeyVerification": { + "type": "text", + "placeholders": { + "sender": {} + } + }, + "startedKeyVerification": "بدأ {sender} عملية التحقق من المفتاح", + "@startedKeyVerification": { + "type": "text", + "placeholders": { + "sender": {} + } + }, + "hidePresences": "إخفاء قائمة الحالة؟", + "@hidePresences": {}, + "incomingMessages": "الرسائل الواردة", + "@incomingMessages": {}, + "presenceStyle": "الحضور:", + "@presenceStyle": { + "type": "text", + "placeholders": {} + }, + "presencesToggle": "إظهار رسائل الحالة من المستخدمين الآخرين", + "@presencesToggle": { + "type": "text", + "placeholders": {} + } +} diff --git a/assets/l10n/intl_be.arb b/assets/l10n/intl_be.arb new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/assets/l10n/intl_be.arb @@ -0,0 +1 @@ +{} diff --git a/assets/l10n/intl_de.arb b/assets/l10n/intl_de.arb index 3e1465c50c..13bf1c48a4 100644 --- a/assets/l10n/intl_de.arb +++ b/assets/l10n/intl_de.arb @@ -2182,7 +2182,7 @@ "@doNotShowAgain": {}, "appearOnTopDetails": "Ermöglicht, dass die App oben angezeigt wird (nicht erforderlich, wenn Sie Fluffychat bereits als Anrufkonto eingerichtet haben)", "@appearOnTopDetails": {}, - "noKeyForThisMessage": "Dies kann passieren, wenn die Nachricht gesendet wurde, bevor du dich auf diesem Gerät bei deinem Konto angemeldet hast.\n\nEs ist auch möglich, dass der Absender dein Gerät blockiert hat oder etwas mit der Internetverbindung schief gelaufen ist.\n\nKannst du die Nachricht in einer anderen Sitzung lesen? Dann kannst du die Nachricht davon übertragen! Gehe zu denEinstellungen > Geräte und vergewissere dich, dass sich deine Geräte gegenseitig verifiziert haben. Wenn du den Raum das nächste Mal öffnest und beide Sitzungen im Vordergrund sind, werden die Schlüssel automatisch übertragen.\n\nDu möchtest die Schlüssel beim Abmelden oder Gerätewechsel nicht verlieren? Stelle sicher, dass du das Chat-Backup in den Einstellungen aktiviert hast.", + "noKeyForThisMessage": "Dies kann passieren, wenn die Nachricht gesendet wurde, bevor du dich auf diesem Gerät bei deinem Konto angemeldet hast.\n\nEs ist auch möglich, dass der Absender dein Gerät blockiert hat oder etwas mit der Internetverbindung schief gelaufen ist.\n\nKannst du die Nachricht in einer anderen Sitzung lesen? Dann kannst du die Nachricht davon übertragen! Gehe zu den Einstellungen > Geräte und vergewissere dich, dass sich deine Geräte gegenseitig verifiziert haben. Wenn du den Raum das nächste Mal öffnest und beide Sitzungen im Vordergrund sind, werden die Schlüssel automatisch übertragen.\n\nDu möchtest die Schlüssel beim Abmelden oder Gerätewechsel nicht verlieren? Stelle sicher, dass du das Chat-Backup in den Einstellungen aktiviert hast.", "@noKeyForThisMessage": {}, "foregroundServiceRunning": "Diese Benachrichtigung wird angezeigt, wenn der Vordergrunddienst ausgeführt wird.", "@foregroundServiceRunning": {}, @@ -2485,5 +2485,106 @@ "joinSpace": "Space beitreten", "@joinSpace": {}, "searchForUsers": "Suche nach @benutzer ...", - "@searchForUsers": {} + "@searchForUsers": {}, + "initAppError": "Beim Starten der App ist ein Fehler aufgetreten", + "@initAppError": {}, + "databaseBuildErrorBody": "Die SQlite-Datenbank kann nicht erstellt werden. Die App versucht vorerst, die Legacy-Datenbank zu verwenden. Bitte melde diesen Fehler an die Entwickler unter {url}. Die Fehlermeldung lautet: {error}", + "@databaseBuildErrorBody": { + "type": "text", + "placeholders": { + "url": {}, + "error": {} + } + }, + "sessionLostBody": "Die App versucht nun, deine Sitzung aus der Sicherung wiederherzustellen. Bitte melde diesen Fehler an die Entwickler unter {url}. Die Fehlermeldung lautet: {error}", + "@sessionLostBody": { + "type": "text", + "placeholders": { + "url": {}, + "error": {} + } + }, + "restoreSessionBody": "Die App versucht nun, deine Sitzung aus der Sicherung wiederherzustellen. Bitte melde diesen Fehler an die Entwickler unter {url}. Die Fehlermeldung lautet: {error}", + "@restoreSessionBody": { + "type": "text", + "placeholders": { + "url": {}, + "error": {} + } + }, + "youInvitedToBy": "📩 Du wurdest per Link eingeladen zu:\n{alias}", + "@youInvitedToBy": { + "placeholders": { + "alias": {} + } + }, + "sendReadReceipts": "Lesebestätigungen senden", + "@sendReadReceipts": {}, + "formattedMessages": "Formatierte Nachrichten", + "@formattedMessages": {}, + "forwardMessageTo": "Nachricht weiterleiten an {roomName}?", + "@forwardMessageTo": { + "type": "text", + "placeholders": { + "roomName": {} + } + }, + "sendTypingNotificationsDescription": "Andere Teilnehmer in einem Chat können sehen, wenn du eine neue Nachricht tippst.", + "@sendTypingNotificationsDescription": {}, + "formattedMessagesDescription": "Formatierte Nachrichteninhalte wie fettgedruckten Text mit Markdown anzeigen.", + "@formattedMessagesDescription": {}, + "verifyOtherUser": "🔐 Anderen Benutzer verifizieren", + "@verifyOtherUser": {}, + "sendReadReceiptsDescription": "Andere Teilnehmer in einem Chat können sehen, ob du eine Nachricht gelesen hast.", + "@sendReadReceiptsDescription": {}, + "transparent": "Transparent", + "@transparent": {}, + "verifyOtherDevice": "🔐 Anderes Gerät verifizieren", + "@verifyOtherDevice": {}, + "verifyOtherUserDescription": "Wenn du einen anderen Benutzer verifizierst, kannst du sicher sein, dass du weißt, an wen du wirklich schreibst. 💪\n\nWenn du eine Verifizierung startest, wird dir und dem anderen Nutzer ein Popup in der App angezeigt. Dort siehst du dann eine Reihe von Emojis oder Zahlen, die ihr miteinander vergleichen müsst.\n\nDas geht am besten, wenn man sich trifft oder einen Videoanruf startet. 👭", + "@verifyOtherUserDescription": {}, + "acceptedKeyVerification": "{sender} hat die Schlüsselverifikation akzeptiert", + "@acceptedKeyVerification": { + "type": "text", + "placeholders": { + "sender": {} + } + }, + "canceledKeyVerification": "{sender} hat die Schlüsselverifikation abgebrochen", + "@canceledKeyVerification": { + "type": "text", + "placeholders": { + "sender": {} + } + }, + "completedKeyVerification": "{sender} hat die Schlüsselverifikation abgeschlossen", + "@completedKeyVerification": { + "type": "text", + "placeholders": { + "sender": {} + } + }, + "isReadyForKeyVerification": "{sender} ist bereit für die Schlüsselverifikation", + "@isReadyForKeyVerification": { + "type": "text", + "placeholders": { + "sender": {} + } + }, + "requestedKeyVerification": "{sender} hat eine Schlüsselverifikation angefragt", + "@requestedKeyVerification": { + "type": "text", + "placeholders": { + "sender": {} + } + }, + "startedKeyVerification": "{sender} hat die Schlüsselverifikation gestartet", + "@startedKeyVerification": { + "type": "text", + "placeholders": { + "sender": {} + } + }, + "verifyOtherDeviceDescription": "Wenn Sie ein anderes Gerät verifizieren, können diese Geräteschlüssel austauschen, was Ihre Sicherheit insgesamt erhöht. 💪 Wenn Sie eine Verifizierung starten, erscheint ein Pop-up in der App auf beiden Geräten. Dort sehen Sie dann eine Reihe von Emojis oder Zahlen, die Sie miteinander vergleichen müssen. Am besten hältst du beide Geräte bereit, bevor du die Verifizierung startest. 🤳", + "@verifyOtherDeviceDescription": {} } diff --git a/assets/l10n/intl_el.arb b/assets/l10n/intl_el.arb index a1c51b58db..438016473b 100644 --- a/assets/l10n/intl_el.arb +++ b/assets/l10n/intl_el.arb @@ -1,2420 +1,2420 @@ { - "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": {} - }, - "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": {} - }, - "chatHasBeenAddedToThisSpace": "", - "@chatHasBeenAddedToThisSpace": {}, - "reply": "", - "@reply": { - "type": "text", - "placeholders": {} - }, - "currentlyActive": "", - "@currentlyActive": { - "type": "text", - "placeholders": {} - }, - "removeYourAvatar": "", - "@removeYourAvatar": { - "type": "text", - "placeholders": {} - }, - "unsupportedAndroidVersion": "", - "@unsupportedAndroidVersion": {}, - "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": {}, - "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" - }, - "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": {} - }, - "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": {} - }, - "id": "", - "@id": { - "type": "text", - "placeholders": {} - }, - "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": {} - } - }, - "removeDevice": "", - "@removeDevice": { - "type": "text", - "placeholders": {} - }, - "unbanUserDescription": "", - "@unbanUserDescription": {}, - "userAndUserAreTyping": "", - "@userAndUserAreTyping": { - "type": "text", - "placeholders": { - "username": {}, - "username2": {} - } - }, - "pleaseClickOnLink": "", - "@pleaseClickOnLink": { - "type": "text", - "placeholders": {} - }, - "saveFile": "", - "@saveFile": { - "type": "text", - "placeholders": {} - }, - "sendOnEnter": "", - "@sendOnEnter": {}, - "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": {} - } - }, - "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": {}, - "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": {}, - "hideRedactedEvents": "", - "@hideRedactedEvents": { - "type": "text", - "placeholders": {} - }, - "online": "", - "@online": { - "type": "text", - "placeholders": {} - }, - "signInWithPassword": "", - "@signInWithPassword": {}, - "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": {}, - "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": {}, - "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": {} - }, - "compareEmojiMatch": "", - "@compareEmojiMatch": { - "type": "text", - "placeholders": {} - }, - "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": {}, - "help": "", - "@help": { - "type": "text", - "placeholders": {} - }, - "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": {}, - "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": {} - }, - "recording": "", - "@recording": { - "type": "text", - "placeholders": {} - }, - "changedTheChatPermissions": "", - "@changedTheChatPermissions": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "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": {} - }, - "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": {} - } - }, - "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": {} - }, - "pleaseChooseAPasscode": "", - "@pleaseChooseAPasscode": { - "type": "text", - "placeholders": {} - }, - "noPasswordRecoveryDescription": "", - "@noPasswordRecoveryDescription": { - "type": "text", - "placeholders": {} - }, - "changedTheProfileAvatar": "", - "@changedTheProfileAvatar": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "allChats": "", - "@allChats": { - "type": "text", - "placeholders": {} - }, - "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": {} - }, - "addToSpace": "", - "@addToSpace": {}, - "unbanFromChat": "", - "@unbanFromChat": { - "type": "text", - "placeholders": {} - }, - "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": {} - }, - "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": {} - }, - "noPermission": "", - "@noPermission": { - "type": "text", - "placeholders": {} - }, - "doNotShowAgain": "", - "@doNotShowAgain": {}, - "activatedEndToEndEncryption": "", - "@activatedEndToEndEncryption": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "report": "", - "@report": {}, - "status": "", - "@status": { - "type": "text", - "placeholders": {} - }, - "compareNumbersMatch": "", - "@compareNumbersMatch": { - "type": "text", - "placeholders": {} - }, - "groupIsPublic": "", - "@groupIsPublic": { - "type": "text", - "placeholders": {} - }, - "verifyStart": "", - "@verifyStart": { - "type": "text", - "placeholders": {} - }, - "memberChanges": "", - "@memberChanges": { - "type": "text", - "placeholders": {} - }, - "joinRoom": "", - "@joinRoom": { - "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": {} - } - }, - "youBannedUser": "", - "@youBannedUser": { - "placeholders": { - "user": {} - } - }, - "theyDontMatch": "", - "@theyDontMatch": { - "type": "text", - "placeholders": {} - }, - "youHaveBeenBannedFromThisChat": "", - "@youHaveBeenBannedFromThisChat": { - "type": "text", - "placeholders": {} - }, - "displaynameHasBeenChanged": "", - "@displaynameHasBeenChanged": { - "type": "text", - "placeholders": {} - }, - "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": {}, - "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": {} - }, - "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": {}, - "removeFromSpace": "", - "@removeFromSpace": {}, - "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": {} - }, - "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": {}, - "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": {} - }, - "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": {} - }, - "passwordForgotten": "", - "@passwordForgotten": { - "type": "text", - "placeholders": {} - }, - "statusExampleMessage": "", - "@statusExampleMessage": { - "type": "text", - "placeholders": {} - }, - "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": {}, - "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": {} - }, - "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": {}, - "anyoneCanJoin": "", - "@anyoneCanJoin": { - "type": "text", - "placeholders": {} - }, - "emotePacks": "", - "@emotePacks": { - "type": "text", - "placeholders": {} - }, - "indexedDbErrorTitle": "", - "@indexedDbErrorTitle": {}, - "endedTheCall": "", - "@endedTheCall": { - "type": "text", - "placeholders": { - "senderName": {} - } - } -} \ No newline at end of file + "showPassword": "", + "@showPassword": { + "type": "text", + "placeholders": {} + }, + "hugContent": "{senderName} σε αγκαλιάζει", + "@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": {} + }, + "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": {} + }, + "chatHasBeenAddedToThisSpace": "", + "@chatHasBeenAddedToThisSpace": {}, + "reply": "", + "@reply": { + "type": "text", + "placeholders": {} + }, + "currentlyActive": "", + "@currentlyActive": { + "type": "text", + "placeholders": {} + }, + "removeYourAvatar": "", + "@removeYourAvatar": { + "type": "text", + "placeholders": {} + }, + "unsupportedAndroidVersion": "", + "@unsupportedAndroidVersion": {}, + "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": {}, + "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" + }, + "singlesignon": "", + "@singlesignon": { + "type": "text", + "placeholders": {} + }, + "warning": "", + "@warning": { + "type": "text", + "placeholders": {} + }, + "password": "", + "@password": { + "type": "text", + "placeholders": {} + }, + "allSpaces": "", + "@allSpaces": {}, + "supposedMxid": "Αυτό θα πρέπει να είναι {mxid}", + "@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": {} + }, + "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": {} + }, + "id": "", + "@id": { + "type": "text", + "placeholders": {} + }, + "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": {} + } + }, + "removeDevice": "", + "@removeDevice": { + "type": "text", + "placeholders": {} + }, + "unbanUserDescription": "", + "@unbanUserDescription": {}, + "userAndUserAreTyping": "", + "@userAndUserAreTyping": { + "type": "text", + "placeholders": { + "username": {}, + "username2": {} + } + }, + "pleaseClickOnLink": "", + "@pleaseClickOnLink": { + "type": "text", + "placeholders": {} + }, + "saveFile": "", + "@saveFile": { + "type": "text", + "placeholders": {} + }, + "sendOnEnter": "Αποστολή με enter", + "@sendOnEnter": {}, + "pickImage": "", + "@pickImage": { + "type": "text", + "placeholders": {} + }, + "answeredTheCall": "{senderName} απάντησε στην κλήση", + "@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": {} + } + }, + "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": {}, + "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": "Ο homeserver υποστηρίζει τους τύπους σύνδεσης:\n{serverVersions}\nΑλλά αυτή η εφαρμογή υποστηρίζει μόνο:\n{supportedVersions}", + "@badServerLoginTypesException": { + "type": "text", + "placeholders": { + "serverVersions": {}, + "supportedVersions": {} + } + }, + "wipeChatBackup": "", + "@wipeChatBackup": { + "type": "text", + "placeholders": {} + }, + "cantOpenUri": "Δεν μπορεί να ανοίξει το URI {uri}", + "@cantOpenUri": { + "type": "text", + "placeholders": { + "uri": {} + } + }, + "sender": "", + "@sender": {}, + "storeInAndroidKeystore": "", + "@storeInAndroidKeystore": {}, + "hideRedactedEvents": "", + "@hideRedactedEvents": { + "type": "text", + "placeholders": {} + }, + "online": "", + "@online": { + "type": "text", + "placeholders": {} + }, + "signInWithPassword": "", + "@signInWithPassword": {}, + "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": "Εισαγωγή από αρχείο .zip", + "@importFromZipFile": {}, + "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": {}, + "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": "Αυτόματη αναπαραγωγή κινούμενων αυτοκόλλητων και emotes", + "@autoplayImages": { + "type": "text", + "placeholder": {} + }, + "compareEmojiMatch": "", + "@compareEmojiMatch": { + "type": "text", + "placeholders": {} + }, + "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": {}, + "help": "", + "@help": { + "type": "text", + "placeholders": {} + }, + "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": {}, + "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": {} + }, + "recording": "", + "@recording": { + "type": "text", + "placeholders": {} + }, + "changedTheChatPermissions": "", + "@changedTheChatPermissions": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "moderator": "", + "@moderator": { + "type": "text", + "placeholders": {} + }, + "optionalRedactReason": "", + "@optionalRedactReason": {}, + "acceptedTheInvitation": "👍 {username} αποδέχτηκε την πρόσκληση", + "@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": "Εξαγωγή πακέτου Emote ως .zip", + "@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": {} + }, + "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": {} + } + }, + "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": {} + }, + "pleaseChooseAPasscode": "", + "@pleaseChooseAPasscode": { + "type": "text", + "placeholders": {} + }, + "noPasswordRecoveryDescription": "", + "@noPasswordRecoveryDescription": { + "type": "text", + "placeholders": {} + }, + "changedTheProfileAvatar": "", + "@changedTheProfileAvatar": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "allChats": "Όλες οι συνομιλίες", + "@allChats": { + "type": "text", + "placeholders": {} + }, + "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": "Ο homeserver υποστηρίζει τις εκδόσεις Spec:\n{serverVersions}\nΑλλά αυτή η εφαρμογή υποστηρίζει μόνο τις {supportedVersions}", + "@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": {} + }, + "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": {} + }, + "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": {} + }, + "noPermission": "", + "@noPermission": { + "type": "text", + "placeholders": {} + }, + "doNotShowAgain": "", + "@doNotShowAgain": {}, + "activatedEndToEndEncryption": "🔐 {username} ενεργοποίησε κρυπτογράφηση από άκρη σε άκρη", + "@activatedEndToEndEncryption": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "report": "", + "@report": {}, + "status": "", + "@status": { + "type": "text", + "placeholders": {} + }, + "compareNumbersMatch": "", + "@compareNumbersMatch": { + "type": "text", + "placeholders": {} + }, + "groupIsPublic": "", + "@groupIsPublic": { + "type": "text", + "placeholders": {} + }, + "verifyStart": "", + "@verifyStart": { + "type": "text", + "placeholders": {} + }, + "memberChanges": "", + "@memberChanges": { + "type": "text", + "placeholders": {} + }, + "joinRoom": "", + "@joinRoom": { + "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": "{senderName} σας στέλνει googly eyes", + "@googlyEyesContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "youBannedUser": "", + "@youBannedUser": { + "placeholders": { + "user": {} + } + }, + "theyDontMatch": "", + "@theyDontMatch": { + "type": "text", + "placeholders": {} + }, + "youHaveBeenBannedFromThisChat": "", + "@youHaveBeenBannedFromThisChat": { + "type": "text", + "placeholders": {} + }, + "displaynameHasBeenChanged": "", + "@displaynameHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "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": {}, + "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": "Εισαγωγή Emojis", + "@importEmojis": {}, + "confirm": "", + "@confirm": { + "type": "text", + "placeholders": {} + }, + "wasDirectChatDisplayName": "", + "@wasDirectChatDisplayName": { + "type": "text", + "placeholders": { + "oldDisplayName": {} + } + }, + "noChatDescriptionYet": "", + "@noChatDescriptionYet": {}, + "defaultPermissionLevel": "", + "@defaultPermissionLevel": { + "type": "text", + "placeholders": {} + }, + "removeFromBundle": "", + "@removeFromBundle": {}, + "numUsersTyping": "", + "@numUsersTyping": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "fontSize": "", + "@fontSize": { + "type": "text", + "placeholders": {} + }, + "whoCanPerformWhichAction": "", + "@whoCanPerformWhichAction": { + "type": "text", + "placeholders": {} + }, + "confirmMatrixId": "Παρακαλούμε επιβεβαιώστε το Matrix ID σας για να διαγράψετε τον λογαριασμό σας.", + "@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": {}, + "removeFromSpace": "", + "@removeFromSpace": {}, + "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": {} + }, + "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": "{username} banned {targetName}", + "@bannedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "sorryThatsNotPossible": "", + "@sorryThatsNotPossible": {}, + "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": "{senderName} σε αγκαλιάζει", + "@cuddleContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "askVerificationRequest": "Αποδοχή αυτού του αιτήματος επαλήθευσης από {username};", + "@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": "Προσθήκη email", + "@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": {} + }, + "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": {} + }, + "passwordForgotten": "", + "@passwordForgotten": { + "type": "text", + "placeholders": {} + }, + "statusExampleMessage": "", + "@statusExampleMessage": { + "type": "text", + "placeholders": {} + }, + "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": {}, + "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": "Μηνύματα bot", + "@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": {} + }, + "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": {}, + "anyoneCanJoin": "Οποιοσδήποτε μπορεί να συμμετάσχει", + "@anyoneCanJoin": { + "type": "text", + "placeholders": {} + }, + "emotePacks": "", + "@emotePacks": { + "type": "text", + "placeholders": {} + }, + "indexedDbErrorTitle": "", + "@indexedDbErrorTitle": {}, + "endedTheCall": "", + "@endedTheCall": { + "type": "text", + "placeholders": { + "senderName": {} + } + } +} diff --git a/assets/l10n/intl_en.arb b/assets/l10n/intl_en.arb index 0783205a60..c0e3aa28be 100644 --- a/assets/l10n/intl_en.arb +++ b/assets/l10n/intl_en.arb @@ -1601,11 +1601,6 @@ "type": "text", "placeholders": {} }, - "renderRichContent": "Render rich message content", - "@renderRichContent": { - "type": "text", - "placeholders": {} - }, "replaceRoomWithNewerVersion": "Replace room with newer version", "@replaceRoomWithNewerVersion": { "type": "text", @@ -1811,6 +1806,16 @@ "type": "text", "placeholders": {} }, + "presenceStyle": "Presence:", + "@presenceStyle": { + "type": "text", + "placeholders": {} + }, + "presencesToggle": "Show status messages from other users", + "@presencesToggle": { + "type": "text", + "placeholders": {} + }, "singlesignon": "Single Sign on", "@singlesignon": { "type": "text", @@ -2261,6 +2266,12 @@ "user": {} } }, + "youInvitedToBy": "📩 You have been invited via link to:\n{alias}", + "@youInvitedToBy": { + "placeholders": { + "alias": {} + } + }, "youInvitedBy": "📩 You have been invited by {user}", "@youInvitedBy": { "placeholders": { @@ -2361,6 +2372,7 @@ } }, "hideUnimportantStateEvents": "Hide unimportant state events", + "hidePresences": "Hide Status List?", "doNotShowAgain": "Do not show again", "wasDirectChatDisplayName": "Empty chat (was {oldDisplayName})", "@wasDirectChatDisplayName": { @@ -3887,6 +3899,16 @@ "conversationLanguageLevel": "What is the language level of this conversation?", "showDefinition": "Show Definition", "acceptedKeyVerification": "{sender} accepted key verification", + "sendReadReceipts": "Send read receipts", + "sendTypingNotificationsDescription": "Other participants in a chat can see when you are typing a new message.", + "sendReadReceiptsDescription": "Other participants in a chat can see when you have read a message.", + "formattedMessages": "Formatted messages", + "formattedMessagesDescription": "Display rich message content like bold text using markdown.", + "verifyOtherUser": "🔐 Verify other user", + "verifyOtherUserDescription": "If you verify another user, you can be sure that you know who you are really writing to. 💪\n\nWhen you start a verification, you and the other user will see a popup in the app. There you will then see a series of emojis or numbers that you have to compare with each other.\n\nThe best way to do this is to meet up or start a video call. 👭", + "verifyOtherDevice": "🔐 Verify other device", + "verifyOtherDeviceDescription": "When you verify another device, those devices can exchange keys, increasing your overall security. 💪 When you start a verification, a popup will appear in the app on both devices. There you will then see a series of emojis or numbers that you have to compare with each other. It's best to have both devices handy before you start the verification. 🤳", + "acceptedKeyVerification": "{sender} accepted key verification", "@acceptedKeyVerification": { "type": "text", "placeholders": { @@ -3952,5 +3974,20 @@ "joinToView": "Join this room to view details", "refresh": "Refresh", "autoPlayTitle": "Auto Play Messages", - "autoPlayDesc": "When enabled, the text-to-speech audio of messages will play automatically when selected." + "autoPlayDesc": "When enabled, the text-to-speech audio of messages will play automatically when selected.", + "transparent": "Transparent", + "incomingMessages": "Incoming messages", + "stickers": "Stickers", + "discover": "Discover", + "commandHint_ignore": "Ignore the given matrix ID", + "commandHint_unignore": "Unignore the given matrix ID", + "unreadChatsInApp": "{appname}: {unread} unread chats", + "@unreadChatsInApp": { + "type": "text", + "placeholders": { + "appname": {}, + "unread": {} + } + }, + "messageAnalytics": "Message Analytics" } \ No newline at end of file diff --git a/assets/l10n/intl_et.arb b/assets/l10n/intl_et.arb index fbbde16d59..e0f38b29ee 100644 --- a/assets/l10n/intl_et.arb +++ b/assets/l10n/intl_et.arb @@ -1,2457 +1,2604 @@ { - "@@locale": "et", - "@@last_modified": "2021-08-14 12:41:10.079944", - "about": "Rakenduse teave", - "@about": { - "type": "text", - "placeholders": {} - }, - "accept": "Nõustu", - "@accept": { - "type": "text", - "placeholders": {} - }, - "acceptedTheInvitation": "👍 {username} võttis kutse vastu", - "@acceptedTheInvitation": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "account": "Kasutajakonto", - "@account": { - "type": "text", - "placeholders": {} - }, - "activatedEndToEndEncryption": "🔐{username} võttis kasutusele läbiva krüptimise", - "@activatedEndToEndEncryption": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "addEmail": "Lisa e-posti aadress", - "@addEmail": { - "type": "text", - "placeholders": {} - }, - "admin": "Peakasutaja", - "@admin": { - "type": "text", - "placeholders": {} - }, - "alias": "alias", - "@alias": { - "type": "text", - "placeholders": {} - }, - "all": "Kõik", - "@all": { - "type": "text", - "placeholders": {} - }, - "allChats": "Kõik vestlused", - "@allChats": { - "type": "text", - "placeholders": {} - }, - "answeredTheCall": "{senderName} vastas kõnele", - "@answeredTheCall": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "anyoneCanJoin": "Kõik võivad liituda", - "@anyoneCanJoin": { - "type": "text", - "placeholders": {} - }, - "appLock": "Rakenduse lukustus", - "@appLock": { - "type": "text", - "placeholders": {} - }, - "archive": "Arhiiv", - "@archive": { - "type": "text", - "placeholders": {} - }, - "areGuestsAllowedToJoin": "Kas külalised võivad liituda", - "@areGuestsAllowedToJoin": { - "type": "text", - "placeholders": {} - }, - "areYouSure": "Kas sa oled kindel?", - "@areYouSure": { - "type": "text", - "placeholders": {} - }, - "areYouSureYouWantToLogout": "Kas sa oled kindel, et soovid välja logida?", - "@areYouSureYouWantToLogout": { - "type": "text", - "placeholders": {} - }, - "askSSSSSign": "Selleks, et teist osapoolt identifitseerivat allkirja anda, palun sisesta oma turvahoidla paroolifraas või taastevõti.", - "@askSSSSSign": { - "type": "text", - "placeholders": {} - }, - "askVerificationRequest": "Kas võtad vastu selle verifitseerimispalve kasutajalt {username}?", - "@askVerificationRequest": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "autoplayImages": "Esita liikuvad kleepse ja emotikone automaatselt", - "@autoplayImages": { - "type": "text", - "placeholder": {} - }, - "badServerLoginTypesException": "See koduserver toetab Matrixi võrku sisselogimiseks:\n{serverVersions}\nAga see rakendus toetab vaid järgmisi võimalusi:\n{supportedVersions}", - "@badServerLoginTypesException": { - "type": "text", - "placeholders": { - "serverVersions": {}, - "supportedVersions": {} - } - }, - "badServerVersionsException": "See koduserver toetab Matrixi spetsifikatsioonist järgmisi versioone:\n{serverVersions}\nAga see rakendus toetab vaid järgmisi versioone: {supportedVersions}", - "@badServerVersionsException": { - "type": "text", - "placeholders": { - "serverVersions": {}, - "supportedVersions": {} - } - }, - "banFromChat": "Keela ligipääs vestlusele", - "@banFromChat": { - "type": "text", - "placeholders": {} - }, - "banned": "Ligipääs vestlusele on keelatud", - "@banned": { - "type": "text", - "placeholders": {} - }, - "bannedUser": "{username} keelas ligipääsu kasutajale {targetName}", - "@bannedUser": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "blockDevice": "Blokeeri seade", - "@blockDevice": { - "type": "text", - "placeholders": {} - }, - "blocked": "Blokeeritud", - "@blocked": { - "type": "text", - "placeholders": {} - }, - "botMessages": "Robotite sõnumid", - "@botMessages": { - "type": "text", - "placeholders": {} - }, - "cancel": "Katkesta", - "@cancel": { - "type": "text", - "placeholders": {} - }, - "cantOpenUri": "{uri} aadressi avamine ei õnnestu", - "@cantOpenUri": { - "type": "text", - "placeholders": { - "uri": {} - } - }, - "changeDeviceName": "Muuda seadme nime", - "@changeDeviceName": { - "type": "text", - "placeholders": {} - }, - "changedTheChatAvatar": "{username} muutis vestluse tunnuspilti", - "@changedTheChatAvatar": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheChatDescriptionTo": "{username} muutis vestluse uueks kirjelduseks „{description}“", - "@changedTheChatDescriptionTo": { - "type": "text", - "placeholders": { - "username": {}, - "description": {} - } - }, - "changedTheChatNameTo": "{username} muutis oma uueks kuvatavaks nimeks „{chatname}“", - "@changedTheChatNameTo": { - "type": "text", - "placeholders": { - "username": {}, - "chatname": {} - } - }, - "changedTheChatPermissions": "{username} muutis vestlusega seotud õigusi", - "@changedTheChatPermissions": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheDisplaynameTo": "{username} muutis uueks kuvatavaks nimeks: {displayname}", - "@changedTheDisplaynameTo": { - "type": "text", - "placeholders": { - "username": {}, - "displayname": {} - } - }, - "changedTheGuestAccessRules": "{username} muutis külaliste ligipääsureegleid", - "@changedTheGuestAccessRules": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheGuestAccessRulesTo": "{username} muutis külaliste ligipääsureegleid järgnevalt: {rules}", - "@changedTheGuestAccessRulesTo": { - "type": "text", - "placeholders": { - "username": {}, - "rules": {} - } - }, - "changedTheHistoryVisibility": "{username} muutis sõnumite ajaloo nähtavust", - "@changedTheHistoryVisibility": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheHistoryVisibilityTo": "{username} muutis sõnumite ajaloo nähtavust järgnevalt: {rules}", - "@changedTheHistoryVisibilityTo": { - "type": "text", - "placeholders": { - "username": {}, - "rules": {} - } - }, - "changedTheJoinRules": "{username} muutis liitumise reegleid", - "@changedTheJoinRules": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheJoinRulesTo": "{username} muutis liitumise reegleid järgnevalt: {joinRules}", - "@changedTheJoinRulesTo": { - "type": "text", - "placeholders": { - "username": {}, - "joinRules": {} - } - }, - "changedTheProfileAvatar": "{username} muutis oma tunnuspilti", - "@changedTheProfileAvatar": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheRoomAliases": "{username} muutis jututoa aliast", - "@changedTheRoomAliases": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changedTheRoomInvitationLink": "{username} muutis kutse linki", - "@changedTheRoomInvitationLink": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "changePassword": "Muuda salasõna", - "@changePassword": { - "type": "text", - "placeholders": {} - }, - "changeTheHomeserver": "Muuda koduserverit", - "@changeTheHomeserver": { - "type": "text", - "placeholders": {} - }, - "changeTheme": "Muuda oma stiili", - "@changeTheme": { - "type": "text", - "placeholders": {} - }, - "changeTheNameOfTheGroup": "Muuda vestlusrühma nime", - "@changeTheNameOfTheGroup": { - "type": "text", - "placeholders": {} - }, - "changeYourAvatar": "Muuda oma tunnuspilti", - "@changeYourAvatar": { - "type": "text", - "placeholders": {} - }, - "channelCorruptedDecryptError": "Kasutatud krüptimine on vigane", - "@channelCorruptedDecryptError": { - "type": "text", - "placeholders": {} - }, - "chat": "Vestlus", - "@chat": { - "type": "text", - "placeholders": {} - }, - "chatBackup": "Varunda vestlus", - "@chatBackup": { - "type": "text", - "placeholders": {} - }, - "chatBackupDescription": "Sinu vestluste varukoopia on krüptitud taastamiseks mõeldud turvavõtmega. Palun vaata, et sa seda ei kaota.", - "@chatBackupDescription": { - "type": "text", - "placeholders": {} - }, - "chatDetails": "Vestluse teave", - "@chatDetails": { - "type": "text", - "placeholders": {} - }, - "chats": "Vestlused", - "@chats": { - "type": "text", - "placeholders": {} - }, - "chooseAStrongPassword": "Vali korralik salasõna", - "@chooseAStrongPassword": { - "type": "text", - "placeholders": {} - }, - "clearArchive": "Kustuta arhiiv", - "@clearArchive": {}, - "close": "Sulge", - "@close": { - "type": "text", - "placeholders": {} - }, - "commandHint_ban": "Sea sellele kasutajale antud jututoas suhtluskeeld", - "@commandHint_ban": { - "type": "text", - "description": "Usage hint for the command /ban" - }, - "commandHint_html": "Saada HTML-vormingus tekst", - "@commandHint_html": { - "type": "text", - "description": "Usage hint for the command /html" - }, - "commandHint_invite": "Kutsu see kasutaja antud jututuppa", - "@commandHint_invite": { - "type": "text", - "description": "Usage hint for the command /invite" - }, - "commandHint_join": "Liitu selle jututoaga", - "@commandHint_join": { - "type": "text", - "description": "Usage hint for the command /join" - }, - "commandHint_kick": "Eemalda antud kasutaja sellest jututoast", - "@commandHint_kick": { - "type": "text", - "description": "Usage hint for the command /kick" - }, - "commandHint_leave": "Lahku sellest jututoast", - "@commandHint_leave": { - "type": "text", - "description": "Usage hint for the command /leave" - }, - "commandHint_me": "Kirjelda ennast", - "@commandHint_me": { - "type": "text", - "description": "Usage hint for the command /me" - }, - "commandHint_myroomavatar": "Määra selles jututoas oma tunnuspilt (mxc-uri vahendusel)", - "@commandHint_myroomavatar": { - "type": "text", - "description": "Usage hint for the command /myroomavatar" - }, - "commandHint_myroomnick": "Määra selles jututoas oma kuvatav nimi", - "@commandHint_myroomnick": { - "type": "text", - "description": "Usage hint for the command /myroomnick" - }, - "commandHint_op": "Seadista selle kasutaja õigusi (vaikimisi: 50)", - "@commandHint_op": { - "type": "text", - "description": "Usage hint for the command /op" - }, - "commandHint_plain": "Saada vormindamata tekst", - "@commandHint_plain": { - "type": "text", - "description": "Usage hint for the command /plain" - }, - "commandHint_react": "Saada vastus reaktsioonina", - "@commandHint_react": { - "type": "text", - "description": "Usage hint for the command /react" - }, - "commandHint_send": "Saada sõnum", - "@commandHint_send": { - "type": "text", - "description": "Usage hint for the command /send" - }, - "commandHint_unban": "Eemalda sellelt kasutajalt antud jututoas suhtluskeeld", - "@commandHint_unban": { - "type": "text", - "description": "Usage hint for the command /unban" - }, - "commandInvalid": "Vigane käsk", - "@commandInvalid": { - "type": "text" - }, - "commandMissing": "{command} ei ole käsk.", - "@commandMissing": { - "type": "text", - "placeholders": { - "command": {} - }, - "description": "State that {command} is not a valid /command." - }, - "compareEmojiMatch": "Palun võrdle emotikone", - "@compareEmojiMatch": { - "type": "text", - "placeholders": {} - }, - "compareNumbersMatch": "Palun võrdle numbreid", - "@compareNumbersMatch": { - "type": "text", - "placeholders": {} - }, - "configureChat": "Seadista vestlust", - "@configureChat": { - "type": "text", - "placeholders": {} - }, - "confirm": "Kinnita", - "@confirm": { - "type": "text", - "placeholders": {} - }, - "connect": "Ühenda", - "@connect": { - "type": "text", - "placeholders": {} - }, - "contactHasBeenInvitedToTheGroup": "Sinu kontakt on kutsutud liituma vestlusrühma", - "@contactHasBeenInvitedToTheGroup": { - "type": "text", - "placeholders": {} - }, - "containsDisplayName": "Sisaldab kuvatavat nime", - "@containsDisplayName": { - "type": "text", - "placeholders": {} - }, - "containsUserName": "Sisaldab kasutajanime", - "@containsUserName": { - "type": "text", - "placeholders": {} - }, - "contentHasBeenReported": "Saatsime selle sisu kohta teate koduserveri haldajate", - "@contentHasBeenReported": { - "type": "text", - "placeholders": {} - }, - "copiedToClipboard": "Kopeerisin lõikelauale", - "@copiedToClipboard": { - "type": "text", - "placeholders": {} - }, - "copy": "Kopeeri", - "@copy": { - "type": "text", - "placeholders": {} - }, - "copyToClipboard": "Kopeeri lõikelauale", - "@copyToClipboard": { - "type": "text", - "placeholders": {} - }, - "couldNotDecryptMessage": "Sõnumi dekrüptimine ei õnnestunud: {error}", - "@couldNotDecryptMessage": { - "type": "text", - "placeholders": { - "error": {} - } - }, - "countParticipants": "{count} osalejat", - "@countParticipants": { - "type": "text", - "placeholders": { - "count": {} - } - }, - "create": "Loo", - "@create": { - "type": "text", - "placeholders": {} - }, - "createdTheChat": "💬 {username} algatas vestluse", - "@createdTheChat": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "createNewSpace": "Uus kogukond", - "@createNewSpace": { - "type": "text", - "placeholders": {} - }, - "currentlyActive": "Hetkel aktiivne", - "@currentlyActive": { - "type": "text", - "placeholders": {} - }, - "darkTheme": "Tume", - "@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": "Järgnevaga eemaldatakse sinu konto kasutusest. Seda tegevust ei saa tagasi pöörata! Kas sa ikka oled kindel?", - "@deactivateAccountWarning": { - "type": "text", - "placeholders": {} - }, - "defaultPermissionLevel": "Vaikimisi õigused", - "@defaultPermissionLevel": { - "type": "text", - "placeholders": {} - }, - "delete": "Kustuta", - "@delete": { - "type": "text", - "placeholders": {} - }, - "deleteAccount": "Kustuta kasutajakonto", - "@deleteAccount": { - "type": "text", - "placeholders": {} - }, - "deleteMessage": "Kustuta sõnum", - "@deleteMessage": { - "type": "text", - "placeholders": {} - }, - "device": "Seade", - "@device": { - "type": "text", - "placeholders": {} - }, - "deviceId": "Seadme tunnus", - "@deviceId": { - "type": "text", - "placeholders": {} - }, - "devices": "Seadmed", - "@devices": { - "type": "text", - "placeholders": {} - }, - "directChats": "Otsevestlused", - "@directChats": { - "type": "text", - "placeholders": {} - }, - "displaynameHasBeenChanged": "Kuvatav nimi on muudetud", - "@displaynameHasBeenChanged": { - "type": "text", - "placeholders": {} - }, - "downloadFile": "Laadi fail alla", - "@downloadFile": { - "type": "text", - "placeholders": {} - }, - "edit": "Muuda", - "@edit": { - "type": "text", - "placeholders": {} - }, - "editBlockedServers": "Muuda blokeeritud serverite loendit", - "@editBlockedServers": { - "type": "text", - "placeholders": {} - }, - "editDisplayname": "Muuda kuvatavat nime", - "@editDisplayname": { - "type": "text", - "placeholders": {} - }, - "editRoomAliases": "Muuda jututoa aliast", - "@editRoomAliases": { - "type": "text", - "placeholders": {} - }, - "editRoomAvatar": "Muuda jututoa tunnuspilti", - "@editRoomAvatar": { - "type": "text", - "placeholders": {} - }, - "emoteExists": "Selline emotsioonitegevus on juba olemas!", - "@emoteExists": { - "type": "text", - "placeholders": {} - }, - "emoteInvalid": "Vigane emotsioonitegevuse lühikood!", - "@emoteInvalid": { - "type": "text", - "placeholders": {} - }, - "emotePacks": "Emotsioonitegevuste pakid jututoa jaoks", - "@emotePacks": { - "type": "text", - "placeholders": {} - }, - "emoteSettings": "Emotsioonitegevuste seadistused", - "@emoteSettings": { - "type": "text", - "placeholders": {} - }, - "emoteShortcode": "Emotsioonitegevuse lühikood", - "@emoteShortcode": { - "type": "text", - "placeholders": {} - }, - "emoteWarnNeedToPick": "Sa pead valima emotsioonitegevuse lühikoodi ja pildi!", - "@emoteWarnNeedToPick": { - "type": "text", - "placeholders": {} - }, - "emptyChat": "Vestlust pole olnud", - "@emptyChat": { - "type": "text", - "placeholders": {} - }, - "enableEmotesGlobally": "Võta emotsioonitegevuste pakid läbivalt kasutusele", - "@enableEmotesGlobally": { - "type": "text", - "placeholders": {} - }, - "enableEncryption": "Kasuta krüptimist", - "@enableEncryption": { - "type": "text", - "placeholders": {} - }, - "enableEncryptionWarning": "Sa ei saa hiljem enam krüptimist välja lülitada. Kas oled kindel?", - "@enableEncryptionWarning": { - "type": "text", - "placeholders": {} - }, - "encrypted": "Krüptitud", - "@encrypted": { - "type": "text", - "placeholders": {} - }, - "encryption": "Krüptimine", - "@encryption": { - "type": "text", - "placeholders": {} - }, - "encryptionNotEnabled": "Krüptimine ei ole kasutusel", - "@encryptionNotEnabled": { - "type": "text", - "placeholders": {} - }, - "endedTheCall": "{senderName} lõpetas kõne", - "@endedTheCall": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "enterAnEmailAddress": "Sisesta e-posti aadress", - "@enterAnEmailAddress": { - "type": "text", - "placeholders": {} - }, - "enterYourHomeserver": "Sisesta oma koduserveri aadress", - "@enterYourHomeserver": { - "type": "text", - "placeholders": {} - }, - "errorObtainingLocation": "Viga asukoha tuvastamisel: {error}", - "@errorObtainingLocation": { - "type": "text", - "placeholders": { - "error": {} - } - }, - "everythingReady": "Kõik on valmis!", - "@everythingReady": { - "type": "text", - "placeholders": {} - }, - "extremeOffensive": "Äärmiselt solvav", - "@extremeOffensive": { - "type": "text", - "placeholders": {} - }, - "fileName": "Faili nimi", - "@fileName": { - "type": "text", - "placeholders": {} - }, - "fluffychat": "FluffyChat", - "@fluffychat": { - "type": "text", - "placeholders": {} - }, - "fontSize": "Fondi suurus", - "@fontSize": { - "type": "text", - "placeholders": {} - }, - "forward": "Edasta", - "@forward": { - "type": "text", - "placeholders": {} - }, - "fromJoining": "Alates liitumise hetkest", - "@fromJoining": { - "type": "text", - "placeholders": {} - }, - "fromTheInvitation": "Kutse saamisest", - "@fromTheInvitation": { - "type": "text", - "placeholders": {} - }, - "goToTheNewRoom": "Hakka kasutama uut jututuba", - "@goToTheNewRoom": { - "type": "text", - "placeholders": {} - }, - "group": "Vestlusrühm", - "@group": { - "type": "text", - "placeholders": {} - }, - "groupIsPublic": "Vestlusrühm on avalik", - "@groupIsPublic": { - "type": "text", - "placeholders": {} - }, - "groups": "Vestlusrühmad", - "@groups": { - "type": "text", - "placeholders": {} - }, - "groupWith": "Vestlusrühm {displayname} kasutajanimega", - "@groupWith": { - "type": "text", - "placeholders": { - "displayname": {} - } - }, - "guestsAreForbidden": "Külalised ei ole lubatud", - "@guestsAreForbidden": { - "type": "text", - "placeholders": {} - }, - "guestsCanJoin": "Külalised võivad liituda", - "@guestsCanJoin": { - "type": "text", - "placeholders": {} - }, - "hasWithdrawnTheInvitationFor": "{username} on võtnud tagasi {targetName} kutse", - "@hasWithdrawnTheInvitationFor": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "help": "Abiteave", - "@help": { - "type": "text", - "placeholders": {} - }, - "hideRedactedEvents": "Peida muudetud sündmused", - "@hideRedactedEvents": { - "type": "text", - "placeholders": {} - }, - "hideUnknownEvents": "Peida tundmatud sündmused", - "@hideUnknownEvents": { - "type": "text", - "placeholders": {} - }, - "howOffensiveIsThisContent": "Kui solvav see sisu on?", - "@howOffensiveIsThisContent": { - "type": "text", - "placeholders": {} - }, - "id": "ID", - "@id": { - "type": "text", - "placeholders": {} - }, - "identity": "Identiteet", - "@identity": { - "type": "text", - "placeholders": {} - }, - "ignore": "Eira", - "@ignore": { - "type": "text", - "placeholders": {} - }, - "ignoredUsers": "Eiratud kasutajad", - "@ignoredUsers": { - "type": "text", - "placeholders": {} - }, - "iHaveClickedOnLink": "Ma olen klõpsinud saadetud linki", - "@iHaveClickedOnLink": { - "type": "text", - "placeholders": {} - }, - "incorrectPassphraseOrKey": "Vigane paroolifraas või taastevõti", - "@incorrectPassphraseOrKey": { - "type": "text", - "placeholders": {} - }, - "inoffensive": "Kahjutu", - "@inoffensive": { - "type": "text", - "placeholders": {} - }, - "inviteContact": "Kutsu sõpru ja tuttavaid", - "@inviteContact": { - "type": "text", - "placeholders": {} - }, - "inviteContactToGroup": "Kutsu sõpru ja tuttavaid {groupName} liikmeks", - "@inviteContactToGroup": { - "type": "text", - "placeholders": { - "groupName": {} - } - }, - "invited": "Kutsutud", - "@invited": { - "type": "text", - "placeholders": {} - }, - "invitedUser": "📩 {username} saatis kutse kasutajale {targetName}", - "@invitedUser": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "invitedUsersOnly": "Ainult kutsutud kasutajatele", - "@invitedUsersOnly": { - "type": "text", - "placeholders": {} - }, - "inviteForMe": "Kutse minu jaoks", - "@inviteForMe": { - "type": "text", - "placeholders": {} - }, - "inviteText": "{username} kutsus sind kasutama Matrix'i-põhist suhtlusrakendust FluffyChat. \n1. Ava fluffychat.im ja paigalda FluffyChat'i rakendus \n2. Liitu kasutajaks või logi sisse olemasoleva Matrix'i kasutajakontoga\n3. Ava kutse link: \n {link}", - "@inviteText": { - "type": "text", - "placeholders": { - "username": {}, - "link": {} - } - }, - "isTyping": "kirjutab…", - "@isTyping": { - "type": "text", - "placeholders": {} - }, - "joinedTheChat": "👋 {username} liitus vestlusega", - "@joinedTheChat": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "joinRoom": "Liitu jututoaga", - "@joinRoom": { - "type": "text", - "placeholders": {} - }, - "kicked": "👞 {username} müksas kasutaja {targetName} välja", - "@kicked": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "kickedAndBanned": "🙅{username} müksas kasutaja {targetName} välja ning seadis talle suhtluskeelu", - "@kickedAndBanned": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "kickFromChat": "Müksa vestlusest välja", - "@kickFromChat": { - "type": "text", - "placeholders": {} - }, - "lastActiveAgo": "Viimati nähtud: {localizedTimeShort}", - "@lastActiveAgo": { - "type": "text", - "placeholders": { - "localizedTimeShort": {} - } - }, - "leave": "Lahku", - "@leave": { - "type": "text", - "placeholders": {} - }, - "leftTheChat": "Lahkus vestlusest", - "@leftTheChat": { - "type": "text", - "placeholders": {} - }, - "license": "Litsents", - "@license": { - "type": "text", - "placeholders": {} - }, - "lightTheme": "Hele", - "@lightTheme": { - "type": "text", - "placeholders": {} - }, - "loadCountMoreParticipants": "Lisa veel {count} osalejat", - "@loadCountMoreParticipants": { - "type": "text", - "placeholders": { - "count": {} - } - }, - "loadingPleaseWait": "Laadin andmeid… Palun oota.", - "@loadingPleaseWait": { - "type": "text", - "placeholders": {} - }, - "loadMore": "Laadi veel…", - "@loadMore": { - "type": "text", - "placeholders": {} - }, - "locationDisabledNotice": "Asukohateenused on seadmes väljalülitatud. Asukoha jagamiseks palun lülita nad sisse.", - "@locationDisabledNotice": { - "type": "text", - "placeholders": {} - }, - "locationPermissionDeniedNotice": "Puudub luba asukohateenuste kasutamiseks. Asukoha jagamiseks palun anna rakendusele vastavad õigused.", - "@locationPermissionDeniedNotice": { - "type": "text", - "placeholders": {} - }, - "login": "Logi sisse", - "@login": { - "type": "text", - "placeholders": {} - }, - "logInTo": "Logi sisse {homeserver} serverisse", - "@logInTo": { - "type": "text", - "placeholders": { - "homeserver": {} - } - }, - "logout": "Logi välja", - "@logout": { - "type": "text", - "placeholders": {} - }, - "memberChanges": "Muudatused liikmeskonnas", - "@memberChanges": { - "type": "text", - "placeholders": {} - }, - "mention": "Märgi ära", - "@mention": { - "type": "text", - "placeholders": {} - }, - "messages": "Sõnumid", - "@messages": { - "type": "text", - "placeholders": {} - }, - "moderator": "Moderaator", - "@moderator": { - "type": "text", - "placeholders": {} - }, - "muteChat": "Summuta vestlus", - "@muteChat": { - "type": "text", - "placeholders": {} - }, - "needPantalaimonWarning": "Palun arvesta, et sa saad hetkel kasutada läbivat krüptimist vaid siis, kui koduserver kasutab Pantalaimon'it.", - "@needPantalaimonWarning": { - "type": "text", - "placeholders": {} - }, - "newChat": "Uus vestlus", - "@newChat": { - "type": "text", - "placeholders": {} - }, - "newMessageInFluffyChat": "💬 Uus sõnum FluffyChat'i vahendusel", - "@newMessageInFluffyChat": { - "type": "text", - "placeholders": {} - }, - "newVerificationRequest": "Uus verifitseerimispäring!", - "@newVerificationRequest": { - "type": "text", - "placeholders": {} - }, - "next": "Edasi", - "@next": { - "type": "text", - "placeholders": {} - }, - "no": "Ei", - "@no": { - "type": "text", - "placeholders": {} - }, - "noConnectionToTheServer": "Puudub ühendus koduserveriga", - "@noConnectionToTheServer": { - "type": "text", - "placeholders": {} - }, - "noEmotesFound": "Ühtegi emotsioonitegevust ei leidunud. 😕", - "@noEmotesFound": { - "type": "text", - "placeholders": {} - }, - "noEncryptionForPublicRooms": "Sa võid krüptimise kasutusele võtta niipea, kui jututuba pole enam avalik.", - "@noEncryptionForPublicRooms": { - "type": "text", - "placeholders": {} - }, - "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": {} - }, - "noMatrixServer": "{server1} pole Matrix'i server, kas kasutame selle asemel {server2} serverit?", - "@noMatrixServer": { - "type": "text", - "placeholders": { - "server1": {}, - "server2": {} - } - }, - "none": "Mitte midagi", - "@none": { - "type": "text", - "placeholders": {} - }, - "noPasswordRecoveryDescription": "Sa pole veel lisanud võimalust salasõna taastamiseks.", - "@noPasswordRecoveryDescription": { - "type": "text", - "placeholders": {} - }, - "noPermission": "Õigused puuduvad", - "@noPermission": { - "type": "text", - "placeholders": {} - }, - "noRoomsFound": "Jututubasid ei leidunud…", - "@noRoomsFound": { - "type": "text", - "placeholders": {} - }, - "notifications": "Teavitused", - "@notifications": { - "type": "text", - "placeholders": {} - }, - "notificationsEnabledForThisAccount": "Teavitused on sellel kontol kasutusel", - "@notificationsEnabledForThisAccount": { - "type": "text", - "placeholders": {} - }, - "numUsersTyping": "{count} kasutajat kirjutavad…", - "@numUsersTyping": { - "type": "text", - "placeholders": { - "count": {} - } - }, - "obtainingLocation": "Tuvastan asukohta…", - "@obtainingLocation": { - "type": "text", - "placeholders": {} - }, - "offensive": "Solvav", - "@offensive": { - "type": "text", - "placeholders": {} - }, - "offline": "Väljas", - "@offline": { - "type": "text", - "placeholders": {} - }, - "ok": "sobib", - "@ok": { - "type": "text", - "placeholders": {} - }, - "online": "Saadaval", - "@online": { - "type": "text", - "placeholders": {} - }, - "onlineKeyBackupEnabled": "Krüptovõtmete veebipõhine varundus on kasutusel", - "@onlineKeyBackupEnabled": { - "type": "text", - "placeholders": {} - }, - "oopsPushError": "Hopsti! Kahjuks tekkis tõuketeavituste seadistamisel viga.", - "@oopsPushError": { - "type": "text", - "placeholders": {} - }, - "oopsSomethingWentWrong": "Hopsti! Midagi läks nüüd viltu…", - "@oopsSomethingWentWrong": { - "type": "text", - "placeholders": {} - }, - "openAppToReadMessages": "Sõnumite lugemiseks ava rakendus", - "@openAppToReadMessages": { - "type": "text", - "placeholders": {} - }, - "openCamera": "Ava kaamera", - "@openCamera": { - "type": "text", - "placeholders": {} - }, - "openInMaps": "Ava kaardirakendusega", - "@openInMaps": { - "type": "text", - "placeholders": {} - }, - "or": "või", - "@or": { - "type": "text", - "placeholders": {} - }, - "participant": "Osaleja", - "@participant": { - "type": "text", - "placeholders": {} - }, - "passphraseOrKey": "paroolifraas või taastevõti", - "@passphraseOrKey": { - "type": "text", - "placeholders": {} - }, - "password": "Salasõna", - "@password": { - "type": "text", - "placeholders": {} - }, - "passwordForgotten": "Salasõna on ununenud", - "@passwordForgotten": { - "type": "text", - "placeholders": {} - }, - "passwordHasBeenChanged": "Salasõna on muudetud", - "@passwordHasBeenChanged": { - "type": "text", - "placeholders": {} - }, - "passwordRecovery": "Salasõna taastamine", - "@passwordRecovery": { - "type": "text", - "placeholders": {} - }, - "people": "Inimesed", - "@people": { - "type": "text", - "placeholders": {} - }, - "pickImage": "Vali pilt", - "@pickImage": { - "type": "text", - "placeholders": {} - }, - "pin": "Klammerda", - "@pin": { - "type": "text", - "placeholders": {} - }, - "play": "Esita {fileName}", - "@play": { - "type": "text", - "placeholders": { - "fileName": {} - } - }, - "pleaseChoose": "Palun vali", - "@pleaseChoose": { - "type": "text", - "placeholders": {} - }, - "pleaseChooseAPasscode": "Palun vali rakenduse PIN-kood", - "@pleaseChooseAPasscode": { - "type": "text", - "placeholders": {} - }, - "pleaseClickOnLink": "Jätkamiseks palun klõpsi sulle saadetud e-kirjas leiduvat linki.", - "@pleaseClickOnLink": { - "type": "text", - "placeholders": {} - }, - "pleaseEnter4Digits": "Rakenduse luku jaoks sisesta 4 numbrit või kui sa sellist võimalust ei soovi kasutada, siis jäta nad tühjaks.", - "@pleaseEnter4Digits": { - "type": "text", - "placeholders": {} - }, - "pleaseEnterYourPassword": "Palun sisesta oma salasõna", - "@pleaseEnterYourPassword": { - "type": "text", - "placeholders": {} - }, - "pleaseEnterYourPin": "Palun sisesta oma PIN-kood", - "@pleaseEnterYourPin": { - "type": "text", - "placeholders": {} - }, - "pleaseEnterYourUsername": "Palun sisesta oma kasutajanimi", - "@pleaseEnterYourUsername": { - "type": "text", - "placeholders": {} - }, - "pleaseFollowInstructionsOnWeb": "Palun järgi veebilehel olevaid juhiseid ja klõpsi nuppu Edasi.", - "@pleaseFollowInstructionsOnWeb": { - "type": "text", - "placeholders": {} - }, - "privacy": "Privaatsus", - "@privacy": { - "type": "text", - "placeholders": {} - }, - "publicRooms": "Avalikud jututoad", - "@publicRooms": { - "type": "text", - "placeholders": {} - }, - "pushRules": "Tõukereeglid", - "@pushRules": { - "type": "text", - "placeholders": {} - }, - "reason": "Põhjus", - "@reason": { - "type": "text", - "placeholders": {} - }, - "recording": "Salvestan", - "@recording": { - "type": "text", - "placeholders": {} - }, - "redactedAnEvent": "{username} muutis sündmust", - "@redactedAnEvent": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "redactMessage": "Muuda sõnumit", - "@redactMessage": { - "type": "text", - "placeholders": {} - }, - "register": "Registreeru", - "@register": { - "type": "text", - "placeholders": {} - }, - "reject": "Lükka tagasi", - "@reject": { - "type": "text", - "placeholders": {} - }, - "rejectedTheInvitation": "{username} lükkas kutse tagasi", - "@rejectedTheInvitation": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "rejoin": "Liitu uuesti", - "@rejoin": { - "type": "text", - "placeholders": {} - }, - "remove": "Eemalda", - "@remove": { - "type": "text", - "placeholders": {} - }, - "removeAllOtherDevices": "Eemalda kõik muud seadmed", - "@removeAllOtherDevices": { - "type": "text", - "placeholders": {} - }, - "removedBy": "{username} eemaldas sündmuse", - "@removedBy": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "removeDevice": "Eemalda seade", - "@removeDevice": { - "type": "text", - "placeholders": {} - }, - "unbanFromChat": "Eemalda suhtluskeeld", - "@unbanFromChat": { - "type": "text", - "placeholders": {} - }, - "removeYourAvatar": "Kustuta oma tunnuspilt", - "@removeYourAvatar": { - "type": "text", - "placeholders": {} - }, - "renderRichContent": "Visualiseeri vormindatud sõnumite sisu", - "@renderRichContent": { - "type": "text", - "placeholders": {} - }, - "replaceRoomWithNewerVersion": "Asenda jututoa senine versioon uuega", - "@replaceRoomWithNewerVersion": { - "type": "text", - "placeholders": {} - }, - "reply": "Vasta", - "@reply": { - "type": "text", - "placeholders": {} - }, - "reportMessage": "Teata sõnumist", - "@reportMessage": { - "type": "text", - "placeholders": {} - }, - "requestPermission": "Palu õigusi", - "@requestPermission": { - "type": "text", - "placeholders": {} - }, - "roomHasBeenUpgraded": "Jututoa vesrioon on uuendatud", - "@roomHasBeenUpgraded": { - "type": "text", - "placeholders": {} - }, - "roomVersion": "Jututoa versioon", - "@roomVersion": { - "type": "text", - "placeholders": {} - }, - "saveFile": "Salvesta fail", - "@saveFile": { - "type": "text", - "placeholders": {} - }, - "search": "Otsi", - "@search": { - "type": "text", - "placeholders": {} - }, - "security": "Turvalisus", - "@security": { - "type": "text", - "placeholders": {} - }, - "seenByUser": "Sõnumit nägi {username}", - "@seenByUser": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "send": "Saada", - "@send": { - "type": "text", - "placeholders": {} - }, - "sendAMessage": "Saada sõnum", - "@sendAMessage": { - "type": "text", - "placeholders": {} - }, - "sendAsText": "Saada tekstisõnumina", - "@sendAsText": { - "type": "text" - }, - "sendAudio": "Saada helifail", - "@sendAudio": { - "type": "text", - "placeholders": {} - }, - "sendFile": "Saada fail", - "@sendFile": { - "type": "text", - "placeholders": {} - }, - "sendImage": "Saada pilt", - "@sendImage": { - "type": "text", - "placeholders": {} - }, - "sendMessages": "Saada sõnumeid", - "@sendMessages": { - "type": "text", - "placeholders": {} - }, - "sendOriginal": "Saada fail muutmata kujul", - "@sendOriginal": { - "type": "text", - "placeholders": {} - }, - "sendSticker": "Saada kleeps", - "@sendSticker": { - "type": "text", - "placeholders": {} - }, - "sendVideo": "Saada videofail", - "@sendVideo": { - "type": "text", - "placeholders": {} - }, - "sentAFile": "📁 {username} saatis faili", - "@sentAFile": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sentAnAudio": "🎤 {username} saatis helifaili", - "@sentAnAudio": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sentAPicture": "🖼️ {username} saatis pildi", - "@sentAPicture": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sentASticker": "😊 {username} saatis kleepsu", - "@sentASticker": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sentAVideo": "🎥 {username} saatis video", - "@sentAVideo": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "sentCallInformations": "{senderName} saatis teavet kõne kohta", - "@sentCallInformations": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "setAsCanonicalAlias": "Määra põhinimeks", - "@setAsCanonicalAlias": { - "type": "text", - "placeholders": {} - }, - "setCustomEmotes": "Kohanda emotsioonitegevusi", - "@setCustomEmotes": { - "type": "text", - "placeholders": {} - }, - "setInvitationLink": "Tee kutselink", - "@setInvitationLink": { - "type": "text", - "placeholders": {} - }, - "setPermissionsLevel": "Seadista õigusi", - "@setPermissionsLevel": { - "type": "text", - "placeholders": {} - }, - "setStatus": "Määra olek", - "@setStatus": { - "type": "text", - "placeholders": {} - }, - "settings": "Seadistused", - "@settings": { - "type": "text", - "placeholders": {} - }, - "share": "Jaga", - "@share": { - "type": "text", - "placeholders": {} - }, - "sharedTheLocation": "{username} jagas oma asukohta", - "@sharedTheLocation": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "shareLocation": "Jaga asukohta", - "@shareLocation": { - "type": "text", - "placeholders": {} - }, - "showPassword": "Näita salasõna", - "@showPassword": { - "type": "text", - "placeholders": {} - }, - "singlesignon": "Ühekordne sisselogimine", - "@singlesignon": { - "type": "text", - "placeholders": {} - }, - "skip": "Jäta vahele", - "@skip": { - "type": "text", - "placeholders": {} - }, - "sourceCode": "Lähtekood", - "@sourceCode": { - "type": "text", - "placeholders": {} - }, - "spaceIsPublic": "Kogukond on avalik", - "@spaceIsPublic": { - "type": "text", - "placeholders": {} - }, - "spaceName": "Kogukonna nimi", - "@spaceName": { - "type": "text", - "placeholders": {} - }, - "startedACall": "{senderName} alustas kõnet", - "@startedACall": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "status": "Olek", - "@status": { - "type": "text", - "placeholders": {} - }, - "statusExampleMessage": "Kuidas sul täna läheb?", - "@statusExampleMessage": { - "type": "text", - "placeholders": {} - }, - "submit": "Saada", - "@submit": { - "type": "text", - "placeholders": {} - }, - "synchronizingPleaseWait": "Sünkroniseerin andmeid… Palun oota.", - "@synchronizingPleaseWait": { - "type": "text", - "placeholders": {} - }, - "systemTheme": "Süsteem", - "@systemTheme": { - "type": "text", - "placeholders": {} - }, - "theyDontMatch": "Nad ei klapi omavahel", - "@theyDontMatch": { - "type": "text", - "placeholders": {} - }, - "theyMatch": "Nad klapivad omavahel", - "@theyMatch": { - "type": "text", - "placeholders": {} - }, - "title": "FluffyChat", - "@title": { - "description": "Title for the application", - "type": "text", - "placeholders": {} - }, - "toggleFavorite": "Muuda olekut lemmikuna", - "@toggleFavorite": { - "type": "text", - "placeholders": {} - }, - "toggleMuted": "Lülita summutamine sisse või välja", - "@toggleMuted": { - "type": "text", - "placeholders": {} - }, - "toggleUnread": "Märgi loetuks / lugemata", - "@toggleUnread": { - "type": "text", - "placeholders": {} - }, - "tooManyRequestsWarning": "Liiga palju päringuid. Palun proovi hiljem uuesti!", - "@tooManyRequestsWarning": { - "type": "text", - "placeholders": {} - }, - "transferFromAnotherDevice": "Tõsta teisest seadmest", - "@transferFromAnotherDevice": { - "type": "text", - "placeholders": {} - }, - "tryToSendAgain": "Proovi uuesti saata", - "@tryToSendAgain": { - "type": "text", - "placeholders": {} - }, - "unavailable": "Eemal", - "@unavailable": { - "type": "text", - "placeholders": {} - }, - "unbannedUser": "{username} eemaldas ligipääsukeelu kasutajalt {targetName}", - "@unbannedUser": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "unblockDevice": "Eemalda seadmelt blokeering", - "@unblockDevice": { - "type": "text", - "placeholders": {} - }, - "unknownDevice": "Tundmatu seade", - "@unknownDevice": { - "type": "text", - "placeholders": {} - }, - "unknownEncryptionAlgorithm": "Tundmatu krüptoalgoritm", - "@unknownEncryptionAlgorithm": { - "type": "text", - "placeholders": {} - }, - "unknownEvent": "Tundmatu sündmuse tüüp „{type}“", - "@unknownEvent": { - "type": "text", - "placeholders": { - "type": {} - } - }, - "unmuteChat": "Lõpeta vestluse vaigistamine", - "@unmuteChat": { - "type": "text", - "placeholders": {} - }, - "unpin": "Eemalda klammerdus", - "@unpin": { - "type": "text", - "placeholders": {} - }, - "unreadChats": "{unreadCount, plural, =1{1 lugemata vestlus} other{{unreadCount} lugemata vestlust}}", - "@unreadChats": { - "type": "text", - "placeholders": { - "unreadCount": {} - } - }, - "userAndOthersAreTyping": "{username} ja {count} muud kirjutavad…", - "@userAndOthersAreTyping": { - "type": "text", - "placeholders": { - "username": {}, - "count": {} - } - }, - "userAndUserAreTyping": "{username} ja {username2} kirjutavad…", - "@userAndUserAreTyping": { - "type": "text", - "placeholders": { - "username": {}, - "username2": {} - } - }, - "userIsTyping": "{username} kirjutab…", - "@userIsTyping": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "userLeftTheChat": "🚪{username} lahkus vestlusest", - "@userLeftTheChat": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "username": "Kasutajanimi", - "@username": { - "type": "text", - "placeholders": {} - }, - "userSentUnknownEvent": "{username} saatis {type} sündmuse", - "@userSentUnknownEvent": { - "type": "text", - "placeholders": { - "username": {}, - "type": {} - } - }, - "verified": "Verifitseeritud", - "@verified": { - "type": "text", - "placeholders": {} - }, - "verify": "Verifitseeri", - "@verify": { - "type": "text", - "placeholders": {} - }, - "verifyStart": "Alusta verifitseerimist", - "@verifyStart": { - "type": "text", - "placeholders": {} - }, - "verifySuccess": "Sinu verifitseerimine õnnestus!", - "@verifySuccess": { - "type": "text", - "placeholders": {} - }, - "verifyTitle": "Verifitseerin teist kasutajakontot", - "@verifyTitle": { - "type": "text", - "placeholders": {} - }, - "videoCall": "Videokõne", - "@videoCall": { - "type": "text", - "placeholders": {} - }, - "visibilityOfTheChatHistory": "Vestluse ajaloo nähtavus", - "@visibilityOfTheChatHistory": { - "type": "text", - "placeholders": {} - }, - "visibleForAllParticipants": "Nähtav kõikidele osalejatele", - "@visibleForAllParticipants": { - "type": "text", - "placeholders": {} - }, - "visibleForEveryone": "Nähtav kõikidele", - "@visibleForEveryone": { - "type": "text", - "placeholders": {} - }, - "voiceMessage": "Häälsõnum", - "@voiceMessage": { - "type": "text", - "placeholders": {} - }, - "waitingPartnerAcceptRequest": "Ootan, et teine osapool nõustuks päringuga…", - "@waitingPartnerAcceptRequest": { - "type": "text", - "placeholders": {} - }, - "waitingPartnerEmoji": "Ootan teise osapoole kinnitust, et tegemist on samade emojidega…", - "@waitingPartnerEmoji": { - "type": "text", - "placeholders": {} - }, - "waitingPartnerNumbers": "Ootan teise osapoole kinnitust, et tegemist on samade numbritega…", - "@waitingPartnerNumbers": { - "type": "text", - "placeholders": {} - }, - "wallpaper": "Taustapilt:", - "@wallpaper": { - "type": "text", - "placeholders": {} - }, - "warning": "Hoiatus!", - "@warning": { - "type": "text", - "placeholders": {} - }, - "weSentYouAnEmail": "Me saatsime sulle e-kirja", - "@weSentYouAnEmail": { - "type": "text", - "placeholders": {} - }, - "whoCanPerformWhichAction": "Erinevatele kasutajatele lubatud toimingud", - "@whoCanPerformWhichAction": { - "type": "text", - "placeholders": {} - }, - "whoIsAllowedToJoinThisGroup": "Kes võivad selle vestlusrühmaga liituda", - "@whoIsAllowedToJoinThisGroup": { - "type": "text", - "placeholders": {} - }, - "whyDoYouWantToReportThis": "Miks sa soovid sellest teatada?", - "@whyDoYouWantToReportThis": { - "type": "text", - "placeholders": {} - }, - "wipeChatBackup": "Kas kustutame sinu vestluste varukoopia ja loome uue taastamiseks mõeldud krüptovõtme?", - "@wipeChatBackup": { - "type": "text", - "placeholders": {} - }, - "withTheseAddressesRecoveryDescription": "Nende e-posti aadresside abil saad taastada oma salasõna.", - "@withTheseAddressesRecoveryDescription": { - "type": "text", - "placeholders": {} - }, - "writeAMessage": "Kirjuta üks sõnum…", - "@writeAMessage": { - "type": "text", - "placeholders": {} - }, - "yes": "Jah", - "@yes": { - "type": "text", - "placeholders": {} - }, - "you": "Sina", - "@you": { - "type": "text", - "placeholders": {} - }, - "youAreNoLongerParticipatingInThisChat": "Sa enam ei osale selles vestluses", - "@youAreNoLongerParticipatingInThisChat": { - "type": "text", - "placeholders": {} - }, - "youHaveBeenBannedFromThisChat": "Sinule on selles vestluses seatud suhtluskeeld", - "@youHaveBeenBannedFromThisChat": { - "type": "text", - "placeholders": {} - }, - "yourPublicKey": "Sinu avalik võti", - "@yourPublicKey": { - "type": "text", - "placeholders": {} - }, - "chatHasBeenAddedToThisSpace": "Lisasime vestluse kogukonda", - "@chatHasBeenAddedToThisSpace": {}, - "addToSpace": "Lisa kogukonda", - "@addToSpace": {}, - "scanQrCode": "Skaneeri QR-koodi", - "@scanQrCode": {}, - "sendOnEnter": "Saada sõnum sisestusklahvi vajutusel", - "@sendOnEnter": {}, - "homeserver": "Koduserver", - "@homeserver": {}, - "serverRequiresEmail": "See koduserver eeldab registreerimisel kasutatava e-postiaadressi kinnitamist.", - "@serverRequiresEmail": {}, - "enableMultiAccounts": "(KATSELINE) Pruugi selles seadmes mitut Matrix'i kasutajakontot", - "@enableMultiAccounts": {}, - "bundleName": "Köite nimi", - "@bundleName": {}, - "removeFromBundle": "Eemalda sellest köitest", - "@removeFromBundle": {}, - "addToBundle": "Lisa köitesse", - "@addToBundle": {}, - "editBundlesForAccount": "Muuda selle kasutajakonto köiteid", - "@editBundlesForAccount": {}, - "addAccount": "Lisa kasutajakonto", - "@addAccount": {}, - "oneClientLoggedOut": "Üks sinu klientrakendustest on Matrix'i võrgust välja loginud", - "@oneClientLoggedOut": {}, - "link": "Link", - "@link": {}, - "yourChatBackupHasBeenSetUp": "Sinu vestluste varundus on seadistatud.", - "@yourChatBackupHasBeenSetUp": {}, - "unverified": "Verifitseerimata", - "@unverified": {}, - "repeatPassword": "Korda salasõna", - "@repeatPassword": {}, - "messageInfo": "Sõnumi teave", - "@messageInfo": {}, - "time": "Kellaaeg", - "@time": {}, - "messageType": "Sõnumi tüüp", - "@messageType": {}, - "sender": "Saatja", - "@sender": {}, - "openGallery": "Ava galerii", - "@openGallery": {}, - "addToSpaceDescription": "Vali kogukond, kuhu soovid seda vestlust lisada.", - "@addToSpaceDescription": {}, - "removeFromSpace": "Eemalda kogukonnast", - "@removeFromSpace": {}, - "start": "Alusta", - "@start": {}, - "commandHint_discardsession": "Loobu sessioonist", - "@commandHint_discardsession": { - "type": "text", - "description": "Usage hint for the command /discardsession" - }, - "commandHint_clearcache": "Tühjenda vahemälu", - "@commandHint_clearcache": { - "type": "text", - "description": "Usage hint for the command /clearcache" - }, - "commandHint_dm": "Alusta otsevestlust\nKrüptimise keelamiseks kasuta --no-encryption võtit", - "@commandHint_dm": { - "type": "text", - "description": "Usage hint for the command /dm" - }, - "commandHint_create": "Loo tühi vestlusrühm\nKrüptimise keelamiseks kasuta --no-encryption võtit", - "@commandHint_create": { - "type": "text", - "description": "Usage hint for the command /create" - }, - "openVideoCamera": "Video salvestamiseks ava kaamera", - "@openVideoCamera": { - "type": "text", - "placeholders": {} - }, - "markAsRead": "Märgi loetuks", - "@markAsRead": {}, - "reportUser": "Teata kasutajast", - "@reportUser": {}, - "openChat": "Ava vestlus", - "@openChat": {}, - "dismiss": "Loobu", - "@dismiss": {}, - "reactedWith": "{sender} reageeris nii {reaction}", - "@reactedWith": { - "type": "text", - "placeholders": { - "sender": {}, - "reaction": {} - } - }, - "emojis": "Emotikonid", - "@emojis": {}, - "placeCall": "Helista", - "@placeCall": {}, - "unsupportedAndroidVersion": "See Androidi versioon ei ole toetatud", - "@unsupportedAndroidVersion": {}, - "voiceCall": "Häälkõne", - "@voiceCall": {}, - "confirmEventUnpin": "Kas sa oled kindel, et tahad klammerdatud sündmuse eemaldada?", - "@confirmEventUnpin": {}, - "pinMessage": "Klammerda sõnum jututuppa", - "@pinMessage": {}, - "videoCallsBetaWarning": "Palun arvesta, et videokõned on veel beetajärgus. Nad ei pruugi veel toimida kõikidel platvormidel korrektselt.", - "@videoCallsBetaWarning": {}, - "emailOrUsername": "E-posti aadress või kasutajanimi", - "@emailOrUsername": {}, - "experimentalVideoCalls": "Katselised videokõned", - "@experimentalVideoCalls": {}, - "unsupportedAndroidVersionLong": "See funktsionaalsus eeldab uuemat Androidi versiooni. Palun kontrolli, kas sinu nutiseadmele leidub süsteemiuuendusi või saaks seal Lineage OS'i kasutada.", - "@unsupportedAndroidVersionLong": {}, - "nextAccount": "Järgmine kasutajakonto", - "@nextAccount": {}, - "separateChatTypes": "Eraldi vestlused ja jututoad", - "@separateChatTypes": { - "type": "text", - "placeholders": {} - }, - "errorAddingWidget": "Vidina lisamisel tekkis viga.", - "@errorAddingWidget": {}, - "widgetNameError": "Palun sisesta kuvatav nimi.", - "@widgetNameError": {}, - "addWidget": "Lisa vidin", - "@addWidget": {}, - "previousAccount": "Eelmine kasutajakonto", - "@previousAccount": {}, - "widgetUrlError": "See pole korrektne URL.", - "@widgetUrlError": {}, - "widgetName": "Nimi", - "@widgetName": {}, - "widgetCustom": "Kohandatud", - "@widgetCustom": {}, - "widgetJitsi": "Jitsi Meet", - "@widgetJitsi": {}, - "widgetEtherpad": "Märkmed ja tekstid", - "@widgetEtherpad": {}, - "widgetVideo": "Video", - "@widgetVideo": {}, - "switchToAccount": "Pruugi kasutajakontot # {number}", - "@switchToAccount": { - "type": "number", - "placeholders": { - "number": {} - } - }, - "youAcceptedTheInvitation": "👍 Sa võtsid kutse vastu", - "@youAcceptedTheInvitation": {}, - "youUnbannedUser": "Sa eemaldasid suhtluskeelu kasutajalt {user}", - "@youUnbannedUser": { - "placeholders": { - "user": {} - } - }, - "youHaveWithdrawnTheInvitationFor": "Sa oled tühistanud kutse kasutajale {user}", - "@youHaveWithdrawnTheInvitationFor": { - "placeholders": { - "user": {} - } - }, - "youBannedUser": "Sa seadsid suhtluskeelu kasutajale {user}", - "@youBannedUser": { - "placeholders": { - "user": {} - } - }, - "youJoinedTheChat": "Sa liitusid vestlusega", - "@youJoinedTheChat": {}, - "youKickedAndBanned": "🙅Sa müksasid kasutaja {user} välja ning seadsid talle suhtluskeelu", - "@youKickedAndBanned": { - "placeholders": { - "user": {} - } - }, - "videoWithSize": "Video ({size})", - "@videoWithSize": { - "type": "text", - "placeholders": { - "size": {} - } - }, - "youRejectedTheInvitation": "Sa lükkasid kutse tagasi", - "@youRejectedTheInvitation": {}, - "youKicked": "👞 Sa müksasid kasutaja {user} välja", - "@youKicked": { - "placeholders": { - "user": {} - } - }, - "youInvitedUser": "📩 Sa saatsid kutse kasutajale {user}", - "@youInvitedUser": { - "placeholders": { - "user": {} - } - }, - "youInvitedBy": "📩 {user} saatis sulle kutse", - "@youInvitedBy": { - "placeholders": { - "user": {} - } - }, - "publish": "Avalda", - "@publish": {}, - "pleaseEnterRecoveryKey": "Palun sisesta oma taastevõti:", - "@pleaseEnterRecoveryKey": {}, - "recoveryKey": "Taastevõti", - "@recoveryKey": {}, - "users": "Kasutajad", - "@users": {}, - "storeInSecureStorageDescription": "Salvesta taastevõti selle seadme turvahoidlas.", - "@storeInSecureStorageDescription": {}, - "saveKeyManuallyDescription": "Salvesta see krüptovõti kasutades selle süsteemi jagamisvalikuid või lõikelauda.", - "@saveKeyManuallyDescription": {}, - "storeInAndroidKeystore": "Vali salvestuskohaks Android KeyStore", - "@storeInAndroidKeystore": {}, - "storeInAppleKeyChain": "Vali salvestuskohaks Apple KeyChain", - "@storeInAppleKeyChain": {}, - "recoveryKeyLost": "Kas taasetvõti on kadunud?", - "@recoveryKeyLost": {}, - "pleaseEnterRecoveryKeyDescription": "Vanade sõnumite lugemiseks palun siseta oma varasemas sessioonis loodud taastevõti. Taastamiseks mõeldud krüptovõti EI OLE sinu salasõna.", - "@pleaseEnterRecoveryKeyDescription": {}, - "storeSecurlyOnThisDevice": "Salvesta turvaliselt selles seadmes", - "@storeSecurlyOnThisDevice": {}, - "unlockOldMessages": "Muuda vanad sõnumid loetavaks", - "@unlockOldMessages": {}, - "countFiles": "{count} faili", - "@countFiles": { - "placeholders": { - "count": {} - } - }, - "dehydrate": "Ekspordi sessiooni teave ja kustuta nutiseadmest rakenduse andmed", - "@dehydrate": {}, - "dehydrateTor": "TOR'i kasutajad: Ekspordi sessioon", - "@dehydrateTor": {}, - "hydrateTor": "TOR'i kasutajatele: impordi viimati eksporditud sessiooni andmed", - "@hydrateTor": {}, - "hydrateTorLong": "Kui viimati TOR'i võrku kasutasid, siis kas sa eksportisid oma sessiooni andmed? Kui jah, siis impordi nad mugavasti ja jätka suhtlemist.", - "@hydrateTorLong": {}, - "indexedDbErrorTitle": "Brauseri privaatse akna kasutamisega seotud asjaolud", - "@indexedDbErrorTitle": {}, - "dehydrateWarning": "Seda tegevust ei saa tagasi pöörata. Palun kontrolli, et sa oled varukoopia turvaliselt salvestanud.", - "@dehydrateWarning": {}, - "dehydrateTorLong": "Kui oled TOR'i võrgu kasutaja, siis enne akna sulgemist palun ekspordi viimase sessiooni andmed.", - "@dehydrateTorLong": {}, - "indexedDbErrorLong": "Privaatse akna puhul andmete salvestamine vaikimisi pole kasutusel.\nPalun toimi alljärgnevalt:\n- ava about:config\n- määra dom.indexedDB.privateBrowsing.enabled väärtuseks true\nVastasel juhul sa ei saa FluffyChat'i kasutada.", - "@indexedDbErrorLong": {}, - "hydrate": "Taasta varundatud failist", - "@hydrate": {}, - "user": "Kasutaja", - "@user": {}, - "custom": "Kohandatud", - "@custom": {}, - "confirmMatrixId": "Konto kustutamiseks palun kinnitage oma Matrix'i ID.", - "@confirmMatrixId": {}, - "supposedMxid": "See peaks olema {mxid}", - "@supposedMxid": { - "type": "text", - "placeholders": { - "mxid": {} - } - }, - "commandHint_markasgroup": "Märgi vestlusrühmaks", - "@commandHint_markasgroup": {}, - "commandHint_markasdm": "Märgi otsevestusluseks antud Matrixi ID jaoks", - "@commandHint_markasdm": {}, - "whyIsThisMessageEncrypted": "Miks see sõnum pole loetav?", - "@whyIsThisMessageEncrypted": {}, - "noKeyForThisMessage": "See võib juhtuda, kui sõnum oli saadetud enne, kui siin seadmes oma kontoga sisse logisid.\n\nSamuti võib juhtuda siis, kui saatja on lugemises selles seadmes blokeerinud või on tekkinud tõrkeid veebiühenduses.\n\nAga mõnes teises seadmes saad seda sõnumit lugeda? Siis sa võid sõnumi sealt üle tõsta. Ava Seadistused -> Seadmed ning kontrolli, et kõik sinu seadmed on omavahel verifitseeritud. Kui avad selle vestluse või jututoa ning mõlemad sessioonid on avatud, siis vajalikud krüptovõtmed saadetakse automaatset.\n\nKas sa soovid vältida krüptovõtmete kadumist väljalogimisel ja seadmete vahetusel? Siis palun kontrolli, et seadistuses on krüptovõtmete varundus sisse lülitatud.", - "@noKeyForThisMessage": {}, - "callingPermissions": "Helistamise õigused", - "@callingPermissions": {}, - "callingAccountDetails": "Võimaldab FluffyChat'il kasutada Androidi helistamisrakendust.", - "@callingAccountDetails": {}, - "appearOnTop": "Luba pealmise rakendusena", - "@appearOnTop": {}, - "otherCallingPermissions": "Mikrofoni, kaamera ja muud FluffyChat'i õigused", - "@otherCallingPermissions": {}, - "newGroup": "Uus jututuba", - "@newGroup": {}, - "newSpace": "Uus kogukond", - "@newSpace": {}, - "enterSpace": "Sisene kogukonda", - "@enterSpace": {}, - "enterRoom": "Ava jututuba", - "@enterRoom": {}, - "appearOnTopDetails": "Sellega lubad rakendust avada kõige pealmisena (pole vajalik, kui Fluffychat on juba seadistatud toimima helistamiskontoga)", - "@appearOnTopDetails": {}, - "callingAccount": "Helistamiskonto", - "@callingAccount": {}, - "screenSharingTitle": "ekraani jagamine", - "@screenSharingTitle": {}, - "foregroundServiceRunning": "See teavitus toimib siis, kui esiplaaniteenus töötab.", - "@foregroundServiceRunning": {}, - "allSpaces": "Kõik kogukonnad", - "@allSpaces": {}, - "screenSharingDetail": "Sa jagad oma ekraani FuffyChat'i vahendusel", - "@screenSharingDetail": {}, - "numChats": "{number} vestlust", - "@numChats": { - "type": "number", - "placeholders": { - "number": {} - } - }, - "hideUnimportantStateEvents": "Peida väheolulised olekuteated", - "@hideUnimportantStateEvents": {}, - "doNotShowAgain": "Ära näita uuesti", - "@doNotShowAgain": {}, - "commandHint_cuddle": "Saada üks kaisutus", - "@commandHint_cuddle": {}, - "commandHint_hug": "Saada üks kallistus", - "@commandHint_hug": {}, - "googlyEyesContent": "{senderName} saatis sulle otsivad silmad", - "@googlyEyesContent": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "cuddleContent": "{senderName} kaisutab sind", - "@cuddleContent": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "hugContent": "{senderName} kallistab sind", - "@hugContent": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "commandHint_googly": "Saada ühed otsivad silmad", - "@commandHint_googly": {}, - "wasDirectChatDisplayName": "Sõnumiteta vestlus (vana nimega {oldDisplayName})", - "@wasDirectChatDisplayName": { - "type": "text", - "placeholders": { - "oldDisplayName": {} - } - }, - "startFirstChat": "Alusta oma esimest vestlust", - "@startFirstChat": {}, - "encryptThisChat": "Krüpti see vestlus", - "@encryptThisChat": {}, - "disableEncryptionWarning": "Kui vestluses on krüptimine kasutusele võetud, siis turvalisuse huvides ei saa seda hiljem välja lülitada.", - "@disableEncryptionWarning": {}, - "sorryThatsNotPossible": "Vabandust... see ei ole võimalik", - "@sorryThatsNotPossible": {}, - "deviceKeys": "Seadme võtmed:", - "@deviceKeys": {}, - "newSpaceDescription": "Kogukonnad võimaldavad sul koondada erinevaid vestlusi ning korraldada avalikku või privaatset ühistegevust.", - "@newSpaceDescription": {}, - "reopenChat": "Alusta vestlust uuesti", - "@reopenChat": {}, - "noOtherDevicesFound": "Muid seadmeid ei leidu", - "@noOtherDevicesFound": {}, - "noBackupWarning": "Hoiatus! Kui sa ei lülita sisse vestluse varundust, siis sul puudub hiljem ligipääs krüptitud sõnumitele. Me tungivalt soovitame, et palun lülita vestluse varundamine sisse enne väljalogimist.", - "@noBackupWarning": {}, - "fileIsTooBigForServer": "Serveri seadistuste alusel on see fail saatmiseks liiga suur.", - "@fileIsTooBigForServer": {}, - "fileHasBeenSavedAt": "Fail on salvestatud kausta: {path}", - "@fileHasBeenSavedAt": { - "type": "text", - "placeholders": { - "path": {} - } - }, - "jumpToLastReadMessage": "Liigu viimase loetud sõnumini", - "@jumpToLastReadMessage": {}, - "readUpToHere": "Siiamaani on loetud", - "@readUpToHere": {}, - "jump": "Hüppa", - "@jump": {}, - "openLinkInBrowser": "Ava link veebibrauseris", - "@openLinkInBrowser": {}, - "report": "teata", - "@report": {}, - "allRooms": "Kõik vestlusrühmad", - "@allRooms": { - "type": "text", - "placeholders": {} - }, - "reportErrorDescription": "Oh appike! Midagi läks valesti. Palun proovi hiljem uuesti. Kui soovid, võid sellest veast arendajatele teatada.", - "@reportErrorDescription": {}, - "signInWithPassword": "Logi sisse salasõnaga", - "@signInWithPassword": {}, - "pleaseTryAgainLaterOrChooseDifferentServer": "Palun proovi hiljem uuesti või muuda serveri nime.", - "@pleaseTryAgainLaterOrChooseDifferentServer": {}, - "signInWith": "Logi sisse kasutades teenusepakkujat {provider}", - "@signInWith": { - "type": "text", - "placeholders": { - "provider": {} - } - }, - "importFromZipFile": "Impordi zip-failist", - "@importFromZipFile": {}, - "exportEmotePack": "Ekspordi emotikonide pakk zip-failina", - "@exportEmotePack": {}, - "replace": "Asenda", - "@replace": {}, - "notAnImage": "See pole pildifail.", - "@notAnImage": {}, - "importNow": "Impordi kohe", - "@importNow": {}, - "importEmojis": "Impordi emojid", - "@importEmojis": {}, - "sendTypingNotifications": "Saada kirjutamise teavitusi", - "@sendTypingNotifications": {}, - "createGroup": "Loo vestlusrühm", - "@createGroup": {}, - "setTheme": "Vali teema:", - "@setTheme": {}, - "inviteContactToGroupQuestion": "Kas sa soovid kutsuda kasutajat {contact} „{groupName}“ jututuppa?", - "@inviteContactToGroupQuestion": {}, - "tryAgain": "Proovi uuesti", - "@tryAgain": {}, - "chatPermissions": "Vestluse õigused", - "@chatPermissions": {}, - "chatDescription": "Vestluse kirjeldus", - "@chatDescription": {}, - "noChatDescriptionYet": "Vestluse kirjeldus on puudu.", - "@noChatDescriptionYet": {}, - "optionalRedactReason": "(Kui soovid lisada) Sõnumi muutmise põhjus...", - "@optionalRedactReason": {}, - "messagesStyle": "Sõnumid:", - "@messagesStyle": {}, - "shareInviteLink": "Jaga kutse linki", - "@shareInviteLink": {}, - "directChat": "Otsevestlus", - "@directChat": {}, - "setChatDescription": "Lisa vestluse kirjeldus", - "@setChatDescription": {}, - "profileNotFound": "Sellist kasutajat serveris ei leidu. Tegemist võib olla kas võrguühenduse probleemiga või sellist kasutajat tõesti pole olemas.", - "@profileNotFound": {}, - "setColorTheme": "Vali värviteema:", - "@setColorTheme": {}, - "invite": "Kutsu", - "@invite": {}, - "invalidServerName": "Vigane serveri nimi", - "@invalidServerName": {}, - "addChatDescription": "Lisa vestluse kirjeldus...", - "@addChatDescription": {}, - "chatDescriptionHasBeenChanged": "Vestluse kirjeldus on muutunud", - "@chatDescriptionHasBeenChanged": {}, - "redactMessageDescription": "Sõnumi muudatus kehtib kõikidele vestluses osalejatele. Seda muudatust ei saa tagasi pöörata.", - "@redactMessageDescription": {}, - "redactedBy": "Muutja: {username}", - "@redactedBy": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "redactedByBecause": "Muutja {username} märkis põhjuseks: „{reason}“", - "@redactedByBecause": { - "type": "text", - "placeholders": { - "username": {}, - "reason": {} - } - }, - "inviteGroupChat": "📨 Kutsu vestlusrühma", - "@inviteGroupChat": {}, - "invitePrivateChat": "📨 Kutsu omavahelisele vestlusele", - "@invitePrivateChat": {}, - "emoteKeyboardNoRecents": "Hiljuti kasutatud emotikonid kuvame siin...", - "@emoteKeyboardNoRecents": { - "type": "text", - "placeholders": {} - }, - "invalidInput": "Vigane sisend!", - "@invalidInput": {}, - "wrongPinEntered": "Sisestasid vale PIN-koodi! Proovi uuesti {seconds} sekundi pärast...", - "@wrongPinEntered": { - "type": "text", - "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": {}, - "pushNotificationsNotAvailable": "Tõuketeavitused pole saadaval", - "@pushNotificationsNotAvailable": {}, - "makeAdminDescription": "Kui annad sellele kasutajale peakasutaja õigused, siis kuna tal on sinuga samad õigused, sa ei saa seda toimingut enam tagasi pöörata.", - "@makeAdminDescription": {}, - "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": {} - } - }, - "learnMore": "Loe lisaks", - "@learnMore": {}, - "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": {}, - "blockListDescription": "Sul on võimalik blokeerida neid kasutajaid, kes sind segavad. Oma isiklikku blokerimisloendisse lisatud kasutajad ei saa sulle saata sõnumeid ega kutseid.", - "@blockListDescription": {}, - "createGroupAndInviteUsers": "Lisavestlusrühm ja kutsu sinna kasutajaid", - "@createGroupAndInviteUsers": {}, - "startConversation": "Alusta vestlust", - "@startConversation": {}, - "blockedUsers": "Blokeeritud kasutajad", - "@blockedUsers": {}, - "groupCanBeFoundViaSearch": "Vestlusrühm on leitav otsinguga", - "@groupCanBeFoundViaSearch": {}, - "noUsersFoundWithQuery": "Päringuga „{query}“ ei leidunud kahkus ühtegi kasutajat. Palun kontrolli, et päringus poleks vigu.", - "@noUsersFoundWithQuery": { - "type": "text", - "placeholders": { - "query": {} - } - }, - "block": "blokeeri", - "@block": {}, - "yourGlobalUserIdIs": "Sinu üldine kasutajatunnus on: ", - "@yourGlobalUserIdIs": {}, - "commandHint_sendraw": "Saada json oma algupärasel kujul", - "@commandHint_sendraw": {}, - "wrongRecoveryKey": "Vabandust..., see ei tundu olema korrektne taastevõti.", - "@wrongRecoveryKey": {}, - "blockUsername": "Eira kasutajanime", - "@blockUsername": {}, - "groupName": "Vestlusrühma nimi", - "@groupName": {}, - "databaseMigrationTitle": "Andmebaas on optimeeritud", - "@databaseMigrationTitle": {}, - "searchChatsRooms": "Otsi #vestlusi, @kasutajaid...", - "@searchChatsRooms": {}, - "databaseMigrationBody": "Palun oota üks hetk. Natuke võib kuluda aega.", - "@databaseMigrationBody": {} -} \ No newline at end of file + "@@locale": "et", + "@@last_modified": "2021-08-14 12:41:10.079944", + "about": "Rakenduse teave", + "@about": { + "type": "text", + "placeholders": {} + }, + "accept": "Nõustu", + "@accept": { + "type": "text", + "placeholders": {} + }, + "acceptedTheInvitation": "👍 {username} võttis kutse vastu", + "@acceptedTheInvitation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "account": "Kasutajakonto", + "@account": { + "type": "text", + "placeholders": {} + }, + "activatedEndToEndEncryption": "🔐{username} võttis kasutusele läbiva krüptimise", + "@activatedEndToEndEncryption": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "addEmail": "Lisa e-posti aadress", + "@addEmail": { + "type": "text", + "placeholders": {} + }, + "admin": "Peakasutaja", + "@admin": { + "type": "text", + "placeholders": {} + }, + "alias": "alias", + "@alias": { + "type": "text", + "placeholders": {} + }, + "all": "Kõik", + "@all": { + "type": "text", + "placeholders": {} + }, + "allChats": "Kõik vestlused", + "@allChats": { + "type": "text", + "placeholders": {} + }, + "answeredTheCall": "{senderName} vastas kõnele", + "@answeredTheCall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "anyoneCanJoin": "Kõik võivad liituda", + "@anyoneCanJoin": { + "type": "text", + "placeholders": {} + }, + "appLock": "Rakenduse lukustus", + "@appLock": { + "type": "text", + "placeholders": {} + }, + "archive": "Arhiiv", + "@archive": { + "type": "text", + "placeholders": {} + }, + "areGuestsAllowedToJoin": "Kas külalised võivad liituda", + "@areGuestsAllowedToJoin": { + "type": "text", + "placeholders": {} + }, + "areYouSure": "Kas sa oled kindel?", + "@areYouSure": { + "type": "text", + "placeholders": {} + }, + "areYouSureYouWantToLogout": "Kas sa oled kindel, et soovid välja logida?", + "@areYouSureYouWantToLogout": { + "type": "text", + "placeholders": {} + }, + "askSSSSSign": "Selleks, et teist osapoolt identifitseerivat allkirja anda, palun sisesta oma turvahoidla paroolifraas või taastevõti.", + "@askSSSSSign": { + "type": "text", + "placeholders": {} + }, + "askVerificationRequest": "Kas võtad vastu selle verifitseerimispalve kasutajalt {username}?", + "@askVerificationRequest": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "autoplayImages": "Esita liikuvad kleepse ja emotikone automaatselt", + "@autoplayImages": { + "type": "text", + "placeholder": {} + }, + "badServerLoginTypesException": "See koduserver toetab Matrixi võrku sisselogimiseks:\n{serverVersions}\nAga see rakendus toetab vaid järgmisi võimalusi:\n{supportedVersions}", + "@badServerLoginTypesException": { + "type": "text", + "placeholders": { + "serverVersions": {}, + "supportedVersions": {} + } + }, + "badServerVersionsException": "See koduserver toetab Matrixi spetsifikatsioonist järgmisi versioone:\n{serverVersions}\nAga see rakendus toetab vaid järgmisi versioone: {supportedVersions}", + "@badServerVersionsException": { + "type": "text", + "placeholders": { + "serverVersions": {}, + "supportedVersions": {} + } + }, + "banFromChat": "Keela ligipääs vestlusele", + "@banFromChat": { + "type": "text", + "placeholders": {} + }, + "banned": "Ligipääs vestlusele on keelatud", + "@banned": { + "type": "text", + "placeholders": {} + }, + "bannedUser": "{username} keelas ligipääsu kasutajale {targetName}", + "@bannedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "blockDevice": "Blokeeri seade", + "@blockDevice": { + "type": "text", + "placeholders": {} + }, + "blocked": "Blokeeritud", + "@blocked": { + "type": "text", + "placeholders": {} + }, + "botMessages": "Robotite sõnumid", + "@botMessages": { + "type": "text", + "placeholders": {} + }, + "cancel": "Katkesta", + "@cancel": { + "type": "text", + "placeholders": {} + }, + "cantOpenUri": "{uri} aadressi avamine ei õnnestu", + "@cantOpenUri": { + "type": "text", + "placeholders": { + "uri": {} + } + }, + "changeDeviceName": "Muuda seadme nime", + "@changeDeviceName": { + "type": "text", + "placeholders": {} + }, + "changedTheChatAvatar": "{username} muutis vestluse tunnuspilti", + "@changedTheChatAvatar": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheChatDescriptionTo": "{username} muutis vestluse uueks kirjelduseks „{description}“", + "@changedTheChatDescriptionTo": { + "type": "text", + "placeholders": { + "username": {}, + "description": {} + } + }, + "changedTheChatNameTo": "{username} muutis oma uueks kuvatavaks nimeks „{chatname}“", + "@changedTheChatNameTo": { + "type": "text", + "placeholders": { + "username": {}, + "chatname": {} + } + }, + "changedTheChatPermissions": "{username} muutis vestlusega seotud õigusi", + "@changedTheChatPermissions": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheDisplaynameTo": "{username} muutis uueks kuvatavaks nimeks: {displayname}", + "@changedTheDisplaynameTo": { + "type": "text", + "placeholders": { + "username": {}, + "displayname": {} + } + }, + "changedTheGuestAccessRules": "{username} muutis külaliste ligipääsureegleid", + "@changedTheGuestAccessRules": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheGuestAccessRulesTo": "{username} muutis külaliste ligipääsureegleid järgnevalt: {rules}", + "@changedTheGuestAccessRulesTo": { + "type": "text", + "placeholders": { + "username": {}, + "rules": {} + } + }, + "changedTheHistoryVisibility": "{username} muutis sõnumite ajaloo nähtavust", + "@changedTheHistoryVisibility": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheHistoryVisibilityTo": "{username} muutis sõnumite ajaloo nähtavust järgnevalt: {rules}", + "@changedTheHistoryVisibilityTo": { + "type": "text", + "placeholders": { + "username": {}, + "rules": {} + } + }, + "changedTheJoinRules": "{username} muutis liitumise reegleid", + "@changedTheJoinRules": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheJoinRulesTo": "{username} muutis liitumise reegleid järgnevalt: {joinRules}", + "@changedTheJoinRulesTo": { + "type": "text", + "placeholders": { + "username": {}, + "joinRules": {} + } + }, + "changedTheProfileAvatar": "{username} muutis oma tunnuspilti", + "@changedTheProfileAvatar": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheRoomAliases": "{username} muutis jututoa aliast", + "@changedTheRoomAliases": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changedTheRoomInvitationLink": "{username} muutis kutse linki", + "@changedTheRoomInvitationLink": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "changePassword": "Muuda salasõna", + "@changePassword": { + "type": "text", + "placeholders": {} + }, + "changeTheHomeserver": "Muuda koduserverit", + "@changeTheHomeserver": { + "type": "text", + "placeholders": {} + }, + "changeTheme": "Muuda oma stiili", + "@changeTheme": { + "type": "text", + "placeholders": {} + }, + "changeTheNameOfTheGroup": "Muuda vestlusrühma nime", + "@changeTheNameOfTheGroup": { + "type": "text", + "placeholders": {} + }, + "changeYourAvatar": "Muuda oma tunnuspilti", + "@changeYourAvatar": { + "type": "text", + "placeholders": {} + }, + "channelCorruptedDecryptError": "Kasutatud krüptimine on vigane", + "@channelCorruptedDecryptError": { + "type": "text", + "placeholders": {} + }, + "chat": "Vestlus", + "@chat": { + "type": "text", + "placeholders": {} + }, + "chatBackup": "Varunda vestlus", + "@chatBackup": { + "type": "text", + "placeholders": {} + }, + "chatBackupDescription": "Sinu vestluste varukoopia on krüptitud taastamiseks mõeldud turvavõtmega. Palun vaata, et sa seda ei kaota.", + "@chatBackupDescription": { + "type": "text", + "placeholders": {} + }, + "chatDetails": "Vestluse teave", + "@chatDetails": { + "type": "text", + "placeholders": {} + }, + "chats": "Vestlused", + "@chats": { + "type": "text", + "placeholders": {} + }, + "chooseAStrongPassword": "Vali korralik salasõna", + "@chooseAStrongPassword": { + "type": "text", + "placeholders": {} + }, + "clearArchive": "Kustuta arhiiv", + "@clearArchive": {}, + "close": "Sulge", + "@close": { + "type": "text", + "placeholders": {} + }, + "commandHint_ban": "Sea sellele kasutajale antud jututoas suhtluskeeld", + "@commandHint_ban": { + "type": "text", + "description": "Usage hint for the command /ban" + }, + "commandHint_html": "Saada HTML-vormingus tekst", + "@commandHint_html": { + "type": "text", + "description": "Usage hint for the command /html" + }, + "commandHint_invite": "Kutsu see kasutaja antud jututuppa", + "@commandHint_invite": { + "type": "text", + "description": "Usage hint for the command /invite" + }, + "commandHint_join": "Liitu selle jututoaga", + "@commandHint_join": { + "type": "text", + "description": "Usage hint for the command /join" + }, + "commandHint_kick": "Eemalda antud kasutaja sellest jututoast", + "@commandHint_kick": { + "type": "text", + "description": "Usage hint for the command /kick" + }, + "commandHint_leave": "Lahku sellest jututoast", + "@commandHint_leave": { + "type": "text", + "description": "Usage hint for the command /leave" + }, + "commandHint_me": "Kirjelda ennast", + "@commandHint_me": { + "type": "text", + "description": "Usage hint for the command /me" + }, + "commandHint_myroomavatar": "Määra selles jututoas oma tunnuspilt (mxc-uri vahendusel)", + "@commandHint_myroomavatar": { + "type": "text", + "description": "Usage hint for the command /myroomavatar" + }, + "commandHint_myroomnick": "Määra selles jututoas oma kuvatav nimi", + "@commandHint_myroomnick": { + "type": "text", + "description": "Usage hint for the command /myroomnick" + }, + "commandHint_op": "Seadista selle kasutaja õigusi (vaikimisi: 50)", + "@commandHint_op": { + "type": "text", + "description": "Usage hint for the command /op" + }, + "commandHint_plain": "Saada vormindamata tekst", + "@commandHint_plain": { + "type": "text", + "description": "Usage hint for the command /plain" + }, + "commandHint_react": "Saada vastus reaktsioonina", + "@commandHint_react": { + "type": "text", + "description": "Usage hint for the command /react" + }, + "commandHint_send": "Saada sõnum", + "@commandHint_send": { + "type": "text", + "description": "Usage hint for the command /send" + }, + "commandHint_unban": "Eemalda sellelt kasutajalt antud jututoas suhtluskeeld", + "@commandHint_unban": { + "type": "text", + "description": "Usage hint for the command /unban" + }, + "commandInvalid": "Vigane käsk", + "@commandInvalid": { + "type": "text" + }, + "commandMissing": "{command} ei ole käsk.", + "@commandMissing": { + "type": "text", + "placeholders": { + "command": {} + }, + "description": "State that {command} is not a valid /command." + }, + "compareEmojiMatch": "Palun võrdle emotikone", + "@compareEmojiMatch": { + "type": "text", + "placeholders": {} + }, + "compareNumbersMatch": "Palun võrdle numbreid", + "@compareNumbersMatch": { + "type": "text", + "placeholders": {} + }, + "configureChat": "Seadista vestlust", + "@configureChat": { + "type": "text", + "placeholders": {} + }, + "confirm": "Kinnita", + "@confirm": { + "type": "text", + "placeholders": {} + }, + "connect": "Ühenda", + "@connect": { + "type": "text", + "placeholders": {} + }, + "contactHasBeenInvitedToTheGroup": "Sinu kontakt on kutsutud liituma vestlusrühma", + "@contactHasBeenInvitedToTheGroup": { + "type": "text", + "placeholders": {} + }, + "containsDisplayName": "Sisaldab kuvatavat nime", + "@containsDisplayName": { + "type": "text", + "placeholders": {} + }, + "containsUserName": "Sisaldab kasutajanime", + "@containsUserName": { + "type": "text", + "placeholders": {} + }, + "contentHasBeenReported": "Saatsime selle sisu kohta teate koduserveri haldajate", + "@contentHasBeenReported": { + "type": "text", + "placeholders": {} + }, + "copiedToClipboard": "Kopeerisin lõikelauale", + "@copiedToClipboard": { + "type": "text", + "placeholders": {} + }, + "copy": "Kopeeri", + "@copy": { + "type": "text", + "placeholders": {} + }, + "copyToClipboard": "Kopeeri lõikelauale", + "@copyToClipboard": { + "type": "text", + "placeholders": {} + }, + "couldNotDecryptMessage": "Sõnumi dekrüptimine ei õnnestunud: {error}", + "@couldNotDecryptMessage": { + "type": "text", + "placeholders": { + "error": {} + } + }, + "countParticipants": "{count} osalejat", + "@countParticipants": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "create": "Loo", + "@create": { + "type": "text", + "placeholders": {} + }, + "createdTheChat": "💬 {username} algatas vestluse", + "@createdTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "createNewSpace": "Uus kogukond", + "@createNewSpace": { + "type": "text", + "placeholders": {} + }, + "currentlyActive": "Hetkel aktiivne", + "@currentlyActive": { + "type": "text", + "placeholders": {} + }, + "darkTheme": "Tume", + "@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": "Järgnevaga eemaldatakse sinu konto kasutusest. Seda tegevust ei saa tagasi pöörata! Kas sa ikka oled kindel?", + "@deactivateAccountWarning": { + "type": "text", + "placeholders": {} + }, + "defaultPermissionLevel": "Vaikimisi õigused", + "@defaultPermissionLevel": { + "type": "text", + "placeholders": {} + }, + "delete": "Kustuta", + "@delete": { + "type": "text", + "placeholders": {} + }, + "deleteAccount": "Kustuta kasutajakonto", + "@deleteAccount": { + "type": "text", + "placeholders": {} + }, + "deleteMessage": "Kustuta sõnum", + "@deleteMessage": { + "type": "text", + "placeholders": {} + }, + "device": "Seade", + "@device": { + "type": "text", + "placeholders": {} + }, + "deviceId": "Seadme tunnus", + "@deviceId": { + "type": "text", + "placeholders": {} + }, + "devices": "Seadmed", + "@devices": { + "type": "text", + "placeholders": {} + }, + "directChats": "Otsevestlused", + "@directChats": { + "type": "text", + "placeholders": {} + }, + "displaynameHasBeenChanged": "Kuvatav nimi on muudetud", + "@displaynameHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "downloadFile": "Laadi fail alla", + "@downloadFile": { + "type": "text", + "placeholders": {} + }, + "edit": "Muuda", + "@edit": { + "type": "text", + "placeholders": {} + }, + "editBlockedServers": "Muuda blokeeritud serverite loendit", + "@editBlockedServers": { + "type": "text", + "placeholders": {} + }, + "editDisplayname": "Muuda kuvatavat nime", + "@editDisplayname": { + "type": "text", + "placeholders": {} + }, + "editRoomAliases": "Muuda jututoa aliast", + "@editRoomAliases": { + "type": "text", + "placeholders": {} + }, + "editRoomAvatar": "Muuda jututoa tunnuspilti", + "@editRoomAvatar": { + "type": "text", + "placeholders": {} + }, + "emoteExists": "Selline emotsioonitegevus on juba olemas!", + "@emoteExists": { + "type": "text", + "placeholders": {} + }, + "emoteInvalid": "Vigane emotsioonitegevuse lühikood!", + "@emoteInvalid": { + "type": "text", + "placeholders": {} + }, + "emotePacks": "Emotsioonitegevuste pakid jututoa jaoks", + "@emotePacks": { + "type": "text", + "placeholders": {} + }, + "emoteSettings": "Emotsioonitegevuste seadistused", + "@emoteSettings": { + "type": "text", + "placeholders": {} + }, + "emoteShortcode": "Emotsioonitegevuse lühikood", + "@emoteShortcode": { + "type": "text", + "placeholders": {} + }, + "emoteWarnNeedToPick": "Sa pead valima emotsioonitegevuse lühikoodi ja pildi!", + "@emoteWarnNeedToPick": { + "type": "text", + "placeholders": {} + }, + "emptyChat": "Vestlust pole olnud", + "@emptyChat": { + "type": "text", + "placeholders": {} + }, + "enableEmotesGlobally": "Võta emotsioonitegevuste pakid läbivalt kasutusele", + "@enableEmotesGlobally": { + "type": "text", + "placeholders": {} + }, + "enableEncryption": "Kasuta krüptimist", + "@enableEncryption": { + "type": "text", + "placeholders": {} + }, + "enableEncryptionWarning": "Sa ei saa hiljem enam krüptimist välja lülitada. Kas oled kindel?", + "@enableEncryptionWarning": { + "type": "text", + "placeholders": {} + }, + "encrypted": "Krüptitud", + "@encrypted": { + "type": "text", + "placeholders": {} + }, + "encryption": "Krüptimine", + "@encryption": { + "type": "text", + "placeholders": {} + }, + "encryptionNotEnabled": "Krüptimine ei ole kasutusel", + "@encryptionNotEnabled": { + "type": "text", + "placeholders": {} + }, + "endedTheCall": "{senderName} lõpetas kõne", + "@endedTheCall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "enterAnEmailAddress": "Sisesta e-posti aadress", + "@enterAnEmailAddress": { + "type": "text", + "placeholders": {} + }, + "enterYourHomeserver": "Sisesta oma koduserveri aadress", + "@enterYourHomeserver": { + "type": "text", + "placeholders": {} + }, + "errorObtainingLocation": "Viga asukoha tuvastamisel: {error}", + "@errorObtainingLocation": { + "type": "text", + "placeholders": { + "error": {} + } + }, + "everythingReady": "Kõik on valmis!", + "@everythingReady": { + "type": "text", + "placeholders": {} + }, + "extremeOffensive": "Äärmiselt solvav", + "@extremeOffensive": { + "type": "text", + "placeholders": {} + }, + "fileName": "Faili nimi", + "@fileName": { + "type": "text", + "placeholders": {} + }, + "fluffychat": "FluffyChat", + "@fluffychat": { + "type": "text", + "placeholders": {} + }, + "fontSize": "Fondi suurus", + "@fontSize": { + "type": "text", + "placeholders": {} + }, + "forward": "Edasta", + "@forward": { + "type": "text", + "placeholders": {} + }, + "fromJoining": "Alates liitumise hetkest", + "@fromJoining": { + "type": "text", + "placeholders": {} + }, + "fromTheInvitation": "Kutse saamisest", + "@fromTheInvitation": { + "type": "text", + "placeholders": {} + }, + "goToTheNewRoom": "Hakka kasutama uut jututuba", + "@goToTheNewRoom": { + "type": "text", + "placeholders": {} + }, + "group": "Vestlusrühm", + "@group": { + "type": "text", + "placeholders": {} + }, + "groupIsPublic": "Vestlusrühm on avalik", + "@groupIsPublic": { + "type": "text", + "placeholders": {} + }, + "groups": "Vestlusrühmad", + "@groups": { + "type": "text", + "placeholders": {} + }, + "groupWith": "Vestlusrühm {displayname} kasutajanimega", + "@groupWith": { + "type": "text", + "placeholders": { + "displayname": {} + } + }, + "guestsAreForbidden": "Külalised ei ole lubatud", + "@guestsAreForbidden": { + "type": "text", + "placeholders": {} + }, + "guestsCanJoin": "Külalised võivad liituda", + "@guestsCanJoin": { + "type": "text", + "placeholders": {} + }, + "hasWithdrawnTheInvitationFor": "{username} on võtnud tagasi {targetName} kutse", + "@hasWithdrawnTheInvitationFor": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "help": "Abiteave", + "@help": { + "type": "text", + "placeholders": {} + }, + "hideRedactedEvents": "Peida muudetud sündmused", + "@hideRedactedEvents": { + "type": "text", + "placeholders": {} + }, + "hideUnknownEvents": "Peida tundmatud sündmused", + "@hideUnknownEvents": { + "type": "text", + "placeholders": {} + }, + "howOffensiveIsThisContent": "Kui solvav see sisu on?", + "@howOffensiveIsThisContent": { + "type": "text", + "placeholders": {} + }, + "id": "ID", + "@id": { + "type": "text", + "placeholders": {} + }, + "identity": "Identiteet", + "@identity": { + "type": "text", + "placeholders": {} + }, + "ignore": "Eira", + "@ignore": { + "type": "text", + "placeholders": {} + }, + "ignoredUsers": "Eiratud kasutajad", + "@ignoredUsers": { + "type": "text", + "placeholders": {} + }, + "iHaveClickedOnLink": "Ma olen klõpsinud saadetud linki", + "@iHaveClickedOnLink": { + "type": "text", + "placeholders": {} + }, + "incorrectPassphraseOrKey": "Vigane paroolifraas või taastevõti", + "@incorrectPassphraseOrKey": { + "type": "text", + "placeholders": {} + }, + "inoffensive": "Kahjutu", + "@inoffensive": { + "type": "text", + "placeholders": {} + }, + "inviteContact": "Kutsu sõpru ja tuttavaid", + "@inviteContact": { + "type": "text", + "placeholders": {} + }, + "inviteContactToGroup": "Kutsu sõpru ja tuttavaid {groupName} liikmeks", + "@inviteContactToGroup": { + "type": "text", + "placeholders": { + "groupName": {} + } + }, + "invited": "Kutsutud", + "@invited": { + "type": "text", + "placeholders": {} + }, + "invitedUser": "📩 {username} saatis kutse kasutajale {targetName}", + "@invitedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "invitedUsersOnly": "Ainult kutsutud kasutajatele", + "@invitedUsersOnly": { + "type": "text", + "placeholders": {} + }, + "inviteForMe": "Kutse minu jaoks", + "@inviteForMe": { + "type": "text", + "placeholders": {} + }, + "inviteText": "{username} kutsus sind kasutama Matrix'i-põhist suhtlusrakendust FluffyChat. \n1. Ava fluffychat.im ja paigalda FluffyChat'i rakendus \n2. Liitu kasutajaks või logi sisse olemasoleva Matrix'i kasutajakontoga\n3. Ava kutse link: \n {link}", + "@inviteText": { + "type": "text", + "placeholders": { + "username": {}, + "link": {} + } + }, + "isTyping": "kirjutab…", + "@isTyping": { + "type": "text", + "placeholders": {} + }, + "joinedTheChat": "👋 {username} liitus vestlusega", + "@joinedTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "joinRoom": "Liitu jututoaga", + "@joinRoom": { + "type": "text", + "placeholders": {} + }, + "kicked": "👞 {username} müksas kasutaja {targetName} välja", + "@kicked": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "kickedAndBanned": "🙅{username} müksas kasutaja {targetName} välja ning seadis talle suhtluskeelu", + "@kickedAndBanned": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "kickFromChat": "Müksa vestlusest välja", + "@kickFromChat": { + "type": "text", + "placeholders": {} + }, + "lastActiveAgo": "Viimati nähtud: {localizedTimeShort}", + "@lastActiveAgo": { + "type": "text", + "placeholders": { + "localizedTimeShort": {} + } + }, + "leave": "Lahku", + "@leave": { + "type": "text", + "placeholders": {} + }, + "leftTheChat": "Lahkus vestlusest", + "@leftTheChat": { + "type": "text", + "placeholders": {} + }, + "license": "Litsents", + "@license": { + "type": "text", + "placeholders": {} + }, + "lightTheme": "Hele", + "@lightTheme": { + "type": "text", + "placeholders": {} + }, + "loadCountMoreParticipants": "Lisa veel {count} osalejat", + "@loadCountMoreParticipants": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "loadingPleaseWait": "Laadin andmeid… Palun oota.", + "@loadingPleaseWait": { + "type": "text", + "placeholders": {} + }, + "loadMore": "Laadi veel…", + "@loadMore": { + "type": "text", + "placeholders": {} + }, + "locationDisabledNotice": "Asukohateenused on seadmes väljalülitatud. Asukoha jagamiseks palun lülita nad sisse.", + "@locationDisabledNotice": { + "type": "text", + "placeholders": {} + }, + "locationPermissionDeniedNotice": "Puudub luba asukohateenuste kasutamiseks. Asukoha jagamiseks palun anna rakendusele vastavad õigused.", + "@locationPermissionDeniedNotice": { + "type": "text", + "placeholders": {} + }, + "login": "Logi sisse", + "@login": { + "type": "text", + "placeholders": {} + }, + "logInTo": "Logi sisse {homeserver} serverisse", + "@logInTo": { + "type": "text", + "placeholders": { + "homeserver": {} + } + }, + "logout": "Logi välja", + "@logout": { + "type": "text", + "placeholders": {} + }, + "memberChanges": "Muudatused liikmeskonnas", + "@memberChanges": { + "type": "text", + "placeholders": {} + }, + "mention": "Märgi ära", + "@mention": { + "type": "text", + "placeholders": {} + }, + "messages": "Sõnumid", + "@messages": { + "type": "text", + "placeholders": {} + }, + "moderator": "Moderaator", + "@moderator": { + "type": "text", + "placeholders": {} + }, + "muteChat": "Summuta vestlus", + "@muteChat": { + "type": "text", + "placeholders": {} + }, + "needPantalaimonWarning": "Palun arvesta, et sa saad hetkel kasutada läbivat krüptimist vaid siis, kui koduserver kasutab Pantalaimon'it.", + "@needPantalaimonWarning": { + "type": "text", + "placeholders": {} + }, + "newChat": "Uus vestlus", + "@newChat": { + "type": "text", + "placeholders": {} + }, + "newMessageInFluffyChat": "💬 Uus sõnum FluffyChat'i vahendusel", + "@newMessageInFluffyChat": { + "type": "text", + "placeholders": {} + }, + "newVerificationRequest": "Uus verifitseerimispäring!", + "@newVerificationRequest": { + "type": "text", + "placeholders": {} + }, + "next": "Edasi", + "@next": { + "type": "text", + "placeholders": {} + }, + "no": "Ei", + "@no": { + "type": "text", + "placeholders": {} + }, + "noConnectionToTheServer": "Puudub ühendus koduserveriga", + "@noConnectionToTheServer": { + "type": "text", + "placeholders": {} + }, + "noEmotesFound": "Ühtegi emotsioonitegevust ei leidunud. 😕", + "@noEmotesFound": { + "type": "text", + "placeholders": {} + }, + "noEncryptionForPublicRooms": "Sa võid krüptimise kasutusele võtta niipea, kui jututuba pole enam avalik.", + "@noEncryptionForPublicRooms": { + "type": "text", + "placeholders": {} + }, + "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": {} + }, + "noMatrixServer": "{server1} pole Matrix'i server, kas kasutame selle asemel {server2} serverit?", + "@noMatrixServer": { + "type": "text", + "placeholders": { + "server1": {}, + "server2": {} + } + }, + "none": "Mitte midagi", + "@none": { + "type": "text", + "placeholders": {} + }, + "noPasswordRecoveryDescription": "Sa pole veel lisanud võimalust salasõna taastamiseks.", + "@noPasswordRecoveryDescription": { + "type": "text", + "placeholders": {} + }, + "noPermission": "Õigused puuduvad", + "@noPermission": { + "type": "text", + "placeholders": {} + }, + "noRoomsFound": "Jututubasid ei leidunud…", + "@noRoomsFound": { + "type": "text", + "placeholders": {} + }, + "notifications": "Teavitused", + "@notifications": { + "type": "text", + "placeholders": {} + }, + "notificationsEnabledForThisAccount": "Teavitused on sellel kontol kasutusel", + "@notificationsEnabledForThisAccount": { + "type": "text", + "placeholders": {} + }, + "numUsersTyping": "{count} kasutajat kirjutavad…", + "@numUsersTyping": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "obtainingLocation": "Tuvastan asukohta…", + "@obtainingLocation": { + "type": "text", + "placeholders": {} + }, + "offensive": "Solvav", + "@offensive": { + "type": "text", + "placeholders": {} + }, + "offline": "Väljas", + "@offline": { + "type": "text", + "placeholders": {} + }, + "ok": "sobib", + "@ok": { + "type": "text", + "placeholders": {} + }, + "online": "Saadaval", + "@online": { + "type": "text", + "placeholders": {} + }, + "onlineKeyBackupEnabled": "Krüptovõtmete veebipõhine varundus on kasutusel", + "@onlineKeyBackupEnabled": { + "type": "text", + "placeholders": {} + }, + "oopsPushError": "Hopsti! Kahjuks tekkis tõuketeavituste seadistamisel viga.", + "@oopsPushError": { + "type": "text", + "placeholders": {} + }, + "oopsSomethingWentWrong": "Hopsti! Midagi läks nüüd viltu…", + "@oopsSomethingWentWrong": { + "type": "text", + "placeholders": {} + }, + "openAppToReadMessages": "Sõnumite lugemiseks ava rakendus", + "@openAppToReadMessages": { + "type": "text", + "placeholders": {} + }, + "openCamera": "Ava kaamera", + "@openCamera": { + "type": "text", + "placeholders": {} + }, + "openInMaps": "Ava kaardirakendusega", + "@openInMaps": { + "type": "text", + "placeholders": {} + }, + "or": "või", + "@or": { + "type": "text", + "placeholders": {} + }, + "participant": "Osaleja", + "@participant": { + "type": "text", + "placeholders": {} + }, + "passphraseOrKey": "paroolifraas või taastevõti", + "@passphraseOrKey": { + "type": "text", + "placeholders": {} + }, + "password": "Salasõna", + "@password": { + "type": "text", + "placeholders": {} + }, + "passwordForgotten": "Salasõna on ununenud", + "@passwordForgotten": { + "type": "text", + "placeholders": {} + }, + "passwordHasBeenChanged": "Salasõna on muudetud", + "@passwordHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "passwordRecovery": "Salasõna taastamine", + "@passwordRecovery": { + "type": "text", + "placeholders": {} + }, + "people": "Inimesed", + "@people": { + "type": "text", + "placeholders": {} + }, + "pickImage": "Vali pilt", + "@pickImage": { + "type": "text", + "placeholders": {} + }, + "pin": "Klammerda", + "@pin": { + "type": "text", + "placeholders": {} + }, + "play": "Esita {fileName}", + "@play": { + "type": "text", + "placeholders": { + "fileName": {} + } + }, + "pleaseChoose": "Palun vali", + "@pleaseChoose": { + "type": "text", + "placeholders": {} + }, + "pleaseChooseAPasscode": "Palun vali rakenduse PIN-kood", + "@pleaseChooseAPasscode": { + "type": "text", + "placeholders": {} + }, + "pleaseClickOnLink": "Jätkamiseks palun klõpsi sulle saadetud e-kirjas leiduvat linki.", + "@pleaseClickOnLink": { + "type": "text", + "placeholders": {} + }, + "pleaseEnter4Digits": "Rakenduse luku jaoks sisesta 4 numbrit või kui sa sellist võimalust ei soovi kasutada, siis jäta nad tühjaks.", + "@pleaseEnter4Digits": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourPassword": "Palun sisesta oma salasõna", + "@pleaseEnterYourPassword": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourPin": "Palun sisesta oma PIN-kood", + "@pleaseEnterYourPin": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourUsername": "Palun sisesta oma kasutajanimi", + "@pleaseEnterYourUsername": { + "type": "text", + "placeholders": {} + }, + "pleaseFollowInstructionsOnWeb": "Palun järgi veebilehel olevaid juhiseid ja klõpsi nuppu Edasi.", + "@pleaseFollowInstructionsOnWeb": { + "type": "text", + "placeholders": {} + }, + "privacy": "Privaatsus", + "@privacy": { + "type": "text", + "placeholders": {} + }, + "publicRooms": "Avalikud jututoad", + "@publicRooms": { + "type": "text", + "placeholders": {} + }, + "pushRules": "Tõukereeglid", + "@pushRules": { + "type": "text", + "placeholders": {} + }, + "reason": "Põhjus", + "@reason": { + "type": "text", + "placeholders": {} + }, + "recording": "Salvestan", + "@recording": { + "type": "text", + "placeholders": {} + }, + "redactedAnEvent": "{username} muutis sündmust", + "@redactedAnEvent": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "redactMessage": "Muuda sõnumit", + "@redactMessage": { + "type": "text", + "placeholders": {} + }, + "register": "Registreeru", + "@register": { + "type": "text", + "placeholders": {} + }, + "reject": "Lükka tagasi", + "@reject": { + "type": "text", + "placeholders": {} + }, + "rejectedTheInvitation": "{username} lükkas kutse tagasi", + "@rejectedTheInvitation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "rejoin": "Liitu uuesti", + "@rejoin": { + "type": "text", + "placeholders": {} + }, + "remove": "Eemalda", + "@remove": { + "type": "text", + "placeholders": {} + }, + "removeAllOtherDevices": "Eemalda kõik muud seadmed", + "@removeAllOtherDevices": { + "type": "text", + "placeholders": {} + }, + "removedBy": "{username} eemaldas sündmuse", + "@removedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "removeDevice": "Eemalda seade", + "@removeDevice": { + "type": "text", + "placeholders": {} + }, + "unbanFromChat": "Eemalda suhtluskeeld", + "@unbanFromChat": { + "type": "text", + "placeholders": {} + }, + "removeYourAvatar": "Kustuta oma tunnuspilt", + "@removeYourAvatar": { + "type": "text", + "placeholders": {} + }, + "renderRichContent": "Visualiseeri vormindatud sõnumite sisu", + "@renderRichContent": { + "type": "text", + "placeholders": {} + }, + "replaceRoomWithNewerVersion": "Asenda jututoa senine versioon uuega", + "@replaceRoomWithNewerVersion": { + "type": "text", + "placeholders": {} + }, + "reply": "Vasta", + "@reply": { + "type": "text", + "placeholders": {} + }, + "reportMessage": "Teata sõnumist", + "@reportMessage": { + "type": "text", + "placeholders": {} + }, + "requestPermission": "Palu õigusi", + "@requestPermission": { + "type": "text", + "placeholders": {} + }, + "roomHasBeenUpgraded": "Jututoa vesrioon on uuendatud", + "@roomHasBeenUpgraded": { + "type": "text", + "placeholders": {} + }, + "roomVersion": "Jututoa versioon", + "@roomVersion": { + "type": "text", + "placeholders": {} + }, + "saveFile": "Salvesta fail", + "@saveFile": { + "type": "text", + "placeholders": {} + }, + "search": "Otsi", + "@search": { + "type": "text", + "placeholders": {} + }, + "security": "Turvalisus", + "@security": { + "type": "text", + "placeholders": {} + }, + "seenByUser": "Sõnumit nägi {username}", + "@seenByUser": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "send": "Saada", + "@send": { + "type": "text", + "placeholders": {} + }, + "sendAMessage": "Saada sõnum", + "@sendAMessage": { + "type": "text", + "placeholders": {} + }, + "sendAsText": "Saada tekstisõnumina", + "@sendAsText": { + "type": "text" + }, + "sendAudio": "Saada helifail", + "@sendAudio": { + "type": "text", + "placeholders": {} + }, + "sendFile": "Saada fail", + "@sendFile": { + "type": "text", + "placeholders": {} + }, + "sendImage": "Saada pilt", + "@sendImage": { + "type": "text", + "placeholders": {} + }, + "sendMessages": "Saada sõnumeid", + "@sendMessages": { + "type": "text", + "placeholders": {} + }, + "sendOriginal": "Saada fail muutmata kujul", + "@sendOriginal": { + "type": "text", + "placeholders": {} + }, + "sendSticker": "Saada kleeps", + "@sendSticker": { + "type": "text", + "placeholders": {} + }, + "sendVideo": "Saada videofail", + "@sendVideo": { + "type": "text", + "placeholders": {} + }, + "sentAFile": "📁 {username} saatis faili", + "@sentAFile": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sentAnAudio": "🎤 {username} saatis helifaili", + "@sentAnAudio": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sentAPicture": "🖼️ {username} saatis pildi", + "@sentAPicture": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sentASticker": "😊 {username} saatis kleepsu", + "@sentASticker": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sentAVideo": "🎥 {username} saatis video", + "@sentAVideo": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "sentCallInformations": "{senderName} saatis teavet kõne kohta", + "@sentCallInformations": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "setAsCanonicalAlias": "Määra põhinimeks", + "@setAsCanonicalAlias": { + "type": "text", + "placeholders": {} + }, + "setCustomEmotes": "Kohanda emotsioonitegevusi", + "@setCustomEmotes": { + "type": "text", + "placeholders": {} + }, + "setInvitationLink": "Tee kutselink", + "@setInvitationLink": { + "type": "text", + "placeholders": {} + }, + "setPermissionsLevel": "Seadista õigusi", + "@setPermissionsLevel": { + "type": "text", + "placeholders": {} + }, + "setStatus": "Määra olek", + "@setStatus": { + "type": "text", + "placeholders": {} + }, + "settings": "Seadistused", + "@settings": { + "type": "text", + "placeholders": {} + }, + "share": "Jaga", + "@share": { + "type": "text", + "placeholders": {} + }, + "sharedTheLocation": "{username} jagas oma asukohta", + "@sharedTheLocation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "shareLocation": "Jaga asukohta", + "@shareLocation": { + "type": "text", + "placeholders": {} + }, + "showPassword": "Näita salasõna", + "@showPassword": { + "type": "text", + "placeholders": {} + }, + "singlesignon": "Ühekordne sisselogimine", + "@singlesignon": { + "type": "text", + "placeholders": {} + }, + "skip": "Jäta vahele", + "@skip": { + "type": "text", + "placeholders": {} + }, + "sourceCode": "Lähtekood", + "@sourceCode": { + "type": "text", + "placeholders": {} + }, + "spaceIsPublic": "Kogukond on avalik", + "@spaceIsPublic": { + "type": "text", + "placeholders": {} + }, + "spaceName": "Kogukonna nimi", + "@spaceName": { + "type": "text", + "placeholders": {} + }, + "startedACall": "{senderName} alustas kõnet", + "@startedACall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "status": "Olek", + "@status": { + "type": "text", + "placeholders": {} + }, + "statusExampleMessage": "Kuidas sul täna läheb?", + "@statusExampleMessage": { + "type": "text", + "placeholders": {} + }, + "submit": "Saada", + "@submit": { + "type": "text", + "placeholders": {} + }, + "synchronizingPleaseWait": "Sünkroniseerin andmeid… Palun oota.", + "@synchronizingPleaseWait": { + "type": "text", + "placeholders": {} + }, + "systemTheme": "Süsteem", + "@systemTheme": { + "type": "text", + "placeholders": {} + }, + "theyDontMatch": "Nad ei klapi omavahel", + "@theyDontMatch": { + "type": "text", + "placeholders": {} + }, + "theyMatch": "Nad klapivad omavahel", + "@theyMatch": { + "type": "text", + "placeholders": {} + }, + "title": "FluffyChat", + "@title": { + "description": "Title for the application", + "type": "text", + "placeholders": {} + }, + "toggleFavorite": "Muuda olekut lemmikuna", + "@toggleFavorite": { + "type": "text", + "placeholders": {} + }, + "toggleMuted": "Lülita summutamine sisse või välja", + "@toggleMuted": { + "type": "text", + "placeholders": {} + }, + "toggleUnread": "Märgi loetuks / lugemata", + "@toggleUnread": { + "type": "text", + "placeholders": {} + }, + "tooManyRequestsWarning": "Liiga palju päringuid. Palun proovi hiljem uuesti!", + "@tooManyRequestsWarning": { + "type": "text", + "placeholders": {} + }, + "transferFromAnotherDevice": "Tõsta teisest seadmest", + "@transferFromAnotherDevice": { + "type": "text", + "placeholders": {} + }, + "tryToSendAgain": "Proovi uuesti saata", + "@tryToSendAgain": { + "type": "text", + "placeholders": {} + }, + "unavailable": "Eemal", + "@unavailable": { + "type": "text", + "placeholders": {} + }, + "unbannedUser": "{username} eemaldas ligipääsukeelu kasutajalt {targetName}", + "@unbannedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "unblockDevice": "Eemalda seadmelt blokeering", + "@unblockDevice": { + "type": "text", + "placeholders": {} + }, + "unknownDevice": "Tundmatu seade", + "@unknownDevice": { + "type": "text", + "placeholders": {} + }, + "unknownEncryptionAlgorithm": "Tundmatu krüptoalgoritm", + "@unknownEncryptionAlgorithm": { + "type": "text", + "placeholders": {} + }, + "unknownEvent": "Tundmatu sündmuse tüüp „{type}“", + "@unknownEvent": { + "type": "text", + "placeholders": { + "type": {} + } + }, + "unmuteChat": "Lõpeta vestluse vaigistamine", + "@unmuteChat": { + "type": "text", + "placeholders": {} + }, + "unpin": "Eemalda klammerdus", + "@unpin": { + "type": "text", + "placeholders": {} + }, + "unreadChats": "{unreadCount, plural, =1{1 lugemata vestlus} other{{unreadCount} lugemata vestlust}}", + "@unreadChats": { + "type": "text", + "placeholders": { + "unreadCount": {} + } + }, + "userAndOthersAreTyping": "{username} ja {count} muud kirjutavad…", + "@userAndOthersAreTyping": { + "type": "text", + "placeholders": { + "username": {}, + "count": {} + } + }, + "userAndUserAreTyping": "{username} ja {username2} kirjutavad…", + "@userAndUserAreTyping": { + "type": "text", + "placeholders": { + "username": {}, + "username2": {} + } + }, + "userIsTyping": "{username} kirjutab…", + "@userIsTyping": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "userLeftTheChat": "🚪{username} lahkus vestlusest", + "@userLeftTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "username": "Kasutajanimi", + "@username": { + "type": "text", + "placeholders": {} + }, + "userSentUnknownEvent": "{username} saatis {type} sündmuse", + "@userSentUnknownEvent": { + "type": "text", + "placeholders": { + "username": {}, + "type": {} + } + }, + "verified": "Verifitseeritud", + "@verified": { + "type": "text", + "placeholders": {} + }, + "verify": "Verifitseeri", + "@verify": { + "type": "text", + "placeholders": {} + }, + "verifyStart": "Alusta verifitseerimist", + "@verifyStart": { + "type": "text", + "placeholders": {} + }, + "verifySuccess": "Sinu verifitseerimine õnnestus!", + "@verifySuccess": { + "type": "text", + "placeholders": {} + }, + "verifyTitle": "Verifitseerin teist kasutajakontot", + "@verifyTitle": { + "type": "text", + "placeholders": {} + }, + "videoCall": "Videokõne", + "@videoCall": { + "type": "text", + "placeholders": {} + }, + "visibilityOfTheChatHistory": "Vestluse ajaloo nähtavus", + "@visibilityOfTheChatHistory": { + "type": "text", + "placeholders": {} + }, + "visibleForAllParticipants": "Nähtav kõikidele osalejatele", + "@visibleForAllParticipants": { + "type": "text", + "placeholders": {} + }, + "visibleForEveryone": "Nähtav kõikidele", + "@visibleForEveryone": { + "type": "text", + "placeholders": {} + }, + "voiceMessage": "Häälsõnum", + "@voiceMessage": { + "type": "text", + "placeholders": {} + }, + "waitingPartnerAcceptRequest": "Ootan, et teine osapool nõustuks päringuga…", + "@waitingPartnerAcceptRequest": { + "type": "text", + "placeholders": {} + }, + "waitingPartnerEmoji": "Ootan teise osapoole kinnitust, et tegemist on samade emojidega…", + "@waitingPartnerEmoji": { + "type": "text", + "placeholders": {} + }, + "waitingPartnerNumbers": "Ootan teise osapoole kinnitust, et tegemist on samade numbritega…", + "@waitingPartnerNumbers": { + "type": "text", + "placeholders": {} + }, + "wallpaper": "Taustapilt:", + "@wallpaper": { + "type": "text", + "placeholders": {} + }, + "warning": "Hoiatus!", + "@warning": { + "type": "text", + "placeholders": {} + }, + "weSentYouAnEmail": "Me saatsime sulle e-kirja", + "@weSentYouAnEmail": { + "type": "text", + "placeholders": {} + }, + "whoCanPerformWhichAction": "Erinevatele kasutajatele lubatud toimingud", + "@whoCanPerformWhichAction": { + "type": "text", + "placeholders": {} + }, + "whoIsAllowedToJoinThisGroup": "Kes võivad selle vestlusrühmaga liituda", + "@whoIsAllowedToJoinThisGroup": { + "type": "text", + "placeholders": {} + }, + "whyDoYouWantToReportThis": "Miks sa soovid sellest teatada?", + "@whyDoYouWantToReportThis": { + "type": "text", + "placeholders": {} + }, + "wipeChatBackup": "Kas kustutame sinu vestluste varukoopia ja loome uue taastamiseks mõeldud krüptovõtme?", + "@wipeChatBackup": { + "type": "text", + "placeholders": {} + }, + "withTheseAddressesRecoveryDescription": "Nende e-posti aadresside abil saad taastada oma salasõna.", + "@withTheseAddressesRecoveryDescription": { + "type": "text", + "placeholders": {} + }, + "writeAMessage": "Kirjuta üks sõnum…", + "@writeAMessage": { + "type": "text", + "placeholders": {} + }, + "yes": "Jah", + "@yes": { + "type": "text", + "placeholders": {} + }, + "you": "Sina", + "@you": { + "type": "text", + "placeholders": {} + }, + "youAreNoLongerParticipatingInThisChat": "Sa enam ei osale selles vestluses", + "@youAreNoLongerParticipatingInThisChat": { + "type": "text", + "placeholders": {} + }, + "youHaveBeenBannedFromThisChat": "Sinule on selles vestluses seatud suhtluskeeld", + "@youHaveBeenBannedFromThisChat": { + "type": "text", + "placeholders": {} + }, + "yourPublicKey": "Sinu avalik võti", + "@yourPublicKey": { + "type": "text", + "placeholders": {} + }, + "chatHasBeenAddedToThisSpace": "Lisasime vestluse kogukonda", + "@chatHasBeenAddedToThisSpace": {}, + "addToSpace": "Lisa kogukonda", + "@addToSpace": {}, + "scanQrCode": "Skaneeri QR-koodi", + "@scanQrCode": {}, + "sendOnEnter": "Saada sõnum sisestusklahvi vajutusel", + "@sendOnEnter": {}, + "homeserver": "Koduserver", + "@homeserver": {}, + "serverRequiresEmail": "See koduserver eeldab registreerimisel kasutatava e-postiaadressi kinnitamist.", + "@serverRequiresEmail": {}, + "enableMultiAccounts": "(KATSELINE) Pruugi selles seadmes mitut Matrix'i kasutajakontot", + "@enableMultiAccounts": {}, + "bundleName": "Köite nimi", + "@bundleName": {}, + "removeFromBundle": "Eemalda sellest köitest", + "@removeFromBundle": {}, + "addToBundle": "Lisa köitesse", + "@addToBundle": {}, + "editBundlesForAccount": "Muuda selle kasutajakonto köiteid", + "@editBundlesForAccount": {}, + "addAccount": "Lisa kasutajakonto", + "@addAccount": {}, + "oneClientLoggedOut": "Üks sinu klientrakendustest on Matrix'i võrgust välja loginud", + "@oneClientLoggedOut": {}, + "link": "Link", + "@link": {}, + "yourChatBackupHasBeenSetUp": "Sinu vestluste varundus on seadistatud.", + "@yourChatBackupHasBeenSetUp": {}, + "unverified": "Verifitseerimata", + "@unverified": {}, + "repeatPassword": "Korda salasõna", + "@repeatPassword": {}, + "messageInfo": "Sõnumi teave", + "@messageInfo": {}, + "time": "Kellaaeg", + "@time": {}, + "messageType": "Sõnumi tüüp", + "@messageType": {}, + "sender": "Saatja", + "@sender": {}, + "openGallery": "Ava galerii", + "@openGallery": {}, + "addToSpaceDescription": "Vali kogukond, kuhu soovid seda vestlust lisada.", + "@addToSpaceDescription": {}, + "removeFromSpace": "Eemalda kogukonnast", + "@removeFromSpace": {}, + "start": "Alusta", + "@start": {}, + "commandHint_discardsession": "Loobu sessioonist", + "@commandHint_discardsession": { + "type": "text", + "description": "Usage hint for the command /discardsession" + }, + "commandHint_clearcache": "Tühjenda vahemälu", + "@commandHint_clearcache": { + "type": "text", + "description": "Usage hint for the command /clearcache" + }, + "commandHint_dm": "Alusta otsevestlust\nKrüptimise keelamiseks kasuta --no-encryption võtit", + "@commandHint_dm": { + "type": "text", + "description": "Usage hint for the command /dm" + }, + "commandHint_create": "Loo tühi vestlusrühm\nKrüptimise keelamiseks kasuta --no-encryption võtit", + "@commandHint_create": { + "type": "text", + "description": "Usage hint for the command /create" + }, + "openVideoCamera": "Video salvestamiseks ava kaamera", + "@openVideoCamera": { + "type": "text", + "placeholders": {} + }, + "markAsRead": "Märgi loetuks", + "@markAsRead": {}, + "reportUser": "Teata kasutajast", + "@reportUser": {}, + "openChat": "Ava vestlus", + "@openChat": {}, + "dismiss": "Loobu", + "@dismiss": {}, + "reactedWith": "{sender} reageeris nii {reaction}", + "@reactedWith": { + "type": "text", + "placeholders": { + "sender": {}, + "reaction": {} + } + }, + "emojis": "Emotikonid", + "@emojis": {}, + "placeCall": "Helista", + "@placeCall": {}, + "unsupportedAndroidVersion": "See Androidi versioon ei ole toetatud", + "@unsupportedAndroidVersion": {}, + "voiceCall": "Häälkõne", + "@voiceCall": {}, + "confirmEventUnpin": "Kas sa oled kindel, et tahad klammerdatud sündmuse eemaldada?", + "@confirmEventUnpin": {}, + "pinMessage": "Klammerda sõnum jututuppa", + "@pinMessage": {}, + "videoCallsBetaWarning": "Palun arvesta, et videokõned on veel beetajärgus. Nad ei pruugi veel toimida kõikidel platvormidel korrektselt.", + "@videoCallsBetaWarning": {}, + "emailOrUsername": "E-posti aadress või kasutajanimi", + "@emailOrUsername": {}, + "experimentalVideoCalls": "Katselised videokõned", + "@experimentalVideoCalls": {}, + "unsupportedAndroidVersionLong": "See funktsionaalsus eeldab uuemat Androidi versiooni. Palun kontrolli, kas sinu nutiseadmele leidub süsteemiuuendusi või saaks seal Lineage OS'i kasutada.", + "@unsupportedAndroidVersionLong": {}, + "nextAccount": "Järgmine kasutajakonto", + "@nextAccount": {}, + "separateChatTypes": "Eraldi vestlused ja jututoad", + "@separateChatTypes": { + "type": "text", + "placeholders": {} + }, + "errorAddingWidget": "Vidina lisamisel tekkis viga.", + "@errorAddingWidget": {}, + "widgetNameError": "Palun sisesta kuvatav nimi.", + "@widgetNameError": {}, + "addWidget": "Lisa vidin", + "@addWidget": {}, + "previousAccount": "Eelmine kasutajakonto", + "@previousAccount": {}, + "widgetUrlError": "See pole korrektne URL.", + "@widgetUrlError": {}, + "widgetName": "Nimi", + "@widgetName": {}, + "widgetCustom": "Kohandatud", + "@widgetCustom": {}, + "widgetJitsi": "Jitsi Meet", + "@widgetJitsi": {}, + "widgetEtherpad": "Märkmed ja tekstid", + "@widgetEtherpad": {}, + "widgetVideo": "Video", + "@widgetVideo": {}, + "switchToAccount": "Pruugi kasutajakontot # {number}", + "@switchToAccount": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "youAcceptedTheInvitation": "👍 Sa võtsid kutse vastu", + "@youAcceptedTheInvitation": {}, + "youUnbannedUser": "Sa eemaldasid suhtluskeelu kasutajalt {user}", + "@youUnbannedUser": { + "placeholders": { + "user": {} + } + }, + "youHaveWithdrawnTheInvitationFor": "Sa oled tühistanud kutse kasutajale {user}", + "@youHaveWithdrawnTheInvitationFor": { + "placeholders": { + "user": {} + } + }, + "youBannedUser": "Sa seadsid suhtluskeelu kasutajale {user}", + "@youBannedUser": { + "placeholders": { + "user": {} + } + }, + "youJoinedTheChat": "Sa liitusid vestlusega", + "@youJoinedTheChat": {}, + "youKickedAndBanned": "🙅Sa müksasid kasutaja {user} välja ning seadsid talle suhtluskeelu", + "@youKickedAndBanned": { + "placeholders": { + "user": {} + } + }, + "videoWithSize": "Video ({size})", + "@videoWithSize": { + "type": "text", + "placeholders": { + "size": {} + } + }, + "youRejectedTheInvitation": "Sa lükkasid kutse tagasi", + "@youRejectedTheInvitation": {}, + "youKicked": "👞 Sa müksasid kasutaja {user} välja", + "@youKicked": { + "placeholders": { + "user": {} + } + }, + "youInvitedUser": "📩 Sa saatsid kutse kasutajale {user}", + "@youInvitedUser": { + "placeholders": { + "user": {} + } + }, + "youInvitedBy": "📩 {user} saatis sulle kutse", + "@youInvitedBy": { + "placeholders": { + "user": {} + } + }, + "publish": "Avalda", + "@publish": {}, + "pleaseEnterRecoveryKey": "Palun sisesta oma taastevõti:", + "@pleaseEnterRecoveryKey": {}, + "recoveryKey": "Taastevõti", + "@recoveryKey": {}, + "users": "Kasutajad", + "@users": {}, + "storeInSecureStorageDescription": "Salvesta taastevõti selle seadme turvahoidlas.", + "@storeInSecureStorageDescription": {}, + "saveKeyManuallyDescription": "Salvesta see krüptovõti kasutades selle süsteemi jagamisvalikuid või lõikelauda.", + "@saveKeyManuallyDescription": {}, + "storeInAndroidKeystore": "Vali salvestuskohaks Android KeyStore", + "@storeInAndroidKeystore": {}, + "storeInAppleKeyChain": "Vali salvestuskohaks Apple KeyChain", + "@storeInAppleKeyChain": {}, + "recoveryKeyLost": "Kas taasetvõti on kadunud?", + "@recoveryKeyLost": {}, + "pleaseEnterRecoveryKeyDescription": "Vanade sõnumite lugemiseks palun siseta oma varasemas sessioonis loodud taastevõti. Taastamiseks mõeldud krüptovõti EI OLE sinu salasõna.", + "@pleaseEnterRecoveryKeyDescription": {}, + "storeSecurlyOnThisDevice": "Salvesta turvaliselt selles seadmes", + "@storeSecurlyOnThisDevice": {}, + "unlockOldMessages": "Muuda vanad sõnumid loetavaks", + "@unlockOldMessages": {}, + "countFiles": "{count} faili", + "@countFiles": { + "placeholders": { + "count": {} + } + }, + "dehydrate": "Ekspordi sessiooni teave ja kustuta nutiseadmest rakenduse andmed", + "@dehydrate": {}, + "dehydrateTor": "TOR'i kasutajad: Ekspordi sessioon", + "@dehydrateTor": {}, + "hydrateTor": "TOR'i kasutajatele: impordi viimati eksporditud sessiooni andmed", + "@hydrateTor": {}, + "hydrateTorLong": "Kui viimati TOR'i võrku kasutasid, siis kas sa eksportisid oma sessiooni andmed? Kui jah, siis impordi nad mugavasti ja jätka suhtlemist.", + "@hydrateTorLong": {}, + "indexedDbErrorTitle": "Brauseri privaatse akna kasutamisega seotud asjaolud", + "@indexedDbErrorTitle": {}, + "dehydrateWarning": "Seda tegevust ei saa tagasi pöörata. Palun kontrolli, et sa oled varukoopia turvaliselt salvestanud.", + "@dehydrateWarning": {}, + "dehydrateTorLong": "Kui oled TOR'i võrgu kasutaja, siis enne akna sulgemist palun ekspordi viimase sessiooni andmed.", + "@dehydrateTorLong": {}, + "indexedDbErrorLong": "Privaatse akna puhul andmete salvestamine vaikimisi pole kasutusel.\nPalun toimi alljärgnevalt:\n- ava about:config\n- määra dom.indexedDB.privateBrowsing.enabled väärtuseks true\nVastasel juhul sa ei saa FluffyChat'i kasutada.", + "@indexedDbErrorLong": {}, + "hydrate": "Taasta varundatud failist", + "@hydrate": {}, + "user": "Kasutaja", + "@user": {}, + "custom": "Kohandatud", + "@custom": {}, + "confirmMatrixId": "Konto kustutamiseks palun kinnitage oma Matrix'i ID.", + "@confirmMatrixId": {}, + "supposedMxid": "See peaks olema {mxid}", + "@supposedMxid": { + "type": "text", + "placeholders": { + "mxid": {} + } + }, + "commandHint_markasgroup": "Märgi vestlusrühmaks", + "@commandHint_markasgroup": {}, + "commandHint_markasdm": "Märgi otsevestusluseks antud Matrixi ID jaoks", + "@commandHint_markasdm": {}, + "whyIsThisMessageEncrypted": "Miks see sõnum pole loetav?", + "@whyIsThisMessageEncrypted": {}, + "noKeyForThisMessage": "See võib juhtuda, kui sõnum oli saadetud enne, kui siin seadmes oma kontoga sisse logisid.\n\nSamuti võib juhtuda siis, kui saatja on lugemises selles seadmes blokeerinud või on tekkinud tõrkeid veebiühenduses.\n\nAga mõnes teises seadmes saad seda sõnumit lugeda? Siis sa võid sõnumi sealt üle tõsta. Ava Seadistused -> Seadmed ning kontrolli, et kõik sinu seadmed on omavahel verifitseeritud. Kui avad selle vestluse või jututoa ning mõlemad sessioonid on avatud, siis vajalikud krüptovõtmed saadetakse automaatset.\n\nKas sa soovid vältida krüptovõtmete kadumist väljalogimisel ja seadmete vahetusel? Siis palun kontrolli, et seadistuses on krüptovõtmete varundus sisse lülitatud.", + "@noKeyForThisMessage": {}, + "callingPermissions": "Helistamise õigused", + "@callingPermissions": {}, + "callingAccountDetails": "Võimaldab FluffyChat'il kasutada Androidi helistamisrakendust.", + "@callingAccountDetails": {}, + "appearOnTop": "Luba pealmise rakendusena", + "@appearOnTop": {}, + "otherCallingPermissions": "Mikrofoni, kaamera ja muud FluffyChat'i õigused", + "@otherCallingPermissions": {}, + "newGroup": "Uus jututuba", + "@newGroup": {}, + "newSpace": "Uus kogukond", + "@newSpace": {}, + "enterSpace": "Sisene kogukonda", + "@enterSpace": {}, + "enterRoom": "Ava jututuba", + "@enterRoom": {}, + "appearOnTopDetails": "Sellega lubad rakendust avada kõige pealmisena (pole vajalik, kui Fluffychat on juba seadistatud toimima helistamiskontoga)", + "@appearOnTopDetails": {}, + "callingAccount": "Helistamiskonto", + "@callingAccount": {}, + "screenSharingTitle": "ekraani jagamine", + "@screenSharingTitle": {}, + "foregroundServiceRunning": "See teavitus toimib siis, kui esiplaaniteenus töötab.", + "@foregroundServiceRunning": {}, + "allSpaces": "Kõik kogukonnad", + "@allSpaces": {}, + "screenSharingDetail": "Sa jagad oma ekraani FuffyChat'i vahendusel", + "@screenSharingDetail": {}, + "numChats": "{number} vestlust", + "@numChats": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "hideUnimportantStateEvents": "Peida väheolulised olekuteated", + "@hideUnimportantStateEvents": {}, + "doNotShowAgain": "Ära näita uuesti", + "@doNotShowAgain": {}, + "commandHint_cuddle": "Saada üks kaisutus", + "@commandHint_cuddle": {}, + "commandHint_hug": "Saada üks kallistus", + "@commandHint_hug": {}, + "googlyEyesContent": "{senderName} saatis sulle otsivad silmad", + "@googlyEyesContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "cuddleContent": "{senderName} kaisutab sind", + "@cuddleContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "hugContent": "{senderName} kallistab sind", + "@hugContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "commandHint_googly": "Saada ühed otsivad silmad", + "@commandHint_googly": {}, + "wasDirectChatDisplayName": "Sõnumiteta vestlus (vana nimega {oldDisplayName})", + "@wasDirectChatDisplayName": { + "type": "text", + "placeholders": { + "oldDisplayName": {} + } + }, + "startFirstChat": "Alusta oma esimest vestlust", + "@startFirstChat": {}, + "encryptThisChat": "Krüpti see vestlus", + "@encryptThisChat": {}, + "disableEncryptionWarning": "Kui vestluses on krüptimine kasutusele võetud, siis turvalisuse huvides ei saa seda hiljem välja lülitada.", + "@disableEncryptionWarning": {}, + "sorryThatsNotPossible": "Vabandust... see ei ole võimalik", + "@sorryThatsNotPossible": {}, + "deviceKeys": "Seadme võtmed:", + "@deviceKeys": {}, + "newSpaceDescription": "Kogukonnad võimaldavad sul koondada erinevaid vestlusi ning korraldada avalikku või privaatset ühistegevust.", + "@newSpaceDescription": {}, + "reopenChat": "Alusta vestlust uuesti", + "@reopenChat": {}, + "noOtherDevicesFound": "Muid seadmeid ei leidu", + "@noOtherDevicesFound": {}, + "noBackupWarning": "Hoiatus! Kui sa ei lülita sisse vestluse varundust, siis sul puudub hiljem ligipääs krüptitud sõnumitele. Me tungivalt soovitame, et palun lülita vestluse varundamine sisse enne väljalogimist.", + "@noBackupWarning": {}, + "fileIsTooBigForServer": "Serveri seadistuste alusel on see fail saatmiseks liiga suur.", + "@fileIsTooBigForServer": {}, + "fileHasBeenSavedAt": "Fail on salvestatud kausta: {path}", + "@fileHasBeenSavedAt": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "jumpToLastReadMessage": "Liigu viimase loetud sõnumini", + "@jumpToLastReadMessage": {}, + "readUpToHere": "Siiamaani on loetud", + "@readUpToHere": {}, + "jump": "Hüppa", + "@jump": {}, + "openLinkInBrowser": "Ava link veebibrauseris", + "@openLinkInBrowser": {}, + "report": "teata", + "@report": {}, + "allRooms": "Kõik vestlusrühmad", + "@allRooms": { + "type": "text", + "placeholders": {} + }, + "reportErrorDescription": "😭 Oh appike! Midagi läks valesti. Kui soovid, võid sellest veast arendajatele teatada.", + "@reportErrorDescription": {}, + "signInWithPassword": "Logi sisse salasõnaga", + "@signInWithPassword": {}, + "pleaseTryAgainLaterOrChooseDifferentServer": "Palun proovi hiljem uuesti või muuda serveri nime.", + "@pleaseTryAgainLaterOrChooseDifferentServer": {}, + "signInWith": "Logi sisse kasutades teenusepakkujat {provider}", + "@signInWith": { + "type": "text", + "placeholders": { + "provider": {} + } + }, + "importFromZipFile": "Impordi zip-failist", + "@importFromZipFile": {}, + "exportEmotePack": "Ekspordi emotikonide pakk zip-failina", + "@exportEmotePack": {}, + "replace": "Asenda", + "@replace": {}, + "notAnImage": "See pole pildifail.", + "@notAnImage": {}, + "importNow": "Impordi kohe", + "@importNow": {}, + "importEmojis": "Impordi emojid", + "@importEmojis": {}, + "sendTypingNotifications": "Saada kirjutamise teavitusi", + "@sendTypingNotifications": {}, + "createGroup": "Loo vestlusrühm", + "@createGroup": {}, + "setTheme": "Vali teema:", + "@setTheme": {}, + "inviteContactToGroupQuestion": "Kas sa soovid kutsuda kasutajat {contact} „{groupName}“ jututuppa?", + "@inviteContactToGroupQuestion": {}, + "tryAgain": "Proovi uuesti", + "@tryAgain": {}, + "chatPermissions": "Vestluse õigused", + "@chatPermissions": {}, + "chatDescription": "Vestluse kirjeldus", + "@chatDescription": {}, + "noChatDescriptionYet": "Vestluse kirjeldus on puudu.", + "@noChatDescriptionYet": {}, + "optionalRedactReason": "(Kui soovid lisada) Sõnumi muutmise põhjus...", + "@optionalRedactReason": {}, + "messagesStyle": "Sõnumid:", + "@messagesStyle": {}, + "shareInviteLink": "Jaga kutse linki", + "@shareInviteLink": {}, + "directChat": "Otsevestlus", + "@directChat": {}, + "setChatDescription": "Lisa vestluse kirjeldus", + "@setChatDescription": {}, + "profileNotFound": "Sellist kasutajat serveris ei leidu. Tegemist võib olla kas võrguühenduse probleemiga või sellist kasutajat tõesti pole olemas.", + "@profileNotFound": {}, + "setColorTheme": "Vali värviteema:", + "@setColorTheme": {}, + "invite": "Kutsu", + "@invite": {}, + "invalidServerName": "Vigane serveri nimi", + "@invalidServerName": {}, + "addChatDescription": "Lisa vestluse kirjeldus...", + "@addChatDescription": {}, + "chatDescriptionHasBeenChanged": "Vestluse kirjeldus on muutunud", + "@chatDescriptionHasBeenChanged": {}, + "redactMessageDescription": "Sõnumi muudatus kehtib kõikidele vestluses osalejatele. Seda muudatust ei saa tagasi pöörata.", + "@redactMessageDescription": {}, + "redactedBy": "Muutja: {username}", + "@redactedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "redactedByBecause": "Muutja {username} märkis põhjuseks: „{reason}“", + "@redactedByBecause": { + "type": "text", + "placeholders": { + "username": {}, + "reason": {} + } + }, + "inviteGroupChat": "📨 Kutsu vestlusrühma", + "@inviteGroupChat": {}, + "invitePrivateChat": "📨 Kutsu omavahelisele vestlusele", + "@invitePrivateChat": {}, + "emoteKeyboardNoRecents": "Hiljuti kasutatud emotikonid kuvame siin...", + "@emoteKeyboardNoRecents": { + "type": "text", + "placeholders": {} + }, + "invalidInput": "Vigane sisend!", + "@invalidInput": {}, + "wrongPinEntered": "Sisestasid vale PIN-koodi! Proovi uuesti {seconds} sekundi pärast...", + "@wrongPinEntered": { + "type": "text", + "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": {}, + "pushNotificationsNotAvailable": "Tõuketeavitused pole saadaval", + "@pushNotificationsNotAvailable": {}, + "makeAdminDescription": "Kui annad sellele kasutajale peakasutaja õigused, siis kuna tal on sinuga samad õigused, sa ei saa seda toimingut enam tagasi pöörata.", + "@makeAdminDescription": {}, + "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": {} + } + }, + "learnMore": "Loe lisaks", + "@learnMore": {}, + "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": {}, + "blockListDescription": "Sul on võimalik blokeerida neid kasutajaid, kes sind segavad. Oma isiklikku blokerimisloendisse lisatud kasutajad ei saa sulle saata sõnumeid ega kutseid.", + "@blockListDescription": {}, + "createGroupAndInviteUsers": "Lisavestlusrühm ja kutsu sinna kasutajaid", + "@createGroupAndInviteUsers": {}, + "startConversation": "Alusta vestlust", + "@startConversation": {}, + "blockedUsers": "Blokeeritud kasutajad", + "@blockedUsers": {}, + "groupCanBeFoundViaSearch": "Vestlusrühm on leitav otsinguga", + "@groupCanBeFoundViaSearch": {}, + "noUsersFoundWithQuery": "Päringuga „{query}“ ei leidunud kahkus ühtegi kasutajat. Palun kontrolli, et päringus poleks vigu.", + "@noUsersFoundWithQuery": { + "type": "text", + "placeholders": { + "query": {} + } + }, + "block": "blokeeri", + "@block": {}, + "yourGlobalUserIdIs": "Sinu üldine kasutajatunnus on: ", + "@yourGlobalUserIdIs": {}, + "commandHint_sendraw": "Saada json oma algupärasel kujul", + "@commandHint_sendraw": {}, + "wrongRecoveryKey": "Vabandust..., see ei tundu olema korrektne taastevõti.", + "@wrongRecoveryKey": {}, + "blockUsername": "Eira kasutajanime", + "@blockUsername": {}, + "groupName": "Vestlusrühma nimi", + "@groupName": {}, + "databaseMigrationTitle": "Andmebaas on optimeeritud", + "@databaseMigrationTitle": {}, + "searchChatsRooms": "Otsi #vestlusi, @kasutajaid...", + "@searchChatsRooms": {}, + "databaseMigrationBody": "Palun oota üks hetk. Natuke võib kuluda aega.", + "@databaseMigrationBody": {}, + "thisDevice": "See seade:", + "@thisDevice": {}, + "publicSpaces": "Avalikud kogukonnad", + "@publicSpaces": {}, + "passwordIsWrong": "Sinu sisestatud salasõna on vale", + "@passwordIsWrong": {}, + "pleaseEnterYourCurrentPassword": "Palun sisesta oma praegune salasõna", + "@pleaseEnterYourCurrentPassword": {}, + "publicLink": "Avalik link", + "@publicLink": {}, + "nothingFound": "Ei leidnud mitte midagi...", + "@nothingFound": {}, + "decline": "Keeldu", + "@decline": {}, + "newPassword": "Uus salasõna", + "@newPassword": {}, + "passwordsDoNotMatch": "Salasõnad ei klapi omavahel", + "@passwordsDoNotMatch": {}, + "subspace": "Jututuba või alamkogukond", + "@subspace": {}, + "select": "Vali", + "@select": {}, + "pleaseChooseAStrongPassword": "Palun sisesta korralik salasõna", + "@pleaseChooseAStrongPassword": {}, + "addChatOrSubSpace": "Lisa vestlus või jututuba", + "@addChatOrSubSpace": {}, + "leaveEmptyToClearStatus": "Senise oleku eemaldamiseks jäta väärtus tühjaks.", + "@leaveEmptyToClearStatus": {}, + "joinSpace": "Liitu kogukonnaga", + "@joinSpace": {}, + "searchForUsers": "Otsi kasutajat @kasutajanimi ...", + "@searchForUsers": {}, + "databaseBuildErrorBody": "SQlite andmebaasi loomine ei õnnestu. Seetõttu üritab rakendus kasutada senist andmehoidlat. Palun teata sellest veast arendajatele siin: {url} märkides veateate: {error}", + "@databaseBuildErrorBody": { + "type": "text", + "placeholders": { + "url": {}, + "error": {} + } + }, + "initAppError": "Rakenduse käivitamisel tekkis viga", + "@initAppError": {}, + "sessionLostBody": "Sinu sessioon on kadunud. Palun teata sellest veast arendajatele siin: {url} märkides veateate: {error}", + "@sessionLostBody": { + "type": "text", + "placeholders": { + "url": {}, + "error": {} + } + }, + "restoreSessionBody": "Nüüd üritab rakendus taastada sinu sessiooni varukoopiast. Palun teata sellest veast arendajatele siin: {url} märkides veateate: {error}", + "@restoreSessionBody": { + "type": "text", + "placeholders": { + "url": {}, + "error": {} + } + }, + "transparent": "Läbipaistev", + "@transparent": {}, + "youInvitedToBy": "📩 Sa oled lingiga saanud kutse jututuppa:\n{alias}", + "@youInvitedToBy": { + "placeholders": { + "alias": {} + } + }, + "sendReadReceipts": "Saada lugemisteatisi", + "@sendReadReceipts": {}, + "verifyOtherUserDescription": "Kui sa oled vestluse teise osapoole verifitseerinud, siis saad kindel olla, et tead, kellega suhtled. 💪\n\nKui alustad verifitseerimist, siis sinul ja teisel osapoolel tekib rakenduses hüpikaken. Seal kuvatakse emotikonide või numbrite jada, mida peate omavahel võrdlema.\n\nKõige lihtsam on seda teha kas omavahelise kohtumise ajal või videokõne kestel. 👭", + "@verifyOtherUserDescription": {}, + "forwardMessageTo": "Kas edastame sõnumi jututuppa {roomName}?", + "@forwardMessageTo": { + "type": "text", + "placeholders": { + "roomName": {} + } + }, + "sendTypingNotificationsDescription": "Muud vestluses osalejad saavad näha, kui sa oled uut sõnumit kirjutamas.", + "@sendTypingNotificationsDescription": {}, + "sendReadReceiptsDescription": "Muud vestluses osalejad näevad, kas oled sõnumit lugenud.", + "@sendReadReceiptsDescription": {}, + "formattedMessages": "Vormindatud sõnumid", + "@formattedMessages": {}, + "verifyOtherUser": "🔐 Verifitseeri teine kasutaja", + "@verifyOtherUser": {}, + "verifyOtherDevice": "🔐 Verifitseeri oma muu seade", + "@verifyOtherDevice": {}, + "canceledKeyVerification": "{sender} katkestas krüptovõtmete verifitseerimise", + "@canceledKeyVerification": { + "type": "text", + "placeholders": { + "sender": {} + } + }, + "completedKeyVerification": "{sender} sai valmis krüptovõtmete verifitseerimise", + "@completedKeyVerification": { + "type": "text", + "placeholders": { + "sender": {} + } + }, + "formattedMessagesDescription": "Kasutades markdown-süntaksit kuva vormindust, nagu rasvases kirjas tekst.", + "@formattedMessagesDescription": {}, + "verifyOtherDeviceDescription": "Kui sa oled oma muu seadme verifitseerinud, siis need seadmed võivad vahetada krüptovõtmeid ning see parandab üldist turvalisust. 💪 Kui alustad verifitseerimist, siis sinu mõlemas seadmes tekib rakenduses hüpikaken. Seal kuvatakse emotikonide või numbrite jada, mida pead omavahel võrdlema. On oluline, et mõlemad seadmed on verifitseerimise alustamisel sinu kõrval. 🤳", + "@verifyOtherDeviceDescription": {}, + "acceptedKeyVerification": "{sender} nõustus krüptovõtmete verifitseerimisega", + "@acceptedKeyVerification": { + "type": "text", + "placeholders": { + "sender": {} + } + }, + "isReadyForKeyVerification": "{sender} on valmis krüptovõtmete verifitseerimiseks", + "@isReadyForKeyVerification": { + "type": "text", + "placeholders": { + "sender": {} + } + }, + "requestedKeyVerification": "{sender} palus krüptovõtmete verifitseerimist", + "@requestedKeyVerification": { + "type": "text", + "placeholders": { + "sender": {} + } + }, + "startedKeyVerification": "{sender} alustas krüptovõtmete verifitseerimist", + "@startedKeyVerification": { + "type": "text", + "placeholders": { + "sender": {} + } + }, + "presenceStyle": "Olekuteated:", + "@presenceStyle": { + "type": "text", + "placeholders": {} + }, + "presencesToggle": "Näita teiste kasutajate olekuteateid", + "@presencesToggle": { + "type": "text", + "placeholders": {} + }, + "incomingMessages": "Saabuvad sõnumid", + "@incomingMessages": {}, + "hidePresences": "Peida olekute loend?", + "@hidePresences": {} +} diff --git a/assets/l10n/intl_eu.arb b/assets/l10n/intl_eu.arb index e4a5c9257a..16645ae991 100644 --- a/assets/l10n/intl_eu.arb +++ b/assets/l10n/intl_eu.arb @@ -2273,7 +2273,7 @@ }, "jumpToLastReadMessage": "Joan irakurritako azken mezura", "@jumpToLastReadMessage": {}, - "reportErrorDescription": "O ez! Zerbaitek huts egin du. Saiatu berriro geroago. Nahi izanez gero, eman garatzaileei errorearen berri.", + "reportErrorDescription": "😭 O ez! Zerbaitek huts egin du. Nahi izanez gero, eman garatzaileei errorearen berri.", "@reportErrorDescription": {}, "cuddleContent": "{senderName}(e)k samurki besarkatu zaitu", "@cuddleContent": { @@ -2485,5 +2485,120 @@ "thisDevice": "Gailu hau:", "@thisDevice": {}, "decline": "Baztertu", - "@decline": {} + "@decline": {}, + "databaseBuildErrorBody": "Ezin izan da SQlite datu-basea eraiki. Aplikazioa aurreko datu-basea erabiltzen saiatuko da oraingoz. Jakinarazi errorea garatzaileei {url} helbidean. Errorearen mezua ondorengoa da: {error}", + "@databaseBuildErrorBody": { + "type": "text", + "placeholders": { + "url": {}, + "error": {} + } + }, + "initAppError": "Errorea aplikazioa abiaraztean", + "@initAppError": {}, + "sessionLostBody": "Zure saioa galdu da. Jakinarazi errorea garatzaileei {url} helbidean. Errorearen mezua ondorengoa da: {error}", + "@sessionLostBody": { + "type": "text", + "placeholders": { + "url": {}, + "error": {} + } + }, + "restoreSessionBody": "Aplikazioa babeskopia erabiliz saioa leheneratzen saiatuko da. Jakinarazi errorea garatzaileei {url} helbidean. Errorearen mezua ondorengoa da: {error}", + "@restoreSessionBody": { + "type": "text", + "placeholders": { + "url": {}, + "error": {} + } + }, + "youInvitedToBy": "📩 Esteka baten bidez gonbidatu zaituzte:\n{alias}", + "@youInvitedToBy": { + "placeholders": { + "alias": {} + } + }, + "transparent": "Gardena", + "@transparent": {}, + "sendReadReceipts": "Bidali irakurri izanaren adierazlea", + "@sendReadReceipts": {}, + "formattedMessages": "Formatua duten mezuak", + "@formattedMessages": {}, + "verifyOtherDevice": "🔐 Egiaztatu beste gailu bat", + "@verifyOtherDevice": {}, + "acceptedKeyVerification": "{sender}(e)k gakoaren egiaztapena onartu du", + "@acceptedKeyVerification": { + "type": "text", + "placeholders": { + "sender": {} + } + }, + "canceledKeyVerification": "{sender}(e)k gakoen egiaztapena ezeztatu du", + "@canceledKeyVerification": { + "type": "text", + "placeholders": { + "sender": {} + } + }, + "requestedKeyVerification": "{sender}(e)k gakoen egiaztapena galdegin du", + "@requestedKeyVerification": { + "type": "text", + "placeholders": { + "sender": {} + } + }, + "sendReadReceiptsDescription": "Txateko beste kideek mezu bat irakurri duzula ikus dezakete.", + "@sendReadReceiptsDescription": {}, + "forwardMessageTo": "Birbidali mezua {roomName}(e)ra?", + "@forwardMessageTo": { + "type": "text", + "placeholders": { + "roomName": {} + } + }, + "completedKeyVerification": "{sender}(e)k gakoen egiaztapena osatu du", + "@completedKeyVerification": { + "type": "text", + "placeholders": { + "sender": {} + } + }, + "isReadyForKeyVerification": "{sender} gakoak egiaztatzeko prest dago", + "@isReadyForKeyVerification": { + "type": "text", + "placeholders": { + "sender": {} + } + }, + "verifyOtherDeviceDescription": "Beste gailu bat egiaztatzean, gailu horiek gakoak truka ditzakete, eta segurtasun orokorra handitu. 💪 Egiaztapena hasten duzunean, laster-leiho bat agertuko da bi gailuetan. Bertan, elkarrekin alderatu behar diren emoji edo zenbaki batzuk ikusiko dituzu. Hobe da bi gailuak eskura izatea egiaztapena hasi aurretik. 🤳", + "@verifyOtherDeviceDescription": {}, + "verifyOtherUserDescription": "Beste erabiltzaile bat egiaztatzen baduzu, ziur egon zaitezke nori idazten ari zaren. 💪\n\nEgiaztapena hasten duzunean, zuk eta beste erabiltzaileak laster-leiho bat ikusiko duzue aplikazioan. Bertan, elkarrekin alderatu behar diren emoji edo zenbaki batzuk erakutsiko dira.\n\nBideo-dei bat hastea edo aurrez-aurre batzea da horretarako modurik onena. 👭", + "@verifyOtherUserDescription": {}, + "formattedMessagesDescription": "Erakutsi mezu aberatsen edukia markdown erabiliz, testu lodia esaterako.", + "@formattedMessagesDescription": {}, + "sendTypingNotificationsDescription": "Txateko beste kideek mezu berri bat idazten ari zarela ikus dezakete.", + "@sendTypingNotificationsDescription": {}, + "verifyOtherUser": "🔐 Egiaztatu beste erabiltzaile bat", + "@verifyOtherUser": {}, + "startedKeyVerification": "{sender}(e)k gakoen egiaztapena hasi du", + "@startedKeyVerification": { + "type": "text", + "placeholders": { + "sender": {} + } + }, + "presencesToggle": "Erakutsi beste erabiltzaileen egoera-mezuak", + "@presencesToggle": { + "type": "text", + "placeholders": {} + }, + "presenceStyle": "Presentzia:", + "@presenceStyle": { + "type": "text", + "placeholders": {} + }, + "incomingMessages": "Jasotako mezuak", + "@incomingMessages": {}, + "hidePresences": "Ezkutatu Egoeren Zerrenda?", + "@hidePresences": {} } diff --git a/assets/l10n/intl_gl.arb b/assets/l10n/intl_gl.arb index ddcefdd8ba..5859851d78 100644 --- a/assets/l10n/intl_gl.arb +++ b/assets/l10n/intl_gl.arb @@ -2320,7 +2320,7 @@ "@exportEmotePack": {}, "replace": "Substituír", "@replace": {}, - "sendTypingNotifications": "Enviar notificación de escritura", + "sendTypingNotifications": "Permitir ver que estás escribindo", "@sendTypingNotifications": {}, "createGroup": "Crear grupo", "@createGroup": {}, @@ -2485,5 +2485,120 @@ "databaseMigrationTitle": "Base de datos optimizada", "@databaseMigrationTitle": {}, "databaseMigrationBody": "Agarda, podería levarnos un pouco.", - "@databaseMigrationBody": {} + "@databaseMigrationBody": {}, + "databaseBuildErrorBody": "Non se puido crear a base de datos SQlite. A app intentará usar a base de datos clásica. Por favor informa deste fallo ás desenvolvedoras en {url}. A mensaxe do erro é: {error}", + "@databaseBuildErrorBody": { + "type": "text", + "placeholders": { + "url": {}, + "error": {} + } + }, + "initAppError": "Houbo un fallo ao iniciar a app", + "@initAppError": {}, + "sessionLostBody": "Estragouse a túa sesión. Por favor informa deste fallo ás desenvolvedoras en {url}. A mensaxe do erro é: {error}", + "@sessionLostBody": { + "type": "text", + "placeholders": { + "url": {}, + "error": {} + } + }, + "restoreSessionBody": "A app vai intentar restablecer a sesión desde a copia de apoio. Por favor informa deste erro ás desenvolvedoras en {url}. A mensaxe do erro é: {error}", + "@restoreSessionBody": { + "type": "text", + "placeholders": { + "url": {}, + "error": {} + } + }, + "youInvitedToBy": "📩 Convidáronte cunha ligazón a:\n{alias}", + "@youInvitedToBy": { + "placeholders": { + "alias": {} + } + }, + "transparent": "Transparente", + "@transparent": {}, + "sendReadReceipts": "Enviar confirmación de lectura", + "@sendReadReceipts": {}, + "sendReadReceiptsDescription": "Outras participantes na conversa poden ver cando liches unha mensaxe.", + "@sendReadReceiptsDescription": {}, + "formattedMessages": "Mensaxes con formato", + "@formattedMessages": {}, + "verifyOtherDevice": "🔐 Verificar outro dispositivo", + "@verifyOtherDevice": {}, + "verifyOtherUser": "🔐 Verificar outra usuaria", + "@verifyOtherUser": {}, + "verifyOtherDeviceDescription": "Ao verificar outro dispositivo estás compartindo as chaves, aumentando a túa seguridade 💪. Ao iniciar a verificación aparecerá unha ventá emerxente nos dous dispositivos. Nesa ventá verás varios emojis ou números que tes que comparar entre eles. O mellor xeito de facelo é ter os dous dispositivos contigo cando inicias o proceso de verificación. 🤳", + "@verifyOtherDeviceDescription": {}, + "canceledKeyVerification": "{sender} desbotou a verificación da chave", + "@canceledKeyVerification": { + "type": "text", + "placeholders": { + "sender": {} + } + }, + "isReadyForKeyVerification": "{sender} xa pode verificar a chave", + "@isReadyForKeyVerification": { + "type": "text", + "placeholders": { + "sender": {} + } + }, + "forwardMessageTo": "Reenviar a mensaxe a {roomName}?", + "@forwardMessageTo": { + "type": "text", + "placeholders": { + "roomName": {} + } + }, + "sendTypingNotificationsDescription": "As outras participantes da conversa poden ver cando estás a escribir unha mensaxe.", + "@sendTypingNotificationsDescription": {}, + "formattedMessagesDescription": "Mostrar texto enriquecido nas mensaxes como letra grosa usando markdown.", + "@formattedMessagesDescription": {}, + "verifyOtherUserDescription": "Se verificas a outra usuaria, podes ter a certeza de que sabes con quen estás a conversar. 💪\n\nAo iniciar a verificación, ti mais a outra usuaria veredes unha ventá emerxente na app onde aparecerán varios emojis ou números que teredes que comparar entre vós.\n\nO mellor xeito de facelo é en persoa o cunha chamada de vídeo. 👭", + "@verifyOtherUserDescription": {}, + "requestedKeyVerification": "{sender} solicitou verificar a chave", + "@requestedKeyVerification": { + "type": "text", + "placeholders": { + "sender": {} + } + }, + "acceptedKeyVerification": "{sender} aceptou a verificación da chave", + "@acceptedKeyVerification": { + "type": "text", + "placeholders": { + "sender": {} + } + }, + "completedKeyVerification": "{sender} completou a verificación da chave", + "@completedKeyVerification": { + "type": "text", + "placeholders": { + "sender": {} + } + }, + "startedKeyVerification": "{sender} comezou coa verificación da chave", + "@startedKeyVerification": { + "type": "text", + "placeholders": { + "sender": {} + } + }, + "presenceStyle": "Presenza:", + "@presenceStyle": { + "type": "text", + "placeholders": {} + }, + "hidePresences": "Agochar Lista de estados?", + "@hidePresences": {}, + "presencesToggle": "Mostra mensaxes de estado de outras usuarias", + "@presencesToggle": { + "type": "text", + "placeholders": {} + }, + "incomingMessages": "Mensaxes recibidas", + "@incomingMessages": {} } diff --git a/assets/l10n/intl_ia.arb b/assets/l10n/intl_ia.arb new file mode 100644 index 0000000000..730f4eae65 --- /dev/null +++ b/assets/l10n/intl_ia.arb @@ -0,0 +1,55 @@ +{ + "repeatPassword": "Repeter le contrasigno", + "@repeatPassword": {}, + "notAnImage": "Non es un file de imagine.", + "@notAnImage": {}, + "remove": "Remover", + "@remove": { + "type": "text", + "placeholders": {} + }, + "importEmojis": "Importar emojis", + "@importEmojis": {}, + "importFromZipFile": "Importar ab un file .zip", + "@importFromZipFile": {}, + "importNow": "Importar ora", + "@importNow": {}, + "exportEmotePack": "Exportar pacchetto de emotes como un .zip", + "@exportEmotePack": {}, + "replace": "Reimplaciar", + "@replace": {}, + "about": "A proposito de", + "@about": { + "type": "text", + "placeholders": {} + }, + "accept": "Acceptar", + "@accept": { + "type": "text", + "placeholders": {} + }, + "acceptedTheInvitation": "👍 {username} acceptava tu invitation", + "@acceptedTheInvitation": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "account": "Conto", + "@account": { + "type": "text", + "placeholders": {} + }, + "addEmail": "Adder email", + "@addEmail": { + "type": "text", + "placeholders": {} + }, + "supposedMxid": "Isto deberea esser {mxid}", + "@supposedMxid": { + "type": "text", + "placeholders": { + "mxid": {} + } + } +} diff --git a/assets/l10n/intl_ru.arb b/assets/l10n/intl_ru.arb index f14a17bd79..a207f45d10 100644 --- a/assets/l10n/intl_ru.arb +++ b/assets/l10n/intl_ru.arb @@ -639,7 +639,7 @@ "type": "text", "placeholders": {} }, - "emoteInvalid": "Недопустимый краткий код эмодзи!", + "emoteInvalid": "Недопустимый код эмодзи!", "@emoteInvalid": { "type": "text", "placeholders": {} @@ -654,7 +654,7 @@ "type": "text", "placeholders": {} }, - "emoteShortcode": "Краткий код для эмодзи", + "emoteShortcode": "Код эмодзи", "@emoteShortcode": { "type": "text", "placeholders": {} @@ -2260,7 +2260,7 @@ "@disableEncryptionWarning": {}, "deviceKeys": "Ключи устройств:", "@deviceKeys": {}, - "noBackupWarning": "Внимание! Без резервных копий, Вы потеряете доступ к своим зашифрованным сообщениям. Крайне рекомендуется включить резервные копии перед выходом.", + "noBackupWarning": "Внимание! Без резервного копиирования, Вы потеряете доступ к своим зашифрованным сообщениям. Крайне рекомендуется включить резервное копирование перед выходом.", "@noBackupWarning": {}, "noOtherDevicesFound": "Другие устройства не найдены", "@noOtherDevicesFound": {}, @@ -2477,5 +2477,128 @@ "joinSpace": "Присоединиться к пространству", "@joinSpace": {}, "searchForUsers": "Поиск @пользователей...", - "@searchForUsers": {} + "@searchForUsers": {}, + "thisDevice": "Данное устройство:", + "@thisDevice": {}, + "decline": "Отклонить", + "@decline": {}, + "databaseBuildErrorBody": "Невозможно собрать базу данных SQlite. Приложение пытается использовать старую базу данных. Пожалуйста, сообщите об этой ошибке разработчикам по адресу {url}. Сообщение об ошибке: {error}", + "@databaseBuildErrorBody": { + "type": "text", + "placeholders": { + "url": {}, + "error": {} + } + }, + "initAppError": "Произошла ошибка при запуске приложения", + "@initAppError": {}, + "sessionLostBody": "Ваш сеанс утерян. Пожалуйста, сообщите об этой ошибке разработчикам по адресу {url}. Сообщение об ошибке: {error}", + "@sessionLostBody": { + "type": "text", + "placeholders": { + "url": {}, + "error": {} + } + }, + "restoreSessionBody": "Приложение пытается восстановить сеанс из резервной копии. Пожалуйста, сообщите об этой ошибке разработчикам по адресу {url}. Сообщение об ошибке: {error}", + "@restoreSessionBody": { + "type": "text", + "placeholders": { + "url": {}, + "error": {} + } + }, + "subspace": "Субпространство", + "@subspace": {}, + "addChatOrSubSpace": "Добавить чат или субпространство", + "@addChatOrSubSpace": {}, + "youInvitedToBy": "📩 Вы были приглашены по ссылке на:\n{alias}", + "@youInvitedToBy": { + "placeholders": { + "alias": {} + } + }, + "sendReadReceipts": "Отправка квитанций о прочтении", + "@sendReadReceipts": {}, + "verifyOtherUser": "🔐 Подтвердить другого пользователя", + "@verifyOtherUser": {}, + "verifyOtherDevice": "🔐 Подтвердить другое устройство", + "@verifyOtherDevice": {}, + "forwardMessageTo": "Переслать сообщение в {roomName}?", + "@forwardMessageTo": { + "type": "text", + "placeholders": { + "roomName": {} + } + }, + "sendReadReceiptsDescription": "Другие участники чата могут видеть, когда вы прочитали сообщение.", + "@sendReadReceiptsDescription": {}, + "transparent": "Прозрачный", + "@transparent": {}, + "verifyOtherUserDescription": "Если вы подтвердите другого пользователя, то вы можете быть уверены зная, кому вы действительно пишете. 💪\n\nКогда вы начинаете подтверждение, вы и другой пользователь увидите всплывающее окно в приложении. Там вы увидите ряд чисел или эмодзи, которые вы должны сравнить друг с другом.\n\nЛучший способ сделать это - встретиться в реальной жизни или по видео звонку. 👭", + "@verifyOtherUserDescription": {}, + "verifyOtherDeviceDescription": "При подтверждении другого устройства эти устройства могут обмениваться ключами, повышая общую безопасность. 💪 При запуске подтверждения в приложении на обоих устройствах появится всплывающее окно. Там вы увидите ряд чисел или эмодзи, которые вы должны сравнить друг с другом. Лучше иметь оба устройства под рукой перед началом проверки. 🤳", + "@verifyOtherDeviceDescription": {}, + "formattedMessagesDescription": "Отображать содержимое расширенных сообщений, такой как жирный текст, с помощью Markdown.", + "@formattedMessagesDescription": {}, + "acceptedKeyVerification": "{sender} принял(а) подтверждение ключей", + "@acceptedKeyVerification": { + "type": "text", + "placeholders": { + "sender": {} + } + }, + "canceledKeyVerification": "{sender} отклонил(а) подтверждение ключей", + "@canceledKeyVerification": { + "type": "text", + "placeholders": { + "sender": {} + } + }, + "sendTypingNotificationsDescription": "Другие участники чата могут видеть, когда вы набираете новое сообщение.", + "@sendTypingNotificationsDescription": {}, + "formattedMessages": "Форматированные сообщения", + "@formattedMessages": {}, + "startedKeyVerification": "{sender} начал(а) подтверждение ключей", + "@startedKeyVerification": { + "type": "text", + "placeholders": { + "sender": {} + } + }, + "isReadyForKeyVerification": "{sender} готов(а) к подтверждению ключей", + "@isReadyForKeyVerification": { + "type": "text", + "placeholders": { + "sender": {} + } + }, + "requestedKeyVerification": "{sender} запросил(а) подтверждение ключей", + "@requestedKeyVerification": { + "type": "text", + "placeholders": { + "sender": {} + } + }, + "completedKeyVerification": "{sender} завершил(а) подтверждение ключей", + "@completedKeyVerification": { + "type": "text", + "placeholders": { + "sender": {} + } + }, + "incomingMessages": "Входящие сообщения", + "@incomingMessages": {}, + "presencesToggle": "Показывать сообщения в статусах других пользователей", + "@presencesToggle": { + "type": "text", + "placeholders": {} + }, + "presenceStyle": "Представление:", + "@presenceStyle": { + "type": "text", + "placeholders": {} + }, + "hidePresences": "Скрыть список статусов?", + "@hidePresences": {} } diff --git a/assets/l10n/intl_sv.arb b/assets/l10n/intl_sv.arb index f47f4464c7..caa4451976 100644 --- a/assets/l10n/intl_sv.arb +++ b/assets/l10n/intl_sv.arb @@ -1,2421 +1,2514 @@ { - "@@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": {} - } - }, - "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": {} - }, - "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": {} - }, - "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": {} - } - }, - "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": {} - }, - "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": {} - }, - "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": {} - } - }, - "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": {} - }, - "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": {} - }, - "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": {} - } - }, - "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": {} - }, - "memberChanges": "Medlemsändringar", - "@memberChanges": { - "type": "text", - "placeholders": {} - }, - "mention": "Nämn", - "@mention": { - "type": "text", - "placeholders": {} - }, - "messages": "Meddelanden", - "@messages": { - "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å aviseringar 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": "Aviseringar ä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": {} - }, - "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": {} - }, - "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": {} - }, - "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": "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": {} - } - }, - "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": {} - }, - "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": {} - } - }, - "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": {} - }, - "youAreNoLongerParticipatingInThisChat": "Du deltar inte längre i denna chatt", - "@youAreNoLongerParticipatingInThisChat": { - "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": "Textstorlek", - "@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": {} - } - }, - "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": {} - }, - "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 gick inte aviseringar att slå på.", - "@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": {} - }, - "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": {}, - "openGallery": "Öppna galleri", - "@openGallery": {}, - "repeatPassword": "Upprepa lösenord", - "@repeatPassword": {}, - "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": {}, - "videoWithSize": "Video ({size})", - "@videoWithSize": { - "type": "text", - "placeholders": { - "size": {} - } - }, - "reportUser": "Rapportera användare", - "@reportUser": {}, - "openChat": "Öppna Chatt", - "@openChat": {}, - "sendOnEnter": "Skicka med Enter", - "@sendOnEnter": {}, - "scanQrCode": "Skanna QR-kod", - "@scanQrCode": {}, - "yourChatBackupHasBeenSetUp": "Din chatt-backup har konfigurerats.", - "@yourChatBackupHasBeenSetUp": {}, - "removeFromBundle": "Ta bort från paket", - "@removeFromBundle": {}, - "enableMultiAccounts": "(BETA) Aktivera multi-konton på denna enhet", - "@enableMultiAccounts": {}, - "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": {}, - "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": {}, - "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": {} - }, - "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": {}, - "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": {}, - "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": {}, - "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": {}, - "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 avisering 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": {}, - "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": {} - } - }, - "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": {} - } - }, - "allRooms": "Alla gruppchattar", - "@allRooms": { - "type": "text", - "placeholders": {} - }, - "reportErrorDescription": "", - "@reportErrorDescription": {}, - "setColorTheme": "Välj färgtema:", - "@setColorTheme": {}, - "banUserDescription": "", - "@banUserDescription": {}, - "removeDevicesDescription": "", - "@removeDevicesDescription": {}, - "tryAgain": "", - "@tryAgain": {}, - "unbanUserDescription": "", - "@unbanUserDescription": {}, - "messagesStyle": "Meddelanden:", - "@messagesStyle": {}, - "chatDescription": "", - "@chatDescription": {}, - "pushNotificationsNotAvailable": "Aviseringar är inte tillgängligt", - "@pushNotificationsNotAvailable": {}, - "invalidServerName": "", - "@invalidServerName": {}, - "chatPermissions": "Chatt-behörigheter", - "@chatPermissions": {}, - "signInWithPassword": "", - "@signInWithPassword": {}, - "makeAdminDescription": "", - "@makeAdminDescription": {}, - "setChatDescription": "Ändra chattens beskrivning", - "@setChatDescription": {}, - "importFromZipFile": "Importera från .zip-fil", - "@importFromZipFile": {}, - "redactedBy": "", - "@redactedBy": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "signInWith": "Logga in med {provider}", - "@signInWith": { - "type": "text", - "placeholders": { - "provider": {} - } - }, - "optionalRedactReason": "", - "@optionalRedactReason": {}, - "archiveRoomDescription": "", - "@archiveRoomDescription": {}, - "exportEmotePack": "", - "@exportEmotePack": {}, - "inviteContactToGroupQuestion": "", - "@inviteContactToGroupQuestion": {}, - "redactedByBecause": "", - "@redactedByBecause": { - "type": "text", - "placeholders": { - "username": {}, - "reason": {} - } - }, - "redactMessageDescription": "", - "@redactMessageDescription": {}, - "invalidInput": "", - "@invalidInput": {}, - "report": "", - "@report": {}, - "addChatDescription": "", - "@addChatDescription": {}, - "hasKnocked": "", - "@hasKnocked": { - "placeholders": { - "user": {} - } - }, - "openLinkInBrowser": "", - "@openLinkInBrowser": {}, - "directChat": "", - "@directChat": {}, - "wrongPinEntered": "", - "@wrongPinEntered": { - "type": "text", - "placeholders": { - "seconds": {} - } - }, - "sendTypingNotifications": "", - "@sendTypingNotifications": {}, - "inviteGroupChat": "", - "@inviteGroupChat": {}, - "invitePrivateChat": "", - "@invitePrivateChat": {}, - "importEmojis": "Importera emojier", - "@importEmojis": {}, - "noChatDescriptionYet": "Ingen chatt-beskrivning än.", - "@noChatDescriptionYet": {}, - "learnMore": "", - "@learnMore": {}, - "notAnImage": "Inte en bildfil.", - "@notAnImage": {}, - "chatDescriptionHasBeenChanged": "", - "@chatDescriptionHasBeenChanged": {}, - "roomUpgradeDescription": "", - "@roomUpgradeDescription": {}, - "pleaseEnterANumber": "", - "@pleaseEnterANumber": {}, - "profileNotFound": "", - "@profileNotFound": {}, - "jump": "", - "@jump": {}, - "shareInviteLink": "", - "@shareInviteLink": {}, - "emoteKeyboardNoRecents": "", - "@emoteKeyboardNoRecents": { - "type": "text", - "placeholders": {} - }, - "setTheme": "Välj tema:", - "@setTheme": {}, - "replace": "Ersätt", - "@replace": {}, - "pleaseTryAgainLaterOrChooseDifferentServer": "", - "@pleaseTryAgainLaterOrChooseDifferentServer": {}, - "createGroup": "", - "@createGroup": {}, - "kickUserDescription": "", - "@kickUserDescription": {}, - "importNow": "Importera nu", - "@importNow": {}, - "invite": "", - "@invite": {} -} \ No newline at end of file + "@@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": {} + } + }, + "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": {} + }, + "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": {} + }, + "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": {} + } + }, + "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": {} + }, + "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": {} + }, + "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": {} + } + }, + "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": {} + }, + "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": {} + }, + "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. Besök fluffychat.im och installera appen\n2. Registrera dig eller logga in\n3. Öppna inbjudningslänk:\n {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": {} + } + }, + "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": {} + }, + "memberChanges": "Medlemsändringar", + "@memberChanges": { + "type": "text", + "placeholders": {} + }, + "mention": "Nämn", + "@mention": { + "type": "text", + "placeholders": {} + }, + "messages": "Meddelanden", + "@messages": { + "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å aviseringar 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": "Aviseringar ä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": {} + }, + "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": {} + }, + "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": {} + }, + "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": "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": {} + } + }, + "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": {} + }, + "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": {} + } + }, + "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": {} + }, + "youAreNoLongerParticipatingInThisChat": "Du deltar inte längre i denna chatt", + "@youAreNoLongerParticipatingInThisChat": { + "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": "Textstorlek", + "@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": {} + } + }, + "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": {} + }, + "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 gick inte aviseringar att slå på.", + "@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": {} + }, + "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": {}, + "openGallery": "Öppna galleri", + "@openGallery": {}, + "repeatPassword": "Upprepa lösenord", + "@repeatPassword": {}, + "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": {}, + "videoWithSize": "Video ({size})", + "@videoWithSize": { + "type": "text", + "placeholders": { + "size": {} + } + }, + "reportUser": "Rapportera användare", + "@reportUser": {}, + "openChat": "Öppna Chatt", + "@openChat": {}, + "sendOnEnter": "Skicka med Enter", + "@sendOnEnter": {}, + "scanQrCode": "Skanna QR-kod", + "@scanQrCode": {}, + "yourChatBackupHasBeenSetUp": "Din chatt-backup har konfigurerats.", + "@yourChatBackupHasBeenSetUp": {}, + "removeFromBundle": "Ta bort från paket", + "@removeFromBundle": {}, + "enableMultiAccounts": "(BETA) Aktivera multi-konton på denna enhet", + "@enableMultiAccounts": {}, + "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": {}, + "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": {}, + "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": {} + }, + "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": {}, + "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": {}, + "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": {}, + "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 för det givante Matrix ID", + "@commandHint_markasdm": {}, + "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 avisering 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": {}, + "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": {} + } + }, + "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": {} + } + }, + "allRooms": "Alla gruppchattar", + "@allRooms": { + "type": "text", + "placeholders": {} + }, + "reportErrorDescription": "😭 Åh nej. Något gick fel. Om du vill ian du rapportera denna bugg till utvecklarna.", + "@reportErrorDescription": {}, + "setColorTheme": "Välj färgtema:", + "@setColorTheme": {}, + "banUserDescription": "Användaren kommer bannlysas från chatten och kommer inte kunna gå med i chatten igen tills bannlysningen avslutas.", + "@banUserDescription": {}, + "removeDevicesDescription": "Du kommer att bli utloggad från den här enheten och kommer inte längre kunna få meddelanden.", + "@removeDevicesDescription": {}, + "tryAgain": "Försök igen", + "@tryAgain": {}, + "unbanUserDescription": "Användaren kommer kunna gå med i chatten igen om den försöker.", + "@unbanUserDescription": {}, + "messagesStyle": "Meddelanden:", + "@messagesStyle": {}, + "chatDescription": "Chattbeskrivning", + "@chatDescription": {}, + "pushNotificationsNotAvailable": "Aviseringar är inte tillgängligt", + "@pushNotificationsNotAvailable": {}, + "invalidServerName": "Ogiltigt servernamn", + "@invalidServerName": {}, + "chatPermissions": "Chatt-behörigheter", + "@chatPermissions": {}, + "signInWithPassword": "Logga in med lösenord", + "@signInWithPassword": {}, + "makeAdminDescription": "När du gör denna användare till administratör kommer du inte kunna ångra det eftersom de kommer ha samma behörigheter som du.", + "@makeAdminDescription": {}, + "setChatDescription": "Ändra chattens beskrivning", + "@setChatDescription": {}, + "importFromZipFile": "Importera från .zip-fil", + "@importFromZipFile": {}, + "redactedBy": "Borttaget av {username}", + "@redactedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "signInWith": "Logga in med {provider}", + "@signInWith": { + "type": "text", + "placeholders": { + "provider": {} + } + }, + "optionalRedactReason": "(Frivilligt) Anledning till att ta bort det här meddelandet…", + "@optionalRedactReason": {}, + "archiveRoomDescription": "Den här chatten kommer flyttas till arkivet. Andra användare kommer kunna se att du har lämnat chatten.", + "@archiveRoomDescription": {}, + "exportEmotePack": "Exportera Emote-pack som .zip", + "@exportEmotePack": {}, + "inviteContactToGroupQuestion": "Vill du bjuda in {contact} till chatten ”{groupName}”?", + "@inviteContactToGroupQuestion": {}, + "redactedByBecause": "Borttaget av {username} på grund av: ”{reason}”", + "@redactedByBecause": { + "type": "text", + "placeholders": { + "username": {}, + "reason": {} + } + }, + "redactMessageDescription": "Meddelandet kommer tas bort för alla medlemmar i denna konversation. Detta kan inte ångras.", + "@redactMessageDescription": {}, + "invalidInput": "Ogiltig input!", + "@invalidInput": {}, + "report": "rapportera", + "@report": {}, + "addChatDescription": "Lägg till en chattbeskrivning…", + "@addChatDescription": {}, + "hasKnocked": "{user} har knackat", + "@hasKnocked": { + "placeholders": { + "user": {} + } + }, + "openLinkInBrowser": "Öppna länk i webbläsare", + "@openLinkInBrowser": {}, + "directChat": "Direktchatt", + "@directChat": {}, + "wrongPinEntered": "Fel pin-kod inslagen! Försök igen om {seconds} sekunder…", + "@wrongPinEntered": { + "type": "text", + "placeholders": { + "seconds": {} + } + }, + "sendTypingNotifications": "Skicka skrivnotifikationer", + "@sendTypingNotifications": {}, + "inviteGroupChat": "📨 Bjud in gruppchatt", + "@inviteGroupChat": {}, + "invitePrivateChat": "📨 Bjud in privat chatt", + "@invitePrivateChat": {}, + "importEmojis": "Importera emojier", + "@importEmojis": {}, + "noChatDescriptionYet": "Ingen chatt-beskrivning än.", + "@noChatDescriptionYet": {}, + "learnMore": "Lär dig mer", + "@learnMore": {}, + "notAnImage": "Inte en bildfil.", + "@notAnImage": {}, + "chatDescriptionHasBeenChanged": "Chattbeskrivningen ändrades", + "@chatDescriptionHasBeenChanged": {}, + "roomUpgradeDescription": "Chatten kommer då att återskapas med den nya rumversionen. Alla medlemmar kommer bli påminda om att de måste byta till den nya chatten. Du kan läsa mer om rumversioner på https://spec.matrix.org/latest/rooms/", + "@roomUpgradeDescription": {}, + "pleaseEnterANumber": "Vänligen ange ett nummer större än 0", + "@pleaseEnterANumber": {}, + "profileNotFound": "Användaren kunde onte hittas på servern. Kanske är det ett anslutningsproblem eller så finns inte användaren.", + "@profileNotFound": {}, + "jump": "Hoppa", + "@jump": {}, + "shareInviteLink": "Dela inbjudningslänk", + "@shareInviteLink": {}, + "emoteKeyboardNoRecents": "Nyligen använda emotes kommer dyka upp här…", + "@emoteKeyboardNoRecents": { + "type": "text", + "placeholders": {} + }, + "setTheme": "Välj tema:", + "@setTheme": {}, + "replace": "Ersätt", + "@replace": {}, + "pleaseTryAgainLaterOrChooseDifferentServer": "Vänligen försök igen eller välj en annan server.", + "@pleaseTryAgainLaterOrChooseDifferentServer": {}, + "createGroup": "Skapa grupp", + "@createGroup": {}, + "kickUserDescription": "Användaren sparkas ut ur chatten men bannlyses inte. I offentliga chattar kan användaren gå med igen när som helst.", + "@kickUserDescription": {}, + "importNow": "Importera nu", + "@importNow": {}, + "invite": "Bjud in", + "@invite": {}, + "databaseBuildErrorBody": "Kan inte bygga SQlite-databasen. Appen försöker använda den gamla databasen för nu. Vänligen rapportera problemet till utvecklarna här: {url}. Felmeddelandet är: {error}", + "@databaseBuildErrorBody": { + "type": "text", + "placeholders": { + "url": {}, + "error": {} + } + }, + "blockListDescription": "Du kan blockera användare som stör dig. Du kommer inte få några meddelanden eller rum-inbjudningar från användarna på din personliga blocklista.", + "@blockListDescription": {}, + "createGroupAndInviteUsers": "Skapa en grupp och bjud in användare", + "@createGroupAndInviteUsers": {}, + "initAppError": "Ett problem skedde när appen initierades", + "@initAppError": {}, + "thisDevice": "Denna enhet:", + "@thisDevice": {}, + "startConversation": "Starta konversation", + "@startConversation": {}, + "publicSpaces": "Offentliga utrymmen", + "@publicSpaces": {}, + "blockedUsers": "Blockerade användare", + "@blockedUsers": {}, + "passwordIsWrong": "Det angivna lösenordet är fel", + "@passwordIsWrong": {}, + "pleaseEnterYourCurrentPassword": "Vänligen skriv ditt nuvarande lösenord", + "@pleaseEnterYourCurrentPassword": {}, + "groupCanBeFoundViaSearch": "Gruppen kan hittas genom sökning", + "@groupCanBeFoundViaSearch": {}, + "publicLink": "Offentlig länk", + "@publicLink": {}, + "noUsersFoundWithQuery": "Tyvärr kunde ingen användare hittas med ”{query}”. Vänligen kontrollera om du gjort ett stavfel.", + "@noUsersFoundWithQuery": { + "type": "text", + "placeholders": { + "query": {} + } + }, + "block": "blockera", + "@block": {}, + "nothingFound": "Inget hittades…", + "@nothingFound": {}, + "yourGlobalUserIdIs": "Ditt globala användar-ID är: ", + "@yourGlobalUserIdIs": {}, + "decline": "Neka", + "@decline": {}, + "newPassword": "Nytt lösenord", + "@newPassword": {}, + "passwordsDoNotMatch": "Lösenorden passar inte", + "@passwordsDoNotMatch": {}, + "commandHint_sendraw": "Skicka rå json", + "@commandHint_sendraw": {}, + "wrongRecoveryKey": "Tyvärr verkar detta inte vara den korrekta återställningsnyckeln.", + "@wrongRecoveryKey": {}, + "subspace": "Underutrymme", + "@subspace": {}, + "select": "Ange val", + "@select": {}, + "sessionLostBody": "Din session är förlorad. Vänligen rapportera detta fel till utvecklarna här: {url}. Felmeddelandet är: {error}", + "@sessionLostBody": { + "type": "text", + "placeholders": { + "url": {}, + "error": {} + } + }, + "pleaseChooseAStrongPassword": "Vänligen välj ett starkt lösenord", + "@pleaseChooseAStrongPassword": {}, + "blockUsername": "Ignorera användarnamn", + "@blockUsername": {}, + "addChatOrSubSpace": "Lägg till chatt eller underutrymme", + "@addChatOrSubSpace": {}, + "groupName": "Gruppnamn", + "@groupName": {}, + "leaveEmptyToClearStatus": "Lämna tom för att ta bort din status.", + "@leaveEmptyToClearStatus": {}, + "joinSpace": "Gå med i utrymme", + "@joinSpace": {}, + "searchForUsers": "Sök efter @användare…", + "@searchForUsers": {}, + "restoreSessionBody": "Appen försöker nu få tillbaks din session från backupen. Vänligen rapportera detta problem till utvecklarna här: {url}. Felmeddelandet är: {error}", + "@restoreSessionBody": { + "type": "text", + "placeholders": { + "url": {}, + "error": {} + } + }, + "databaseMigrationTitle": "Databasen är optimerad", + "@databaseMigrationTitle": {}, + "searchChatsRooms": "Sök efter #chattar, @användare…", + "@searchChatsRooms": {}, + "databaseMigrationBody": "Var vänlig vänta. Detta kan ta en stund.", + "@databaseMigrationBody": {} +} diff --git a/assets/l10n/intl_uk.arb b/assets/l10n/intl_uk.arb index db84a70b7f..bc2134afd7 100644 --- a/assets/l10n/intl_uk.arb +++ b/assets/l10n/intl_uk.arb @@ -1,2457 +1,2604 @@ { - "@@locale": "uk", - "@@last_modified": "2021-08-14 12:41:09.790615", - "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": {} - } - }, - "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": {} - } - }, - "banFromChat": "Заблокувати в бесіді", - "@banFromChat": { - "type": "text", - "placeholders": {} - }, - "banned": "Заблоковано", - "@banned": { - "type": "text", - "placeholders": {} - }, - "bannedUser": "{username} блокує {targetName}", - "@bannedUser": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "blockDevice": "Заблокувати пристрій", - "@blockDevice": { - "type": "text", - "placeholders": {} - }, - "cancel": "Скасувати", - "@cancel": { - "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": {} - } - }, - "changeTheHomeserver": "Змінити домашній сервер", - "@changeTheHomeserver": { - "type": "text", - "placeholders": {} - }, - "changeTheme": "Змінити стиль", - "@changeTheme": { - "type": "text", - "placeholders": {} - }, - "changeTheNameOfTheGroup": "Змінити назву групи", - "@changeTheNameOfTheGroup": { - "type": "text", - "placeholders": {} - }, - "channelCorruptedDecryptError": "Шифрування було пошкоджено", - "@channelCorruptedDecryptError": { - "type": "text", - "placeholders": {} - }, - "chat": "Бесіда", - "@chat": { - "type": "text", - "placeholders": {} - }, - "chatDetails": "Подробиці бесіди", - "@chatDetails": { - "type": "text", - "placeholders": {} - }, - "chooseAStrongPassword": "Виберіть надійний пароль", - "@chooseAStrongPassword": { - "type": "text", - "placeholders": {} - }, - "close": "Закрити", - "@close": { - "type": "text", - "placeholders": {} - }, - "compareEmojiMatch": "Порівняйте емодзі", - "@compareEmojiMatch": { - "type": "text", - "placeholders": {} - }, - "compareNumbersMatch": "Порівняйте цифри", - "@compareNumbersMatch": { - "type": "text", - "placeholders": {} - }, - "confirm": "Підтвердити", - "@confirm": { - "type": "text", - "placeholders": {} - }, - "connect": "Під'єднатись", - "@connect": { - "type": "text", - "placeholders": {} - }, - "contactHasBeenInvitedToTheGroup": "Контакт був запрошений в групу", - "@contactHasBeenInvitedToTheGroup": { - "type": "text", - "placeholders": {} - }, - "copiedToClipboard": "Скопійовано в буфер обміну", - "@copiedToClipboard": { - "type": "text", - "placeholders": {} - }, - "copy": "Копіювати", - "@copy": { - "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": {} - } - }, - "currentlyActive": "Зараз у мережі", - "@currentlyActive": { - "type": "text", - "placeholders": {} - }, - "darkTheme": "Темний", - "@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": {} - } - }, - "delete": "Видалити", - "@delete": { - "type": "text", - "placeholders": {} - }, - "deleteMessage": "Видалити повідомлення", - "@deleteMessage": { - "type": "text", - "placeholders": {} - }, - "device": "Пристрій", - "@device": { - "type": "text", - "placeholders": {} - }, - "devices": "Пристрої", - "@devices": { - "type": "text", - "placeholders": {} - }, - "displaynameHasBeenChanged": "Показуване ім'я було змінено", - "@displaynameHasBeenChanged": { - "type": "text", - "placeholders": {} - }, - "downloadFile": "Завантажити файл", - "@downloadFile": { - "type": "text", - "placeholders": {} - }, - "editDisplayname": "Змінити показуване ім'я", - "@editDisplayname": { - "type": "text", - "placeholders": {} - }, - "emoteExists": "Емодзі вже існує!", - "@emoteExists": { - "type": "text", - "placeholders": {} - }, - "emoteInvalid": "Неприпустимий короткий код емодзі!", - "@emoteInvalid": { - "type": "text", - "placeholders": {} - }, - "emoteSettings": "Налаштування емодзі", - "@emoteSettings": { - "type": "text", - "placeholders": {} - }, - "emoteShortcode": "Короткий код для емодзі", - "@emoteShortcode": { - "type": "text", - "placeholders": {} - }, - "emoteWarnNeedToPick": "Укажіть короткий код емодзі та зображення!", - "@emoteWarnNeedToPick": { - "type": "text", - "placeholders": {} - }, - "emptyChat": "Порожня бесіда", - "@emptyChat": { - "type": "text", - "placeholders": {} - }, - "enableEncryptionWarning": "Ви більше не зможете вимкнути шифрування. Ви впевнені?", - "@enableEncryptionWarning": { - "type": "text", - "placeholders": {} - }, - "encryption": "Шифрування", - "@encryption": { - "type": "text", - "placeholders": {} - }, - "encryptionNotEnabled": "Шифрування вимкнено", - "@encryptionNotEnabled": { - "type": "text", - "placeholders": {} - }, - "endedTheCall": "{senderName} завершує виклик", - "@endedTheCall": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "enterYourHomeserver": "Введіть адресу домашнього сервера", - "@enterYourHomeserver": { - "type": "text", - "placeholders": {} - }, - "fileName": "Назва файлу", - "@fileName": { - "type": "text", - "placeholders": {} - }, - "fluffychat": "FluffyChat", - "@fluffychat": { - "type": "text", - "placeholders": {} - }, - "forward": "Переслати", - "@forward": { - "type": "text", - "placeholders": {} - }, - "fromJoining": "З моменту приєднання", - "@fromJoining": { - "type": "text", - "placeholders": {} - }, - "fromTheInvitation": "З моменту запрошення", - "@fromTheInvitation": { - "type": "text", - "placeholders": {} - }, - "group": "Група", - "@group": { - "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": {} - }, - "hasWithdrawnTheInvitationFor": "{username} відкликає запрошення для {targetName}", - "@hasWithdrawnTheInvitationFor": { - "type": "text", - "placeholders": { - "username": {}, - "targetName": {} - } - }, - "help": "Довідка", - "@help": { - "type": "text", - "placeholders": {} - }, - "id": "ID", - "@id": { - "type": "text", - "placeholders": {} - }, - "identity": "Ідентифікація", - "@identity": { - "type": "text", - "placeholders": {} - }, - "incorrectPassphraseOrKey": "Неправильна парольна фраза або ключ відновлення", - "@incorrectPassphraseOrKey": { - "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": {} - }, - "inviteText": "{username} запрошує вас у FluffyChat. \n1. Перейдіть на fluffychat.im й установіть застосунок \n2. Зареєструйтесь або ввійдіть \n3. Відкрийте запрошувальне посилання:\n {link}", - "@inviteText": { - "type": "text", - "placeholders": { - "username": {}, - "link": {} - } - }, - "isTyping": "пише…", - "@isTyping": { - "type": "text", - "placeholders": {} - }, - "joinedTheChat": "👋 {username} приєднується до бесіди", - "@joinedTheChat": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "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": {} - } - }, - "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": {} - }, - "moderator": "Модератор", - "@moderator": { - "type": "text", - "placeholders": {} - }, - "muteChat": "Вимкнути сповіщення", - "@muteChat": { - "type": "text", - "placeholders": {} - }, - "needPantalaimonWarning": "Майте на увазі, що на цей час вам потрібен Pantalaimon, щоб використовувати наскрізне шифрування.", - "@needPantalaimonWarning": { - "type": "text", - "placeholders": {} - }, - "newMessageInFluffyChat": "💬 Нове повідомлення у FluffyChat", - "@newMessageInFluffyChat": { - "type": "text", - "placeholders": {} - }, - "newVerificationRequest": "Новий запит перевірки!", - "@newVerificationRequest": { - "type": "text", - "placeholders": {} - }, - "noEmotesFound": "Емоджі не знайдено. 😕", - "@noEmotesFound": { - "type": "text", - "placeholders": {} - }, - "noGoogleServicesWarning": "Схоже, Firebase Cloud Messaging недоступна на вашому пристрої. Щоб отримувати push-сповіщення, радимо встановити ntfy. За допомогою ntfy або іншого постачальника Unified Push ви можете отримувати push-сповіщення у безпечний спосіб. Ви можете завантажити ntfy з PlayStore або з F-Droid.", - "@noGoogleServicesWarning": { - "type": "text", - "placeholders": {} - }, - "none": "Нічого", - "@none": { - "type": "text", - "placeholders": {} - }, - "noPermission": "Немає прав доступу", - "@noPermission": { - "type": "text", - "placeholders": {} - }, - "noRoomsFound": "Кімнат не знайдено…", - "@noRoomsFound": { - "type": "text", - "placeholders": {} - }, - "ok": "Гаразд", - "@ok": { - "type": "text", - "placeholders": {} - }, - "onlineKeyBackupEnabled": "Резервне онлайн-копіювання ключів увімкнено", - "@onlineKeyBackupEnabled": { - "type": "text", - "placeholders": {} - }, - "oopsSomethingWentWrong": "Халепа, щось пішло не так…", - "@oopsSomethingWentWrong": { - "type": "text", - "placeholders": {} - }, - "openAppToReadMessages": "Відкрийте застосунок читання повідомлень", - "@openAppToReadMessages": { - "type": "text", - "placeholders": {} - }, - "openCamera": "Відкрити камеру", - "@openCamera": { - "type": "text", - "placeholders": {} - }, - "passphraseOrKey": "парольна фраза або ключ відновлення", - "@passphraseOrKey": { - "type": "text", - "placeholders": {} - }, - "password": "Пароль", - "@password": { - "type": "text", - "placeholders": {} - }, - "pickImage": "Вибрати зображення", - "@pickImage": { - "type": "text", - "placeholders": {} - }, - "play": "Відтворити {fileName}", - "@play": { - "type": "text", - "placeholders": { - "fileName": {} - } - }, - "pleaseEnterYourPassword": "Введіть свій пароль", - "@pleaseEnterYourPassword": { - "type": "text", - "placeholders": {} - }, - "pleaseEnterYourUsername": "Введіть своє ім'я користувача", - "@pleaseEnterYourUsername": { - "type": "text", - "placeholders": {} - }, - "publicRooms": "Загальнодоступні кімнати", - "@publicRooms": { - "type": "text", - "placeholders": {} - }, - "recording": "Запис", - "@recording": { - "type": "text", - "placeholders": {} - }, - "redactedAnEvent": "{username} змінює подію", - "@redactedAnEvent": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "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": {} - }, - "reply": "Відповісти", - "@reply": { - "type": "text", - "placeholders": {} - }, - "requestPermission": "Запит дозволу", - "@requestPermission": { - "type": "text", - "placeholders": {} - }, - "roomHasBeenUpgraded": "Кімнату було оновлено", - "@roomHasBeenUpgraded": { - "type": "text", - "placeholders": {} - }, - "seenByUser": "Переглянуто {username}", - "@seenByUser": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "send": "Надіслати", - "@send": { - "type": "text", - "placeholders": {} - }, - "sendAMessage": "Надіслати повідомлення", - "@sendAMessage": { - "type": "text", - "placeholders": {} - }, - "sendFile": "Надіслати файл", - "@sendFile": { - "type": "text", - "placeholders": {} - }, - "sendImage": "Надіслати зображення", - "@sendImage": { - "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": {} - } - }, - "setInvitationLink": "Указати посилання для запрошення", - "@setInvitationLink": { - "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": {} - } - }, - "skip": "Пропустити", - "@skip": { - "type": "text", - "placeholders": {} - }, - "sourceCode": "Джерельний код", - "@sourceCode": { - "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": {} - }, - "tryToSendAgain": "Спробуйте надіслати ще раз", - "@tryToSendAgain": { - "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": {} - }, - "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": {} - } - }, - "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": {} - }, - "whoIsAllowedToJoinThisGroup": "Кому дозволено приєднуватися до цієї групи", - "@whoIsAllowedToJoinThisGroup": { - "type": "text", - "placeholders": {} - }, - "writeAMessage": "Написати повідомлення…", - "@writeAMessage": { - "type": "text", - "placeholders": {} - }, - "yes": "Так", - "@yes": { - "type": "text", - "placeholders": {} - }, - "you": "Ви", - "@you": { - "type": "text", - "placeholders": {} - }, - "youAreNoLongerParticipatingInThisChat": "Ви більше не берете участь у цій бесіді", - "@youAreNoLongerParticipatingInThisChat": { - "type": "text", - "placeholders": {} - }, - "youHaveBeenBannedFromThisChat": "Ви були заблоковані у цій бесіді", - "@youHaveBeenBannedFromThisChat": { - "type": "text", - "placeholders": {} - }, - "pushRules": "Правила сповіщень", - "@pushRules": { - "type": "text", - "placeholders": {} - }, - "notificationsEnabledForThisAccount": "Сповіщення ввімкнені для цього облікового запису", - "@notificationsEnabledForThisAccount": { - "type": "text", - "placeholders": {} - }, - "notifications": "Сповіщення", - "@notifications": { - "type": "text", - "placeholders": {} - }, - "memberChanges": "Зміни учасників", - "@memberChanges": { - "type": "text", - "placeholders": {} - }, - "inviteForMe": "Запрошення для мене", - "@inviteForMe": { - "type": "text", - "placeholders": {} - }, - "enterAnEmailAddress": "Введіть адресу е-пошти", - "@enterAnEmailAddress": { - "type": "text", - "placeholders": {} - }, - "encrypted": "Зашифровано", - "@encrypted": { - "type": "text", - "placeholders": {} - }, - "enableEmotesGlobally": "Увімкнути пакунок емоджі глобально", - "@enableEmotesGlobally": { - "type": "text", - "placeholders": {} - }, - "emotePacks": "Набори емоджі для кімнати", - "@emotePacks": { - "type": "text", - "placeholders": {} - }, - "edit": "Редагувати", - "@edit": { - "type": "text", - "placeholders": {} - }, - "directChats": "Особисті бесіди", - "@directChats": { - "type": "text", - "placeholders": {} - }, - "deviceId": "ID пристрою", - "@deviceId": { - "type": "text", - "placeholders": {} - }, - "deleteAccount": "Видалити обліковий запис", - "@deleteAccount": { - "type": "text", - "placeholders": {} - }, - "deactivateAccountWarning": "Це деактивує ваш обліковий запис. Це неможливо скасувати! Ви впевнені?", - "@deactivateAccountWarning": { - "type": "text", - "placeholders": {} - }, - "containsUserName": "Містить ім’я користувача", - "@containsUserName": { - "type": "text", - "placeholders": {} - }, - "containsDisplayName": "Містить показуване ім’я", - "@containsDisplayName": { - "type": "text", - "placeholders": {} - }, - "changePassword": "Змінити пароль", - "@changePassword": { - "type": "text", - "placeholders": {} - }, - "changeDeviceName": "Змінити назву пристрою", - "@changeDeviceName": { - "type": "text", - "placeholders": {} - }, - "botMessages": "Повідомлення ботів", - "@botMessages": { - "type": "text", - "placeholders": {} - }, - "or": "Або", - "@or": { - "type": "text", - "placeholders": {} - }, - "setAsCanonicalAlias": "Установити основним псевдонімом", - "@setAsCanonicalAlias": { - "type": "text", - "placeholders": {} - }, - "verified": "Перевірений", - "@verified": { - "type": "text", - "placeholders": {} - }, - "blocked": "Заблоковано", - "@blocked": { - "type": "text", - "placeholders": {} - }, - "no": "Ні", - "@no": { - "type": "text", - "placeholders": {} - }, - "sendOnEnter": "Надсилати натисканням Enter", - "@sendOnEnter": {}, - "commandHint_ban": "Заблокувати цього користувача кімнати", - "@commandHint_ban": { - "type": "text", - "description": "Usage hint for the command /ban" - }, - "commandHint_kick": "Вилучити цього користувача з цієї кімнати", - "@commandHint_kick": { - "type": "text", - "description": "Usage hint for the command /kick" - }, - "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" - }, - "commandMissing": "{command} не є командою.", - "@commandMissing": { - "type": "text", - "placeholders": { - "command": {} - }, - "description": "State that {command} is not a valid /command." - }, - "copyToClipboard": "Копіювати до буфера обміну", - "@copyToClipboard": { - "type": "text", - "placeholders": {} - }, - "createNewSpace": "Новий простір", - "@createNewSpace": { - "type": "text", - "placeholders": {} - }, - "enableEncryption": "Увімкнути шифрування", - "@enableEncryption": { - "type": "text", - "placeholders": {} - }, - "joinRoom": "Приєднатися до кімнати", - "@joinRoom": { - "type": "text", - "placeholders": {} - }, - "mention": "Згадати", - "@mention": { - "type": "text", - "placeholders": {} - }, - "next": "Далі", - "@next": { - "type": "text", - "placeholders": {} - }, - "noConnectionToTheServer": "Немає з'єднання з сервером", - "@noConnectionToTheServer": { - "type": "text", - "placeholders": {} - }, - "scanQrCode": "Сканувати QR-код", - "@scanQrCode": {}, - "noPasswordRecoveryDescription": "Ви ще не додали спосіб відновлення пароля.", - "@noPasswordRecoveryDescription": { - "type": "text", - "placeholders": {} - }, - "numUsersTyping": "{count} користувачів пишуть…", - "@numUsersTyping": { - "type": "text", - "placeholders": { - "count": {} - } - }, - "online": "Онлайн", - "@online": { - "type": "text", - "placeholders": {} - }, - "oopsPushError": "Дідько! На жаль, сталася помилка під час налаштування push-сповіщень.", - "@oopsPushError": { - "type": "text", - "placeholders": {} - }, - "passwordForgotten": "Забули пароль", - "@passwordForgotten": { - "type": "text", - "placeholders": {} - }, - "pleaseChoose": "Виберіть", - "@pleaseChoose": { - "type": "text", - "placeholders": {} - }, - "pleaseEnter4Digits": "Введіть 4 цифри або залиште порожнім, щоб вимкнути блокування застосунку.", - "@pleaseEnter4Digits": { - "type": "text", - "placeholders": {} - }, - "redactMessage": "Редагувати повідомлення", - "@redactMessage": { - "type": "text", - "placeholders": {} - }, - "register": "Зареєструватися", - "@register": { - "type": "text", - "placeholders": {} - }, - "reportMessage": "Поскаржитися на повідомлення", - "@reportMessage": { - "type": "text", - "placeholders": {} - }, - "replaceRoomWithNewerVersion": "Замінити кімнату новішою версією", - "@replaceRoomWithNewerVersion": { - "type": "text", - "placeholders": {} - }, - "sendAudio": "Надіслати аудіо", - "@sendAudio": { - "type": "text", - "placeholders": {} - }, - "setCustomEmotes": "Установити користувацькі емоджі", - "@setCustomEmotes": { - "type": "text", - "placeholders": {} - }, - "weSentYouAnEmail": "Ми надіслали вам електронний лист", - "@weSentYouAnEmail": { - "type": "text", - "placeholders": {} - }, - "wipeChatBackup": "Стерти резервну копію бесіди, щоб створити новий ключ відновлення?", - "@wipeChatBackup": { - "type": "text", - "placeholders": {} - }, - "addToSpace": "Додати простір", - "@addToSpace": {}, - "roomVersion": "Версія кімнати", - "@roomVersion": { - "type": "text", - "placeholders": {} - }, - "iHaveClickedOnLink": "Мною виконано перехід за посиланням", - "@iHaveClickedOnLink": { - "type": "text", - "placeholders": {} - }, - "startedACall": "{senderName} розпочинає виклик", - "@startedACall": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "appLock": "Блокування застосунку", - "@appLock": { - "type": "text", - "placeholders": {} - }, - "commandInvalid": "Неприпустима команда", - "@commandInvalid": { - "type": "text" - }, - "extremeOffensive": "Украй образливий", - "@extremeOffensive": { - "type": "text", - "placeholders": {} - }, - "howOffensiveIsThisContent": "Наскільки образливий цей вміст?", - "@howOffensiveIsThisContent": { - "type": "text", - "placeholders": {} - }, - "participant": "Учасник", - "@participant": { - "type": "text", - "placeholders": {} - }, - "addEmail": "Додати е-пошту", - "@addEmail": { - "type": "text", - "placeholders": {} - }, - "ignore": "Нехтувати", - "@ignore": { - "type": "text", - "placeholders": {} - }, - "fontSize": "Розмір шрифту", - "@fontSize": { - "type": "text", - "placeholders": {} - }, - "badServerVersionsException": "Домашній сервер підтримує такі версії специфікацій:\n{serverVersions}\nАле цей застосунок підтримує лише {supportedVersions}", - "@badServerVersionsException": { - "type": "text", - "placeholders": { - "serverVersions": {}, - "supportedVersions": {} - } - }, - "areYouSureYouWantToLogout": "Ви впевнені, що хочете вийти?", - "@areYouSureYouWantToLogout": { - "type": "text", - "placeholders": {} - }, - "badServerLoginTypesException": "Домашній сервер підтримує такі типи входу:\n{serverVersions}\nАле цей застосунок підтримує лише:\n{supportedVersions}", - "@badServerLoginTypesException": { - "type": "text", - "placeholders": { - "serverVersions": {}, - "supportedVersions": {} - } - }, - "all": "Усі", - "@all": { - "type": "text", - "placeholders": {} - }, - "allChats": "Усі бесіди", - "@allChats": { - "type": "text", - "placeholders": {} - }, - "commandHint_join": "Приєднатися до цієї кімнати", - "@commandHint_join": { - "type": "text", - "description": "Usage hint for the command /join" - }, - "chats": "Бесіди", - "@chats": { - "type": "text", - "placeholders": {} - }, - "changeYourAvatar": "Змінити аватар", - "@changeYourAvatar": { - "type": "text", - "placeholders": {} - }, - "link": "Посилання", - "@link": {}, - "security": "Безпека", - "@security": { - "type": "text", - "placeholders": {} - }, - "sendSticker": "Надіслати наліпку", - "@sendSticker": { - "type": "text", - "placeholders": {} - }, - "errorObtainingLocation": "Помилка під час отримання розташування: {error}", - "@errorObtainingLocation": { - "type": "text", - "placeholders": { - "error": {} - } - }, - "hideRedactedEvents": "Сховати змінені події", - "@hideRedactedEvents": { - "type": "text", - "placeholders": {} - }, - "synchronizingPleaseWait": "Синхронізація… Будь ласка, зачекайте.", - "@synchronizingPleaseWait": { - "type": "text", - "placeholders": {} - }, - "noMatrixServer": "{server1} не є сервером matrix, використовувати {server2} натомість?", - "@noMatrixServer": { - "type": "text", - "placeholders": { - "server1": {}, - "server2": {} - } - }, - "reason": "Причина", - "@reason": { - "type": "text", - "placeholders": {} - }, - "defaultPermissionLevel": "Типовий рівень дозволів", - "@defaultPermissionLevel": { - "type": "text", - "placeholders": {} - }, - "sendAsText": "Надіслати як текст", - "@sendAsText": { - "type": "text" - }, - "saveFile": "Зберегти файл", - "@saveFile": { - "type": "text", - "placeholders": {} - }, - "autoplayImages": "Автоматично відтворювати анімовані наліпки та емоджі", - "@autoplayImages": { - "type": "text", - "placeholder": {} - }, - "pleaseChooseAPasscode": "Виберіть код доступу", - "@pleaseChooseAPasscode": { - "type": "text", - "placeholders": {} - }, - "pleaseClickOnLink": "Натисніть на посилання в електронному листі, а потім продовжуйте.", - "@pleaseClickOnLink": { - "type": "text", - "placeholders": {} - }, - "toggleUnread": "Позначити прочитаним/непрочитаним", - "@toggleUnread": { - "type": "text", - "placeholders": {} - }, - "transferFromAnotherDevice": "Перенесення з іншого пристрою", - "@transferFromAnotherDevice": { - "type": "text", - "placeholders": {} - }, - "sendMessages": "Надсилати повідомлення", - "@sendMessages": { - "type": "text", - "placeholders": {} - }, - "sendOriginal": "Надіслати оригінал", - "@sendOriginal": { - "type": "text", - "placeholders": {} - }, - "whoCanPerformWhichAction": "Хто і яку дію може виконувати", - "@whoCanPerformWhichAction": { - "type": "text", - "placeholders": {} - }, - "whyDoYouWantToReportThis": "Чому ви хочете поскаржитися?", - "@whyDoYouWantToReportThis": { - "type": "text", - "placeholders": {} - }, - "messages": "Повідомлення", - "@messages": { - "type": "text", - "placeholders": {} - }, - "newChat": "Нова бесіда", - "@newChat": { - "type": "text", - "placeholders": {} - }, - "everythingReady": "Усе готово!", - "@everythingReady": { - "type": "text", - "placeholders": {} - }, - "homeserver": "Домашній сервер", - "@homeserver": {}, - "goToTheNewRoom": "Перейти до нової кімнати", - "@goToTheNewRoom": { - "type": "text", - "placeholders": {} - }, - "groups": "Групи", - "@groups": { - "type": "text", - "placeholders": {} - }, - "inoffensive": "Необразливий", - "@inoffensive": { - "type": "text", - "placeholders": {} - }, - "noEncryptionForPublicRooms": "Активувати шифрування можна лише тоді, коли кімната більше не буде загальнодоступною.", - "@noEncryptionForPublicRooms": { - "type": "text", - "placeholders": {} - }, - "chatHasBeenAddedToThisSpace": "Бесіду додано до цього простору", - "@chatHasBeenAddedToThisSpace": {}, - "chatBackupDescription": "Ваші старі повідомлення захищені ключем відновлення. Переконайтеся, що ви не втратите його.", - "@chatBackupDescription": { - "type": "text", - "placeholders": {} - }, - "chatBackup": "Резервне копіювання бесіди", - "@chatBackup": { - "type": "text", - "placeholders": {} - }, - "yourChatBackupHasBeenSetUp": "Резервне копіювання бесіди налаштовано.", - "@yourChatBackupHasBeenSetUp": {}, - "clearArchive": "Очистити архів", - "@clearArchive": {}, - "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" - }, - "hideUnknownEvents": "Сховати невідомі події", - "@hideUnknownEvents": { - "type": "text", - "placeholders": {} - }, - "ignoredUsers": "Нехтувані користувачі", - "@ignoredUsers": { - "type": "text", - "placeholders": {} - }, - "obtainingLocation": "Отримання розташування…", - "@obtainingLocation": { - "type": "text", - "placeholders": {} - }, - "offensive": "Образливий", - "@offensive": { - "type": "text", - "placeholders": {} - }, - "offline": "Офлайн", - "@offline": { - "type": "text", - "placeholders": {} - }, - "addAccount": "Додати обліковий запис", - "@addAccount": {}, - "enableMultiAccounts": "(БЕТА) Увімкнути кілька облікових записів на цьому пристрої", - "@enableMultiAccounts": {}, - "openInMaps": "Відкрити в картах", - "@openInMaps": { - "type": "text", - "placeholders": {} - }, - "serverRequiresEmail": "Цей сервер потребує перевірки вашої адресу е-пошти для реєстрації.", - "@serverRequiresEmail": {}, - "pleaseFollowInstructionsOnWeb": "Виконайте вказівки вебсайту та торкніться далі.", - "@pleaseFollowInstructionsOnWeb": { - "type": "text", - "placeholders": {} - }, - "sendVideo": "Надіслати відео", - "@sendVideo": { - "type": "text", - "placeholders": {} - }, - "removeYourAvatar": "Вилучити свій аватар", - "@removeYourAvatar": { - "type": "text", - "placeholders": {} - }, - "unpin": "Відкріпити", - "@unpin": { - "type": "text", - "placeholders": {} - }, - "setPermissionsLevel": "Указати рівні дозволів", - "@setPermissionsLevel": { - "type": "text", - "placeholders": {} - }, - "shareLocation": "Поділитися місцеперебуванням", - "@shareLocation": { - "type": "text", - "placeholders": {} - }, - "singlesignon": "Єдиний вхід", - "@singlesignon": { - "type": "text", - "placeholders": {} - }, - "tooManyRequestsWarning": "Забагато запитів. Спробуйте пізніше!", - "@tooManyRequestsWarning": { - "type": "text", - "placeholders": {} - }, - "unavailable": "Недоступний", - "@unavailable": { - "type": "text", - "placeholders": {} - }, - "unreadChats": "{unreadCount, plural, =1{1 непрочитана бесіда} few{{unreadCount} непрочитані бесіди} many{{unreadCount} непрочитаних бесід} other{{unreadCount} непрочитані бесіди}}", - "@unreadChats": { - "type": "text", - "placeholders": { - "unreadCount": {} - } - }, - "withTheseAddressesRecoveryDescription": "За допомогою цих адрес ви можете відновити свій пароль.", - "@withTheseAddressesRecoveryDescription": { - "type": "text", - "placeholders": {} - }, - "privacy": "Приватність", - "@privacy": { - "type": "text", - "placeholders": {} - }, - "search": "Пошук", - "@search": { - "type": "text", - "placeholders": {} - }, - "sentCallInformations": "{senderName} надсилає відомості про виклик", - "@sentCallInformations": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "cantOpenUri": "Не вдалося відкрити URI {uri}", - "@cantOpenUri": { - "type": "text", - "placeholders": { - "uri": {} - } - }, - "contentHasBeenReported": "Скаргу на вміст надіслано адміністраторам сервера", - "@contentHasBeenReported": { - "type": "text", - "placeholders": {} - }, - "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" - }, - "configureChat": "Налаштувати бесіду", - "@configureChat": { - "type": "text", - "placeholders": {} - }, - "editBlockedServers": "Редагувати заблоковані сервери", - "@editBlockedServers": { - "type": "text", - "placeholders": {} - }, - "showPassword": "Показати пароль", - "@showPassword": { - "type": "text", - "placeholders": {} - }, - "editRoomAliases": "Змінити псевдоніми кімнати", - "@editRoomAliases": { - "type": "text", - "placeholders": {} - }, - "editRoomAvatar": "Змінити аватар кімнати", - "@editRoomAvatar": { - "type": "text", - "placeholders": {} - }, - "passwordHasBeenChanged": "Пароль змінено", - "@passwordHasBeenChanged": { - "type": "text", - "placeholders": {} - }, - "passwordRecovery": "Відновлення пароля", - "@passwordRecovery": { - "type": "text", - "placeholders": {} - }, - "people": "Люди", - "@people": { - "type": "text", - "placeholders": {} - }, - "pin": "Закріпити", - "@pin": { - "type": "text", - "placeholders": {} - }, - "pleaseEnterYourPin": "Введіть свій PIN-код", - "@pleaseEnterYourPin": { - "type": "text", - "placeholders": {} - }, - "spaceName": "Назва простору", - "@spaceName": { - "type": "text", - "placeholders": {} - }, - "warning": "Попередження!", - "@warning": { - "type": "text", - "placeholders": {} - }, - "yourPublicKey": "Ваш відкритий ключ", - "@yourPublicKey": { - "type": "text", - "placeholders": {} - }, - "spaceIsPublic": "Простір загальнодоступний", - "@spaceIsPublic": { - "type": "text", - "placeholders": {} - }, - "status": "Статус", - "@status": { - "type": "text", - "placeholders": {} - }, - "unverified": "Неперевірений", - "@unverified": {}, - "locationDisabledNotice": "Служби визначення місцеположення вимкнені. Увімкніть їх, щоб могти надавати доступ до вашого місцеположення.", - "@locationDisabledNotice": { - "type": "text", - "placeholders": {} - }, - "locationPermissionDeniedNotice": "Дозвіл на розташування відхилено. Надайте можливість ділитися своїм місцеперебуванням.", - "@locationPermissionDeniedNotice": { - "type": "text", - "placeholders": {} - }, - "oneClientLoggedOut": "На одному з ваших клієнтів виконано вихід із системи", - "@oneClientLoggedOut": {}, - "bundleName": "Назва вузла", - "@bundleName": {}, - "toggleFavorite": "Перемикнути вибране", - "@toggleFavorite": { - "type": "text", - "placeholders": {} - }, - "removeFromBundle": "Вилучити з цього вузла", - "@removeFromBundle": {}, - "toggleMuted": "Увімкнути/вимкнути звук", - "@toggleMuted": { - "type": "text", - "placeholders": {} - }, - "editBundlesForAccount": "Змінити вузол для цього облікового запису", - "@editBundlesForAccount": {}, - "addToBundle": "Додати до вузлів", - "@addToBundle": {}, - "repeatPassword": "Повторіть пароль", - "@repeatPassword": {}, - "messageInfo": "Відомості про повідомлення", - "@messageInfo": {}, - "time": "Час", - "@time": {}, - "messageType": "Тип повідомлення", - "@messageType": {}, - "openGallery": "Відкрити галерею", - "@openGallery": {}, - "sender": "Відправник", - "@sender": {}, - "addToSpaceDescription": "Виберіть простір, щоб додати до нього цю бесіду.", - "@addToSpaceDescription": {}, - "removeFromSpace": "Вилучити з простору", - "@removeFromSpace": {}, - "start": "Почати", - "@start": {}, - "commandHint_discardsession": "Відкинути сеанс", - "@commandHint_discardsession": { - "type": "text", - "description": "Usage hint for the command /discardsession" - }, - "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_dm": "Початок особистої бесіди\nВикористовуйте --no-encryption, що вимкнути шифрування", - "@commandHint_dm": { - "type": "text", - "description": "Usage hint for the command /dm" - }, - "openVideoCamera": "Відкрити камеру для відео", - "@openVideoCamera": { - "type": "text", - "placeholders": {} - }, - "publish": "Опублікувати", - "@publish": {}, - "videoWithSize": "Відео ({size})", - "@videoWithSize": { - "type": "text", - "placeholders": { - "size": {} - } - }, - "dismiss": "Відхилити", - "@dismiss": {}, - "markAsRead": "Позначити прочитаним", - "@markAsRead": {}, - "reportUser": "Поскаржився на користувача", - "@reportUser": {}, - "openChat": "Відкрити бесіду", - "@openChat": {}, - "reactedWith": "{sender} реагує з {reaction}", - "@reactedWith": { - "type": "text", - "placeholders": { - "sender": {}, - "reaction": {} - } - }, - "emojis": "Емоджі", - "@emojis": {}, - "pinMessage": "Прикріпити в кімнаті", - "@pinMessage": {}, - "confirmEventUnpin": "Ви впевнені, що бажаєте назавжди відкріпите подію?", - "@confirmEventUnpin": {}, - "placeCall": "Здійснити виклик", - "@placeCall": {}, - "unsupportedAndroidVersion": "Непідтримувана версія Android", - "@unsupportedAndroidVersion": {}, - "voiceCall": "Голосовий виклик", - "@voiceCall": {}, - "unsupportedAndroidVersionLong": "Для цієї функції потрібна новіша версія Android. Перевірте наявність оновлень або підтримку Lineage OS.", - "@unsupportedAndroidVersionLong": {}, - "videoCallsBetaWarning": "Зауважте, що відеовиклики на ранньому етапі розробки. Вони можуть працювати не так, як очікувалося, або взагалі не працювати на всіх платформах.", - "@videoCallsBetaWarning": {}, - "emailOrUsername": "Електронна адреса або ім’я користувача", - "@emailOrUsername": {}, - "experimentalVideoCalls": "Експериментальні відеовиклики", - "@experimentalVideoCalls": {}, - "switchToAccount": "Перемкнутися на обліковий запис {number}", - "@switchToAccount": { - "type": "number", - "placeholders": { - "number": {} - } - }, - "nextAccount": "Наступний обліковий запис", - "@nextAccount": {}, - "previousAccount": "Попередній обліковий запис", - "@previousAccount": {}, - "addWidget": "Додати віджет", - "@addWidget": {}, - "widgetVideo": "Відео", - "@widgetVideo": {}, - "widgetCustom": "Користувацький", - "@widgetCustom": {}, - "widgetName": "Назва", - "@widgetName": {}, - "widgetNameError": "Укажіть коротку назву.", - "@widgetNameError": {}, - "widgetEtherpad": "Текстова примітка", - "@widgetEtherpad": {}, - "widgetJitsi": "Jitsi Meet", - "@widgetJitsi": {}, - "widgetUrlError": "Це недійсна URL-адреса.", - "@widgetUrlError": {}, - "errorAddingWidget": "Помилка додавання віджета.", - "@errorAddingWidget": {}, - "separateChatTypes": "Розділіть особисті бесіди та групи", - "@separateChatTypes": { - "type": "text", - "placeholders": {} - }, - "youInvitedBy": "📩 Ви були запрошені {user}", - "@youInvitedBy": { - "placeholders": { - "user": {} - } - }, - "youAcceptedTheInvitation": "👍 Ви погодилися на запрошення", - "@youAcceptedTheInvitation": {}, - "youRejectedTheInvitation": "Ви відхилили запрошення", - "@youRejectedTheInvitation": {}, - "youHaveWithdrawnTheInvitationFor": "Ви відкликали запрошення для {user}", - "@youHaveWithdrawnTheInvitationFor": { - "placeholders": { - "user": {} - } - }, - "youBannedUser": "Ви заблокували {user}", - "@youBannedUser": { - "placeholders": { - "user": {} - } - }, - "youKickedAndBanned": "🙅 Ви вилучили й заблокували {user}", - "@youKickedAndBanned": { - "placeholders": { - "user": {} - } - }, - "youJoinedTheChat": "Ви приєдналися до бесіди", - "@youJoinedTheChat": {}, - "youKicked": "👞 Ви вилучили {user}", - "@youKicked": { - "placeholders": { - "user": {} - } - }, - "youUnbannedUser": "Ви розблокували {user}", - "@youUnbannedUser": { - "placeholders": { - "user": {} - } - }, - "youInvitedUser": "📩 Ви запросили {user}", - "@youInvitedUser": { - "placeholders": { - "user": {} - } - }, - "saveKeyManuallyDescription": "Збережіть цей ключ вручну, запустивши діалогове вікно спільного доступу до системи або буфер обміну.", - "@saveKeyManuallyDescription": {}, - "storeInAndroidKeystore": "Зберегти в Android KeyStore", - "@storeInAndroidKeystore": {}, - "storeInAppleKeyChain": "Зберегти в Apple KeyChain", - "@storeInAppleKeyChain": {}, - "storeSecurlyOnThisDevice": "Зберегти безпечно на цей пристрій", - "@storeSecurlyOnThisDevice": {}, - "pleaseEnterRecoveryKeyDescription": "Щоб розблокувати старі повідомлення, введіть ключ відновлення, згенерований у попередньому сеансі. Ваш ключ відновлення це НЕ ваш пароль.", - "@pleaseEnterRecoveryKeyDescription": {}, - "pleaseEnterRecoveryKey": "Введіть ключ відновлення:", - "@pleaseEnterRecoveryKey": {}, - "recoveryKey": "Ключ відновлення", - "@recoveryKey": {}, - "recoveryKeyLost": "Ключ відновлення втрачено?", - "@recoveryKeyLost": {}, - "users": "Користувачі", - "@users": {}, - "unlockOldMessages": "Розблокувати старі повідомлення", - "@unlockOldMessages": {}, - "storeInSecureStorageDescription": "Збережіть ключ відновлення в безпечному сховищі цього пристрою.", - "@storeInSecureStorageDescription": {}, - "countFiles": "{count} файлів", - "@countFiles": { - "placeholders": { - "count": {} - } - }, - "hydrate": "Відновлення з файлу резервної копії", - "@hydrate": {}, - "hydrateTorLong": "Минулого разу ви експортували свій сеанс із TOR? Швидко імпортуйте його та продовжуйте спілкування.", - "@hydrateTorLong": {}, - "indexedDbErrorTitle": "Проблеми приватного режиму", - "@indexedDbErrorTitle": {}, - "indexedDbErrorLong": "На жаль, сховище повідомлень не ввімкнуто у приватному режимі типово.\nВідкрийте\n - about:config\n - установіть для dom.indexedDB.privateBrowsing.enabled значення true\nІнакше запустити FluffyChat буде неможливо.", - "@indexedDbErrorLong": {}, - "dehydrate": "Експортувати сеанс та очистити пристрій", - "@dehydrate": {}, - "dehydrateWarning": "Цю дію не можна скасувати. Переконайтеся, що ви безпечно зберігаєте файл резервної копії.", - "@dehydrateWarning": {}, - "dehydrateTor": "Користувачі TOR: експорт сеансу", - "@dehydrateTor": {}, - "dehydrateTorLong": "Для користувачів TOR рекомендується експортувати сеанс перед закриттям вікна.", - "@dehydrateTorLong": {}, - "hydrateTor": "Користувачі TOR: імпорт експортованого сеансу", - "@hydrateTor": {}, - "user": "Користувач", - "@user": {}, - "custom": "Користувацький", - "@custom": {}, - "supposedMxid": "Це має бути {mxid}", - "@supposedMxid": { - "type": "text", - "placeholders": { - "mxid": {} - } - }, - "confirmMatrixId": "Підтвердьте свій Matrix ID, щоб видалити свій обліковий запис.", - "@confirmMatrixId": {}, - "commandHint_markasgroup": "Позначити групою", - "@commandHint_markasgroup": {}, - "commandHint_markasdm": "Позначити кімнатою особистого спілкування для надання Matrix ID", - "@commandHint_markasdm": {}, - "whyIsThisMessageEncrypted": "Чому це повідомлення нечитабельне?", - "@whyIsThisMessageEncrypted": {}, - "noKeyForThisMessage": "Це може статися, якщо повідомлення було надіслано до того, як ви ввійшли у свій обліковий запис на цьому пристрої.\n\nТакож можливо, що відправник заблокував ваш пристрій або щось пішло не так з під'єднанням до інтернету.\n\nЧи можете ви прочитати повідомлення на іншому сеансі? Тоді ви зможете перенести повідомлення з нього! Перейдіть до Налаштування > Пристрої та переконайтеся, що ваші пристрої перевірили один одного. Коли ви відкриєте кімнату наступного разу й обидва сеанси будуть на активні, ключі будуть передані автоматично.\n\nВи ж не хочете втрачати ключі після виходу або зміни пристроїв? Переконайтеся, що ви ввімкнули резервне копіювання бесід у налаштуваннях.", - "@noKeyForThisMessage": {}, - "foregroundServiceRunning": "Це сповіщення з'являється під час роботи основної служби.", - "@foregroundServiceRunning": {}, - "screenSharingTitle": "спільний доступ до екрана", - "@screenSharingTitle": {}, - "callingPermissions": "Дозволи на виклик", - "@callingPermissions": {}, - "callingAccount": "Обліковий запис для виклику", - "@callingAccount": {}, - "callingAccountDetails": "Дозволяє FluffyChat використовувати основний застосунок Android для набору номера.", - "@callingAccountDetails": {}, - "appearOnTop": "З'являтися зверху", - "@appearOnTop": {}, - "appearOnTopDetails": "Дозволяє застосунку показуватися зверху (не потрібно, якщо Fluffychat вже налаштований обліковим записом для викликів)", - "@appearOnTopDetails": {}, - "newGroup": "Нова група", - "@newGroup": {}, - "newSpace": "Новий простір", - "@newSpace": {}, - "enterSpace": "Увійти в простір", - "@enterSpace": {}, - "enterRoom": "Увійти в кімнату", - "@enterRoom": {}, - "otherCallingPermissions": "Мікрофон, камера та інші дозволи FluffyChat", - "@otherCallingPermissions": {}, - "allSpaces": "Усі простори", - "@allSpaces": {}, - "screenSharingDetail": "Ви ділитеся своїм екраном FuffyChat", - "@screenSharingDetail": {}, - "numChats": "{number} бесід", - "@numChats": { - "type": "number", - "placeholders": { - "number": {} - } - }, - "hideUnimportantStateEvents": "Сховати неважливі державні свята", - "@hideUnimportantStateEvents": {}, - "doNotShowAgain": "Не показувати знову", - "@doNotShowAgain": {}, - "commandHint_cuddle": "Надіслати пригортайку", - "@commandHint_cuddle": {}, - "googlyEyesContent": "{senderName} надсилає вам гугл-очі", - "@googlyEyesContent": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "commandHint_googly": "Надіслати кілька гугл-очей", - "@commandHint_googly": {}, - "commandHint_hug": "Надіслати обійми", - "@commandHint_hug": {}, - "cuddleContent": "{senderName} пригортається до вас", - "@cuddleContent": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "hugContent": "{senderName} обіймає вас", - "@hugContent": { - "type": "text", - "placeholders": { - "senderName": {} - } - }, - "wasDirectChatDisplayName": "Порожня бесіда (раніше {oldDisplayName})", - "@wasDirectChatDisplayName": { - "type": "text", - "placeholders": { - "oldDisplayName": {} - } - }, - "startFirstChat": "Розпочніть свою першу бесіду", - "@startFirstChat": {}, - "newSpaceDescription": "Простори дозволяють об'єднувати ваші бесіди та створювати приватні або загальнодоступні спільноти.", - "@newSpaceDescription": {}, - "encryptThisChat": "Зашифрувати цю бесіду", - "@encryptThisChat": {}, - "disableEncryptionWarning": "З міркувань безпеки ви не можете вимкнути шифрування в бесіді, ув якій воно було ввімкнене раніше.", - "@disableEncryptionWarning": {}, - "sorryThatsNotPossible": "Вибачте... це неможливо", - "@sorryThatsNotPossible": {}, - "deviceKeys": "Ключі пристрою:", - "@deviceKeys": {}, - "reopenChat": "Відновити бесіду", - "@reopenChat": {}, - "noOtherDevicesFound": "Інших пристроїв не знайдено", - "@noOtherDevicesFound": {}, - "noBackupWarning": "Увага! Якщо ви не ввімкнете резервне копіювання бесіди, ви втратите доступ до своїх зашифрованих повідомлень. Наполегливо радимо ввімкнути резервне копіювання бесіди перед виходом.", - "@noBackupWarning": {}, - "fileIsTooBigForServer": "Сервер повідомляє, що файл завеликий для надсилання.", - "@fileIsTooBigForServer": {}, - "fileHasBeenSavedAt": "Файл збережено в {path}", - "@fileHasBeenSavedAt": { - "type": "text", - "placeholders": { - "path": {} - } - }, - "jumpToLastReadMessage": "Перейти до останнього прочитаного повідомлення", - "@jumpToLastReadMessage": {}, - "readUpToHere": "Читати тут", - "@readUpToHere": {}, - "jump": "Перейти", - "@jump": {}, - "openLinkInBrowser": "Відкрити посилання у браузері", - "@openLinkInBrowser": {}, - "allRooms": "Усі групові бесіди", - "@allRooms": { - "type": "text", - "placeholders": {} - }, - "reportErrorDescription": "О, ні. Щось пішло не так. Повторіть спробу пізніше. Якщо хочете, можете повідомити про помилку розробникам.", - "@reportErrorDescription": {}, - "report": "повідомити", - "@report": {}, - "pleaseTryAgainLaterOrChooseDifferentServer": "Спробуйте пізніше або виберіть інший сервер.", - "@pleaseTryAgainLaterOrChooseDifferentServer": {}, - "signInWithPassword": "Увійти за допомогою пароля", - "@signInWithPassword": {}, - "signInWith": "Увійти через {provider}", - "@signInWith": { - "type": "text", - "placeholders": { - "provider": {} - } - }, - "notAnImage": "Не файл зображення.", - "@notAnImage": {}, - "importNow": "Імпортувати зараз", - "@importNow": {}, - "importEmojis": "Імпорт емодзі", - "@importEmojis": {}, - "importFromZipFile": "Імпорт з файлу .zip", - "@importFromZipFile": {}, - "replace": "Замінити", - "@replace": {}, - "exportEmotePack": "Експортувати набір смайликів у форматі .zip", - "@exportEmotePack": {}, - "sendTypingNotifications": "Надсилати сповіщення про ввід тексту", - "@sendTypingNotifications": {}, - "createGroup": "Створити групу", - "@createGroup": {}, - "inviteContactToGroupQuestion": "Хочете запросити {contact} до бесіди \"{groupName}\"?", - "@inviteContactToGroupQuestion": {}, - "messagesStyle": "Повідомлення:", - "@messagesStyle": {}, - "shareInviteLink": "Надіслати запрошувальне посилання", - "@shareInviteLink": {}, - "tryAgain": "Повторіть спробу", - "@tryAgain": {}, - "setTheme": "Налаштувати тему:", - "@setTheme": {}, - "setColorTheme": "Налаштувати колірну тему:", - "@setColorTheme": {}, - "addChatDescription": "Додати опис бесіди...", - "@addChatDescription": {}, - "chatPermissions": "Дозволи бесіди", - "@chatPermissions": {}, - "chatDescription": "Опис бесіди", - "@chatDescription": {}, - "chatDescriptionHasBeenChanged": "Опис бесіди змінено", - "@chatDescriptionHasBeenChanged": {}, - "noChatDescriptionYet": "Опис бесіди ще не створено.", - "@noChatDescriptionYet": {}, - "invalidServerName": "Недійсна назва сервера", - "@invalidServerName": {}, - "optionalRedactReason": "(Необов'язково) Причина редагування цього повідомлення...", - "@optionalRedactReason": {}, - "redactedBy": "Відредаговано {username}", - "@redactedBy": { - "type": "text", - "placeholders": { - "username": {} - } - }, - "directChat": "Особисте повідомлення", - "@directChat": {}, - "redactedByBecause": "Відредаговано {username}, тому що: \"{reason}\"", - "@redactedByBecause": { - "type": "text", - "placeholders": { - "username": {}, - "reason": {} - } - }, - "profileNotFound": "Не вдалося знайти користувача на сервері. Можливо, проблема зі з'єднанням або користувач не існує.", - "@profileNotFound": {}, - "invite": "Запросити", - "@invite": {}, - "redactMessageDescription": "Повідомлення буде відредаговано для всіх учасників цієї розмови. Це не можна скасувати.", - "@redactMessageDescription": {}, - "setChatDescription": "Налаштувати опис бесіди", - "@setChatDescription": {}, - "inviteGroupChat": "📨 Запросити до групової бесіди", - "@inviteGroupChat": {}, - "invitePrivateChat": "📨 Запросити до приватної бесіди", - "@invitePrivateChat": {}, - "emoteKeyboardNoRecents": "Тут з'являться нещодавно використані смайлики...", - "@emoteKeyboardNoRecents": { - "type": "text", - "placeholders": {} - }, - "invalidInput": "Недійсний ввід!", - "@invalidInput": {}, - "wrongPinEntered": "Введено неправильний PIN! Повторіть спробу за {seconds} секунд...", - "@wrongPinEntered": { - "type": "text", - "placeholders": { - "seconds": {} - } - }, - "banUserDescription": "Користувача буде заблоковано в бесіді, і він не зможе знову увійти в неї, поки його не буде розблоковано.", - "@banUserDescription": {}, - "removeDevicesDescription": "Ви вийдете з цього пристрою і більше не зможете отримувати повідомлення.", - "@removeDevicesDescription": {}, - "unbanUserDescription": "Користувач зможе знову увійти в бесіду, якщо спробує.", - "@unbanUserDescription": {}, - "pushNotificationsNotAvailable": "Push-сповіщення недоступні", - "@pushNotificationsNotAvailable": {}, - "makeAdminDescription": "Після того, як ви зробите цього користувача адміністратором, ви, можливо, не зможете це скасувати, оскільки він матиме ті самі права, що й ви.", - "@makeAdminDescription": {}, - "archiveRoomDescription": "Бесіду буде переміщено до архіву. Інші користувачі зможуть побачити, що ви вийшли з неї.", - "@archiveRoomDescription": {}, - "hasKnocked": "{user} стукає до вас", - "@hasKnocked": { - "placeholders": { - "user": {} - } - }, - "learnMore": "Докладніше", - "@learnMore": {}, - "roomUpgradeDescription": "Після цього бесіду буде відтворено з новою версією кімнати. Усі учасники отримають сповіщення, що їм потрібно перейти до нової бесіди. Ви можете дізнатися більше про версії кімнат на https://spec.matrix.org/latest/rooms/", - "@roomUpgradeDescription": {}, - "pleaseEnterANumber": "Введіть число більше ніж 0", - "@pleaseEnterANumber": {}, - "kickUserDescription": "Користувача вигнали з бесіди, але не заблокували. До загальнодоступних бесід користувач може приєднатися будь-коли.", - "@kickUserDescription": {}, - "blockListDescription": "Ви можете заблокувати користувачів, які вас турбують. Ви не зможете отримувати жодних повідомлень або запрошень до кімнати від користувачів з вашого персонального списку блокування.", - "@blockListDescription": {}, - "createGroupAndInviteUsers": "Створити групу та запросити користувачів", - "@createGroupAndInviteUsers": {}, - "startConversation": "Розпочати розмову", - "@startConversation": {}, - "blockedUsers": "Заблоковані користувачі", - "@blockedUsers": {}, - "groupCanBeFoundViaSearch": "Групу можна знайти через пошук", - "@groupCanBeFoundViaSearch": {}, - "noUsersFoundWithQuery": "На жаль, не знайдено жодного користувача з запитом \"{query}\".Перевірте, чи не було допущено помилки.", - "@noUsersFoundWithQuery": { - "type": "text", - "placeholders": { - "query": {} - } - }, - "block": "блокування", - "@block": {}, - "yourGlobalUserIdIs": "Ваш глобальний ID користувача: ", - "@yourGlobalUserIdIs": {}, - "commandHint_sendraw": "Надіслати необроблений json", - "@commandHint_sendraw": {}, - "wrongRecoveryKey": "Вибачте... схоже, це неправильний ключ відновлення.", - "@wrongRecoveryKey": {}, - "blockUsername": "Ігнорувати ім'я користувача", - "@blockUsername": {}, - "groupName": "Назва групи", - "@groupName": {}, - "databaseMigrationTitle": "Базу даних оптимізовано", - "@databaseMigrationTitle": {}, - "searchChatsRooms": "Пошук для #chats, @users...", - "@searchChatsRooms": {}, - "databaseMigrationBody": "Зачекайте, будь ласка. Це може тривати деякий час.", - "@databaseMigrationBody": {} + "@@locale": "uk", + "@@last_modified": "2021-08-14 12:41:09.790615", + "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": {} + } + }, + "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": {} + } + }, + "banFromChat": "Заблокувати в бесіді", + "@banFromChat": { + "type": "text", + "placeholders": {} + }, + "banned": "Заблоковано", + "@banned": { + "type": "text", + "placeholders": {} + }, + "bannedUser": "{username} блокує {targetName}", + "@bannedUser": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "blockDevice": "Заблокувати пристрій", + "@blockDevice": { + "type": "text", + "placeholders": {} + }, + "cancel": "Скасувати", + "@cancel": { + "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": {} + } + }, + "changeTheHomeserver": "Змінити домашній сервер", + "@changeTheHomeserver": { + "type": "text", + "placeholders": {} + }, + "changeTheme": "Змінити стиль", + "@changeTheme": { + "type": "text", + "placeholders": {} + }, + "changeTheNameOfTheGroup": "Змінити назву групи", + "@changeTheNameOfTheGroup": { + "type": "text", + "placeholders": {} + }, + "channelCorruptedDecryptError": "Шифрування було пошкоджено", + "@channelCorruptedDecryptError": { + "type": "text", + "placeholders": {} + }, + "chat": "Бесіда", + "@chat": { + "type": "text", + "placeholders": {} + }, + "chatDetails": "Подробиці бесіди", + "@chatDetails": { + "type": "text", + "placeholders": {} + }, + "chooseAStrongPassword": "Виберіть надійний пароль", + "@chooseAStrongPassword": { + "type": "text", + "placeholders": {} + }, + "close": "Закрити", + "@close": { + "type": "text", + "placeholders": {} + }, + "compareEmojiMatch": "Порівняйте емодзі", + "@compareEmojiMatch": { + "type": "text", + "placeholders": {} + }, + "compareNumbersMatch": "Порівняйте цифри", + "@compareNumbersMatch": { + "type": "text", + "placeholders": {} + }, + "confirm": "Підтвердити", + "@confirm": { + "type": "text", + "placeholders": {} + }, + "connect": "Під'єднатись", + "@connect": { + "type": "text", + "placeholders": {} + }, + "contactHasBeenInvitedToTheGroup": "Контакт був запрошений в групу", + "@contactHasBeenInvitedToTheGroup": { + "type": "text", + "placeholders": {} + }, + "copiedToClipboard": "Скопійовано в буфер обміну", + "@copiedToClipboard": { + "type": "text", + "placeholders": {} + }, + "copy": "Копіювати", + "@copy": { + "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": {} + } + }, + "currentlyActive": "Зараз у мережі", + "@currentlyActive": { + "type": "text", + "placeholders": {} + }, + "darkTheme": "Темний", + "@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": {} + } + }, + "delete": "Видалити", + "@delete": { + "type": "text", + "placeholders": {} + }, + "deleteMessage": "Видалити повідомлення", + "@deleteMessage": { + "type": "text", + "placeholders": {} + }, + "device": "Пристрій", + "@device": { + "type": "text", + "placeholders": {} + }, + "devices": "Пристрої", + "@devices": { + "type": "text", + "placeholders": {} + }, + "displaynameHasBeenChanged": "Показуване ім'я було змінено", + "@displaynameHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "downloadFile": "Завантажити файл", + "@downloadFile": { + "type": "text", + "placeholders": {} + }, + "editDisplayname": "Змінити показуване ім'я", + "@editDisplayname": { + "type": "text", + "placeholders": {} + }, + "emoteExists": "Емодзі вже існує!", + "@emoteExists": { + "type": "text", + "placeholders": {} + }, + "emoteInvalid": "Неприпустимий короткий код емодзі!", + "@emoteInvalid": { + "type": "text", + "placeholders": {} + }, + "emoteSettings": "Налаштування емодзі", + "@emoteSettings": { + "type": "text", + "placeholders": {} + }, + "emoteShortcode": "Короткий код для емодзі", + "@emoteShortcode": { + "type": "text", + "placeholders": {} + }, + "emoteWarnNeedToPick": "Укажіть короткий код емодзі та зображення!", + "@emoteWarnNeedToPick": { + "type": "text", + "placeholders": {} + }, + "emptyChat": "Порожня бесіда", + "@emptyChat": { + "type": "text", + "placeholders": {} + }, + "enableEncryptionWarning": "Ви більше не зможете вимкнути шифрування. Ви впевнені?", + "@enableEncryptionWarning": { + "type": "text", + "placeholders": {} + }, + "encryption": "Шифрування", + "@encryption": { + "type": "text", + "placeholders": {} + }, + "encryptionNotEnabled": "Шифрування вимкнено", + "@encryptionNotEnabled": { + "type": "text", + "placeholders": {} + }, + "endedTheCall": "{senderName} завершує виклик", + "@endedTheCall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "enterYourHomeserver": "Введіть адресу домашнього сервера", + "@enterYourHomeserver": { + "type": "text", + "placeholders": {} + }, + "fileName": "Назва файлу", + "@fileName": { + "type": "text", + "placeholders": {} + }, + "fluffychat": "FluffyChat", + "@fluffychat": { + "type": "text", + "placeholders": {} + }, + "forward": "Переслати", + "@forward": { + "type": "text", + "placeholders": {} + }, + "fromJoining": "З моменту приєднання", + "@fromJoining": { + "type": "text", + "placeholders": {} + }, + "fromTheInvitation": "З моменту запрошення", + "@fromTheInvitation": { + "type": "text", + "placeholders": {} + }, + "group": "Група", + "@group": { + "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": {} + }, + "hasWithdrawnTheInvitationFor": "{username} відкликає запрошення для {targetName}", + "@hasWithdrawnTheInvitationFor": { + "type": "text", + "placeholders": { + "username": {}, + "targetName": {} + } + }, + "help": "Довідка", + "@help": { + "type": "text", + "placeholders": {} + }, + "id": "ID", + "@id": { + "type": "text", + "placeholders": {} + }, + "identity": "Ідентифікація", + "@identity": { + "type": "text", + "placeholders": {} + }, + "incorrectPassphraseOrKey": "Неправильна парольна фраза або ключ відновлення", + "@incorrectPassphraseOrKey": { + "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": {} + }, + "inviteText": "{username} запрошує вас у FluffyChat. \n1. Перейдіть на fluffychat.im й установіть застосунок \n2. Зареєструйтесь або ввійдіть \n3. Відкрийте запрошувальне посилання:\n {link}", + "@inviteText": { + "type": "text", + "placeholders": { + "username": {}, + "link": {} + } + }, + "isTyping": "пише…", + "@isTyping": { + "type": "text", + "placeholders": {} + }, + "joinedTheChat": "👋 {username} приєднується до бесіди", + "@joinedTheChat": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "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": {} + } + }, + "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": {} + }, + "moderator": "Модератор", + "@moderator": { + "type": "text", + "placeholders": {} + }, + "muteChat": "Вимкнути сповіщення", + "@muteChat": { + "type": "text", + "placeholders": {} + }, + "needPantalaimonWarning": "Майте на увазі, що на цей час вам потрібен Pantalaimon, щоб використовувати наскрізне шифрування.", + "@needPantalaimonWarning": { + "type": "text", + "placeholders": {} + }, + "newMessageInFluffyChat": "💬 Нове повідомлення у FluffyChat", + "@newMessageInFluffyChat": { + "type": "text", + "placeholders": {} + }, + "newVerificationRequest": "Новий запит перевірки!", + "@newVerificationRequest": { + "type": "text", + "placeholders": {} + }, + "noEmotesFound": "Емоджі не знайдено. 😕", + "@noEmotesFound": { + "type": "text", + "placeholders": {} + }, + "noGoogleServicesWarning": "Схоже, Firebase Cloud Messaging недоступна на вашому пристрої. Щоб отримувати push-сповіщення, радимо встановити ntfy. За допомогою ntfy або іншого постачальника Unified Push ви можете отримувати push-сповіщення у безпечний спосіб. Ви можете завантажити ntfy з PlayStore або з F-Droid.", + "@noGoogleServicesWarning": { + "type": "text", + "placeholders": {} + }, + "none": "Нічого", + "@none": { + "type": "text", + "placeholders": {} + }, + "noPermission": "Немає прав доступу", + "@noPermission": { + "type": "text", + "placeholders": {} + }, + "noRoomsFound": "Кімнат не знайдено…", + "@noRoomsFound": { + "type": "text", + "placeholders": {} + }, + "ok": "Гаразд", + "@ok": { + "type": "text", + "placeholders": {} + }, + "onlineKeyBackupEnabled": "Резервне онлайн-копіювання ключів увімкнено", + "@onlineKeyBackupEnabled": { + "type": "text", + "placeholders": {} + }, + "oopsSomethingWentWrong": "Халепа, щось пішло не так…", + "@oopsSomethingWentWrong": { + "type": "text", + "placeholders": {} + }, + "openAppToReadMessages": "Відкрийте застосунок читання повідомлень", + "@openAppToReadMessages": { + "type": "text", + "placeholders": {} + }, + "openCamera": "Відкрити камеру", + "@openCamera": { + "type": "text", + "placeholders": {} + }, + "passphraseOrKey": "парольна фраза або ключ відновлення", + "@passphraseOrKey": { + "type": "text", + "placeholders": {} + }, + "password": "Пароль", + "@password": { + "type": "text", + "placeholders": {} + }, + "pickImage": "Вибрати зображення", + "@pickImage": { + "type": "text", + "placeholders": {} + }, + "play": "Відтворити {fileName}", + "@play": { + "type": "text", + "placeholders": { + "fileName": {} + } + }, + "pleaseEnterYourPassword": "Введіть свій пароль", + "@pleaseEnterYourPassword": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourUsername": "Введіть своє ім'я користувача", + "@pleaseEnterYourUsername": { + "type": "text", + "placeholders": {} + }, + "publicRooms": "Загальнодоступні кімнати", + "@publicRooms": { + "type": "text", + "placeholders": {} + }, + "recording": "Запис", + "@recording": { + "type": "text", + "placeholders": {} + }, + "redactedAnEvent": "{username} змінює подію", + "@redactedAnEvent": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "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": {} + }, + "reply": "Відповісти", + "@reply": { + "type": "text", + "placeholders": {} + }, + "requestPermission": "Запит дозволу", + "@requestPermission": { + "type": "text", + "placeholders": {} + }, + "roomHasBeenUpgraded": "Кімнату було оновлено", + "@roomHasBeenUpgraded": { + "type": "text", + "placeholders": {} + }, + "seenByUser": "Переглянуто {username}", + "@seenByUser": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "send": "Надіслати", + "@send": { + "type": "text", + "placeholders": {} + }, + "sendAMessage": "Надіслати повідомлення", + "@sendAMessage": { + "type": "text", + "placeholders": {} + }, + "sendFile": "Надіслати файл", + "@sendFile": { + "type": "text", + "placeholders": {} + }, + "sendImage": "Надіслати зображення", + "@sendImage": { + "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": {} + } + }, + "setInvitationLink": "Указати посилання для запрошення", + "@setInvitationLink": { + "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": {} + } + }, + "skip": "Пропустити", + "@skip": { + "type": "text", + "placeholders": {} + }, + "sourceCode": "Джерельний код", + "@sourceCode": { + "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": {} + }, + "tryToSendAgain": "Спробуйте надіслати ще раз", + "@tryToSendAgain": { + "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": {} + }, + "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": {} + } + }, + "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": {} + }, + "whoIsAllowedToJoinThisGroup": "Кому дозволено приєднуватися до цієї групи", + "@whoIsAllowedToJoinThisGroup": { + "type": "text", + "placeholders": {} + }, + "writeAMessage": "Написати повідомлення…", + "@writeAMessage": { + "type": "text", + "placeholders": {} + }, + "yes": "Так", + "@yes": { + "type": "text", + "placeholders": {} + }, + "you": "Ви", + "@you": { + "type": "text", + "placeholders": {} + }, + "youAreNoLongerParticipatingInThisChat": "Ви більше не берете участь у цій бесіді", + "@youAreNoLongerParticipatingInThisChat": { + "type": "text", + "placeholders": {} + }, + "youHaveBeenBannedFromThisChat": "Ви були заблоковані у цій бесіді", + "@youHaveBeenBannedFromThisChat": { + "type": "text", + "placeholders": {} + }, + "pushRules": "Правила сповіщень", + "@pushRules": { + "type": "text", + "placeholders": {} + }, + "notificationsEnabledForThisAccount": "Сповіщення ввімкнені для цього облікового запису", + "@notificationsEnabledForThisAccount": { + "type": "text", + "placeholders": {} + }, + "notifications": "Сповіщення", + "@notifications": { + "type": "text", + "placeholders": {} + }, + "memberChanges": "Зміни учасників", + "@memberChanges": { + "type": "text", + "placeholders": {} + }, + "inviteForMe": "Запрошення для мене", + "@inviteForMe": { + "type": "text", + "placeholders": {} + }, + "enterAnEmailAddress": "Введіть адресу е-пошти", + "@enterAnEmailAddress": { + "type": "text", + "placeholders": {} + }, + "encrypted": "Зашифровано", + "@encrypted": { + "type": "text", + "placeholders": {} + }, + "enableEmotesGlobally": "Увімкнути пакунок емоджі глобально", + "@enableEmotesGlobally": { + "type": "text", + "placeholders": {} + }, + "emotePacks": "Набори емоджі для кімнати", + "@emotePacks": { + "type": "text", + "placeholders": {} + }, + "edit": "Редагувати", + "@edit": { + "type": "text", + "placeholders": {} + }, + "directChats": "Особисті бесіди", + "@directChats": { + "type": "text", + "placeholders": {} + }, + "deviceId": "ID пристрою", + "@deviceId": { + "type": "text", + "placeholders": {} + }, + "deleteAccount": "Видалити обліковий запис", + "@deleteAccount": { + "type": "text", + "placeholders": {} + }, + "deactivateAccountWarning": "Це деактивує ваш обліковий запис. Це неможливо скасувати! Ви впевнені?", + "@deactivateAccountWarning": { + "type": "text", + "placeholders": {} + }, + "containsUserName": "Містить ім’я користувача", + "@containsUserName": { + "type": "text", + "placeholders": {} + }, + "containsDisplayName": "Містить показуване ім’я", + "@containsDisplayName": { + "type": "text", + "placeholders": {} + }, + "changePassword": "Змінити пароль", + "@changePassword": { + "type": "text", + "placeholders": {} + }, + "changeDeviceName": "Змінити назву пристрою", + "@changeDeviceName": { + "type": "text", + "placeholders": {} + }, + "botMessages": "Повідомлення ботів", + "@botMessages": { + "type": "text", + "placeholders": {} + }, + "or": "Або", + "@or": { + "type": "text", + "placeholders": {} + }, + "setAsCanonicalAlias": "Установити основним псевдонімом", + "@setAsCanonicalAlias": { + "type": "text", + "placeholders": {} + }, + "verified": "Перевірений", + "@verified": { + "type": "text", + "placeholders": {} + }, + "blocked": "Заблоковано", + "@blocked": { + "type": "text", + "placeholders": {} + }, + "no": "Ні", + "@no": { + "type": "text", + "placeholders": {} + }, + "sendOnEnter": "Надсилати натисканням Enter", + "@sendOnEnter": {}, + "commandHint_ban": "Заблокувати цього користувача кімнати", + "@commandHint_ban": { + "type": "text", + "description": "Usage hint for the command /ban" + }, + "commandHint_kick": "Вилучити цього користувача з цієї кімнати", + "@commandHint_kick": { + "type": "text", + "description": "Usage hint for the command /kick" + }, + "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" + }, + "commandMissing": "{command} не є командою.", + "@commandMissing": { + "type": "text", + "placeholders": { + "command": {} + }, + "description": "State that {command} is not a valid /command." + }, + "copyToClipboard": "Копіювати до буфера обміну", + "@copyToClipboard": { + "type": "text", + "placeholders": {} + }, + "createNewSpace": "Новий простір", + "@createNewSpace": { + "type": "text", + "placeholders": {} + }, + "enableEncryption": "Увімкнути шифрування", + "@enableEncryption": { + "type": "text", + "placeholders": {} + }, + "joinRoom": "Приєднатися до кімнати", + "@joinRoom": { + "type": "text", + "placeholders": {} + }, + "mention": "Згадати", + "@mention": { + "type": "text", + "placeholders": {} + }, + "next": "Далі", + "@next": { + "type": "text", + "placeholders": {} + }, + "noConnectionToTheServer": "Немає з'єднання з сервером", + "@noConnectionToTheServer": { + "type": "text", + "placeholders": {} + }, + "scanQrCode": "Сканувати QR-код", + "@scanQrCode": {}, + "noPasswordRecoveryDescription": "Ви ще не додали спосіб відновлення пароля.", + "@noPasswordRecoveryDescription": { + "type": "text", + "placeholders": {} + }, + "numUsersTyping": "{count} користувачів пишуть…", + "@numUsersTyping": { + "type": "text", + "placeholders": { + "count": {} + } + }, + "online": "Онлайн", + "@online": { + "type": "text", + "placeholders": {} + }, + "oopsPushError": "Дідько! На жаль, сталася помилка під час налаштування push-сповіщень.", + "@oopsPushError": { + "type": "text", + "placeholders": {} + }, + "passwordForgotten": "Забули пароль", + "@passwordForgotten": { + "type": "text", + "placeholders": {} + }, + "pleaseChoose": "Виберіть", + "@pleaseChoose": { + "type": "text", + "placeholders": {} + }, + "pleaseEnter4Digits": "Введіть 4 цифри або залиште порожнім, щоб вимкнути блокування застосунку.", + "@pleaseEnter4Digits": { + "type": "text", + "placeholders": {} + }, + "redactMessage": "Редагувати повідомлення", + "@redactMessage": { + "type": "text", + "placeholders": {} + }, + "register": "Зареєструватися", + "@register": { + "type": "text", + "placeholders": {} + }, + "reportMessage": "Поскаржитися на повідомлення", + "@reportMessage": { + "type": "text", + "placeholders": {} + }, + "replaceRoomWithNewerVersion": "Замінити кімнату новішою версією", + "@replaceRoomWithNewerVersion": { + "type": "text", + "placeholders": {} + }, + "sendAudio": "Надіслати аудіо", + "@sendAudio": { + "type": "text", + "placeholders": {} + }, + "setCustomEmotes": "Установити користувацькі емоджі", + "@setCustomEmotes": { + "type": "text", + "placeholders": {} + }, + "weSentYouAnEmail": "Ми надіслали вам електронний лист", + "@weSentYouAnEmail": { + "type": "text", + "placeholders": {} + }, + "wipeChatBackup": "Стерти резервну копію бесіди, щоб створити новий ключ відновлення?", + "@wipeChatBackup": { + "type": "text", + "placeholders": {} + }, + "addToSpace": "Додати простір", + "@addToSpace": {}, + "roomVersion": "Версія кімнати", + "@roomVersion": { + "type": "text", + "placeholders": {} + }, + "iHaveClickedOnLink": "Мною виконано перехід за посиланням", + "@iHaveClickedOnLink": { + "type": "text", + "placeholders": {} + }, + "startedACall": "{senderName} розпочинає виклик", + "@startedACall": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "appLock": "Блокування застосунку", + "@appLock": { + "type": "text", + "placeholders": {} + }, + "commandInvalid": "Неприпустима команда", + "@commandInvalid": { + "type": "text" + }, + "extremeOffensive": "Украй образливий", + "@extremeOffensive": { + "type": "text", + "placeholders": {} + }, + "howOffensiveIsThisContent": "Наскільки образливий цей вміст?", + "@howOffensiveIsThisContent": { + "type": "text", + "placeholders": {} + }, + "participant": "Учасник", + "@participant": { + "type": "text", + "placeholders": {} + }, + "addEmail": "Додати е-пошту", + "@addEmail": { + "type": "text", + "placeholders": {} + }, + "ignore": "Нехтувати", + "@ignore": { + "type": "text", + "placeholders": {} + }, + "fontSize": "Розмір шрифту", + "@fontSize": { + "type": "text", + "placeholders": {} + }, + "badServerVersionsException": "Домашній сервер підтримує такі версії специфікацій:\n{serverVersions}\nАле цей застосунок підтримує лише {supportedVersions}", + "@badServerVersionsException": { + "type": "text", + "placeholders": { + "serverVersions": {}, + "supportedVersions": {} + } + }, + "areYouSureYouWantToLogout": "Ви впевнені, що хочете вийти?", + "@areYouSureYouWantToLogout": { + "type": "text", + "placeholders": {} + }, + "badServerLoginTypesException": "Домашній сервер підтримує такі типи входу:\n{serverVersions}\nАле цей застосунок підтримує лише:\n{supportedVersions}", + "@badServerLoginTypesException": { + "type": "text", + "placeholders": { + "serverVersions": {}, + "supportedVersions": {} + } + }, + "all": "Усі", + "@all": { + "type": "text", + "placeholders": {} + }, + "allChats": "Усі бесіди", + "@allChats": { + "type": "text", + "placeholders": {} + }, + "commandHint_join": "Приєднатися до цієї кімнати", + "@commandHint_join": { + "type": "text", + "description": "Usage hint for the command /join" + }, + "chats": "Бесіди", + "@chats": { + "type": "text", + "placeholders": {} + }, + "changeYourAvatar": "Змінити аватар", + "@changeYourAvatar": { + "type": "text", + "placeholders": {} + }, + "link": "Посилання", + "@link": {}, + "security": "Безпека", + "@security": { + "type": "text", + "placeholders": {} + }, + "sendSticker": "Надіслати наліпку", + "@sendSticker": { + "type": "text", + "placeholders": {} + }, + "errorObtainingLocation": "Помилка під час отримання розташування: {error}", + "@errorObtainingLocation": { + "type": "text", + "placeholders": { + "error": {} + } + }, + "hideRedactedEvents": "Сховати змінені події", + "@hideRedactedEvents": { + "type": "text", + "placeholders": {} + }, + "synchronizingPleaseWait": "Синхронізація… Будь ласка, зачекайте.", + "@synchronizingPleaseWait": { + "type": "text", + "placeholders": {} + }, + "noMatrixServer": "{server1} не є сервером matrix, використовувати {server2} натомість?", + "@noMatrixServer": { + "type": "text", + "placeholders": { + "server1": {}, + "server2": {} + } + }, + "reason": "Причина", + "@reason": { + "type": "text", + "placeholders": {} + }, + "defaultPermissionLevel": "Типовий рівень дозволів", + "@defaultPermissionLevel": { + "type": "text", + "placeholders": {} + }, + "sendAsText": "Надіслати як текст", + "@sendAsText": { + "type": "text" + }, + "saveFile": "Зберегти файл", + "@saveFile": { + "type": "text", + "placeholders": {} + }, + "autoplayImages": "Автоматично відтворювати анімовані наліпки та емоджі", + "@autoplayImages": { + "type": "text", + "placeholder": {} + }, + "pleaseChooseAPasscode": "Виберіть код доступу", + "@pleaseChooseAPasscode": { + "type": "text", + "placeholders": {} + }, + "pleaseClickOnLink": "Натисніть на посилання в електронному листі, а потім продовжуйте.", + "@pleaseClickOnLink": { + "type": "text", + "placeholders": {} + }, + "toggleUnread": "Позначити прочитаним/непрочитаним", + "@toggleUnread": { + "type": "text", + "placeholders": {} + }, + "transferFromAnotherDevice": "Перенесення з іншого пристрою", + "@transferFromAnotherDevice": { + "type": "text", + "placeholders": {} + }, + "sendMessages": "Надсилати повідомлення", + "@sendMessages": { + "type": "text", + "placeholders": {} + }, + "sendOriginal": "Надіслати оригінал", + "@sendOriginal": { + "type": "text", + "placeholders": {} + }, + "whoCanPerformWhichAction": "Хто і яку дію може виконувати", + "@whoCanPerformWhichAction": { + "type": "text", + "placeholders": {} + }, + "whyDoYouWantToReportThis": "Чому ви хочете поскаржитися?", + "@whyDoYouWantToReportThis": { + "type": "text", + "placeholders": {} + }, + "messages": "Повідомлення", + "@messages": { + "type": "text", + "placeholders": {} + }, + "newChat": "Нова бесіда", + "@newChat": { + "type": "text", + "placeholders": {} + }, + "everythingReady": "Усе готово!", + "@everythingReady": { + "type": "text", + "placeholders": {} + }, + "homeserver": "Домашній сервер", + "@homeserver": {}, + "goToTheNewRoom": "Перейти до нової кімнати", + "@goToTheNewRoom": { + "type": "text", + "placeholders": {} + }, + "groups": "Групи", + "@groups": { + "type": "text", + "placeholders": {} + }, + "inoffensive": "Необразливий", + "@inoffensive": { + "type": "text", + "placeholders": {} + }, + "noEncryptionForPublicRooms": "Активувати шифрування можна лише тоді, коли кімната більше не буде загальнодоступною.", + "@noEncryptionForPublicRooms": { + "type": "text", + "placeholders": {} + }, + "chatHasBeenAddedToThisSpace": "Бесіду додано до цього простору", + "@chatHasBeenAddedToThisSpace": {}, + "chatBackupDescription": "Ваші старі повідомлення захищені ключем відновлення. Переконайтеся, що ви не втратите його.", + "@chatBackupDescription": { + "type": "text", + "placeholders": {} + }, + "chatBackup": "Резервне копіювання бесіди", + "@chatBackup": { + "type": "text", + "placeholders": {} + }, + "yourChatBackupHasBeenSetUp": "Резервне копіювання бесіди налаштовано.", + "@yourChatBackupHasBeenSetUp": {}, + "clearArchive": "Очистити архів", + "@clearArchive": {}, + "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" + }, + "hideUnknownEvents": "Сховати невідомі події", + "@hideUnknownEvents": { + "type": "text", + "placeholders": {} + }, + "ignoredUsers": "Нехтувані користувачі", + "@ignoredUsers": { + "type": "text", + "placeholders": {} + }, + "obtainingLocation": "Отримання розташування…", + "@obtainingLocation": { + "type": "text", + "placeholders": {} + }, + "offensive": "Образливий", + "@offensive": { + "type": "text", + "placeholders": {} + }, + "offline": "Офлайн", + "@offline": { + "type": "text", + "placeholders": {} + }, + "addAccount": "Додати обліковий запис", + "@addAccount": {}, + "enableMultiAccounts": "(БЕТА) Увімкнути кілька облікових записів на цьому пристрої", + "@enableMultiAccounts": {}, + "openInMaps": "Відкрити в картах", + "@openInMaps": { + "type": "text", + "placeholders": {} + }, + "serverRequiresEmail": "Цей сервер потребує перевірки вашої адресу е-пошти для реєстрації.", + "@serverRequiresEmail": {}, + "pleaseFollowInstructionsOnWeb": "Виконайте вказівки вебсайту та торкніться далі.", + "@pleaseFollowInstructionsOnWeb": { + "type": "text", + "placeholders": {} + }, + "sendVideo": "Надіслати відео", + "@sendVideo": { + "type": "text", + "placeholders": {} + }, + "removeYourAvatar": "Вилучити свій аватар", + "@removeYourAvatar": { + "type": "text", + "placeholders": {} + }, + "unpin": "Відкріпити", + "@unpin": { + "type": "text", + "placeholders": {} + }, + "setPermissionsLevel": "Указати рівні дозволів", + "@setPermissionsLevel": { + "type": "text", + "placeholders": {} + }, + "shareLocation": "Поділитися місцеперебуванням", + "@shareLocation": { + "type": "text", + "placeholders": {} + }, + "singlesignon": "Єдиний вхід", + "@singlesignon": { + "type": "text", + "placeholders": {} + }, + "tooManyRequestsWarning": "Забагато запитів. Спробуйте пізніше!", + "@tooManyRequestsWarning": { + "type": "text", + "placeholders": {} + }, + "unavailable": "Недоступний", + "@unavailable": { + "type": "text", + "placeholders": {} + }, + "unreadChats": "{unreadCount, plural, =1{1 непрочитана бесіда} few{{unreadCount} непрочитані бесіди} many{{unreadCount} непрочитаних бесід} other{{unreadCount} непрочитані бесіди}}", + "@unreadChats": { + "type": "text", + "placeholders": { + "unreadCount": {} + } + }, + "withTheseAddressesRecoveryDescription": "За допомогою цих адрес ви можете відновити свій пароль.", + "@withTheseAddressesRecoveryDescription": { + "type": "text", + "placeholders": {} + }, + "privacy": "Приватність", + "@privacy": { + "type": "text", + "placeholders": {} + }, + "search": "Пошук", + "@search": { + "type": "text", + "placeholders": {} + }, + "sentCallInformations": "{senderName} надсилає відомості про виклик", + "@sentCallInformations": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "cantOpenUri": "Не вдалося відкрити URI {uri}", + "@cantOpenUri": { + "type": "text", + "placeholders": { + "uri": {} + } + }, + "contentHasBeenReported": "Скаргу на вміст надіслано адміністраторам сервера", + "@contentHasBeenReported": { + "type": "text", + "placeholders": {} + }, + "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" + }, + "configureChat": "Налаштувати бесіду", + "@configureChat": { + "type": "text", + "placeholders": {} + }, + "editBlockedServers": "Редагувати заблоковані сервери", + "@editBlockedServers": { + "type": "text", + "placeholders": {} + }, + "showPassword": "Показати пароль", + "@showPassword": { + "type": "text", + "placeholders": {} + }, + "editRoomAliases": "Змінити псевдоніми кімнати", + "@editRoomAliases": { + "type": "text", + "placeholders": {} + }, + "editRoomAvatar": "Змінити аватар кімнати", + "@editRoomAvatar": { + "type": "text", + "placeholders": {} + }, + "passwordHasBeenChanged": "Пароль змінено", + "@passwordHasBeenChanged": { + "type": "text", + "placeholders": {} + }, + "passwordRecovery": "Відновлення пароля", + "@passwordRecovery": { + "type": "text", + "placeholders": {} + }, + "people": "Люди", + "@people": { + "type": "text", + "placeholders": {} + }, + "pin": "Закріпити", + "@pin": { + "type": "text", + "placeholders": {} + }, + "pleaseEnterYourPin": "Введіть свій PIN-код", + "@pleaseEnterYourPin": { + "type": "text", + "placeholders": {} + }, + "spaceName": "Назва простору", + "@spaceName": { + "type": "text", + "placeholders": {} + }, + "warning": "Попередження!", + "@warning": { + "type": "text", + "placeholders": {} + }, + "yourPublicKey": "Ваш відкритий ключ", + "@yourPublicKey": { + "type": "text", + "placeholders": {} + }, + "spaceIsPublic": "Простір загальнодоступний", + "@spaceIsPublic": { + "type": "text", + "placeholders": {} + }, + "status": "Статус", + "@status": { + "type": "text", + "placeholders": {} + }, + "unverified": "Неперевірений", + "@unverified": {}, + "locationDisabledNotice": "Служби визначення місцеположення вимкнені. Увімкніть їх, щоб могти надавати доступ до вашого місцеположення.", + "@locationDisabledNotice": { + "type": "text", + "placeholders": {} + }, + "locationPermissionDeniedNotice": "Дозвіл на розташування відхилено. Надайте можливість ділитися своїм місцеперебуванням.", + "@locationPermissionDeniedNotice": { + "type": "text", + "placeholders": {} + }, + "oneClientLoggedOut": "На одному з ваших клієнтів виконано вихід із системи", + "@oneClientLoggedOut": {}, + "bundleName": "Назва вузла", + "@bundleName": {}, + "toggleFavorite": "Перемикнути вибране", + "@toggleFavorite": { + "type": "text", + "placeholders": {} + }, + "removeFromBundle": "Вилучити з цього вузла", + "@removeFromBundle": {}, + "toggleMuted": "Увімкнути/вимкнути звук", + "@toggleMuted": { + "type": "text", + "placeholders": {} + }, + "editBundlesForAccount": "Змінити вузол для цього облікового запису", + "@editBundlesForAccount": {}, + "addToBundle": "Додати до вузлів", + "@addToBundle": {}, + "repeatPassword": "Повторіть пароль", + "@repeatPassword": {}, + "messageInfo": "Відомості про повідомлення", + "@messageInfo": {}, + "time": "Час", + "@time": {}, + "messageType": "Тип повідомлення", + "@messageType": {}, + "openGallery": "Відкрити галерею", + "@openGallery": {}, + "sender": "Відправник", + "@sender": {}, + "addToSpaceDescription": "Виберіть простір, щоб додати до нього цю бесіду.", + "@addToSpaceDescription": {}, + "removeFromSpace": "Вилучити з простору", + "@removeFromSpace": {}, + "start": "Почати", + "@start": {}, + "commandHint_discardsession": "Відкинути сеанс", + "@commandHint_discardsession": { + "type": "text", + "description": "Usage hint for the command /discardsession" + }, + "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_dm": "Початок особистої бесіди\nВикористовуйте --no-encryption, що вимкнути шифрування", + "@commandHint_dm": { + "type": "text", + "description": "Usage hint for the command /dm" + }, + "openVideoCamera": "Відкрити камеру для відео", + "@openVideoCamera": { + "type": "text", + "placeholders": {} + }, + "publish": "Опублікувати", + "@publish": {}, + "videoWithSize": "Відео ({size})", + "@videoWithSize": { + "type": "text", + "placeholders": { + "size": {} + } + }, + "dismiss": "Відхилити", + "@dismiss": {}, + "markAsRead": "Позначити прочитаним", + "@markAsRead": {}, + "reportUser": "Поскаржився на користувача", + "@reportUser": {}, + "openChat": "Відкрити бесіду", + "@openChat": {}, + "reactedWith": "{sender} реагує з {reaction}", + "@reactedWith": { + "type": "text", + "placeholders": { + "sender": {}, + "reaction": {} + } + }, + "emojis": "Емоджі", + "@emojis": {}, + "pinMessage": "Прикріпити в кімнаті", + "@pinMessage": {}, + "confirmEventUnpin": "Ви впевнені, що бажаєте назавжди відкріпите подію?", + "@confirmEventUnpin": {}, + "placeCall": "Здійснити виклик", + "@placeCall": {}, + "unsupportedAndroidVersion": "Непідтримувана версія Android", + "@unsupportedAndroidVersion": {}, + "voiceCall": "Голосовий виклик", + "@voiceCall": {}, + "unsupportedAndroidVersionLong": "Для цієї функції потрібна новіша версія Android. Перевірте наявність оновлень або підтримку Lineage OS.", + "@unsupportedAndroidVersionLong": {}, + "videoCallsBetaWarning": "Зауважте, що відеовиклики на ранньому етапі розробки. Вони можуть працювати не так, як очікувалося, або взагалі не працювати на всіх платформах.", + "@videoCallsBetaWarning": {}, + "emailOrUsername": "Електронна адреса або ім’я користувача", + "@emailOrUsername": {}, + "experimentalVideoCalls": "Експериментальні відеовиклики", + "@experimentalVideoCalls": {}, + "switchToAccount": "Перемкнутися на обліковий запис {number}", + "@switchToAccount": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "nextAccount": "Наступний обліковий запис", + "@nextAccount": {}, + "previousAccount": "Попередній обліковий запис", + "@previousAccount": {}, + "addWidget": "Додати віджет", + "@addWidget": {}, + "widgetVideo": "Відео", + "@widgetVideo": {}, + "widgetCustom": "Користувацький", + "@widgetCustom": {}, + "widgetName": "Назва", + "@widgetName": {}, + "widgetNameError": "Укажіть коротку назву.", + "@widgetNameError": {}, + "widgetEtherpad": "Текстова примітка", + "@widgetEtherpad": {}, + "widgetJitsi": "Jitsi Meet", + "@widgetJitsi": {}, + "widgetUrlError": "Це недійсна URL-адреса.", + "@widgetUrlError": {}, + "errorAddingWidget": "Помилка додавання віджета.", + "@errorAddingWidget": {}, + "separateChatTypes": "Розділіть особисті бесіди та групи", + "@separateChatTypes": { + "type": "text", + "placeholders": {} + }, + "youInvitedBy": "📩 Ви були запрошені {user}", + "@youInvitedBy": { + "placeholders": { + "user": {} + } + }, + "youAcceptedTheInvitation": "👍 Ви погодилися на запрошення", + "@youAcceptedTheInvitation": {}, + "youRejectedTheInvitation": "Ви відхилили запрошення", + "@youRejectedTheInvitation": {}, + "youHaveWithdrawnTheInvitationFor": "Ви відкликали запрошення для {user}", + "@youHaveWithdrawnTheInvitationFor": { + "placeholders": { + "user": {} + } + }, + "youBannedUser": "Ви заблокували {user}", + "@youBannedUser": { + "placeholders": { + "user": {} + } + }, + "youKickedAndBanned": "🙅 Ви вилучили й заблокували {user}", + "@youKickedAndBanned": { + "placeholders": { + "user": {} + } + }, + "youJoinedTheChat": "Ви приєдналися до бесіди", + "@youJoinedTheChat": {}, + "youKicked": "👞 Ви вилучили {user}", + "@youKicked": { + "placeholders": { + "user": {} + } + }, + "youUnbannedUser": "Ви розблокували {user}", + "@youUnbannedUser": { + "placeholders": { + "user": {} + } + }, + "youInvitedUser": "📩 Ви запросили {user}", + "@youInvitedUser": { + "placeholders": { + "user": {} + } + }, + "saveKeyManuallyDescription": "Збережіть цей ключ вручну, запустивши діалогове вікно спільного доступу до системи або буфер обміну.", + "@saveKeyManuallyDescription": {}, + "storeInAndroidKeystore": "Зберегти в Android KeyStore", + "@storeInAndroidKeystore": {}, + "storeInAppleKeyChain": "Зберегти в Apple KeyChain", + "@storeInAppleKeyChain": {}, + "storeSecurlyOnThisDevice": "Зберегти безпечно на цей пристрій", + "@storeSecurlyOnThisDevice": {}, + "pleaseEnterRecoveryKeyDescription": "Щоб розблокувати старі повідомлення, введіть ключ відновлення, згенерований у попередньому сеансі. Ваш ключ відновлення це НЕ ваш пароль.", + "@pleaseEnterRecoveryKeyDescription": {}, + "pleaseEnterRecoveryKey": "Введіть ключ відновлення:", + "@pleaseEnterRecoveryKey": {}, + "recoveryKey": "Ключ відновлення", + "@recoveryKey": {}, + "recoveryKeyLost": "Ключ відновлення втрачено?", + "@recoveryKeyLost": {}, + "users": "Користувачі", + "@users": {}, + "unlockOldMessages": "Розблокувати старі повідомлення", + "@unlockOldMessages": {}, + "storeInSecureStorageDescription": "Збережіть ключ відновлення в безпечному сховищі цього пристрою.", + "@storeInSecureStorageDescription": {}, + "countFiles": "{count} файлів", + "@countFiles": { + "placeholders": { + "count": {} + } + }, + "hydrate": "Відновлення з файлу резервної копії", + "@hydrate": {}, + "hydrateTorLong": "Минулого разу ви експортували свій сеанс із TOR? Швидко імпортуйте його та продовжуйте спілкування.", + "@hydrateTorLong": {}, + "indexedDbErrorTitle": "Проблеми приватного режиму", + "@indexedDbErrorTitle": {}, + "indexedDbErrorLong": "На жаль, сховище повідомлень не ввімкнуто у приватному режимі типово.\nВідкрийте\n - about:config\n - установіть для dom.indexedDB.privateBrowsing.enabled значення true\nІнакше запустити FluffyChat буде неможливо.", + "@indexedDbErrorLong": {}, + "dehydrate": "Експортувати сеанс та очистити пристрій", + "@dehydrate": {}, + "dehydrateWarning": "Цю дію не можна скасувати. Переконайтеся, що ви безпечно зберігаєте файл резервної копії.", + "@dehydrateWarning": {}, + "dehydrateTor": "Користувачі TOR: експорт сеансу", + "@dehydrateTor": {}, + "dehydrateTorLong": "Для користувачів TOR рекомендується експортувати сеанс перед закриттям вікна.", + "@dehydrateTorLong": {}, + "hydrateTor": "Користувачі TOR: імпорт експортованого сеансу", + "@hydrateTor": {}, + "user": "Користувач", + "@user": {}, + "custom": "Користувацький", + "@custom": {}, + "supposedMxid": "Це має бути {mxid}", + "@supposedMxid": { + "type": "text", + "placeholders": { + "mxid": {} + } + }, + "confirmMatrixId": "Підтвердьте свій Matrix ID, щоб видалити свій обліковий запис.", + "@confirmMatrixId": {}, + "commandHint_markasgroup": "Позначити групою", + "@commandHint_markasgroup": {}, + "commandHint_markasdm": "Позначити кімнатою особистого спілкування для надання Matrix ID", + "@commandHint_markasdm": {}, + "whyIsThisMessageEncrypted": "Чому це повідомлення нечитабельне?", + "@whyIsThisMessageEncrypted": {}, + "noKeyForThisMessage": "Це може статися, якщо повідомлення було надіслано до того, як ви ввійшли у свій обліковий запис на цьому пристрої.\n\nТакож можливо, що відправник заблокував ваш пристрій або щось пішло не так з під'єднанням до інтернету.\n\nЧи можете ви прочитати повідомлення на іншому сеансі? Тоді ви зможете перенести повідомлення з нього! Перейдіть до Налаштування > Пристрої та переконайтеся, що ваші пристрої перевірили один одного. Коли ви відкриєте кімнату наступного разу й обидва сеанси будуть на активні, ключі будуть передані автоматично.\n\nВи ж не хочете втрачати ключі після виходу або зміни пристроїв? Переконайтеся, що ви ввімкнули резервне копіювання бесід у налаштуваннях.", + "@noKeyForThisMessage": {}, + "foregroundServiceRunning": "Це сповіщення з'являється під час роботи основної служби.", + "@foregroundServiceRunning": {}, + "screenSharingTitle": "спільний доступ до екрана", + "@screenSharingTitle": {}, + "callingPermissions": "Дозволи на виклик", + "@callingPermissions": {}, + "callingAccount": "Обліковий запис для виклику", + "@callingAccount": {}, + "callingAccountDetails": "Дозволяє FluffyChat використовувати основний застосунок Android для набору номера.", + "@callingAccountDetails": {}, + "appearOnTop": "З'являтися зверху", + "@appearOnTop": {}, + "appearOnTopDetails": "Дозволяє застосунку показуватися зверху (не потрібно, якщо Fluffychat вже налаштований обліковим записом для викликів)", + "@appearOnTopDetails": {}, + "newGroup": "Нова група", + "@newGroup": {}, + "newSpace": "Новий простір", + "@newSpace": {}, + "enterSpace": "Увійти в простір", + "@enterSpace": {}, + "enterRoom": "Увійти в кімнату", + "@enterRoom": {}, + "otherCallingPermissions": "Мікрофон, камера та інші дозволи FluffyChat", + "@otherCallingPermissions": {}, + "allSpaces": "Усі простори", + "@allSpaces": {}, + "screenSharingDetail": "Ви ділитеся своїм екраном FuffyChat", + "@screenSharingDetail": {}, + "numChats": "{number} бесід", + "@numChats": { + "type": "number", + "placeholders": { + "number": {} + } + }, + "hideUnimportantStateEvents": "Сховати неважливі державні свята", + "@hideUnimportantStateEvents": {}, + "doNotShowAgain": "Не показувати знову", + "@doNotShowAgain": {}, + "commandHint_cuddle": "Надіслати пригортайку", + "@commandHint_cuddle": {}, + "googlyEyesContent": "{senderName} надсилає вам гугл-очі", + "@googlyEyesContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "commandHint_googly": "Надіслати кілька гугл-очей", + "@commandHint_googly": {}, + "commandHint_hug": "Надіслати обійми", + "@commandHint_hug": {}, + "cuddleContent": "{senderName} пригортається до вас", + "@cuddleContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "hugContent": "{senderName} обіймає вас", + "@hugContent": { + "type": "text", + "placeholders": { + "senderName": {} + } + }, + "wasDirectChatDisplayName": "Порожня бесіда (раніше {oldDisplayName})", + "@wasDirectChatDisplayName": { + "type": "text", + "placeholders": { + "oldDisplayName": {} + } + }, + "startFirstChat": "Розпочніть свою першу бесіду", + "@startFirstChat": {}, + "newSpaceDescription": "Простори дозволяють об'єднувати ваші бесіди та створювати приватні або загальнодоступні спільноти.", + "@newSpaceDescription": {}, + "encryptThisChat": "Зашифрувати цю бесіду", + "@encryptThisChat": {}, + "disableEncryptionWarning": "З міркувань безпеки ви не можете вимкнути шифрування в бесіді, ув якій воно було ввімкнене раніше.", + "@disableEncryptionWarning": {}, + "sorryThatsNotPossible": "Вибачте... це неможливо", + "@sorryThatsNotPossible": {}, + "deviceKeys": "Ключі пристрою:", + "@deviceKeys": {}, + "reopenChat": "Відновити бесіду", + "@reopenChat": {}, + "noOtherDevicesFound": "Інших пристроїв не знайдено", + "@noOtherDevicesFound": {}, + "noBackupWarning": "Увага! Якщо ви не ввімкнете резервне копіювання бесіди, ви втратите доступ до своїх зашифрованих повідомлень. Наполегливо радимо ввімкнути резервне копіювання бесіди перед виходом.", + "@noBackupWarning": {}, + "fileIsTooBigForServer": "Сервер повідомляє, що файл завеликий для надсилання.", + "@fileIsTooBigForServer": {}, + "fileHasBeenSavedAt": "Файл збережено в {path}", + "@fileHasBeenSavedAt": { + "type": "text", + "placeholders": { + "path": {} + } + }, + "jumpToLastReadMessage": "Перейти до останнього прочитаного повідомлення", + "@jumpToLastReadMessage": {}, + "readUpToHere": "Читати тут", + "@readUpToHere": {}, + "jump": "Перейти", + "@jump": {}, + "openLinkInBrowser": "Відкрити посилання у браузері", + "@openLinkInBrowser": {}, + "allRooms": "Усі групові бесіди", + "@allRooms": { + "type": "text", + "placeholders": {} + }, + "reportErrorDescription": "О, ні. Щось пішло не так. Якщо хочете, можете повідомити про помилку розробникам.", + "@reportErrorDescription": {}, + "report": "повідомити", + "@report": {}, + "pleaseTryAgainLaterOrChooseDifferentServer": "Спробуйте пізніше або виберіть інший сервер.", + "@pleaseTryAgainLaterOrChooseDifferentServer": {}, + "signInWithPassword": "Увійти за допомогою пароля", + "@signInWithPassword": {}, + "signInWith": "Увійти через {provider}", + "@signInWith": { + "type": "text", + "placeholders": { + "provider": {} + } + }, + "notAnImage": "Не файл зображення.", + "@notAnImage": {}, + "importNow": "Імпортувати зараз", + "@importNow": {}, + "importEmojis": "Імпорт емодзі", + "@importEmojis": {}, + "importFromZipFile": "Імпорт з файлу .zip", + "@importFromZipFile": {}, + "replace": "Замінити", + "@replace": {}, + "exportEmotePack": "Експортувати набір смайликів у форматі .zip", + "@exportEmotePack": {}, + "sendTypingNotifications": "Надсилати сповіщення про ввід тексту", + "@sendTypingNotifications": {}, + "createGroup": "Створити групу", + "@createGroup": {}, + "inviteContactToGroupQuestion": "Хочете запросити {contact} до бесіди \"{groupName}\"?", + "@inviteContactToGroupQuestion": {}, + "messagesStyle": "Повідомлення:", + "@messagesStyle": {}, + "shareInviteLink": "Надіслати запрошувальне посилання", + "@shareInviteLink": {}, + "tryAgain": "Повторіть спробу", + "@tryAgain": {}, + "setTheme": "Налаштувати тему:", + "@setTheme": {}, + "setColorTheme": "Налаштувати колірну тему:", + "@setColorTheme": {}, + "addChatDescription": "Додати опис бесіди...", + "@addChatDescription": {}, + "chatPermissions": "Дозволи бесіди", + "@chatPermissions": {}, + "chatDescription": "Опис бесіди", + "@chatDescription": {}, + "chatDescriptionHasBeenChanged": "Опис бесіди змінено", + "@chatDescriptionHasBeenChanged": {}, + "noChatDescriptionYet": "Опис бесіди ще не створено.", + "@noChatDescriptionYet": {}, + "invalidServerName": "Недійсна назва сервера", + "@invalidServerName": {}, + "optionalRedactReason": "(Необов'язково) Причина редагування цього повідомлення...", + "@optionalRedactReason": {}, + "redactedBy": "Відредаговано {username}", + "@redactedBy": { + "type": "text", + "placeholders": { + "username": {} + } + }, + "directChat": "Особисте повідомлення", + "@directChat": {}, + "redactedByBecause": "Відредаговано {username}, тому що: \"{reason}\"", + "@redactedByBecause": { + "type": "text", + "placeholders": { + "username": {}, + "reason": {} + } + }, + "profileNotFound": "Не вдалося знайти користувача на сервері. Можливо, проблема зі з'єднанням або користувач не існує.", + "@profileNotFound": {}, + "invite": "Запросити", + "@invite": {}, + "redactMessageDescription": "Повідомлення буде відредаговано для всіх учасників цієї розмови. Це не можна скасувати.", + "@redactMessageDescription": {}, + "setChatDescription": "Налаштувати опис бесіди", + "@setChatDescription": {}, + "inviteGroupChat": "📨 Запросити до групової бесіди", + "@inviteGroupChat": {}, + "invitePrivateChat": "📨 Запросити до приватної бесіди", + "@invitePrivateChat": {}, + "emoteKeyboardNoRecents": "Тут з'являться нещодавно використані смайлики...", + "@emoteKeyboardNoRecents": { + "type": "text", + "placeholders": {} + }, + "invalidInput": "Недійсний ввід!", + "@invalidInput": {}, + "wrongPinEntered": "Введено неправильний PIN! Повторіть спробу за {seconds} секунд...", + "@wrongPinEntered": { + "type": "text", + "placeholders": { + "seconds": {} + } + }, + "banUserDescription": "Користувача буде заблоковано в бесіді, і він не зможе знову увійти в неї, поки його не буде розблоковано.", + "@banUserDescription": {}, + "removeDevicesDescription": "Ви вийдете з цього пристрою і більше не зможете отримувати повідомлення.", + "@removeDevicesDescription": {}, + "unbanUserDescription": "Користувач зможе знову увійти в бесіду, якщо спробує.", + "@unbanUserDescription": {}, + "pushNotificationsNotAvailable": "Push-сповіщення недоступні", + "@pushNotificationsNotAvailable": {}, + "makeAdminDescription": "Після того, як ви зробите цього користувача адміністратором, ви, можливо, не зможете це скасувати, оскільки він матиме ті самі права, що й ви.", + "@makeAdminDescription": {}, + "archiveRoomDescription": "Бесіду буде переміщено до архіву. Інші користувачі зможуть побачити, що ви вийшли з неї.", + "@archiveRoomDescription": {}, + "hasKnocked": "{user} стукає до вас", + "@hasKnocked": { + "placeholders": { + "user": {} + } + }, + "learnMore": "Докладніше", + "@learnMore": {}, + "roomUpgradeDescription": "Після цього бесіду буде відтворено з новою версією кімнати. Усі учасники отримають сповіщення, що їм потрібно перейти до нової бесіди. Ви можете дізнатися більше про версії кімнат на https://spec.matrix.org/latest/rooms/", + "@roomUpgradeDescription": {}, + "pleaseEnterANumber": "Введіть число більше ніж 0", + "@pleaseEnterANumber": {}, + "kickUserDescription": "Користувача вигнали з бесіди, але не заблокували. До загальнодоступних бесід користувач може приєднатися будь-коли.", + "@kickUserDescription": {}, + "blockListDescription": "Ви можете заблокувати користувачів, які вас турбують. Ви не зможете отримувати жодних повідомлень або запрошень до кімнати від користувачів з вашого персонального списку блокування.", + "@blockListDescription": {}, + "createGroupAndInviteUsers": "Створити групу та запросити користувачів", + "@createGroupAndInviteUsers": {}, + "startConversation": "Розпочати розмову", + "@startConversation": {}, + "blockedUsers": "Заблоковані користувачі", + "@blockedUsers": {}, + "groupCanBeFoundViaSearch": "Групу можна знайти через пошук", + "@groupCanBeFoundViaSearch": {}, + "noUsersFoundWithQuery": "На жаль, не знайдено жодного користувача з запитом \"{query}\".Перевірте, чи не було допущено помилки.", + "@noUsersFoundWithQuery": { + "type": "text", + "placeholders": { + "query": {} + } + }, + "block": "блокування", + "@block": {}, + "yourGlobalUserIdIs": "Ваш глобальний ID користувача: ", + "@yourGlobalUserIdIs": {}, + "commandHint_sendraw": "Надіслати необроблений json", + "@commandHint_sendraw": {}, + "wrongRecoveryKey": "Вибачте... схоже, це неправильний ключ відновлення.", + "@wrongRecoveryKey": {}, + "blockUsername": "Ігнорувати ім'я користувача", + "@blockUsername": {}, + "groupName": "Назва групи", + "@groupName": {}, + "databaseMigrationTitle": "Базу даних оптимізовано", + "@databaseMigrationTitle": {}, + "searchChatsRooms": "Пошук для #chats, @users...", + "@searchChatsRooms": {}, + "databaseMigrationBody": "Зачекайте, будь ласка. Це може тривати деякий час.", + "@databaseMigrationBody": {}, + "thisDevice": "Цей пристрій:", + "@thisDevice": {}, + "publicSpaces": "Загальнодоступний простір", + "@publicSpaces": {}, + "passwordIsWrong": "Введений пароль неправильний", + "@passwordIsWrong": {}, + "pleaseEnterYourCurrentPassword": "Введіть поточний пароль", + "@pleaseEnterYourCurrentPassword": {}, + "publicLink": "Загальнодоступне посилання", + "@publicLink": {}, + "nothingFound": "Нічого не знайдено...", + "@nothingFound": {}, + "decline": "Відхилити", + "@decline": {}, + "newPassword": "Новий пароль", + "@newPassword": {}, + "passwordsDoNotMatch": "Паролі відрізняються", + "@passwordsDoNotMatch": {}, + "subspace": "Підпростір", + "@subspace": {}, + "select": "Вибрати", + "@select": {}, + "pleaseChooseAStrongPassword": "Виберіть надійний пароль", + "@pleaseChooseAStrongPassword": {}, + "addChatOrSubSpace": "Додати бесіду або підпростір", + "@addChatOrSubSpace": {}, + "leaveEmptyToClearStatus": "Лишіть порожнім, щоб оновити статус.", + "@leaveEmptyToClearStatus": {}, + "joinSpace": "Приєднатися до простору", + "@joinSpace": {}, + "searchForUsers": "Пошук @користувачів...", + "@searchForUsers": {}, + "sessionLostBody": "Ваш сеанс втрачено. Будь ласка, повідомте про цю помилку розробникам за адресою {url}. Текст помилки: {error}", + "@sessionLostBody": { + "type": "text", + "placeholders": { + "url": {}, + "error": {} + } + }, + "databaseBuildErrorBody": "Не вдалося створити базу даних SQlite. Застосунок намагається використовувати стару базу даних. Будь ласка, повідомте про цю помилку розробникам за адресою {url}. Текст помилки: {error}", + "@databaseBuildErrorBody": { + "type": "text", + "placeholders": { + "url": {}, + "error": {} + } + }, + "initAppError": "Виникла помилка під час запуску застосунку", + "@initAppError": {}, + "restoreSessionBody": "Наразі застосунок намагається відновити ваш сеанс з резервної копії. Будь ласка, повідомте про цю помилку розробникам за адресою {url}. Текст помилки: {error}", + "@restoreSessionBody": { + "type": "text", + "placeholders": { + "url": {}, + "error": {} + } + }, + "youInvitedToBy": "📩 Вас запрошено за посиланням на:\n{alias}", + "@youInvitedToBy": { + "placeholders": { + "alias": {} + } + }, + "acceptedKeyVerification": "{sender} погоджується звірити ключі", + "@acceptedKeyVerification": { + "type": "text", + "placeholders": { + "sender": {} + } + }, + "canceledKeyVerification": "{sender} скасовує звірення ключів", + "@canceledKeyVerification": { + "type": "text", + "placeholders": { + "sender": {} + } + }, + "requestedKeyVerification": "{sender} просить звірити ключі", + "@requestedKeyVerification": { + "type": "text", + "placeholders": { + "sender": {} + } + }, + "transparent": "Прозорий", + "@transparent": {}, + "sendReadReceiptsDescription": "Інші учасники бесіди бачитимуть, що ви прочитали повідомлення.", + "@sendReadReceiptsDescription": {}, + "formattedMessages": "Форматовані повідомлення", + "@formattedMessages": {}, + "forwardMessageTo": "Переслати повідомлення до {roomName}?", + "@forwardMessageTo": { + "type": "text", + "placeholders": { + "roomName": {} + } + }, + "sendReadReceipts": "Надіслати підтвердження прочитання", + "@sendReadReceipts": {}, + "sendTypingNotificationsDescription": "Інші учасники бесіди бачитимуть, коли ви набираєте нове повідомлення.", + "@sendTypingNotificationsDescription": {}, + "formattedMessagesDescription": "Показувати розширений вміст повідомлень, наприклад, жирний текст, використовуючи markdown.", + "@formattedMessagesDescription": {}, + "verifyOtherUser": "🔐 Звірити іншого користувача", + "@verifyOtherUser": {}, + "verifyOtherUserDescription": "Якщо ви звіряєте іншого користувача, ви можете бути впевнені, що знаєте, кому ви насправді пишете. 💪\n\nКоли ви почнете звірення, ви та інший користувач побачите спливне вікно в застосунку. Там ви побачите набір смайликів або чисел, які вам потрібно буде порівняти між собою.\n\nНайкращий спосіб зробити це — зустрітися або розпочати відеовиклик. 👭", + "@verifyOtherUserDescription": {}, + "verifyOtherDeviceDescription": "Коли ви звіряєте інший пристрій, ці пристрої можуть обмінюватися ключами, підвищуючи вашу загальну безпеку. 💪 Коли ви розпочнете звірення, в застосунку на обох пристроях з'явиться спливне вікно. Там ви побачите набір смайликів або чисел, які вам потрібно буде порівняти між собою. Найкраще мати обидва пристрої під рукою перед початком звірення. 🤳", + "@verifyOtherDeviceDescription": {}, + "verifyOtherDevice": "🔐 Звірити інший пристрій", + "@verifyOtherDevice": {}, + "completedKeyVerification": "{sender} завершує звірення ключів", + "@completedKeyVerification": { + "type": "text", + "placeholders": { + "sender": {} + } + }, + "isReadyForKeyVerification": "{sender} готовий до звірення ключів", + "@isReadyForKeyVerification": { + "type": "text", + "placeholders": { + "sender": {} + } + }, + "startedKeyVerification": "{sender} розпочинає звірення ключів", + "@startedKeyVerification": { + "type": "text", + "placeholders": { + "sender": {} + } + }, + "presenceStyle": "Присутність:", + "@presenceStyle": { + "type": "text", + "placeholders": {} + }, + "presencesToggle": "Показувати повідомлення про стан від інших користувачів", + "@presencesToggle": { + "type": "text", + "placeholders": {} + }, + "hidePresences": "Сховати список станів?", + "@hidePresences": {}, + "incomingMessages": "Вхідні повідомлення", + "@incomingMessages": {} } diff --git a/assets/l10n/intl_zh.arb b/assets/l10n/intl_zh.arb index 36fca52005..e92dd66832 100644 --- a/assets/l10n/intl_zh.arb +++ b/assets/l10n/intl_zh.arb @@ -2298,7 +2298,7 @@ "path": {} } }, - "reportErrorDescription": "😭哦不。出了点差错。如果你愿意,可以向开发人员报告此错误。", + "reportErrorDescription": "😭 哦不。出了点差错。如果你愿意,可以向开发人员报告此错误。", "@reportErrorDescription": {}, "noBackupWarning": "警告!如果不启用聊天备份,你将无法访问加密消息。强烈建议在注销前先启用聊天备份。", "@noBackupWarning": {}, @@ -2453,5 +2453,152 @@ "searchChatsRooms": "搜索 #聊天,@用户…", "@searchChatsRooms": {}, "databaseMigrationBody": "请稍候。可能需要稍等片刻。", - "@databaseMigrationBody": {} + "@databaseMigrationBody": {}, + "thisDevice": "此设备:", + "@thisDevice": {}, + "publicSpaces": "公开空间", + "@publicSpaces": {}, + "passwordIsWrong": "你输入的密码有误", + "@passwordIsWrong": {}, + "pleaseEnterYourCurrentPassword": "请输入你当前的密码", + "@pleaseEnterYourCurrentPassword": {}, + "publicLink": "公开链接", + "@publicLink": {}, + "nothingFound": "未找到任何内容…", + "@nothingFound": {}, + "decline": "拒绝", + "@decline": {}, + "newPassword": "新的密码", + "@newPassword": {}, + "passwordsDoNotMatch": "密码不匹配", + "@passwordsDoNotMatch": {}, + "subspace": "子空间", + "@subspace": {}, + "select": "选择", + "@select": {}, + "pleaseChooseAStrongPassword": "请选择一个强密码", + "@pleaseChooseAStrongPassword": {}, + "addChatOrSubSpace": "添加聊天或子空间", + "@addChatOrSubSpace": {}, + "leaveEmptyToClearStatus": "留空以清除你的状态。", + "@leaveEmptyToClearStatus": {}, + "joinSpace": "加入空间", + "@joinSpace": {}, + "searchForUsers": "搜索 @用户…", + "@searchForUsers": {}, + "databaseBuildErrorBody": "无法构建 SQLite 数据库。目前应用尝试使用旧数据库。请将此错误报告给开发者,网址为 {url}。错误消息为:{error}", + "@databaseBuildErrorBody": { + "type": "text", + "placeholders": { + "url": {}, + "error": {} + } + }, + "initAppError": "在初始化应用时发生错误", + "@initAppError": {}, + "sessionLostBody": "你的会话已丢失。请将此错误报告给开发者,网址为 {url}。错误消息为:{error}", + "@sessionLostBody": { + "type": "text", + "placeholders": { + "url": {}, + "error": {} + } + }, + "restoreSessionBody": "应用现在尝试从备份中恢复你的会话。请将此错误报告给开发者,网址为 {url}。错误消息为:{error}", + "@restoreSessionBody": { + "type": "text", + "placeholders": { + "url": {}, + "error": {} + } + }, + "sendTypingNotificationsDescription": "聊天中的其他参与者可以看到你正在输入新消息。", + "@sendTypingNotificationsDescription": {}, + "formattedMessagesDescription": "使用 Markdown 显示富文本内容,例如加粗文本。", + "@formattedMessagesDescription": {}, + "verifyOtherUserDescription": "如果你验证了其他用户,就可以确保你清楚自己正在与谁进行通信。💪\n\n当你开始验证时,你和其他用户将在应用中看到一个弹出窗口。然后你会看到一系列表情符号或数字,你和其他用户需要比较它们是否一致。\n\n最好的方式是线下会面或开始视频通话。👭", + "@verifyOtherUserDescription": {}, + "verifyOtherDeviceDescription": "当你验证另一个设备时,这些设备可以交换密钥,从而提高整体安全性。 💪 当你开始验证时,两个设备上的应用都将显示一个弹出窗口。然后你会看到一系列表情符号或数字,你需要比较两个设备上显示的内容。在开始验证之前,最好将两个设备都放在手边。🤳", + "@verifyOtherDeviceDescription": {}, + "canceledKeyVerification": "{sender} 取消了密钥验证", + "@canceledKeyVerification": { + "type": "text", + "placeholders": { + "sender": {} + } + }, + "sendReadReceipts": "发送已读回执", + "@sendReadReceipts": {}, + "formattedMessages": "格式化的消息", + "@formattedMessages": {}, + "verifyOtherDevice": "🔐 验证其它设备", + "@verifyOtherDevice": {}, + "verifyOtherUser": "🔐 验证其他用户", + "@verifyOtherUser": {}, + "forwardMessageTo": "转发消息至 {roomName} ?", + "@forwardMessageTo": { + "type": "text", + "placeholders": { + "roomName": {} + } + }, + "sendReadReceiptsDescription": "聊天中的其他参与者可以看到你是否读过消息。", + "@sendReadReceiptsDescription": {}, + "acceptedKeyVerification": "{sender} 接受了密钥验证", + "@acceptedKeyVerification": { + "type": "text", + "placeholders": { + "sender": {} + } + }, + "isReadyForKeyVerification": "{sender} 已准备好进行密钥验证", + "@isReadyForKeyVerification": { + "type": "text", + "placeholders": { + "sender": {} + } + }, + "completedKeyVerification": "{sender} 完成了密钥验证", + "@completedKeyVerification": { + "type": "text", + "placeholders": { + "sender": {} + } + }, + "requestedKeyVerification": "{sender} 请求了密钥验证", + "@requestedKeyVerification": { + "type": "text", + "placeholders": { + "sender": {} + } + }, + "startedKeyVerification": "{sender} 开始了密钥验证", + "@startedKeyVerification": { + "type": "text", + "placeholders": { + "sender": {} + } + }, + "transparent": "透明", + "@transparent": {}, + "youInvitedToBy": "📩 你已通过链接被邀请到:\n{alias}", + "@youInvitedToBy": { + "placeholders": { + "alias": {} + } + }, + "presencesToggle": "显示其他用户的状态消息", + "@presencesToggle": { + "type": "text", + "placeholders": {} + }, + "presenceStyle": "是否在线:", + "@presenceStyle": { + "type": "text", + "placeholders": {} + }, + "hidePresences": "隐藏状态列表?", + "@hidePresences": {}, + "incomingMessages": "传入消息", + "@incomingMessages": {} } diff --git a/assets/typing.gif b/assets/typing.gif deleted file mode 100644 index 7c8154721c..0000000000 Binary files a/assets/typing.gif and /dev/null differ diff --git a/assets/typing.svg b/assets/typing.svg deleted file mode 100644 index a126464653..0000000000 --- a/assets/typing.svg +++ /dev/null @@ -1,80 +0,0 @@ - - - - - - - - - - - - - - diff --git a/docs/.well-known/org.flathub.VerifiedApps.txt b/docs/.well-known/org.flathub.VerifiedApps.txt new file mode 100644 index 0000000000..a9a5eb471e --- /dev/null +++ b/docs/.well-known/org.flathub.VerifiedApps.txt @@ -0,0 +1,2 @@ +# im.fluffychat.Fluffychat +8b25b37b-f160-4350-b4f6-9a04554e8f9e \ No newline at end of file diff --git a/docs/ZenKurenaido-Regular.ttf b/docs/ZenKurenaido-Regular.ttf deleted file mode 100644 index fe08f0a85c..0000000000 Binary files a/docs/ZenKurenaido-Regular.ttf and /dev/null differ diff --git a/docs/bg.svg b/docs/bg.svg deleted file mode 100644 index 362754b44d..0000000000 --- a/docs/bg.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/docs/code_style.md b/docs/code_style.md deleted file mode 100644 index 712830d545..0000000000 --- a/docs/code_style.md +++ /dev/null @@ -1,138 +0,0 @@ -# Code Style - -FluffyChat tries to be as minimal as possible even in the code style. We try to keep the code clean, simple and easy to read. The source code of the app is under `/lib` with the main entry point `/lib/main.dart`. - -### Directory Structure: - - -- /lib - - /config - - app_config.dart - - ...Constants, styles and other configurations - - /utils - - handy_function.dart - - ...Helper functions and extensions - - /pages - - /chat - - chat.dart - - chat_view.dart - - /chat_list - - chat_list.dart - - chat_list_view.dart - - ...The pages of the app separated in Controllers and Views - - /widgets - - /layouts - - ...Custom widgets created for this project - - main.dart - - -Most of the business model is in the Famedly Matrix Dart SDK. We try to not keep a model inside of the source code but extend it under `/utils`. - -### Separation of Controllers and Views - -We split views and controller logic with stateful widgets as controller where the build method just builds a stateless widget which receives the state as the only parameter. A common controller would look like this: - -```dart -// /lib/controller/enter_name_controller.dart -import 'package:flutter/material.dart'; - -class EnterName extends StatefulWidget { - @override - EnterNameController createState() => EnterNameController(); -} - -class EnterNameController extends State { - final TextEditingController textEditingController = TextEditingController(); - String name = 'Unknown'; - - /// Changes the name with the content in the textfield. If the textfield is - /// empty, this breaks up and displays a SnackBar. - void setNameAction() { - if (textEditingController.text.isEmpty) { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text('You have not entered your name'), - ), - ); - return; - } - setState(() => name = textEditingController.text); - } - - @override - Widget build(BuildContext context) => EnterNameView(this); -} -``` - -So we have a controller for a `EnterName` view which as a `TextEditingController`, a state `name` and an action `void setNameAction()`. Actions must always be methods of a type, that we dont need to pass parameters in the corresponding view class and must have dartdoc comments. - -The view class could look like this: - -```dart -// /lib/views/enter_name_view.dart -import 'package:flutter/material.dart'; - -class EnterNameView extends StatelessWidget { - final EnterNameController controller; - - const EnterNameView(this.controller, {Key key}) : super(key: key); - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: Text('Your name: ${controller.name}'), - ), - body: Center( - child: TextField( - controller: controller.textEditingController, - ), - ), - floatingActionButton: FloatingActionButton( - onPressed: controller.setNameAction, - child: Icon(Icons.save), - ), - ); - } -} -``` - -Views should just contain code which describes the view. All other parameters or logic should be in the controller. The job of the view class is just to take the current state and build the widget tree and pipe the callbacks back. If there is any calulation necessary which is not solveable as a simple if-else or switch statement, it should be done in an external helper function unter `/lib/utils/`. - -All file names must be lower_snake_case. All views must have a `View` suffix and all controller must have a `Controller` suffix. Widgets may have a controller too but they should pass the callbacks back to the view where possible. Calling one line methods directly in the view is only recommended if there is no need to pass a parameter. - -To perform an action on state initialization we use the initState method: -```dart -@override - void initState() { - // TODO: implement initState - super.initState(); - } -``` - -And the dispose method to perform an action on disposing: -```dart -@override - void dispose() { - // TODO: implement dispose - super.dispose(); - } -``` - -To run code after the widget was created first we use the WidgetBindings in the initState: -```dart -@override - void initState() { - WidgetsBinding.instance!.addPostFrameCallback((_) { - // Do something when build is finished - }); - super.initState(); - } -``` - -### Formatting - -We do not allow code with wrong formatting. Please run `flutter format lib` if your IDE doesn't do this automatically. - -### Code Analyzis - -We do not allow codes with dart errors or warnings. We use the [pedantic](https://pub.dev/packages/pedantic) package for static code analysis with additional rules under `analysis_options.yaml`. diff --git a/docs/fdroid_repo.md b/docs/fdroid_repo.md deleted file mode 100644 index 77790e56ff..0000000000 --- a/docs/fdroid_repo.md +++ /dev/null @@ -1,56 +0,0 @@ -# F-Droid Repository - -Our own F-Droid repository contains the Google Services which is not possible in the main F-Droid repository. Release candidates -are also published on it. - -## Add Repository to F-Droid - -Easiest way to add the Repository is to either **scan the QR-Code** or if you are on your phone **directly click it**. - - - - - - -### If the QR-Code doesn't work: - -First check if you have f-droid installed. If not you can get it from: [https://f-droid.org/](https://f-droid.org/). -After you made sure you installed it and you didn't have it installed before you can try again the QR-Code. -If this still isn't working follow the next steps: - -1. Open the f-droid App -2. Go to the `Settings` Tab in the Bottom bar -3. Click the `Repositories` Action -4. Click on the plus sign at the top. -5. Fill in `https://fluffychat.im/repo/stable/repo/` into the top field and `5EDB5C4395B2F2D9BA682F6A1D275170CCE5365A6FA27D2220EA8D52A6D95F07` in the bottom field. - -## What is the fingerprint? - -The fingerprint of the Repository is: `5EDB5C4395B2F2D9BA682F6A1D275170CCE5365A6FA27D2220EA8D52A6D95F07` - -# Nightly Repository - -## Add Repository to F-Droid - -Easiest way to add the Repository is to either **scan the QR-Code** or if you are on your phone **directly click** it. - - - - - - -### If the QR-Code doesn't work: - -First check if you have f-droid installed. If not you can get it from: [https://f-droid.org/](https://f-droid.org/). -After you made sure you installed it and you didn't have it installed before you can try again the QR-Code. -If this still isn't working follow the next steps: - -1. Open the f-droid App -2. Go to the `Settings` Tab in the Bottom bar -3. Click the `Repositories` Action -4. Click on the plus sign at the top. -5. Fill in `https://fluffychat.im/repo/nightly/repo/` into the top field and `21A469657300576478B623DF99D8EB889A80BCD939ACA60A4074741BEAEC397D` in the bottom field. - -## What is the fingerprint? - -The fingerprint of the Repository is: `21A469657300576478B623DF99D8EB889A80BCD939ACA60A4074741BEAEC397D` diff --git a/docs/feature1.gif b/docs/feature1.gif new file mode 100644 index 0000000000..db6c8beb8a Binary files /dev/null and b/docs/feature1.gif differ diff --git a/docs/feature2.gif b/docs/feature2.gif new file mode 100644 index 0000000000..d6cf974b23 Binary files /dev/null and b/docs/feature2.gif differ diff --git a/docs/feature3.gif b/docs/feature3.gif new file mode 100644 index 0000000000..cd56dc5328 Binary files /dev/null and b/docs/feature3.gif differ diff --git a/docs/feature4.gif b/docs/feature4.gif new file mode 100644 index 0000000000..4f1c35dfdd Binary files /dev/null and b/docs/feature4.gif differ diff --git a/docs/feature5.gif b/docs/feature5.gif new file mode 100644 index 0000000000..b301d8fa0c Binary files /dev/null and b/docs/feature5.gif differ diff --git a/docs/feature6.gif b/docs/feature6.gif new file mode 100644 index 0000000000..d9fdba8d3e Binary files /dev/null and b/docs/feature6.gif differ diff --git a/docs/feature7.gif b/docs/feature7.gif new file mode 100644 index 0000000000..ced2184e1a Binary files /dev/null and b/docs/feature7.gif differ diff --git a/docs/feature8.gif b/docs/feature8.gif new file mode 100644 index 0000000000..95bf4e8171 Binary files /dev/null and b/docs/feature8.gif differ diff --git a/docs/feature9.gif b/docs/feature9.gif new file mode 100644 index 0000000000..a05001d089 Binary files /dev/null and b/docs/feature9.gif differ diff --git a/docs/index.html b/docs/index.html index cbd27caa50..0d82ae5187 100644 --- a/docs/index.html +++ b/docs/index.html @@ -17,25 +17,39 @@ - - -

- Fluffy - Chat -

- - -
+
+ +
+ FluffyChat Logo +

The cutest messenger in [matrix] +

+ + Mobile and desktop screenshots + + -
- - - - - - - - - - - - - - - - - - - +
+
+ Animated dancing woman +

Easy to use

+

FluffyChat is designed to be as easy to use as possible. No one + should be left behind.

+
+
+ Animated pencil +

Material You

+

The well polished design is based on Material You and works great on + all platforms.

+
+
+ Animated mechanical arm +

Secure

+

With end-to-end encryption, cross-signing and encrypted backups, + FluffyChat is one of the most secure messenger out there.

+
+ + +
+ Animated planet earth +

Decentral

+

You can choose the server you want to use or + even self-host your own!

+
+
+ Animated bell +

Push Notifications

+

You can choose between Firebase Cloud Messaging or the more privacy + focused Unified Push.

+
+
+ Animated rocket +

Spaces

+

With spaces you can join or create a community which organizes chats + and users. Using sub-spaces you can even nest your communities.

+
+ + +
+ Animated glass sphere +

Video calls

+

Still an experimental feature but you can already try out video and + audio calls, compatible with other [matrix] clients.

+
+
+ Animated chick +

Stickers

+

Create your own sticker sets and share them with your friends. You + can even use them as inline emojis.

+
+
+ Animated whoa emoji +

Compatible

+

FluffyChat is compatible with any other [matrix] client like Element, + Nheko, Cinny + or NeoChat. +

+
-
- Source - code - - - Privacy - - - Changelog - - - Translations - - - FluffyChat F-Droid - repository - - - Contact - - - Created - by Krille Fear +
+
- + \ No newline at end of file diff --git a/docs/info-logo.png b/docs/info-logo.png new file mode 100644 index 0000000000..ceb42f09b5 Binary files /dev/null and b/docs/info-logo.png differ diff --git a/docs/mastodon.svg b/docs/mastodon.svg new file mode 100644 index 0000000000..0f8baebfc9 --- /dev/null +++ b/docs/mastodon.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/docs/qr-nightly.svg b/docs/qr-nightly.svg deleted file mode 100644 index cabc07a4bd..0000000000 --- a/docs/qr-nightly.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/qr-stable.svg b/docs/qr-stable.svg deleted file mode 100644 index e6560a0803..0000000000 --- a/docs/qr-stable.svg +++ /dev/null @@ -1,543 +0,0 @@ - - - - -Created by potrace 1.16, written by Peter Selinger 2001-2019 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ios/Podfile b/ios/Podfile index a069cc7946..c8df069d31 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -38,6 +38,12 @@ post_install do |installer| installer.pods_project.targets.each do |target| flutter_additional_ios_build_settings(target) target.build_configurations.each do |config| + # ensure all dependencies are using SQLCipher instead of SQLite + xcconfig_path = config.base_configuration_reference.real_path + xcconfig = File.read(xcconfig_path) + new_xcconfig = xcconfig.sub(' -l"sqlite3"', '') + File.open(xcconfig_path, "w") { |file| file << new_xcconfig } + config.build_settings['ENABLE_BITCODE'] = 'NO' # see https://github.com/flutter-webrtc/flutter-webrtc/issues/1054 diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 53f589e158..20a12af44a 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -232,7 +232,7 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 1240; - LastUpgradeCheck = 1430; + LastUpgradeCheck = 1510; ORGANIZATIONNAME = ""; TargetAttributes = { 97C146ED1CF9000F007C117D = { diff --git a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index a6b826db27..5e31d3d342 100644 --- a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -1,6 +1,6 @@ defaultPageBuilder( context, + state, const HomeserverPicker(), ), redirect: loggedInRedirect, @@ -85,6 +86,7 @@ abstract class AppRoutes { path: 'login', pageBuilder: (context, state) => defaultPageBuilder( context, + state, const Login(), ), redirect: loggedInRedirect, @@ -94,6 +96,7 @@ abstract class AppRoutes { path: 'signup', pageBuilder: (context, state) => defaultPageBuilder( context, + state, const SignupPage(), ), redirect: loggedInRedirect, @@ -105,6 +108,7 @@ abstract class AppRoutes { path: '/logs', pageBuilder: (context, state) => defaultPageBuilder( context, + state, const LogViewer(), ), ), @@ -113,6 +117,7 @@ abstract class AppRoutes { path: '/user_age', pageBuilder: (context, state) => defaultPageBuilder( context, + state, const PUserAge(), ), redirect: loggedOutRedirect, @@ -121,6 +126,7 @@ abstract class AppRoutes { ShellRoute( pageBuilder: (context, state, child) => defaultPageBuilder( context, + state, FluffyThemes.isColumnMode(context) && state.fullPath?.startsWith('/rooms/settings') == false ? TwoColumnLayout( @@ -141,6 +147,7 @@ abstract class AppRoutes { path: '/spaces/:roomid', pageBuilder: (context, state) => defaultPageBuilder( context, + state, ChatDetails( roomId: state.pathParameters['roomid']!, ), @@ -151,6 +158,7 @@ abstract class AppRoutes { path: '/join_with_link', pageBuilder: (context, state) => defaultPageBuilder( context, + state, const JoinClassWithLink(), ), redirect: loggedOutRedirect, @@ -161,6 +169,7 @@ abstract class AppRoutes { redirect: loggedOutRedirect, pageBuilder: (context, state) => defaultPageBuilder( context, + state, FluffyThemes.isColumnMode(context) ? const EmptyPage() : ChatList( @@ -173,6 +182,7 @@ abstract class AppRoutes { path: 'mylearning', pageBuilder: (context, state) => defaultPageBuilder( context, + state, const StudentAnalyticsPage(), ), redirect: loggedOutRedirect, @@ -181,6 +191,7 @@ abstract class AppRoutes { path: 'analytics', pageBuilder: (context, state) => defaultPageBuilder( context, + state, const AnalyticsClassList(), ), redirect: loggedOutRedirect, @@ -190,6 +201,7 @@ abstract class AppRoutes { redirect: loggedOutRedirect, pageBuilder: (context, state) => defaultPageBuilder( context, + state, const ClassAnalyticsPage(), ), ), @@ -200,6 +212,7 @@ abstract class AppRoutes { path: 'archive', pageBuilder: (context, state) => defaultPageBuilder( context, + state, const Archive(), ), routes: [ @@ -207,6 +220,7 @@ abstract class AppRoutes { path: ':roomid', pageBuilder: (context, state) => defaultPageBuilder( context, + state, ChatPage( roomId: state.pathParameters['roomid']!, ), @@ -220,6 +234,7 @@ abstract class AppRoutes { path: 'newprivatechat', pageBuilder: (context, state) => defaultPageBuilder( context, + state, const NewPrivateChat(), ), redirect: loggedOutRedirect, @@ -231,6 +246,7 @@ abstract class AppRoutes { // Pangea# pageBuilder: (context, state) => defaultPageBuilder( context, + state, const NewGroup(), ), redirect: loggedOutRedirect, @@ -239,6 +255,7 @@ abstract class AppRoutes { path: ':spaceid', pageBuilder: (context, state) => defaultPageBuilder( context, + state, const NewGroup(), ), redirect: loggedOutRedirect, @@ -249,6 +266,7 @@ abstract class AppRoutes { path: 'newspace', pageBuilder: (context, state) => defaultPageBuilder( context, + state, const NewSpace(), ), redirect: loggedOutRedirect, @@ -258,6 +276,7 @@ abstract class AppRoutes { path: 'newspace/:newexchange', pageBuilder: (context, state) => defaultPageBuilder( context, + state, const NewSpace(), ), redirect: loggedOutRedirect, @@ -266,6 +285,7 @@ abstract class AppRoutes { path: 'join_exchange/:exchangeid', pageBuilder: (context, state) => defaultPageBuilder( context, + state, const AddExchangeToClass(), ), redirect: loggedOutRedirect, @@ -274,6 +294,7 @@ abstract class AppRoutes { path: 'partner', pageBuilder: (context, state) => defaultPageBuilder( context, + state, const FindPartner(), ), redirect: loggedOutRedirect, @@ -282,6 +303,7 @@ abstract class AppRoutes { ShellRoute( pageBuilder: (context, state, child) => defaultPageBuilder( context, + state, FluffyThemes.isColumnMode(context) ? TwoColumnLayout( mainView: const Settings(), @@ -295,6 +317,7 @@ abstract class AppRoutes { path: 'settings', pageBuilder: (context, state) => defaultPageBuilder( context, + state, FluffyThemes.isColumnMode(context) ? const EmptyPage() : const Settings(), @@ -304,6 +327,7 @@ abstract class AppRoutes { path: 'notifications', pageBuilder: (context, state) => defaultPageBuilder( context, + state, const SettingsNotifications(), ), redirect: loggedOutRedirect, @@ -312,6 +336,7 @@ abstract class AppRoutes { path: 'style', pageBuilder: (context, state) => defaultPageBuilder( context, + state, const SettingsStyle(), ), redirect: loggedOutRedirect, @@ -320,6 +345,7 @@ abstract class AppRoutes { path: 'devices', pageBuilder: (context, state) => defaultPageBuilder( context, + state, const DevicesSettings(), ), redirect: loggedOutRedirect, @@ -328,6 +354,7 @@ abstract class AppRoutes { path: 'chat', pageBuilder: (context, state) => defaultPageBuilder( context, + state, const SettingsChat(), ), routes: [ @@ -335,6 +362,7 @@ abstract class AppRoutes { path: 'emotes', pageBuilder: (context, state) => defaultPageBuilder( context, + state, const EmotesSettings(), ), ), @@ -366,6 +394,7 @@ abstract class AppRoutes { redirect: loggedOutRedirect, pageBuilder: (context, state) => defaultPageBuilder( context, + state, const SettingsSecurity(), ), routes: [ @@ -374,6 +403,7 @@ abstract class AppRoutes { pageBuilder: (context, state) { return defaultPageBuilder( context, + state, const SettingsPassword(), ); }, @@ -384,6 +414,7 @@ abstract class AppRoutes { pageBuilder: (context, state) { return defaultPageBuilder( context, + state, SettingsIgnoreList( initialUserId: state.extra?.toString(), ), @@ -395,6 +426,7 @@ abstract class AppRoutes { path: '3pid', pageBuilder: (context, state) => defaultPageBuilder( context, + state, const Settings3Pid(), ), redirect: loggedOutRedirect, @@ -406,6 +438,7 @@ abstract class AppRoutes { path: 'learning', pageBuilder: (context, state) => defaultPageBuilder( context, + state, const SettingsLearning(), ), redirect: loggedOutRedirect, @@ -414,6 +447,7 @@ abstract class AppRoutes { path: 'subscription', pageBuilder: (context, state) => defaultPageBuilder( context, + state, const SubscriptionManagement(), ), redirect: loggedOutRedirect, @@ -428,6 +462,7 @@ abstract class AppRoutes { path: ':roomid', pageBuilder: (context, state) => defaultPageBuilder( context, + state, ChatPage( roomId: state.pathParameters['roomid']!, shareText: state.uri.queryParameters['body'], @@ -440,6 +475,7 @@ abstract class AppRoutes { // path: 'encryption', // pageBuilder: (context, state) => defaultPageBuilder( // context, + // state, // const ChatEncryptionSettings(), // ), // redirect: loggedOutRedirect, @@ -449,6 +485,7 @@ abstract class AppRoutes { path: 'invite', pageBuilder: (context, state) => defaultPageBuilder( context, + state, InvitationSelection( roomId: state.pathParameters['roomid']!, ), @@ -459,6 +496,7 @@ abstract class AppRoutes { path: 'details', pageBuilder: (context, state) => defaultPageBuilder( context, + state, ChatDetails( roomId: state.pathParameters['roomid']!, ), @@ -468,6 +506,7 @@ abstract class AppRoutes { path: 'members', pageBuilder: (context, state) => defaultPageBuilder( context, + state, ChatMembersPage( roomId: state.pathParameters['roomid']!, ), @@ -478,6 +517,7 @@ abstract class AppRoutes { path: 'permissions', pageBuilder: (context, state) => defaultPageBuilder( context, + state, const ChatPermissionsSettings(), ), redirect: loggedOutRedirect, @@ -487,6 +527,7 @@ abstract class AppRoutes { path: 'class_settings', pageBuilder: (context, state) => defaultPageBuilder( context, + state, const ClassSettingsPage(), ), redirect: loggedOutRedirect, @@ -496,6 +537,7 @@ abstract class AppRoutes { path: 'invite', pageBuilder: (context, state) => defaultPageBuilder( context, + state, InvitationSelection( roomId: state.pathParameters['roomid']!, ), @@ -506,6 +548,7 @@ abstract class AppRoutes { path: 'multiple_emotes', pageBuilder: (context, state) => defaultPageBuilder( context, + state, const MultipleEmotesSettings(), ), redirect: loggedOutRedirect, @@ -514,6 +557,7 @@ abstract class AppRoutes { path: 'emotes', pageBuilder: (context, state) => defaultPageBuilder( context, + state, const EmotesSettings(), ), redirect: loggedOutRedirect, @@ -522,6 +566,7 @@ abstract class AppRoutes { path: 'emotes/:state_key', pageBuilder: (context, state) => defaultPageBuilder( context, + state, const EmotesSettings(), ), redirect: loggedOutRedirect, @@ -537,17 +582,23 @@ abstract class AppRoutes { ), ]; - static Page defaultPageBuilder(BuildContext context, Widget child) => - CustomTransitionPage( - child: child, - transitionsBuilder: (context, animation, secondaryAnimation, child) => - FluffyThemes.isColumnMode(context) - ? FadeTransition(opacity: animation, child: child) - : CupertinoPageTransition( - primaryRouteAnimation: animation, - secondaryRouteAnimation: secondaryAnimation, - linearTransition: false, - child: child, - ), - ); + static Page defaultPageBuilder( + BuildContext context, + GoRouterState state, + Widget child, + ) => + FluffyThemes.isColumnMode(context) + ? CustomTransitionPage( + key: state.pageKey, + restorationId: state.pageKey.value, + child: child, + transitionsBuilder: + (context, animation, secondaryAnimation, child) => + FadeTransition(opacity: animation, child: child), + ) + : MaterialPage( + key: state.pageKey, + restorationId: state.pageKey.value, + child: child, + ); } diff --git a/lib/config/setting_keys.dart b/lib/config/setting_keys.dart index 63a3e6b59a..0766249bfa 100644 --- a/lib/config/setting_keys.dart +++ b/lib/config/setting_keys.dart @@ -17,13 +17,17 @@ abstract class SettingKeys { static const String unifiedPushRegistered = 'chat.fluffy.unifiedpush.registered'; static const String unifiedPushEndpoint = 'chat.fluffy.unifiedpush.endpoint'; - static const String notificationCurrentIds = 'chat.fluffy.notification_ids'; static const String ownStatusMessage = 'chat.fluffy.status_msg'; static const String dontAskForBootstrapKey = 'chat.fluffychat.dont_ask_bootstrap'; static const String autoplayImages = 'chat.fluffy.autoplay_images'; static const String sendTypingNotifications = 'chat.fluffy.send_typing_notifications'; + static const String sendPublicReadReceipts = + 'chat.fluffy.send_public_read_receipts'; static const String sendOnEnter = 'chat.fluffy.send_on_enter'; static const String experimentalVoip = 'chat.fluffy.experimental_voip'; + static const String showPresences = 'chat.fluffy.show_presences'; + static const String displayChatDetailsColumn = + 'chat.fluffy.display_chat_details_column'; } diff --git a/lib/config/themes.dart b/lib/config/themes.dart index 4615eae9c2..64ea62c492 100644 --- a/lib/config/themes.dart +++ b/lib/config/themes.dart @@ -73,7 +73,7 @@ abstract class FluffyThemes { useMaterial3: true, brightness: brightness, colorScheme: colorScheme, - textTheme: PlatformInfos.isDesktop || PlatformInfos.isWeb + textTheme: PlatformInfos.isDesktop ? brightness == Brightness.light ? Typography.material2018().black.merge(fallbackTextTheme) : Typography.material2018().white.merge(fallbackTextTheme) @@ -89,17 +89,24 @@ abstract class FluffyThemes { borderRadius: BorderRadius.circular(AppConfig.borderRadius), ), ), + textSelectionTheme: TextSelectionThemeData( + selectionColor: colorScheme.onBackground.withAlpha(128), + ), inputDecorationTheme: InputDecorationTheme( - border: UnderlineInputBorder( + border: OutlineInputBorder( borderSide: BorderSide.none, borderRadius: BorderRadius.circular(AppConfig.borderRadius / 2), ), + contentPadding: const EdgeInsets.all(12), filled: true, ), appBarTheme: AppBarTheme( toolbarHeight: FluffyThemes.isColumnMode(context) ? 72 : 56, - shadowColor: Colors.grey.withAlpha(64), - surfaceTintColor: colorScheme.background, + shadowColor: FluffyThemes.isColumnMode(context) + ? Colors.grey.withAlpha(64) + : null, + surfaceTintColor: + FluffyThemes.isColumnMode(context) ? colorScheme.background : null, systemOverlayStyle: SystemUiOverlayStyle( statusBarColor: Colors.transparent, statusBarIconBrightness: brightness.reversed, diff --git a/lib/main.dart b/lib/main.dart index ab2a1d22d8..6be6edc913 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -59,6 +59,7 @@ void main() async { AppLifecycleState.detached == WidgetsBinding.instance.lifecycleState) { // Do not send online presences when app is in background fetch mode. for (final client in clients) { + client.backgroundSync = false; client.syncPresence = PresenceType.offline; } @@ -121,6 +122,7 @@ class AppStarter with WidgetsBindingObserver { ); // Switching to foreground mode needs to reenable send online sync presence. for (final client in clients) { + client.backgroundSync = true; client.syncPresence = PresenceType.online; } startGui(clients, store); diff --git a/lib/pages/archive/archive_view.dart b/lib/pages/archive/archive_view.dart index fc5c3e250c..dc73addb94 100644 --- a/lib/pages/archive/archive_view.dart +++ b/lib/pages/archive/archive_view.dart @@ -1,6 +1,7 @@ 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/pages/archive/archive.dart'; @@ -59,6 +60,8 @@ class ArchiveView extends StatelessWidget { itemBuilder: (BuildContext context, int i) => ChatListItem( controller.archive[i], onForget: () => controller.forgetRoomAction(i), + onTap: () => context + .go('/rooms/archive/${controller.archive[i].id}'), ), ); } diff --git a/lib/pages/bootstrap/bootstrap_dialog.dart b/lib/pages/bootstrap/bootstrap_dialog.dart index 4cb276ba7e..8bf4f4b022 100644 --- a/lib/pages/bootstrap/bootstrap_dialog.dart +++ b/lib/pages/bootstrap/bootstrap_dialog.dart @@ -266,6 +266,7 @@ class BootstrapDialogState extends State { ), hintText: L10n.of(context)!.recoveryKey, errorText: _recoveryKeyInputError, + errorMaxLines: 2, ), ), const SizedBox(height: 16), @@ -290,6 +291,7 @@ class BootstrapDialogState extends State { final key = _recoveryKeyTextEditingController .text .trim(); + if (key.isEmpty) return; await bootstrap.newSsssKey!.unlock( keyOrPassphrase: key, ); @@ -317,6 +319,11 @@ class BootstrapDialogState extends State { () => _recoveryKeyInputError = e.toLocalizedString(context), ); + } on FormatException catch (_) { + setState( + () => _recoveryKeyInputError = + L10n.of(context)!.wrongRecoveryKey, + ); } catch (e, s) { ErrorReporter( context, @@ -351,6 +358,16 @@ class BootstrapDialogState extends State { onPressed: _recoveryKeyInputLoading ? null : () async { + final consent = await showOkCancelAlertDialog( + context: context, + title: L10n.of(context)!.verifyOtherDevice, + message: L10n.of(context)! + .verifyOtherDeviceDescription, + okLabel: L10n.of(context)!.ok, + cancelLabel: L10n.of(context)!.cancel, + fullyCapitalizedForMaterial: false, + ); + if (consent != OkCancelResult.ok) return; final req = await showFutureLoadingDialog( context: context, future: () async { diff --git a/lib/pages/chat/chat.dart b/lib/pages/chat/chat.dart index 67e459e03c..9176e3e6b9 100644 --- a/lib/pages/chat/chat.dart +++ b/lib/pages/chat/chat.dart @@ -8,6 +8,7 @@ import 'package:device_info_plus/device_info_plus.dart'; import 'package:emoji_picker_flutter/emoji_picker_flutter.dart'; import 'package:file_picker/file_picker.dart'; import 'package:fluffychat/config/app_config.dart'; +import 'package:fluffychat/config/setting_keys.dart'; import 'package:fluffychat/config/themes.dart'; import 'package:fluffychat/pages/chat/chat_view.dart'; import 'package:fluffychat/pages/chat/event_info_dialog.dart'; @@ -27,7 +28,6 @@ import 'package:fluffychat/pangea/utils/firebase_analytics.dart'; import 'package:fluffychat/pangea/utils/report_message.dart'; import 'package:fluffychat/pangea/widgets/chat/message_toolbar.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'; import 'package:fluffychat/utils/matrix_sdk_extensions/filtered_timeline_extension.dart'; @@ -46,13 +46,13 @@ import 'package:image_picker/image_picker.dart'; import 'package:matrix/matrix.dart'; import 'package:scroll_to_index/scroll_to_index.dart'; import 'package:shared_preferences/shared_preferences.dart'; +import 'package:universal_html/html.dart' as html; import '../../utils/account_bundles.dart'; import '../../utils/localized_exception_extension.dart'; import '../../utils/matrix_sdk_extensions/matrix_file_extension.dart'; import 'send_file_dialog.dart'; import 'send_location_dialog.dart'; -import 'sticker_picker_dialog.dart'; class ChatPage extends StatelessWidget { final String roomId; @@ -80,31 +80,10 @@ class ChatPage extends StatelessWidget { ); } - return Row( - children: [ - Expanded( - child: ChatPageWithRoom( - key: Key('chat_page_$roomId'), - room: room, - shareText: shareText, - ), - ), - if (FluffyThemes.isThreeColumnMode(context) && - room.membership == Membership.join) - Container( - width: FluffyThemes.columnWidth, - clipBehavior: Clip.hardEdge, - decoration: BoxDecoration( - border: Border( - left: BorderSide( - width: 1, - color: Theme.of(context).dividerColor, - ), - ), - ), - child: ChatDetails(roomId: roomId), - ), - ], + return ChatPageWithRoom( + key: Key('chat_page_$roomId'), + room: room, + shareText: shareText, ); } } @@ -125,7 +104,7 @@ class ChatPageWithRoom extends StatefulWidget { class ChatController extends State with WidgetsBindingObserver { -// #Pangea + // #Pangea final PangeaController pangeaController = MatrixState.pangeaController; late Choreographer choreographer = Choreographer(pangeaController, this); // Pangea# @@ -142,6 +121,7 @@ class ChatController extends State final AutoScrollController scrollController = AutoScrollController(); FocusNode inputFocus = FocusNode(); + StreamSubscription? onFocusSub; Timer? typingCoolDown; Timer? typingTimeout; @@ -155,26 +135,32 @@ class ChatController extends State // void onDragDone(DropDoneDetails details) async { // setState(() => dragging = false); - // final bytesList = await showFutureLoadingDialog( + // if (details.files.isEmpty) return; + // final result = await showFutureLoadingDialog( // context: context, - // future: () => Future.wait( - // details.files.map( - // (xfile) => xfile.readAsBytes(), - // ), - // ), + // future: () async { + // final clientConfig = await room.client.getConfig(); + // final maxUploadSize = clientConfig.mUploadSize ?? 100 * 1024 * 1024; + // final matrixFiles = await Future.wait( + // details.files.map( + // (xfile) async { + // final length = await xfile.length(); + // if (length > maxUploadSize) { + // throw FileTooBigMatrixException(length, maxUploadSize); + // } + // return MatrixFile( + // bytes: await xfile.readAsBytes(), + // name: xfile.name, + // mimeType: xfile.mimeType, + // ).detectFileType; + // }, + // ), + // ); + // return matrixFiles; + // }, // ); - // if (bytesList.error != null) return; - - // final matrixFiles = []; - // for (var i = 0; i < bytesList.result!.length; i++) { - // matrixFiles.add( - // MatrixFile( - // bytes: bytesList.result![i], - // name: details.files[i].name, - // ).detectFileType, - // ); - // } - // if (matrixFiles.isEmpty) return; + // final matrixFiles = result.result; + // if (matrixFiles == null || matrixFiles.isEmpty) return; // await showAdaptiveDialog( // context: context, @@ -185,7 +171,6 @@ class ChatController extends State // ); // } // Pangea# - bool get canSaveSelectedEvent => selectedEvents.length == 1 && { @@ -245,7 +230,7 @@ class ChatController extends State EmojiPickerType emojiPickerType = EmojiPickerType.keyboard; // #Pangea - // void requestHistory() async { + // void requestHistory([_]) async { Future requestHistory() async { if (timeline == null) return; // Pangea# @@ -274,6 +259,7 @@ class ChatController extends State setState(() => _scrolledUp = true); } else if (scrollController.position.pixels <= 0 && _scrolledUp == true) { setState(() => _scrolledUp = false); + setReadMarker(); } if (scrollController.position.pixels == 0 || @@ -300,7 +286,12 @@ class ChatController extends State inputFocus.addListener(_inputFocusListener); _loadDraft(); super.initState(); + _displayChatDetailsColumn = ValueNotifier( + Matrix.of(context).store.getBool(SettingKeys.displayChatDetailsColumn) ?? + false, + ); sendingClient = Matrix.of(context).client; + WidgetsBinding.instance.addObserver(this); // #Pangea if (!mounted) return; Future.delayed(const Duration(seconds: 1), () async { @@ -343,6 +334,9 @@ class ChatController extends State ); // Pangea# _tryLoadTimeline(); + if (kIsWeb) { + onFocusSub = html.window.onFocus.listen((_) => setReadMarker()); + } } void _tryLoadTimeline() async { @@ -350,7 +344,10 @@ class ChatController extends State try { await loadTimelineFuture; final fullyRead = room.fullyRead; - if (fullyRead.isEmpty) return; + if (fullyRead.isEmpty) { + setReadMarker(); + return; + } if (timeline!.events.any((event) => event.eventId == fullyRead)) { Logs().v('Scroll up to visible event', fullyRead); setReadMarker(); @@ -384,6 +381,11 @@ class ChatController extends State int? animateInEventIndex; void onInsert(int i) { + if (timeline?.events[i].status == EventStatus.synced) { + final index = timeline!.events.firstIndexWhereNotError; + if (i == index) setReadMarker(eventId: timeline?.events[i].eventId); + } + // setState will be called by updateView() anyway animateInEventIndex = i; } @@ -462,7 +464,6 @@ class ChatController extends State @override void didChangeAppLifecycleState(AppLifecycleState state) { if (state != AppLifecycleState.resumed) return; - if (!_scrolledUp) return; setReadMarker(); } @@ -470,20 +471,32 @@ class ChatController extends State void setReadMarker({String? eventId}) { if (_setReadMarkerFuture != null) return; + if (_scrolledUp) return; if (scrollUpBannerEventId != null) return; if (eventId == null && !room.hasNewMessages && room.notificationCount == 0) { return; } - if (!Matrix.of(context).webHasFocus) return; + + // Do not send read markers when app is not in foreground + if (kIsWeb && !Matrix.of(context).webHasFocus) return; + if (!kIsWeb && + WidgetsBinding.instance.lifecycleState != AppLifecycleState.resumed) { + return; + } final timeline = this.timeline; if (timeline == null || timeline.events.isEmpty) return; Logs().d('Set read marker...', eventId); // ignore: unawaited_futures - _setReadMarkerFuture = timeline.setReadMarker(eventId: eventId).then((_) { + _setReadMarkerFuture = timeline + .setReadMarker( + eventId: eventId, + public: AppConfig.sendPublicReadReceipts, + ) + .then((_) { _setReadMarkerFuture = null; }); if (eventId == null || eventId == timeline.room.lastEvent?.eventId) { @@ -496,6 +509,7 @@ class ChatController extends State timeline?.cancelSubscriptions(); timeline = null; inputFocus.removeListener(_inputFocusListener); + onFocusSub?.cancel(); //#Pangea choreographer.stateListener.close(); choreographer.dispose(); @@ -535,6 +549,12 @@ class ChatController extends State }); // #Pangea + final List edittingEvents = []; + void clearEdittingEvent(String eventId) { + edittingEvents.remove(eventId); + setState(() {}); + } + // 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. @@ -577,6 +597,7 @@ class ChatController extends State // editEventId: editEvent?.eventId, // parseCommands: parseCommands, // ); + final previousEdit = editEvent; room .pangeaSendTextEvent( sendController.text, @@ -592,6 +613,13 @@ class ChatController extends State ) .then( (String? msgEventId) { + // #Pangea + setState(() { + if (previousEdit != null) { + edittingEvents.add(previousEdit.eventId); + } + }); + // Pangea# GoogleAnalytics.sendMessage( room.id, room.classCode, @@ -614,6 +642,7 @@ class ChatController extends State useType: useType ?? UseType.un, time: DateTime.now(), ), + isEdit: previousEdit != null, ); if (choreo != null && @@ -627,6 +656,7 @@ class ChatController extends State ...choreo.toGrammarConstructUse(msgEventId, room.id), ], originalSent!.langCode, + isEdit: previousEdit != null, ); } }, @@ -755,24 +785,6 @@ class ChatController extends State ); } - void sendStickerAction() async { - final sticker = await showAdaptiveBottomSheet( - context: context, - builder: (c) => StickerPickerDialog(room: room), - ); - if (sticker == null) return; - final eventContent = { - 'body': sticker.body, - if (sticker.info != null) 'info': sticker.info, - 'url': sticker.url.toString(), - }; - // send the sticker - await room.sendEvent( - eventContent, - type: EventTypes.Sticker, - ); - } - void voiceMessageAction() async { final scaffoldMessenger = ScaffoldMessenger.of(context); if (PlatformInfos.isAndroid) { @@ -791,7 +803,6 @@ class ChatController extends State // #Pangea // if (await Record().hasPermission() == false) return; // Pangea# - final result = await showDialog( context: context, barrierDismissible: false, @@ -832,12 +843,11 @@ class ChatController extends State }); } + void hideEmojiPicker() { + setState(() => showEmojiPicker = false); + } + void emojiPickerAction() { -// #Pangea - if (choreographer.itController.isOpen) { - return; - } - // Pangea# if (showEmojiPicker) { inputFocus.requestFocus(); } else { @@ -1137,7 +1147,6 @@ class ChatController extends State ); }); await loadTimelineFuture; - setReadMarker(); } scrollController.jumpTo(0); } @@ -1219,7 +1228,7 @@ class ChatController extends State void clearSelectedEvents() => setState(() { selectedEvents.clear(); showEmojiPicker = false; -//#Pangea + //#Pangea choreographer.messageOptions.resetSelectedDisplayLang(); //Pangea# }); @@ -1290,7 +1299,6 @@ class ChatController extends State if (choreographer.itController.isOpen) { return; } - // Pangea# if (!event.redacted) { if (selectedEvents.contains(event)) { @@ -1354,9 +1362,6 @@ class ChatController extends State if (choice == 'camera-video') { openVideoCameraAction(); } - if (choice == 'sticker') { - sendStickerAction(); - } if (choice == 'location') { sendLocationAction(); } @@ -1401,7 +1406,6 @@ class ChatController extends State void onInputBarChanged(String text) { if (_inputTextIsEmpty != text.isEmpty) { - setReadMarker(); setState(() { _inputTextIsEmpty = text.isEmpty; }); @@ -1567,7 +1571,11 @@ class ChatController extends State ); } - void setToolbarDisplayController(String eventId) { + void setToolbarDisplayController( + String eventId, { + Event? nextEvent, + Event? previousEvent, + }) { final Event? event = timeline!.events.firstWhereOrNull( (e) => e.eventId == eventId, ); @@ -1583,6 +1591,8 @@ class ChatController extends State pangeaMessageEvent: _pangeaMessageEvents[eventId]!, immersionMode: choreographer.immersionMode, controller: this, + nextEvent: nextEvent, + previousEvent: previousEvent, ); _toolbarDisplayControllers[eventId]!.setToolbar(); } catch (e, s) { @@ -1606,16 +1616,85 @@ class ChatController extends State return _pangeaMessageEvents[eventId]; } - ToolbarDisplayController? getToolbarDisplayController(String eventId) { + ToolbarDisplayController? getToolbarDisplayController( + String eventId, { + Event? nextEvent, + Event? previousEvent, + }) { if (_toolbarDisplayControllers[eventId] == null) { - setToolbarDisplayController(eventId); + setToolbarDisplayController( + eventId, + nextEvent: nextEvent, + previousEvent: previousEvent, + ); } return _toolbarDisplayControllers[eventId]; } // Pangea# + late final ValueNotifier _displayChatDetailsColumn; + + void toggleDisplayChatDetailsColumn() async { + await Matrix.of(context).store.setBool( + SettingKeys.displayChatDetailsColumn, + !_displayChatDetailsColumn.value, + ); + _displayChatDetailsColumn.value = !_displayChatDetailsColumn.value; + } + @override - Widget build(BuildContext context) => ChatView(this); + Widget build(BuildContext context) => Row( + children: [ + Expanded( + child: ChatView(this), + ), + AnimatedSize( + duration: FluffyThemes.animationDuration, + curve: FluffyThemes.animationCurve, + child: ValueListenableBuilder( + valueListenable: _displayChatDetailsColumn, + builder: (context, displayChatDetailsColumn, _) { + if (!FluffyThemes.isThreeColumnMode(context) || + room.membership != Membership.join || + !displayChatDetailsColumn) { + return const SizedBox( + height: double.infinity, + width: 0, + ); + } + return Container( + width: FluffyThemes.columnWidth, + clipBehavior: Clip.hardEdge, + decoration: BoxDecoration( + border: Border( + left: BorderSide( + width: 1, + color: Theme.of(context).dividerColor, + ), + ), + ), + child: ChatDetails( + roomId: roomId, + embeddedCloseButton: IconButton( + icon: const Icon(Icons.close), + onPressed: toggleDisplayChatDetailsColumn, + ), + ), + ); + }, + ), + ), + ], + ); } enum EmojiPickerType { reaction, keyboard } + +extension on List { + int get firstIndexWhereNotError { + if (isEmpty) return 0; + final index = indexWhere((event) => !event.status.isError); + if (index == -1) return length; + return index; + } +} diff --git a/lib/pages/chat/chat_app_bar_list_tile.dart b/lib/pages/chat/chat_app_bar_list_tile.dart new file mode 100644 index 0000000000..1e0ec82599 --- /dev/null +++ b/lib/pages/chat/chat_app_bar_list_tile.dart @@ -0,0 +1,61 @@ +import 'package:flutter/material.dart'; + +import 'package:flutter_linkify/flutter_linkify.dart'; + +import 'package:fluffychat/config/app_config.dart'; +import 'package:fluffychat/utils/url_launcher.dart'; + +class ChatAppBarListTile extends StatelessWidget { + final Widget? leading; + final String title; + final Widget? trailing; + final void Function()? onTap; + + const ChatAppBarListTile({ + super.key, + this.leading, + required this.title, + this.trailing, + this.onTap, + }); + + @override + Widget build(BuildContext context) { + final leading = this.leading; + final trailing = this.trailing; + final fontSize = AppConfig.messageFontSize * AppConfig.fontSizeFactor; + return InkWell( + onTap: onTap, + child: Row( + children: [ + if (leading != null) leading, + Expanded( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 4.0), + child: Linkify( + text: title, + options: const LinkifyOptions(humanize: false), + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: TextStyle( + color: Theme.of(context).colorScheme.onSurfaceVariant, + overflow: TextOverflow.ellipsis, + fontSize: fontSize, + ), + linkStyle: TextStyle( + color: Theme.of(context).colorScheme.onSurfaceVariant, + fontSize: fontSize, + decoration: TextDecoration.underline, + decorationColor: + Theme.of(context).colorScheme.onSurfaceVariant, + ), + onOpen: (url) => UrlLauncher(context, url.url).launchUrl(), + ), + ), + ), + if (trailing != null) trailing, + ], + ), + ); + } +} diff --git a/lib/pages/chat/chat_app_bar_title.dart b/lib/pages/chat/chat_app_bar_title.dart index 1cb84b48e3..5d3f344570 100644 --- a/lib/pages/chat/chat_app_bar_title.dart +++ b/lib/pages/chat/chat_app_bar_title.dart @@ -26,7 +26,9 @@ class ChatAppBarTitle extends StatelessWidget { highlightColor: Colors.transparent, onTap: controller.isArchived ? null - : () => context.go('/rooms/${room.id}/details'), + : () => FluffyThemes.isThreeColumnMode(context) + ? controller.toggleDisplayChatDetailsColumn() + : context.go('/rooms/${room.id}/details'), child: Row( children: [ Hero( @@ -37,7 +39,6 @@ class ChatAppBarTitle extends StatelessWidget { MatrixLocals(L10n.of(context)!), ), size: 32, - presenceUserId: room.directChatMatrixID, ), ), const SizedBox(width: 12), diff --git a/lib/pages/chat/chat_emoji_picker.dart b/lib/pages/chat/chat_emoji_picker.dart index 5e45113be1..516084d990 100644 --- a/lib/pages/chat/chat_emoji_picker.dart +++ b/lib/pages/chat/chat_emoji_picker.dart @@ -1,9 +1,10 @@ -import 'package:flutter/material.dart'; - import 'package:emoji_picker_flutter/emoji_picker_flutter.dart'; +import 'package:fluffychat/config/themes.dart'; +import 'package:fluffychat/pages/chat/sticker_picker_dialog.dart'; +import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:matrix/matrix.dart'; -import 'package:fluffychat/config/themes.dart'; import 'chat.dart'; class ChatEmojiPicker extends StatelessWidget { @@ -16,30 +17,73 @@ class ChatEmojiPicker extends StatelessWidget { return AnimatedContainer( duration: FluffyThemes.animationDuration, curve: FluffyThemes.animationCurve, + clipBehavior: Clip.hardEdge, + decoration: const BoxDecoration(), height: controller.showEmojiPicker ? MediaQuery.of(context).size.height / 2 : 0, child: controller.showEmojiPicker - ? EmojiPicker( - onEmojiSelected: controller.onEmojiSelected, - onBackspacePressed: controller.emojiPickerBackspace, - config: Config( - backspaceColor: theme.colorScheme.primary, - bgColor: Color.lerp( - theme.colorScheme.background, - theme.colorScheme.primaryContainer, - 0.25, - )!, - iconColor: theme.colorScheme.primary.withOpacity(0.5), - iconColorSelected: theme.colorScheme.primary, - indicatorColor: theme.colorScheme.primary, - noRecents: const NoRecent(), - skinToneDialogBgColor: Color.lerp( - theme.colorScheme.background, - theme.colorScheme.primaryContainer, - 0.75, - )!, - skinToneIndicatorColor: theme.colorScheme.onBackground, + ? DefaultTabController( + length: 2, + child: Column( + children: [ + TabBar( + tabs: [ + Tab(text: L10n.of(context)!.emojis), + Tab(text: L10n.of(context)!.stickers), + ], + ), + Expanded( + child: TabBarView( + children: [ + EmojiPicker( + onEmojiSelected: controller.onEmojiSelected, + onBackspacePressed: controller.emojiPickerBackspace, + config: Config( + emojiViewConfig: EmojiViewConfig( + noRecents: const NoRecent(), + backgroundColor: Theme.of(context) + .colorScheme + .onInverseSurface, + ), + bottomActionBarConfig: const BottomActionBarConfig( + enabled: false, + ), + categoryViewConfig: CategoryViewConfig( + backspaceColor: theme.colorScheme.primary, + iconColor: + theme.colorScheme.primary.withOpacity(0.5), + iconColorSelected: theme.colorScheme.primary, + indicatorColor: theme.colorScheme.primary, + ), + skinToneConfig: SkinToneConfig( + dialogBackgroundColor: Color.lerp( + theme.colorScheme.background, + theme.colorScheme.primaryContainer, + 0.75, + )!, + indicatorColor: theme.colorScheme.onBackground, + ), + ), + ), + StickerPickerDialog( + room: controller.room, + onSelected: (sticker) { + controller.room.sendEvent( + { + 'body': sticker.body, + 'info': sticker.info ?? {}, + 'url': sticker.url.toString(), + }, + type: EventTypes.Sticker, + ); + controller.hideEmojiPicker(); + }, + ), + ], + ), + ), + ], ), ) : null, diff --git a/lib/pages/chat/chat_event_list.dart b/lib/pages/chat/chat_event_list.dart index c32e239347..67e9358f2a 100644 --- a/lib/pages/chat/chat_event_list.dart +++ b/lib/pages/chat/chat_event_list.dart @@ -6,6 +6,7 @@ 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/account_config.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'; @@ -27,7 +28,6 @@ class ChatEventList extends StatelessWidget { final events = controller.timeline!.events .where((event) => event.isVisibleInGui) .toList(); - final animateInEventIndex = controller.animateInEventIndex; // create a map of eventId --> index to greatly improve performance of @@ -37,11 +37,14 @@ class ChatEventList extends StatelessWidget { thisEventsKeyMap[events[i].eventId] = i; } + final hasWallpaper = + controller.room.client.applicationAccountConfig.wallpaperUrl != null; + return SelectionArea( child: ListView.custom( padding: EdgeInsets.only( top: 16, - bottom: 4, + bottom: 8, left: horizontalPadding, right: horizontalPadding, ), @@ -94,8 +97,12 @@ class ChatEventList extends StatelessWidget { if (controller.timeline!.canRequestHistory) { return Builder( builder: (context) { + // #Pangea WidgetsBinding.instance .addPostFrameCallback((_) => controller.requestHistory); + // WidgetsBinding.instance + // .addPostFrameCallback(controller.requestHistory); + // Pangea# return Center( child: IconButton( onPressed: controller.requestHistory, @@ -147,8 +154,8 @@ class ChatEventList extends StatelessWidget { onSelect: controller.onSelectMessage, scrollToEventId: (String eventId) => controller.scrollToEventId(eventId), - // #Pangea longPressSelect: controller.selectedEvents.isNotEmpty, + // #Pangea selectedDisplayLang: controller.choreographer.messageOptions.selectedDisplayLang, immersionMode: controller.choreographer.immersionMode, @@ -162,6 +169,9 @@ class ChatEventList extends StatelessWidget { controller.readMarkerEventId == event.eventId && controller.timeline?.allowNewEvent == false, nextEvent: i + 1 < events.length ? events[i + 1] : null, + previousEvent: i > 0 ? events[i - 1] : null, + avatarPresenceBackgroundColor: + hasWallpaper ? Colors.transparent : null, ), ); }, diff --git a/lib/pages/chat/chat_input_row.dart b/lib/pages/chat/chat_input_row.dart index bd1653fe03..fa2a801c05 100644 --- a/lib/pages/chat/chat_input_row.dart +++ b/lib/pages/chat/chat_input_row.dart @@ -2,14 +2,11 @@ import 'package:animations/animations.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/pangea/widgets/chat/message_actions.dart'; import 'package:fluffychat/utils/platform_infos.dart'; import 'package:fluffychat/widgets/avatar.dart'; import 'package:fluffychat/widgets/matrix.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; -import 'package:keyboard_shortcuts/keyboard_shortcuts.dart'; import 'package:matrix/matrix.dart'; import '../../config/themes.dart'; @@ -27,6 +24,8 @@ class ChatInputRow extends StatelessWidget { controller.emojiPickerType == EmojiPickerType.reaction) { return const SizedBox.shrink(); } + const height = 48.0; + // #Pangea return Column( children: [ @@ -43,7 +42,7 @@ class ChatInputRow extends StatelessWidget { if (controller.selectedEvents .every((event) => event.status == EventStatus.error)) SizedBox( - height: 56, + height: height, child: TextButton( style: TextButton.styleFrom( foregroundColor: Theme.of(context).colorScheme.error, @@ -59,7 +58,7 @@ class ChatInputRow extends StatelessWidget { ) else SizedBox( - height: 56, + height: height, child: TextButton( onPressed: controller.forwardEventsAction, child: Row( @@ -76,7 +75,7 @@ class ChatInputRow extends StatelessWidget { .status .isSent ? SizedBox( - height: 56, + height: height, child: TextButton( onPressed: controller.replyAction, child: Row( @@ -88,7 +87,7 @@ class ChatInputRow extends StatelessWidget { ), ) : SizedBox( - height: 56, + height: height, child: TextButton( onPressed: controller.sendAgainAction, child: Row( @@ -103,197 +102,209 @@ class ChatInputRow extends StatelessWidget { : 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.sendController.text.isEmpty ? 56 : 0, - width: controller.sendController.text.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), + // #Pangea + // const SizedBox(width: 4), + // KeyBoardShortcuts( + // keysToPress: { + // LogicalKeyboardKey.altLeft, + // LogicalKeyboardKey.keyA, + // }, + // onKeysPressed: () => + // controller.onAddPopupMenuButtonSelected('file'), + // helpLabel: L10n.of(context)!.sendFile, + // child: + // Pangea# + AnimatedContainer( + duration: FluffyThemes.animationDuration, + curve: FluffyThemes.animationCurve, + height: height, + // #Pangea + // width: + // controller.sendController.text.isEmpty ? height : 0, + width: controller.sendController.text.isEmpty && + controller.pangeaController.permissionsController + .showChatInputAddButton(controller.roomId) + ? height + : 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), ), - //#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), + ), + //#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), ), -//#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), + ), + //#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), ), - //#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), + ), + //#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), ), - 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), + ), + 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), + ), + //#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), ), - ], - ), + ), + ], ), ), + // #Pangea + // ), + // Pangea# Container( - height: 56, + height: height, + width: height, 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, - ); - }, - child: Icon( - controller.showEmojiPicker - ? Icons.keyboard - : Icons.emoji_emotions_outlined, - key: ValueKey(controller.showEmojiPicker), - ), + child: + // #Pangea + // KeyBoardShortcuts( + // keysToPress: { + // LogicalKeyboardKey.altLeft, + // LogicalKeyboardKey.keyE, + // }, + // onKeysPressed: controller.emojiPickerAction, + // helpLabel: L10n.of(context)!.emojis, + // child: + // Pangea# + 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.add_reaction_outlined, + key: ValueKey(controller.showEmojiPicker), ), - onPressed: controller.emojiPickerAction, ), + onPressed: controller.emojiPickerAction, ), + // #Pangea + // ), + // Pangea# ), // #Pangea // if (Matrix.of(context).isMultiAccount && // Matrix.of(context).hasComplexBundles && // Matrix.of(context).currentBundle!.length > 1) // Container( - // height: 56, + // width: height, + // height: height, // alignment: Alignment.center, // child: _ChatAccountPicker(controller), // ), // Pangea# Expanded( child: Padding( - padding: const EdgeInsets.symmetric(vertical: 4.0), + padding: const EdgeInsets.symmetric(vertical: 0.0), child: InputBar( room: controller.room, minLines: 1, maxLines: 8, - // #Pangea - // autofocus: !PlatformInfos.isMobile, - autofocus: false, - // Pangea# + autofocus: !PlatformInfos.isMobile, keyboardType: TextInputType.multiline, textInputAction: AppConfig.sendOnEnter == true && PlatformInfos.isMobile @@ -303,11 +314,17 @@ class ChatInputRow extends StatelessWidget { // onSubmitted: controller.onInputBarSubmitted, onSubmitted: (String value) => controller.onInputBarSubmitted(value, context), - // #Pangea + // Pangea# onSubmitImage: controller.sendImageFromClipBoard, focusNode: controller.inputFocus, controller: controller.sendController, decoration: InputDecoration( + contentPadding: const EdgeInsets.only( + left: 6.0, + right: 6.0, + bottom: 6.0, + top: 3.0, + ), hintText: L10n.of(context)!.writeAMessage, hintMaxLines: 1, border: InputBorder.none, @@ -318,31 +335,46 @@ class ChatInputRow extends StatelessWidget { ), ), ), - if (PlatformInfos.platformCanRecord && - controller.sendController.text.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.sendController.text.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# + Container( + height: height, + width: height, + alignment: Alignment.center, + child: PlatformInfos.platformCanRecord && + controller.sendController.text.isEmpty + ? FloatingActionButton.small( + tooltip: L10n.of(context)!.voiceMessage, + onPressed: controller.voiceMessageAction, + elevation: 0, + heroTag: null, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(height), + ), + backgroundColor: + Theme.of(context).colorScheme.primary, + foregroundColor: + Theme.of(context).colorScheme.onPrimary, + child: const Icon(Icons.mic_none_outlined), + ) + : + // #Pangea + ChoreographerSendButton(controller: controller), + // FloatingActionButton.small( + // tooltip: L10n.of(context)!.send, + // onPressed: controller.send, + // elevation: 0, + // heroTag: null, + // shape: RoundedRectangleBorder( + // borderRadius: BorderRadius.circular(height), + // ), + // backgroundColor: Theme.of(context) + // .colorScheme + // .onPrimaryContainer, + // foregroundColor: + // Theme.of(context).colorScheme.onPrimary, + // child: const Icon(Icons.send_outlined), + // ), + // Pangea# + ), ], ), ], diff --git a/lib/pages/chat/chat_view.dart b/lib/pages/chat/chat_view.dart index 9f20616f3a..57255ffc92 100644 --- a/lib/pages/chat/chat_view.dart +++ b/lib/pages/chat/chat_view.dart @@ -1,20 +1,21 @@ import 'package:badges/badges.dart'; -import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/config/themes.dart'; import 'package:fluffychat/pages/chat/chat.dart'; +import 'package:fluffychat/pages/chat/chat_app_bar_list_tile.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/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/utils/account_config.dart'; import 'package:fluffychat/widgets/chat_settings_popup_menu.dart'; import 'package:fluffychat/widgets/connection_status_header.dart'; +import 'package:fluffychat/widgets/matrix.dart'; +import 'package:fluffychat/widgets/mxc_image.dart'; import 'package:fluffychat/widgets/unread_rooms_badge.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; @@ -118,7 +119,8 @@ class ChatView extends StatelessWidget { ChatSettingsPopupMenu(controller.room, !controller.room.isDirectChat), ]; } - // } else if (!controller.room.isArchived) { + + // else if (!controller.room.isArchived) { // return [ // if (Matrix.of(context).voipPlugin != null && // controller.room.isDirectChat) @@ -146,6 +148,8 @@ class ChatView extends StatelessWidget { final bottomSheetPadding = FluffyThemes.isColumnMode(context) ? 16.0 : 8.0; final scrollUpBannerEventId = controller.scrollUpBannerEventId; + final accountConfig = Matrix.of(context).client.applicationAccountConfig; + return PopScope( canPop: controller.selectedEvents.isEmpty && !controller.showEmojiPicker, onPopInvoked: (pop) async { @@ -156,272 +160,276 @@ class ChatView extends StatelessWidget { controller.emojiPickerAction(); } }, - child: GestureDetector( - onTapDown: (_) => controller.setReadMarker(), - behavior: HitTestBehavior.opaque, - child: MouseRegion( - onEnter: (_) => controller.setReadMarker(), - child: StreamBuilder( - stream: controller.room.onUpdate.stream - .rateLimit(const Duration(seconds: 1)), - builder: (context, snapshot) => FutureBuilder( - future: controller.loadTimelineFuture, - builder: (BuildContext context, snapshot) { - return Scaffold( - appBar: AppBar( - actionsIconTheme: IconThemeData( - color: controller.selectedEvents.isEmpty - ? null - : Theme.of(context).colorScheme.primary, - ), - leading: controller.selectMode - ? IconButton( + child: StreamBuilder( + stream: controller.room.onUpdate.stream + .rateLimit(const Duration(seconds: 1)), + builder: (context, snapshot) => FutureBuilder( + future: controller.loadTimelineFuture, + builder: (BuildContext context, snapshot) { + var appbarBottomHeight = 0.0; + if (controller.room.pinnedEventIds.isNotEmpty) { + appbarBottomHeight += 42; + } + if (scrollUpBannerEventId != null) { + appbarBottomHeight += 42; + } + final tombstoneEvent = + controller.room.getState(EventTypes.RoomTombstone); + if (tombstoneEvent != null) { + appbarBottomHeight += 42; + } + return Scaffold( + appBar: AppBar( + actionsIconTheme: IconThemeData( + color: controller.selectedEvents.isEmpty + ? null + : Theme.of(context).colorScheme.primary, + ), + leading: controller.selectMode + ? IconButton( + icon: const Icon(Icons.close), + onPressed: controller.clearSelectedEvents, + tooltip: L10n.of(context)!.close, + color: Theme.of(context).colorScheme.primary, + ) + : UnreadRoomsBadge( + filter: (r) => + r.id != controller.roomId + // #Pangea + && + !r.isAnalyticsRoom, + // Pangea#, + badgePosition: BadgePosition.topEnd(end: 8, top: 4), + child: const Center(child: BackButton()), + ), + titleSpacing: 0, + title: ChatAppBarTitle(controller), + actions: _appBarActions(context), + bottom: PreferredSize( + preferredSize: Size.fromHeight(appbarBottomHeight), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + PinnedEvents(controller), + if (tombstoneEvent != null) + ChatAppBarListTile( + title: tombstoneEvent.parsedTombstoneContent.body, + leading: const Padding( + padding: EdgeInsets.all(8.0), + child: Icon(Icons.upgrade_outlined), + ), + trailing: TextButton( + onPressed: controller.goToNewRoomAction, + child: Text(L10n.of(context)!.goToTheNewRoom), + ), + ), + if (scrollUpBannerEventId != null) + ChatAppBarListTile( + leading: IconButton( + color: + Theme.of(context).colorScheme.onSurfaceVariant, icon: const Icon(Icons.close), - onPressed: controller.clearSelectedEvents, tooltip: L10n.of(context)!.close, - color: Theme.of(context).colorScheme.primary, - ) - : UnreadRoomsBadge( - filter: (r) => - r.id != controller.roomId - // #Pangea - && - !r.isAnalyticsRoom, - // Pangea# - badgePosition: BadgePosition.topEnd(end: 8, top: 4), - child: const Center(child: BackButton()), + onPressed: () { + controller.discardScrollUpBannerEventId(); + controller.setReadMarker(); + }, + ), + title: L10n.of(context)!.jumpToLastReadMessage, + trailing: TextButton( + onPressed: () { + controller.scrollToEventId( + scrollUpBannerEventId, + ); + controller.discardScrollUpBannerEventId(); + }, + child: Text(L10n.of(context)!.jump), ), - titleSpacing: 0, - title: ChatAppBarTitle(controller), - actions: _appBarActions(context), + ), + ], ), - // #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 + // 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!, ) - // #Pangea - : controller.choreographer.errorService.error != null - ? ChoreographerHasErrorButton( - controller.pangeaController, - controller.choreographer.errorService.error!, + : controller.showPermissionsError + ? LanguagePermissionsButtons( + choreographer: controller.choreographer, + roomID: controller.roomId, ) - : controller.showPermissionsError - ? LanguagePermissionsButtons( - choreographer: controller.choreographer, - roomID: controller.roomId, - ) - : null) - // #Pangea - : null, - body: - // #Pangea - // DropTarget( - // onDragDone: controller.onDragDone, - // onDragEntered: controller.onDragEntered, - // onDragExited: controller.onDragExited, - // child: - // Pangea# - Stack( - children: [ - SafeArea( - child: Column( - children: [ - TombstoneDisplay(controller), - if (scrollUpBannerEventId != null) - Material( - color: Theme.of(context) - .colorScheme - .surfaceVariant, - shape: Border( - bottom: BorderSide( - width: 1, - color: Theme.of(context).dividerColor, + : null) + // #Pangea + : null, + body: + // #Pangea + // DropTarget( + // onDragDone: controller.onDragDone, + // onDragEntered: controller.onDragEntered, + // onDragExited: controller.onDragExited, + // child: + // Pangea# + Stack( + children: [ + if (accountConfig.wallpaperUrl != null) + Opacity( + opacity: accountConfig.wallpaperOpacity ?? 1, + child: MxcImage( + uri: accountConfig.wallpaperUrl, + fit: BoxFit.cover, + isThumbnail: true, + width: FluffyThemes.columnWidth * 4, + height: FluffyThemes.columnWidth * 4, + placeholder: (_) => Container(), + ), + ), + SafeArea( + child: Column( + children: [ + Expanded( + child: GestureDetector( + onTap: controller.clearSingleSelectedEvent, + child: Builder( + builder: (context) { + if (controller.timeline == null) { + return const Center( + child: CircularProgressIndicator.adaptive( + strokeWidth: 2, + ), + ); + } + return ChatEventList( + controller: controller, + ); + }, + ), + ), + ), + if (controller.room.canSendDefaultMessages && + controller.room.membership == Membership.join) + // #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, ), - ), - child: ListTile( - leading: IconButton( + constraints: const BoxConstraints( + maxWidth: FluffyThemes.columnWidth * 2.5, + ), + alignment: Alignment.center, + child: Material( + clipBehavior: Clip.hardEdge, color: Theme.of(context) .colorScheme - .onSurfaceVariant, - icon: const Icon(Icons.close), - tooltip: L10n.of(context)!.close, - onPressed: () { - controller.discardScrollUpBannerEventId(); - controller.setReadMarker(); - }, - ), - title: Text( - L10n.of(context)!.jumpToLastReadMessage, - ), - contentPadding: - const EdgeInsets.only(left: 8), - trailing: TextButton( - onPressed: () { - controller.scrollToEventId( - scrollUpBannerEventId, - ); - controller.discardScrollUpBannerEventId(); - }, - child: Text(L10n.of(context)!.jump), - ), - ), - ), - PinnedEvents(controller), - Expanded( - child: GestureDetector( - onTap: controller.clearSingleSelectedEvent, - child: Builder( - builder: (context) { - if (controller.timeline == null) { - return const Center( - child: - CircularProgressIndicator.adaptive( - strokeWidth: 2, - ), - ); - } - return ChatEventList( - controller: controller, - ); - }, - ), - ), - ), - if (controller.room.canSendDefaultMessages && - controller.room.membership == Membership.join) - // #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, - ), + .surfaceVariant, + borderRadius: const BorderRadius.all( + Radius.circular(24), + ), + child: controller.room.isAbandonedDMRoom == + true + ? Row( + mainAxisAlignment: + MainAxisAlignment.spaceEvenly, + children: [ + TextButton.icon( + style: TextButton.styleFrom( + padding: const EdgeInsets.all( + 16, ), - 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, - ), + 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, ), - ], - ) - : Column( - mainAxisSize: MainAxisSize.min, - children: [ - const ConnectionStatusHeader(), - ReactionsPicker(controller), - ReplyDisplay(controller), - ChatInputRow(controller), - ChatEmojiPicker(controller), - ], + ), + 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 - // if (controller.dragging) - // Container( - // color: Theme.of(context) - // .scaffoldBackgroundColor - // .withOpacity(0.9), - // alignment: Alignment.center, - // child: const Icon( - // Icons.upload_outlined, - // size: 100, - // ), - // ), - // Pangea# - ], - ), - ), - ], + ), + ), + ], + ), ), - // ), - ); - }, - ), - ), + // #Pangea + // if (controller.dragging) + // Container( + // color: Theme.of(context) + // .scaffoldBackgroundColor + // .withOpacity(0.9), + // alignment: Alignment.center, + // child: const Icon( + // Icons.upload_outlined, + // size: 100, + // ), + // ), + // Pangea# + ], + ), + ); + }, ), ), ); diff --git a/lib/pages/chat/command_hints.dart b/lib/pages/chat/command_hints.dart index 750f8134b1..d3b5b974ff 100644 --- a/lib/pages/chat/command_hints.dart +++ b/lib/pages/chat/command_hints.dart @@ -52,6 +52,10 @@ String commandHint(L10n l10n, String command) { return l10n.commandHint_cuddle; case 'sendraw': return l10n.commandHint_sendraw; + case 'ignore': + return l10n.commandHint_ignore; + case 'unignore': + return l10n.commandHint_unignore; default: return ""; } diff --git a/lib/pages/chat/events/audio_player.dart b/lib/pages/chat/events/audio_player.dart index 56b005d4bd..8ca40cb47c 100644 --- a/lib/pages/chat/events/audio_player.dart +++ b/lib/pages/chat/events/audio_player.dart @@ -31,9 +31,9 @@ class AudioPlayerWidget extends StatefulWidget { this.color = Colors.black, // #Pangea this.matrixFile, - super.key, this.autoplay = false, // Pangea# + super.key, }); @override @@ -236,6 +236,27 @@ class AudioPlayerState extends State { late final List waveform; + void _toggleSpeed() async { + final audioPlayer = this.audioPlayer; + if (audioPlayer == null) return; + switch (audioPlayer.speed) { + case 1.0: + await audioPlayer.setSpeed(1.5); + break; + case 1.5: + await audioPlayer.setSpeed(2.0); + break; + case 2.0: + await audioPlayer.setSpeed(0.5); + break; + case 0.5: + default: + await audioPlayer.setSpeed(1.0); + break; + } + setState(() {}); + } + // #Pangea Future _downloadMatrixFile() async { if (kIsWeb) return; @@ -272,12 +293,12 @@ class AudioPlayerState extends State { @override Widget build(BuildContext context) { final statusText = this.statusText ??= _durationString ?? '00:00'; + final audioPlayer = this.audioPlayer; return Padding( padding: const EdgeInsets.all(16), child: Row( mainAxisSize: MainAxisSize.min, children: [ - const SizedBox(width: 4), SizedBox( width: buttonSize, height: buttonSize, @@ -354,6 +375,35 @@ class AudioPlayerState extends State { ), ), ), + const SizedBox(width: 4), + Stack( + children: [ + SizedBox( + width: buttonSize, + height: buttonSize, + child: InkWell( + splashColor: widget.color.withAlpha(128), + borderRadius: BorderRadius.circular(64), + onTap: audioPlayer == null ? null : _toggleSpeed, + child: Icon(Icons.mic_none_outlined, color: widget.color), + ), + ), + if (audioPlayer != null) + Positioned( + bottom: 0, + left: 0, + right: 0, + child: Text( + '${audioPlayer.speed.toString()}x', + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 9.0, + color: widget.color, + ), + ), + ), + ], + ), ], ), ); diff --git a/lib/pages/chat/events/html_message.dart b/lib/pages/chat/events/html_message.dart index a98ab4fc10..f914344abd 100644 --- a/lib/pages/chat/events/html_message.dart +++ b/lib/pages/chat/events/html_message.dart @@ -46,7 +46,7 @@ class HtmlMessage extends StatelessWidget { final newHtml = parts .map( (linkifyElement) => linkifyElement is! UrlElement - ? Uri.encodeComponent(linkifyElement.text) + ? linkifyElement.text.replaceAll('<', '<') : '${linkifyElement.text}', ) .join(' '); @@ -163,7 +163,7 @@ class HtmlMessage extends StatelessWidget { ), }, extensions: [ - RoomPillExtension(context, room), + RoomPillExtension(context, room, fontSize, linkColor), CodeExtension(fontSize: fontSize), MatrixMathExtension( style: TextStyle(fontSize: fontSize, color: textColor), @@ -172,6 +172,7 @@ class HtmlMessage extends StatelessWidget { SpoilerExtension(textColor: textColor), const ImageExtension(), FontColorExtension(), + FallbackTextExtension(fontSize: fontSize), ], onLinkTap: (url, _, element) => UrlLauncher( context, @@ -195,6 +196,8 @@ class HtmlMessage extends StatelessWidget { // ); } + static const Set fallbackTextTags = {'tg-forward'}; + /// Keep in sync with: https://spec.matrix.org/v1.6/client-server-api/#mroommessage-msgtypes static const Set allowedHtmlTags = { 'font', @@ -240,7 +243,7 @@ class HtmlMessage extends StatelessWidget { 'rp', 'rt', // Workaround for https://github.com/krille-chan/fluffychat/issues/507 - 'tg-forward', + ...fallbackTextTags, }; } @@ -433,11 +436,29 @@ class CodeExtension extends HtmlExtension { ); } +class FallbackTextExtension extends HtmlExtension { + final double fontSize; + + FallbackTextExtension({required this.fontSize}); + @override + Set get supportedTags => HtmlMessage.fallbackTextTags; + + @override + InlineSpan build(ExtensionContext context) => TextSpan( + text: context.element?.text ?? '', + style: TextStyle( + fontSize: fontSize, + ), + ); +} + class RoomPillExtension extends HtmlExtension { final Room room; final BuildContext context; + final double fontSize; + final Color color; - RoomPillExtension(this.context, this.room); + RoomPillExtension(this.context, this.room, this.fontSize, this.color); @override Set get supportedTags => {'a'}; @@ -474,6 +495,8 @@ class RoomPillExtension extends HtmlExtension { avatar: _cachedUsers[room.id + matrixId]?.avatarUrl, uri: href, outerContext: this.context, + fontSize: fontSize, + color: color, ), ), ); @@ -489,6 +512,8 @@ class RoomPillExtension extends HtmlExtension { avatar: room.avatar, uri: href, outerContext: this.context, + fontSize: fontSize, + color: color, ), ); } @@ -503,6 +528,8 @@ class MatrixPill extends StatelessWidget { final BuildContext outerContext; final Uri? avatar; final String uri; + final double? fontSize; + final Color? color; const MatrixPill({ super.key, @@ -510,41 +537,34 @@ class MatrixPill extends StatelessWidget { required this.outerContext, this.avatar, required this.uri, + required this.fontSize, + required this.color, }); @override Widget build(BuildContext context) { return InkWell( onTap: UrlLauncher(outerContext, uri).launchUrl, - child: Material( - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(AppConfig.borderRadius), - side: BorderSide( - color: Theme.of(outerContext).colorScheme.onPrimaryContainer, - width: 0.5, + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Avatar( + mxContent: avatar, + name: name, + size: 16, ), - ), - color: Theme.of(outerContext).colorScheme.primaryContainer, - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 6.0), - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - Avatar( - mxContent: avatar, - name: name, - size: 16, - ), - const SizedBox(width: 6), - Text( - name, - style: TextStyle( - color: Theme.of(outerContext).colorScheme.onPrimaryContainer, - ), - ), - ], + const SizedBox(width: 6), + Text( + name, + style: TextStyle( + color: color, + decorationColor: color, + decoration: TextDecoration.underline, + fontSize: fontSize, + height: 1.25, + ), ), - ), + ], ), ); } diff --git a/lib/pages/chat/events/image_bubble.dart b/lib/pages/chat/events/image_bubble.dart index 71b03b6e38..de07991445 100644 --- a/lib/pages/chat/events/image_bubble.dart +++ b/lib/pages/chat/events/image_bubble.dart @@ -1,11 +1,11 @@ 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'; +import '../../../widgets/blur_hash.dart'; class ImageBubble extends StatelessWidget { final Event event; @@ -25,7 +25,7 @@ class ImageBubble extends StatelessWidget { this.tapToView = true, this.maxSize = true, this.backgroundColor, - this.fit = BoxFit.cover, + this.fit = BoxFit.contain, this.thumbnailOnly = true, this.width = 400, this.height = 300, @@ -36,35 +36,18 @@ class ImageBubble extends StatelessWidget { }); Widget _buildPlaceholder(BuildContext context) { - if (event.messageType == MessageTypes.Sticker) { - return const Center( - child: CircularProgressIndicator.adaptive(), - ); - } final String blurHashString = event.infoMap['xyz.amorgan.blurhash'] is String ? event.infoMap['xyz.amorgan.blurhash'] : 'LEHV6nWB2yk8pyo0adR*.7kCMdnj'; - final ratio = event.infoMap['w'] is int && event.infoMap['h'] is int - ? event.infoMap['w'] / event.infoMap['h'] - : 1.0; - var width = 32; - 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, - height: this.height, + width: width, + height: height, child: BlurHash( - hash: blurHashString, - decodingWidth: width, - decodingHeight: height, - imageFit: fit, + blurhash: blurHashString, + width: width, + height: height, + fit: fit, ), ); } @@ -100,22 +83,16 @@ class ImageBubble extends StatelessWidget { borderRadius: borderRadius, child: Hero( tag: event.eventId, - child: ConstrainedBox( - constraints: maxSize - ? BoxConstraints( - maxWidth: width, - maxHeight: height, - ) - : const BoxConstraints.expand(), - child: MxcImage( - event: event, - width: width, - height: height, - fit: fit, - animated: animated, - isThumbnail: thumbnailOnly, - placeholder: _buildPlaceholder, - ), + child: MxcImage( + event: event, + width: width, + height: height, + fit: fit, + animated: animated, + isThumbnail: thumbnailOnly, + placeholder: event.messageType == MessageTypes.Sticker + ? null + : _buildPlaceholder, ), ), ), diff --git a/lib/pages/chat/events/map_bubble.dart b/lib/pages/chat/events/map_bubble.dart index c441c7d64c..d9cea7695b 100644 --- a/lib/pages/chat/events/map_bubble.dart +++ b/lib/pages/chat/events/map_bubble.dart @@ -1,5 +1,4 @@ import 'package:flutter/material.dart'; - import 'package:flutter_map/flutter_map.dart'; import 'package:latlong2/latlong.dart'; @@ -32,8 +31,8 @@ class MapBubble extends StatelessWidget { children: [ FlutterMap( options: MapOptions( - center: LatLng(latitude, longitude), - zoom: zoom, + initialCenter: LatLng(latitude, longitude), + initialZoom: zoom, ), children: [ TileLayer( @@ -50,7 +49,7 @@ class MapBubble extends StatelessWidget { point: LatLng(latitude, longitude), width: 30, height: 30, - builder: (_) => Transform.translate( + child: Transform.translate( // No idea why the offset has to be like this, instead of -15 // It has been determined by trying out, though, that this yields // the tip of the location pin to be static when zooming. diff --git a/lib/pages/chat/events/message.dart b/lib/pages/chat/events/message.dart index 5b1a56cf5e..ff206d2b0a 100644 --- a/lib/pages/chat/events/message.dart +++ b/lib/pages/chat/events/message.dart @@ -25,6 +25,7 @@ import 'verification_request_content.dart'; class Message extends StatelessWidget { final Event event; final Event? nextEvent; + final Event? previousEvent; final bool displayReadMarker; final void Function(Event) onSelect; final void Function(Event) onAvatarTab; @@ -43,10 +44,12 @@ class Message extends StatelessWidget { final bool definitions; final ChatController controller; // Pangea# + final Color? avatarPresenceBackgroundColor; const Message( this.event, { this.nextEvent, + this.previousEvent, this.displayReadMarker = false, this.longPressSelect = false, required this.onSelect, @@ -65,13 +68,25 @@ class Message extends StatelessWidget { required this.definitions, required this.controller, // Pangea# + this.avatarPresenceBackgroundColor, super.key, }); + // #Pangea + PangeaMessageEvent? get pangeaMessageEvent => + controller.getPangeaMessageEvent(event.eventId); + // Pangea# + @override Widget build(BuildContext context) { // #Pangea debugPrint('Message.build()'); + WidgetsBinding.instance.addPostFrameCallback((_) { + if (controller.edittingEvents.contains(event.eventId)) { + pangeaMessageEvent?.updateLatestEdit(); + controller.clearEdittingEvent(event.eventId); + } + }); // Pangea# if (!{ EventTypes.Message, @@ -97,31 +112,40 @@ class Message extends StatelessWidget { final displayTime = event.type == EventTypes.RoomCreate || nextEvent == null || !event.originServerTs.sameEnvironment(nextEvent!.originServerTs); - final sameSender = nextEvent != null && + final nextEventSameSender = nextEvent != null && { EventTypes.Message, EventTypes.Sticker, EventTypes.Encrypted, }.contains(nextEvent!.type) && - nextEvent?.relationshipType == null && nextEvent!.senderId == event.senderId && !displayTime; + + final previousEventSameSender = previousEvent != null && + { + EventTypes.Message, + EventTypes.Sticker, + EventTypes.Encrypted, + }.contains(previousEvent!.type) && + previousEvent!.senderId == event.senderId && + previousEvent!.originServerTs.sameEnvironment(event.originServerTs); + final textColor = ownMessage - ? Theme.of(context).colorScheme.onPrimaryContainer + ? Theme.of(context).colorScheme.onPrimary : Theme.of(context).colorScheme.onBackground; final rowMainAxisAlignment = ownMessage ? MainAxisAlignment.end : MainAxisAlignment.start; final displayEvent = event.getDisplayEvent(timeline); + const hardCorner = Radius.circular(4); + const roundedCorner = Radius.circular(AppConfig.borderRadius); final borderRadius = BorderRadius.only( - topLeft: !ownMessage - ? const Radius.circular(4) - : const Radius.circular(AppConfig.borderRadius), - topRight: const Radius.circular(AppConfig.borderRadius), - bottomLeft: const Radius.circular(AppConfig.borderRadius), - bottomRight: ownMessage - ? const Radius.circular(4) - : const Radius.circular(AppConfig.borderRadius), + topLeft: !ownMessage && nextEventSameSender ? hardCorner : roundedCorner, + topRight: ownMessage && nextEventSameSender ? hardCorner : roundedCorner, + bottomLeft: + !ownMessage && previousEventSameSender ? hardCorner : roundedCorner, + bottomRight: + ownMessage && previousEventSameSender ? hardCorner : roundedCorner, ); final noBubble = { MessageTypes.Video, @@ -137,16 +161,19 @@ class Message extends StatelessWidget { if (ownMessage) { color = displayEvent.status.isError ? Colors.redAccent - : Theme.of(context).colorScheme.primaryContainer; + : Theme.of(context).colorScheme.primary; } // #Pangea - final PangeaMessageEvent? pangeaMessageEvent = - controller.getPangeaMessageEvent(event.eventId); ToolbarDisplayController? toolbarController; - if (event.messageType == MessageTypes.Text || + if (event.type == EventTypes.Message && + event.messageType == MessageTypes.Text || event.messageType == MessageTypes.Notice) { - toolbarController = controller.getToolbarDisplayController(event.eventId); + toolbarController = controller.getToolbarDisplayController( + event.eventId, + nextEvent: nextEvent, + previousEvent: previousEvent, + ); } // Pangea# @@ -179,7 +206,7 @@ class Message extends StatelessWidget { onChanged: (_) => onSelect(event), ), ) - else if (sameSender || ownMessage) + else if (nextEventSameSender || ownMessage) SizedBox( width: Avatar.defaultSize, child: Center( @@ -206,6 +233,7 @@ class Message extends StatelessWidget { mxContent: user.avatarUrl, name: user.calcDisplayname(), presenceUserId: user.stateKey, + presenceBackgroundColor: avatarPresenceBackgroundColor, onTap: () => onAvatarTab(event), ); }, @@ -215,7 +243,7 @@ class Message extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ - if (!sameSender) + if (!nextEventSameSender) Padding( padding: const EdgeInsets.only(left: 8.0, bottom: 4), child: ownMessage || event.room.isDirectChat @@ -231,7 +259,6 @@ class Message extends StatelessWidget { displayname, style: TextStyle( fontSize: 12, - fontWeight: FontWeight.bold, color: (Theme.of(context).brightness == Brightness.light ? displayname.color @@ -253,8 +280,8 @@ class Message extends StatelessWidget { onLongPress: longPressSelect ? null : () { + HapticFeedback.heavyImpact(); onSelect(event); - HapticFeedback.selectionClick(); }, child: AnimatedOpacity( opacity: animateIn @@ -351,7 +378,8 @@ class Message extends StatelessWidget { borderRadius: borderRadius, // #Pangea selected: selected, - pangeaMessageEvent: pangeaMessageEvent, + pangeaMessageEvent: + toolbarController?.pangeaMessageEvent, immersionMode: immersionMode, toolbarController: toolbarController, // Pangea# @@ -361,7 +389,9 @@ class Message extends StatelessWidget { RelationshipTypes.edit, ) // #Pangea || - (pangeaMessageEvent?.showUseType ?? + (toolbarController + ?.pangeaMessageEvent + .showUseType ?? false) // Pangea# ) @@ -373,10 +403,12 @@ class Message extends StatelessWidget { mainAxisSize: MainAxisSize.min, children: [ // #Pangea - if (pangeaMessageEvent - ?.showUseType ?? + if (toolbarController + ?.pangeaMessageEvent + .showUseType ?? false) ...[ - pangeaMessageEvent!.useType + toolbarController! + .pangeaMessageEvent.useType .iconView( context, textColor.withAlpha(164), @@ -447,25 +479,34 @@ class Message extends StatelessWidget { BorderRadius.circular(AppConfig.borderRadius / 2), clipBehavior: Clip.antiAlias, child: Padding( - padding: const EdgeInsets.all(4.0), + padding: const EdgeInsets.only(top: 4.0), child: Text( event.originServerTs.localizedTime(context), - style: TextStyle(fontSize: 13 * AppConfig.fontSizeFactor), + style: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 12 * AppConfig.fontSizeFactor, + color: Theme.of(context).colorScheme.secondary, + ), ), ), ), ), ), row, - if (showReceiptsRow) - Padding( - padding: EdgeInsets.only( - top: 4.0, - left: (ownMessage ? 0 : Avatar.defaultSize) + 12.0, - right: 12.0, - ), - child: MessageReactions(event, timeline), - ), + AnimatedSize( + duration: FluffyThemes.animationDuration, + curve: FluffyThemes.animationCurve, + child: !showReceiptsRow + ? const SizedBox.shrink() + : Padding( + padding: EdgeInsets.only( + top: 4.0, + left: (ownMessage ? 0 : Avatar.defaultSize) + 12.0, + right: ownMessage ? 0 : 12.0, + ), + child: MessageReactions(event, timeline), + ), + ), if (displayReadMarker) Row( children: [ @@ -525,16 +566,18 @@ class Message extends StatelessWidget { constraints: const BoxConstraints( maxWidth: FluffyThemes.columnWidth * 2.5, ), - padding: const EdgeInsets.symmetric( - horizontal: 8.0, - vertical: 4.0, + padding: EdgeInsets.only( + left: 8.0, + right: 8.0, + top: nextEventSameSender ? 1.0 : 4.0, + bottom: previousEventSameSender ? 1.0 : 4.0, ), child: container, ), Positioned( left: ownMessage ? null : 48, right: ownMessage ? 4 : null, - bottom: showReceiptsRow ? 28 : 0, + top: displayTime ? 38 : 0, child: AnimatedScale( duration: Duration( milliseconds: @@ -547,28 +590,50 @@ class Message extends StatelessWidget { child: Material( color: Theme.of(context) .colorScheme - .tertiaryContainer + .secondaryContainer .withOpacity(0.9), elevation: Theme.of(context).appBarTheme.scrolledUnderElevation ?? 4, borderRadius: BorderRadius.circular(AppConfig.borderRadius), shadowColor: Theme.of(context).appBarTheme.shadowColor, - child: SizedBox( - width: 32, - height: 32, - child: IconButton( - icon: Icon( - // #Pangea - // Icons.adaptive.more_outlined, - Icons.add_reaction_outlined, - // Pangea# - size: 16, - color: - Theme.of(context).colorScheme.onTertiaryContainer, + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + if (event.room.canSendDefaultMessages) + SizedBox( + width: 32, + height: 32, + child: IconButton( + icon: Icon( + Icons.reply_outlined, + size: 16, + color: Theme.of(context) + .colorScheme + .onTertiaryContainer, + ), + tooltip: L10n.of(context)!.reply, + onPressed: event.room.canSendDefaultMessages + ? () => onSwipe() + : null, + ), + ), + SizedBox( + width: 32, + height: 32, + child: IconButton( + icon: Icon( + Icons.more_vert, + size: 16, + color: Theme.of(context) + .colorScheme + .onTertiaryContainer, + ), + tooltip: L10n.of(context)!.select, + onPressed: () => onSelect(event), + ), ), - onPressed: () => onSelect(event), - ), + ], ), ), ), diff --git a/lib/pages/chat/events/message_content.dart b/lib/pages/chat/events/message_content.dart index 9b930cf839..935ba0b69e 100644 --- a/lib/pages/chat/events/message_content.dart +++ b/lib/pages/chat/events/message_content.dart @@ -1,4 +1,5 @@ -import 'package:fluffychat/pages/chat/events/html_message.dart'; +import 'dart:math'; + import 'package:fluffychat/pages/chat/events/video_player.dart'; import 'package:fluffychat/pangea/models/pangea_message_event.dart'; import 'package:fluffychat/pangea/widgets/chat/message_context_menu.dart'; @@ -18,10 +19,10 @@ import '../../../utils/platform_infos.dart'; import '../../../utils/url_launcher.dart'; import 'audio_player.dart'; import 'cute_events.dart'; +import 'html_message.dart'; import 'image_bubble.dart'; import 'map_bubble.dart'; import 'message_download_content.dart'; -import 'sticker.dart'; class MessageContent extends StatelessWidget { final Event event; @@ -58,11 +59,7 @@ class MessageContent extends StatelessWidget { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text( - event.type == EventTypes.Encrypted - ? l10n.needPantalaimonWarning - : event.calcLocalizedBodyFallback( - MatrixLocals(l10n), - ), + event.calcLocalizedBodyFallback(MatrixLocals(l10n)), ), ), ); @@ -123,21 +120,54 @@ class MessageContent extends StatelessWidget { final fontSize = AppConfig.messageFontSize * AppConfig.fontSizeFactor; final buttonTextColor = textColor; switch (event.type) { - case EventTypes.Message: + // #Pangea + // case EventTypes.Message: + // Pangea# case EventTypes.Encrypted: + // #Pangea + return _ButtonContent( + textColor: buttonTextColor, + onPressed: () {}, + icon: '🔒', + label: L10n.of(context)!.encrypted, + fontSize: fontSize, + ); + case EventTypes.Message: + // Pangea# case EventTypes.Sticker: switch (event.messageType) { case MessageTypes.Image: + case MessageTypes.Sticker: + if (event.redacted) continue textmessage; + const maxSize = 256.0; + final w = event.content + .tryGetMap('info') + ?.tryGet('w'); + final h = event.content + .tryGetMap('info') + ?.tryGet('h'); + var width = maxSize; + var height = maxSize; + var fit = event.messageType == MessageTypes.Sticker + ? BoxFit.contain + : BoxFit.cover; + if (w != null && h != null) { + fit = BoxFit.contain; + if (w > h) { + width = maxSize; + height = max(32, maxSize * (h / w)); + } else { + height = maxSize; + width = max(32, maxSize * (w / h)); + } + } return ImageBubble( event, - width: 400, - height: 300, - fit: BoxFit.cover, + width: width, + height: height, + fit: fit, borderRadius: borderRadius, ); - case MessageTypes.Sticker: - if (event.redacted) continue textmessage; - return Sticker(event); case CuteEventContent.eventType: return CuteContent(event); case MessageTypes.Audio: @@ -190,14 +220,16 @@ class MessageContent extends StatelessWidget { // else we fall through to the normal message rendering continue textmessage; case MessageTypes.BadEncrypted: - case EventTypes.Encrypted: - return _ButtonContent( - textColor: buttonTextColor, - onPressed: () => _verifyOrRequestKey(context), - icon: '🔒', - label: L10n.of(context)!.encrypted, - fontSize: fontSize, - ); + // #Pangea + // case EventTypes.Encrypted: + // return _ButtonContent( + // textColor: buttonTextColor, + // onPressed: () => _verifyOrRequestKey(context), + // icon: '🔒', + // label: L10n.of(context)!.encrypted, + // fontSize: fontSize, + // ); + // Pangea# case MessageTypes.Location: final geoUri = Uri.tryParse(event.content.tryGet('geo_uri')!); diff --git a/lib/pages/chat/events/message_reactions.dart b/lib/pages/chat/events/message_reactions.dart index 755f8992a3..94482d5271 100644 --- a/lib/pages/chat/events/message_reactions.dart +++ b/lib/pages/chat/events/message_reactions.dart @@ -43,9 +43,11 @@ class MessageReactions extends StatelessWidget { final reactionList = reactionMap.values.toList(); reactionList.sort((a, b) => b.count - a.count > 0 ? 1 : -1); + final ownMessage = event.senderId == event.room.client.userID; return Wrap( spacing: 4.0, runSpacing: 4.0, + alignment: ownMessage ? WrapAlignment.end : WrapAlignment.start, children: [ ...reactionList.map( (r) => _Reaction( @@ -77,8 +79,8 @@ class MessageReactions extends StatelessWidget { ), if (allReactionEvents.any((e) => e.status.isSending)) const SizedBox( - width: 28, - height: 28, + width: 24, + height: 24, child: Padding( padding: EdgeInsets.all(4.0), child: CircularProgressIndicator.adaptive(strokeWidth: 1), @@ -91,17 +93,17 @@ class MessageReactions extends StatelessWidget { class _Reaction extends StatelessWidget { final String? reactionKey; - final int? count; + final int count; final bool? reacted; final void Function()? onTap; final void Function()? onLongPress; const _Reaction({ - this.reactionKey, - this.count, - this.reacted, - this.onTap, - this.onLongPress, + required this.reactionKey, + required this.count, + required this.reacted, + required this.onTap, + required this.onLongPress, }); @override @@ -109,7 +111,7 @@ class _Reaction extends StatelessWidget { final textColor = Theme.of(context).brightness == Brightness.dark ? Colors.white : Colors.black; - final color = Theme.of(context).scaffoldBackgroundColor; + final color = Theme.of(context).colorScheme.background; final fontSize = DefaultTextStyle.of(context).style.fontSize; Widget content; if (reactionKey!.startsWith('mxc://')) { @@ -121,14 +123,16 @@ class _Reaction extends StatelessWidget { width: 9999, height: fontSize, ), - const SizedBox(width: 4), - Text( - count.toString(), - style: TextStyle( - color: textColor, - fontSize: DefaultTextStyle.of(context).style.fontSize, + if (count > 1) ...[ + const SizedBox(width: 4), + Text( + count.toString(), + style: TextStyle( + color: textColor, + fontSize: DefaultTextStyle.of(context).style.fontSize, + ), ), - ), + ], ], ); } else { @@ -137,7 +141,7 @@ class _Reaction extends StatelessWidget { renderKey = renderKey.getRange(0, 9) + Characters('…'); } content = Text( - '$renderKey $count', + renderKey.toString() + (count > 1 ? ' $count' : ''), style: TextStyle( color: textColor, fontSize: DefaultTextStyle.of(context).style.fontSize, @@ -147,19 +151,19 @@ class _Reaction extends StatelessWidget { return InkWell( onTap: () => onTap != null ? onTap!() : null, onLongPress: () => onLongPress != null ? onLongPress!() : null, - borderRadius: BorderRadius.circular(AppConfig.borderRadius), + borderRadius: BorderRadius.circular(AppConfig.borderRadius / 2), child: Container( decoration: BoxDecoration( color: color, - border: reacted! - ? Border.all( - width: 1, - color: Theme.of(context).colorScheme.primary, - ) - : null, - borderRadius: BorderRadius.circular(AppConfig.borderRadius), + border: Border.all( + width: 1, + color: reacted! + ? Theme.of(context).colorScheme.primary + : Theme.of(context).colorScheme.primaryContainer, + ), + borderRadius: BorderRadius.circular(AppConfig.borderRadius / 2), ), - padding: const EdgeInsets.symmetric(horizontal: 5, vertical: 3), + padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 2), child: content, ), ); diff --git a/lib/pages/chat/events/reply_content.dart b/lib/pages/chat/events/reply_content.dart index 830f630a4e..c4813f5852 100644 --- a/lib/pages/chat/events/reply_content.dart +++ b/lib/pages/chat/events/reply_content.dart @@ -10,12 +10,14 @@ class ReplyContent extends StatelessWidget { final Event replyEvent; final bool ownMessage; final Timeline? timeline; + final Color? backgroundColor; const ReplyContent( this.replyEvent, { this.ownMessage = false, super.key, this.timeline, + this.backgroundColor, }); static const BorderRadius borderRadius = BorderRadius.only( @@ -29,9 +31,16 @@ class ReplyContent extends StatelessWidget { final displayEvent = timeline != null ? replyEvent.getDisplayEvent(timeline) : replyEvent; final fontSize = AppConfig.messageFontSize * AppConfig.fontSizeFactor; + final color = ownMessage + ? Theme.of(context).colorScheme.primaryContainer + : Theme.of(context).colorScheme.primary; return Material( - color: Theme.of(context).colorScheme.background.withOpacity(0.33), + color: backgroundColor ?? + Theme.of(context) + .colorScheme + .background + .withOpacity(ownMessage ? 0.2 : 0.33), borderRadius: borderRadius, child: Row( mainAxisSize: MainAxisSize.min, @@ -39,7 +48,7 @@ class ReplyContent extends StatelessWidget { Container( width: 3, height: fontSize * 2 + 16, - color: Theme.of(context).colorScheme.primary, + color: color, ), const SizedBox(width: 6), Flexible( @@ -56,7 +65,7 @@ class ReplyContent extends StatelessWidget { overflow: TextOverflow.ellipsis, style: TextStyle( fontWeight: FontWeight.bold, - color: Theme.of(context).colorScheme.primary, + color: color, fontSize: fontSize, ), ); @@ -72,7 +81,7 @@ class ReplyContent extends StatelessWidget { maxLines: 1, style: TextStyle( color: ownMessage - ? Theme.of(context).colorScheme.onPrimaryContainer + ? Theme.of(context).colorScheme.onPrimary : 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 b5e54eba33..861247b95e 100644 --- a/lib/pages/chat/events/state_message.dart +++ b/lib/pages/chat/events/state_message.dart @@ -13,15 +13,12 @@ class StateMessage extends StatelessWidget { @override Widget build(BuildContext context) { return Padding( - padding: const EdgeInsets.symmetric( - horizontal: 8.0, - vertical: 4.0, - ), + padding: const EdgeInsets.symmetric(horizontal: 8.0), child: Center( child: Container( padding: const EdgeInsets.all(8), decoration: BoxDecoration( - color: Theme.of(context).colorScheme.onInverseSurface, + color: Theme.of(context).colorScheme.background, borderRadius: BorderRadius.circular(AppConfig.borderRadius / 2), ), child: FutureBuilder( @@ -34,8 +31,7 @@ class StateMessage extends StatelessWidget { ), textAlign: TextAlign.center, style: TextStyle( - fontSize: 14 * AppConfig.fontSizeFactor, - color: Theme.of(context).colorScheme.onSecondaryContainer, + fontSize: 12 * AppConfig.fontSizeFactor, decoration: event.redacted ? TextDecoration.lineThrough : null, ), diff --git a/lib/pages/chat/events/sticker.dart b/lib/pages/chat/events/sticker.dart deleted file mode 100644 index 8e52bfe397..0000000000 --- a/lib/pages/chat/events/sticker.dart +++ /dev/null @@ -1,40 +0,0 @@ -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 '../../../config/app_config.dart'; -import 'image_bubble.dart'; - -class Sticker extends StatefulWidget { - final Event event; - - const Sticker(this.event, {super.key}); - - @override - StickerState createState() => StickerState(); -} - -class StickerState extends State { - bool? animated; - - @override - Widget build(BuildContext context) { - return ImageBubble( - widget.event, - width: 400, - height: 400, - fit: BoxFit.contain, - onTap: () { - setState(() => animated = true); - showOkAlertDialog( - context: context, - message: widget.event.body, - okLabel: L10n.of(context)!.ok, - ); - }, - animated: animated ?? AppConfig.autoplayImages, - ); - } -} diff --git a/lib/pages/chat/events/video_player.dart b/lib/pages/chat/events/video_player.dart index 573e1eb145..66e50b7833 100644 --- a/lib/pages/chat/events/video_player.dart +++ b/lib/pages/chat/events/video_player.dart @@ -4,7 +4,6 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:chewie/chewie.dart'; -import 'package:flutter_blurhash/flutter_blurhash.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:matrix/matrix.dart'; import 'package:path_provider/path_provider.dart'; @@ -14,6 +13,7 @@ import 'package:video_player/video_player.dart'; import 'package:fluffychat/pages/chat/events/image_bubble.dart'; import 'package:fluffychat/utils/localized_exception_extension.dart'; import 'package:fluffychat/utils/matrix_sdk_extensions/event_extension.dart'; +import 'package:fluffychat/widgets/blur_hash.dart'; import '../../../utils/error_reporter.dart'; class EventVideoPlayer extends StatefulWidget { @@ -112,7 +112,7 @@ class EventVideoPlayerState extends State { ), ) else - BlurHash(hash: blurHash), + BlurHash(blurhash: blurHash, width: 300, height: 300), Center( child: OutlinedButton.icon( style: OutlinedButton.styleFrom( diff --git a/lib/pages/chat/input_bar.dart b/lib/pages/chat/input_bar.dart index cad1391ce1..8d4bfe6174 100644 --- a/lib/pages/chat/input_bar.dart +++ b/lib/pages/chat/input_bar.dart @@ -1,15 +1,15 @@ +import 'package:emojis/emoji.dart'; +import 'package:fluffychat/config/app_config.dart'; +import 'package:fluffychat/pangea/widgets/igc/pangea_text_controller.dart'; +import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_file_extension.dart'; +import 'package:fluffychat/utils/platform_infos.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; - -import 'package:emojis/emoji.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 '../../widgets/matrix.dart'; class InputBar extends StatelessWidget { @@ -455,16 +455,34 @@ class InputBar extends StatelessWidget { link: controller!.choreographer.inputLayerLinkAndKey.link, // Pangea# child: TypeAheadField>( - direction: AxisDirection.up, + direction: VerticalDirection.up, hideOnEmpty: true, hideOnLoading: true, - keepSuggestionsOnSuggestionSelected: true, + controller: controller, + focusNode: focusNode, + hideOnSelect: false, debounceDuration: const Duration(milliseconds: 50), // show suggestions after 50ms idle time (default is 300) // #Pangea key: controller!.choreographer.inputLayerLinkAndKey.key, - // Pangea# - textFieldConfiguration: TextFieldConfiguration( + // builder: (context, controller, focusNode) => TextField( + builder: (context, _, focusNode) => TextField( + // Pangea# + controller: controller, + focusNode: focusNode, + contentInsertionConfiguration: ContentInsertionConfiguration( + onContentInserted: (KeyboardInsertedContent content) { + final data = content.data; + if (data == null) return; + + final file = MatrixFile( + mimeType: content.mimeType, + bytes: data, + name: content.uri.split('/').last, + ).detectFileType; + room.sendFileEvent(file, shrinkImageMaxDimension: 1600); + }, + ), minLines: minLines, maxLines: maxLines, keyboardType: keyboardType!, @@ -479,13 +497,11 @@ class InputBar extends StatelessWidget { onTap: () { controller!.onInputTap( context, - fNode: focusNode!, + 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 @@ -496,13 +512,13 @@ class InputBar extends StatelessWidget { suggestionsCallback: getSuggestions, itemBuilder: (c, s) => buildSuggestion(c, s, Matrix.of(context).client), - onSuggestionSelected: (Map suggestion) => + onSelected: (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 + emptyBuilder: (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 669ca737a3..be4ea73ed5 100644 --- a/lib/pages/chat/pinned_events.dart +++ b/lib/pages/chat/pinned_events.dart @@ -4,14 +4,12 @@ import 'package:flutter/material.dart'; import 'package:adaptive_dialog/adaptive_dialog.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; -import 'package:flutter_linkify/flutter_linkify.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/pages/chat/chat.dart'; +import 'package:fluffychat/pages/chat/chat_app_bar_list_tile.dart'; import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart'; -import 'package:fluffychat/utils/url_launcher.dart'; class PinnedEvents extends StatelessWidget { final ChatController controller; @@ -65,80 +63,32 @@ class PinnedEvents extends StatelessWidget { future: controller.room.getEventById(pinnedEventIds.last), builder: (context, snapshot) { final event = snapshot.data; - - if (event == null) { - return const SizedBox.shrink(); - } - - final fontSize = AppConfig.messageFontSize * AppConfig.fontSizeFactor; - return Material( - color: Theme.of(context).colorScheme.surfaceVariant, - shape: Border( - bottom: BorderSide( - width: 1, - color: Theme.of(context).dividerColor, - ), + return FutureBuilder( + future: event?.calcLocalizedBody( + MatrixLocals(L10n.of(context)!), + withSenderNamePrefix: true, + hideReply: true, ), - child: InkWell( - onTap: () => _displayPinnedEventsDialog(context), - child: Row( - children: [ - IconButton( - splashRadius: 20, - iconSize: 20, - color: Theme.of(context).colorScheme.onSurfaceVariant, - icon: const Icon(Icons.push_pin), - tooltip: L10n.of(context)!.unpin, - onPressed: - controller.room.canSendEvent(EventTypes.RoomPinnedEvents) - ? () => controller.unpinEvent(event.eventId) - : null, - ), - Expanded( - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 4.0), - child: FutureBuilder( - future: event.calcLocalizedBody( - MatrixLocals(L10n.of(context)!), - withSenderNamePrefix: true, - hideReply: true, - ), - builder: (context, snapshot) { - return Linkify( - text: snapshot.data ?? - event.calcLocalizedBodyFallback( - MatrixLocals(L10n.of(context)!), - withSenderNamePrefix: true, - hideReply: true, - ), - options: const LinkifyOptions(humanize: false), - maxLines: 2, - style: TextStyle( - color: - Theme.of(context).colorScheme.onSurfaceVariant, - overflow: TextOverflow.ellipsis, - fontSize: fontSize, - decoration: event.redacted - ? TextDecoration.lineThrough - : null, - ), - linkStyle: TextStyle( - color: - Theme.of(context).colorScheme.onSurfaceVariant, - fontSize: fontSize, - decoration: TextDecoration.underline, - decorationColor: - Theme.of(context).colorScheme.onSurfaceVariant, - ), - onOpen: (url) => - UrlLauncher(context, url.url).launchUrl(), - ); - }, - ), - ), - ), - ], + builder: (context, snapshot) => ChatAppBarListTile( + title: snapshot.data ?? + event?.calcLocalizedBodyFallback( + MatrixLocals(L10n.of(context)!), + withSenderNamePrefix: true, + hideReply: true, + ) ?? + L10n.of(context)!.loadingPleaseWait, + leading: IconButton( + splashRadius: 20, + iconSize: 20, + color: Theme.of(context).colorScheme.onSurfaceVariant, + icon: const Icon(Icons.push_pin), + tooltip: L10n.of(context)!.unpin, + onPressed: + controller.room.canSendEvent(EventTypes.RoomPinnedEvents) + ? () => controller.unpinEvent(event!.eventId) + : null, ), + onTap: () => _displayPinnedEventsDialog(context), ), ); }, diff --git a/lib/pages/chat/reactions_picker.dart b/lib/pages/chat/reactions_picker.dart index 6434c99703..7256e00bc4 100644 --- a/lib/pages/chat/reactions_picker.dart +++ b/lib/pages/chat/reactions_picker.dart @@ -60,7 +60,7 @@ class ReactionsPicker extends StatelessWidget { Expanded( child: Container( decoration: BoxDecoration( - color: Theme.of(context).secondaryHeaderColor, + color: Theme.of(context).colorScheme.onInverseSurface, borderRadius: const BorderRadius.only( bottomRight: Radius.circular(AppConfig.borderRadius), ), @@ -92,7 +92,7 @@ class ReactionsPicker extends StatelessWidget { width: 36, height: 56, decoration: BoxDecoration( - color: Theme.of(context).secondaryHeaderColor, + color: Theme.of(context).colorScheme.onInverseSurface, shape: BoxShape.circle, ), child: const Icon(Icons.add_outlined), diff --git a/lib/pages/chat/recording_dialog.dart b/lib/pages/chat/recording_dialog.dart index a0ba712d39..2fdc1e07bc 100644 --- a/lib/pages/chat/recording_dialog.dart +++ b/lib/pages/chat/recording_dialog.dart @@ -27,10 +27,7 @@ class RecordingDialogState extends State { bool error = false; String? _recordedPath; - // #Pangea - // final _audioRecorder = Record(); - final _audioRecorder = AudioRecorder(); - // Pangea# + final _audioRecorder = Record(); final List amplitudeTimeline = []; static const int bitRate = 64000; @@ -48,28 +45,11 @@ 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; - // #Pangea - // await _audioRecorder.start( - // path: _recordedPath, - // bitRate: bitRate, - // samplingRate: samplingRate, - // ); await _audioRecorder.start( - RecordConfig( - encoder: audioCodec, - bitRate: bitRate, - // samplingRate: samplingRate, - ), - path: _recordedPath!, + path: _recordedPath, + bitRate: bitRate, + samplingRate: samplingRate, ); - // Pangea# setState(() => _duration = Duration.zero); _recorderSubscription?.cancel(); _recorderSubscription = diff --git a/lib/pages/chat/reply_display.dart b/lib/pages/chat/reply_display.dart index 3bb638abc6..67bf47c527 100644 --- a/lib/pages/chat/reply_display.dart +++ b/lib/pages/chat/reply_display.dart @@ -21,29 +21,28 @@ class ReplyDisplay extends StatelessWidget { ? 56 : 0, clipBehavior: Clip.hardEdge, - decoration: const BoxDecoration(), - child: Material( - color: Theme.of(context).secondaryHeaderColor, - child: Row( - children: [ - IconButton( - tooltip: L10n.of(context)!.close, - icon: const Icon(Icons.close), - onPressed: controller.cancelReplyEventAction, - ), - Expanded( - child: controller.replyEvent != null - ? ReplyContent( - controller.replyEvent!, - timeline: controller.timeline!, - ) - : _EditContent( - controller.editEvent - ?.getDisplayEvent(controller.timeline!), - ), - ), - ], - ), + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.onInverseSurface, + ), + child: Row( + children: [ + IconButton( + tooltip: L10n.of(context)!.close, + icon: const Icon(Icons.close), + onPressed: controller.cancelReplyEventAction, + ), + Expanded( + child: controller.replyEvent != null + ? ReplyContent( + controller.replyEvent!, + timeline: controller.timeline!, + backgroundColor: Colors.transparent, + ) + : _EditContent( + controller.editEvent?.getDisplayEvent(controller.timeline!), + ), + ), + ], ), ); } diff --git a/lib/pages/chat/send_file_dialog.dart b/lib/pages/chat/send_file_dialog.dart index e5f070fd7b..b2885a635a 100644 --- a/lib/pages/chat/send_file_dialog.dart +++ b/lib/pages/chat/send_file_dialog.dart @@ -37,7 +37,7 @@ class SendFileDialogState extends State { await showFutureLoadingDialog( context: context, future: () async { - file = await file.resizeVideo(); + file = origImage ? file : await file.resizeVideo(); thumbnail = await file.getVideoThumbnail(); }, ); @@ -126,6 +126,38 @@ class SendFileDialogState extends State { ), ], ); + } else if (widget.files.every((file) => file is MatrixVideoFile)) { + contentWidget = Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text(fileName), + const SizedBox(height: 16), + // Workaround for SwitchListTile.adaptive crashes in CupertinoDialog + Row( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + CupertinoSwitch( + value: origImage, + onChanged: (v) => setState(() => origImage = v), + ), + 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), + ], + ), + ), + ], + ), + ], + ); } else { contentWidget = Text('$fileName ($sizeString)'); } diff --git a/lib/pages/chat/sticker_picker_dialog.dart b/lib/pages/chat/sticker_picker_dialog.dart index 16065c9162..39e8fef5df 100644 --- a/lib/pages/chat/sticker_picker_dialog.dart +++ b/lib/pages/chat/sticker_picker_dialog.dart @@ -1,15 +1,20 @@ +import 'package:fluffychat/config/app_config.dart'; +import 'package:fluffychat/widgets/mxc_image.dart'; import 'package:flutter/material.dart'; - import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:matrix/matrix.dart'; import '../../widgets/avatar.dart'; -import 'events/image_bubble.dart'; class StickerPickerDialog extends StatefulWidget { final Room room; + final void Function(ImagePackImageContent) onSelected; - const StickerPickerDialog({required this.room, super.key}); + const StickerPickerDialog({ + required this.onSelected, + required this.room, + super.key, + }); @override StickerPickerDialogState createState() => StickerPickerDialogState(); @@ -58,24 +63,14 @@ class StickerPickerDialogState extends State { GridView.builder( itemCount: imageKeys.length, gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent( - maxCrossAxisExtent: 100, + maxCrossAxisExtent: 128, ), shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), itemBuilder: (BuildContext context, int imageIndex) { final image = pack.images[imageKeys[imageIndex]]!; - final fakeEvent = Event( - type: EventTypes.Sticker, - content: { - 'url': image.url.toString(), - 'info': image.info, - }, - originServerTs: DateTime.now(), - room: widget.room, - eventId: 'fake_event', - senderId: widget.room.client.userID!, - ); return InkWell( + radius: AppConfig.borderRadius, key: ValueKey(image.url.toString()), onTap: () { // copy the image @@ -83,17 +78,16 @@ class StickerPickerDialogState extends State { ImagePackImageContent.fromJson(image.toJson().copy()); // set the body, if it doesn't exist, to the key imageCopy.body ??= imageKeys[imageIndex]; - Navigator.of(context, rootNavigator: false) - .pop(imageCopy); + widget.onSelected(imageCopy); }, child: AbsorbPointer( absorbing: true, - child: ImageBubble( - fakeEvent, - tapToView: false, + child: MxcImage( + uri: image.url, fit: BoxFit.contain, - width: 100, - height: 100, + width: 128, + height: 128, + animated: true, ), ), ); @@ -104,6 +98,7 @@ class StickerPickerDialogState extends State { }; return Scaffold( + backgroundColor: Theme.of(context).colorScheme.onInverseSurface, body: SizedBox( width: double.maxFinite, child: CustomScrollView( @@ -112,28 +107,49 @@ class StickerPickerDialogState extends State { floating: true, pinned: true, automaticallyImplyLeading: false, - titleSpacing: 0, - backgroundColor: Theme.of(context).dialogBackgroundColor, - leading: IconButton( - icon: const Icon(Icons.close), - onPressed: Navigator.of(context, rootNavigator: false).pop, - ), - title: TextField( - autofocus: false, - decoration: InputDecoration( - hintText: L10n.of(context)!.search, - suffix: const Icon(Icons.search_outlined), - contentPadding: const EdgeInsets.symmetric(horizontal: 16), + backgroundColor: Colors.transparent, + title: SizedBox( + height: 42, + child: TextField( + autofocus: false, + decoration: InputDecoration( + hintText: L10n.of(context)!.search, + prefixIcon: const Icon(Icons.search_outlined), + contentPadding: EdgeInsets.zero, + ), + onChanged: (s) => setState(() => searchFilter = s), ), - onChanged: (s) => setState(() => searchFilter = s), ), ), - SliverList( - delegate: SliverChildBuilderDelegate( - packBuilder, - childCount: packSlugs.length, + if (packSlugs.isEmpty) + SliverFillRemaining( + child: Center( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text(L10n.of(context)!.noEmotesFound), + // #Pangea + // const SizedBox(height: 12), + // OutlinedButton.icon( + // onPressed: () => UrlLauncher( + // context, + // 'https://matrix.to/#/#fluffychat-stickers:janian.de', + // ).launchUrl(), + // icon: const Icon(Icons.explore_outlined), + // label: Text(L10n.of(context)!.discover), + // ), + // Pangea# + ], + ), + ), + ) + else + SliverList( + delegate: SliverChildBuilderDelegate( + packBuilder, + childCount: packSlugs.length, + ), ), - ), ], ), ), diff --git a/lib/pages/chat/tombstone_display.dart b/lib/pages/chat/tombstone_display.dart deleted file mode 100644 index e080a00095..0000000000 --- a/lib/pages/chat/tombstone_display.dart +++ /dev/null @@ -1,45 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'package:flutter_gen/gen_l10n/l10n.dart'; -import 'package:matrix/matrix.dart'; - -import 'chat.dart'; - -class TombstoneDisplay extends StatelessWidget { - final ChatController controller; - const TombstoneDisplay(this.controller, {super.key}); - - @override - Widget build(BuildContext context) { - if (controller.room.getState(EventTypes.RoomTombstone) == null) { - return const SizedBox.shrink(); - } - return SizedBox( - height: 72, - child: Material( - color: Theme.of(context).colorScheme.surfaceVariant, - elevation: 1, - child: ListTile( - leading: CircleAvatar( - foregroundColor: Theme.of(context).colorScheme.onSecondary, - backgroundColor: Theme.of(context).colorScheme.secondary, - child: const Icon(Icons.upgrade_outlined), - ), - title: Text( - controller.room - .getState(EventTypes.RoomTombstone)! - .parsedTombstoneContent - .body, - maxLines: 1, - overflow: TextOverflow.ellipsis, - style: TextStyle( - color: Theme.of(context).colorScheme.onSurfaceVariant, - ), - ), - subtitle: Text(L10n.of(context)!.goToTheNewRoom), - onTap: controller.goToNewRoomAction, - ), - ), - ); - } -} diff --git a/lib/pages/chat/typing_indicators.dart b/lib/pages/chat/typing_indicators.dart index 8101fd76fe..e816f465d5 100644 --- a/lib/pages/chat/typing_indicators.dart +++ b/lib/pages/chat/typing_indicators.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:flutter/material.dart'; import 'package:fluffychat/config/app_config.dart'; @@ -70,10 +72,7 @@ class TypingIndicators extends StatelessWidget { Padding( padding: const EdgeInsets.only(top: topPadding), child: Material( - color: Theme.of(context).appBarTheme.backgroundColor, - elevation: 6, - shadowColor: - Theme.of(context).secondaryHeaderColor.withAlpha(100), + color: Theme.of(context).colorScheme.surfaceVariant, borderRadius: const BorderRadius.only( topLeft: Radius.circular(2), topRight: Radius.circular(AppConfig.borderRadius), @@ -81,14 +80,8 @@ class TypingIndicators extends StatelessWidget { bottomRight: Radius.circular(AppConfig.borderRadius), ), child: Padding( - padding: const EdgeInsets.all(8), - child: typingUsers.isEmpty - ? null - : Image.asset( - 'assets/typing.gif', - height: 30, - filterQuality: FilterQuality.medium, - ), + padding: const EdgeInsets.symmetric(horizontal: 8), + child: typingUsers.isEmpty ? null : const _TypingDots(), ), ), ), @@ -98,3 +91,66 @@ class TypingIndicators extends StatelessWidget { ); } } + +class _TypingDots extends StatefulWidget { + const _TypingDots(); + + @override + State<_TypingDots> createState() => __TypingDotsState(); +} + +class __TypingDotsState extends State<_TypingDots> { + int _tick = 0; + + late final Timer _timer; + + static const Duration animationDuration = Duration(milliseconds: 300); + + @override + void initState() { + _timer = Timer.periodic( + animationDuration, + (_) { + if (!mounted) { + return; + } + setState(() { + _tick = (_tick + 1) % 4; + }); + }, + ); + super.initState(); + } + + @override + void dispose() { + _timer.cancel(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + const size = 8.0; + + return Row( + mainAxisSize: MainAxisSize.min, + children: [ + for (var i = 1; i <= 3; i++) + AnimatedContainer( + duration: animationDuration * 1.5, + curve: FluffyThemes.animationCurve, + width: size, + height: _tick == i ? size * 2 : size, + margin: EdgeInsets.symmetric( + horizontal: 2, + vertical: _tick == i ? 4 : 8, + ), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(size * 2), + color: Theme.of(context).colorScheme.secondary, + ), + ), + ], + ); + } +} diff --git a/lib/pages/chat_details/chat_details.dart b/lib/pages/chat_details/chat_details.dart index e600f1a51c..07a12876e0 100644 --- a/lib/pages/chat_details/chat_details.dart +++ b/lib/pages/chat_details/chat_details.dart @@ -24,10 +24,12 @@ enum AliasActions { copy, delete, setCanonical } class ChatDetails extends StatefulWidget { final String roomId; + final Widget? embeddedCloseButton; const ChatDetails({ super.key, required this.roomId, + this.embeddedCloseButton, }); @override @@ -84,34 +86,19 @@ class ChatDetailsController extends State { void editAliases() async { final room = Matrix.of(context).client.getRoomById(roomId!); - // The current endpoint doesnt seem to be implemented in Synapse. This may - // change in the future and then we just need to switch to this api call: - // - // final aliases = await showFutureLoadingDialog( - // context: context, - // future: () => room.client.requestRoomAliases(room.id), - // ); - // - // While this is not working we use the unstable api: - final aliases = await showFutureLoadingDialog( + final aliasesResult = await showFutureLoadingDialog( context: context, - future: () => room!.client - .request( - RequestType.GET, - '/client/unstable/org.matrix.msc2432/rooms/${Uri.encodeComponent(room.id)}/aliases', - ) - .then( - (response) => List.from(response['aliases'] as Iterable), - ), + future: () => room!.client.getLocalAliases(room.id), ); - // Switch to the stable api once it is implemented. - if (aliases.error != null) return; - final adminMode = room!.canSendEvent('m.room.canonical_alias'); - if (aliases.result!.isEmpty && (room.canonicalAlias.isNotEmpty)) { - aliases.result!.add(room.canonicalAlias); + final aliases = aliasesResult.result; + + if (aliases == null) return; + final adminMode = room!.canSendEvent(EventTypes.RoomCanonicalAlias); + if (aliases.isEmpty && (room.canonicalAlias.isNotEmpty)) { + aliases.add(room.canonicalAlias); } - if (aliases.result!.isEmpty && adminMode) { + if (aliases.isEmpty && adminMode) { return setAliasAction(); } final select = await showConfirmationDialog( @@ -123,8 +110,7 @@ class ChatDetailsController extends State { actions: [ if (adminMode) AlertDialogAction(label: L10n.of(context)!.create, key: 'new'), - ...aliases.result! - .map((alias) => AlertDialogAction(key: alias, label: alias)), + ...aliases.map((alias) => AlertDialogAction(key: alias, label: alias)), ], ); if (select == null) return; diff --git a/lib/pages/chat_details/chat_details_view.dart b/lib/pages/chat_details/chat_details_view.dart index 434e1e41db..ddb64b1676 100644 --- a/lib/pages/chat_details/chat_details_view.dart +++ b/lib/pages/chat_details/chat_details_view.dart @@ -46,8 +46,6 @@ class ChatDetailsView extends StatelessWidget { ); } - final isEmbedded = GoRouterState.of(context).fullPath == '/rooms/:roomid'; - return StreamBuilder( stream: room.onUpdate.stream, builder: (context, snapshot) { @@ -62,36 +60,35 @@ class ChatDetailsView extends StatelessWidget { MatrixLocals(L10n.of(context)!), ); return Scaffold( - appBar: isEmbedded - ? null - : AppBar( - leading: const Center(child: BackButton()), - elevation: Theme.of(context).appBarTheme.elevation, - actions: [ - // #Pangeas - // 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), - ], - // #Pangea - title: ClassNameHeader( - controller: controller, - room: room, - ), - // title: Text(L10n.of(context)!.chatDetails), - // Pangea# - backgroundColor: - Theme.of(context).appBarTheme.backgroundColor, - ), + appBar: AppBar( + leading: controller.widget.embeddedCloseButton ?? + const Center(child: BackButton()), + elevation: Theme.of(context).appBarTheme.elevation, + actions: [ + // #Pangeas + //if (room.canonicalAlias.isNotEmpty) + // IconButton( + // tooltip: L10n.of(context)!.share, + // icon: Icon(Icons.adaptive.share_outlined), + // onPressed: () => FluffyShare.share( + // L10n.of(context)!.youInvitedToBy( + // AppConfig.inviteLinkPrefix + room.canonicalAlias, + // ), + // context, + // ), + // ), + if (controller.widget.embeddedCloseButton == null) + ChatSettingsPopupMenu(room, false), + ], + // #Pangea + title: ClassNameHeader( + controller: controller, + room: room, + ), + // title: Text(L10n.of(context)!.chatDetails), + // Pangea# + backgroundColor: Theme.of(context).appBarTheme.backgroundColor, + ), body: MaxWidthBody( child: ListView.builder( physics: const NeverScrollableScrollPhysics(), @@ -124,7 +121,9 @@ class ChatDetailsView extends StatelessWidget { ), ), child: Hero( - tag: isEmbedded + tag: controller + .widget.embeddedCloseButton != + null ? 'embedded_content_banner' : 'content_banner', child: Avatar( diff --git a/lib/pages/chat_encryption_settings/chat_encryption_settings.dart b/lib/pages/chat_encryption_settings/chat_encryption_settings.dart index c7aed03a37..559aa20633 100644 --- a/lib/pages/chat_encryption_settings/chat_encryption_settings.dart +++ b/lib/pages/chat_encryption_settings/chat_encryption_settings.dart @@ -70,6 +70,15 @@ class ChatEncryptionSettingsController extends State { } void startVerification() async { + final consent = await showOkCancelAlertDialog( + context: context, + title: L10n.of(context)!.verifyOtherUser, + message: L10n.of(context)!.verifyOtherUserDescription, + okLabel: L10n.of(context)!.ok, + cancelLabel: L10n.of(context)!.cancel, + fullyCapitalizedForMaterial: false, + ); + if (consent != OkCancelResult.ok) return; final req = await room.client.userDeviceKeys[room.directChatMatrixID]! .startVerification(); req.onUpdate = () { diff --git a/lib/pages/chat_list/chat_list.dart b/lib/pages/chat_list/chat_list.dart index 7dd0a735e9..c39298d6c8 100644 --- a/lib/pages/chat_list/chat_list.dart +++ b/lib/pages/chat_list/chat_list.dart @@ -6,7 +6,6 @@ import 'package:collection/collection.dart'; 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/pangea/controllers/pangea_controller.dart'; import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart'; import 'package:fluffychat/pangea/utils/add_to_space.dart'; @@ -23,6 +22,7 @@ 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:flutter_shortcuts/flutter_shortcuts.dart'; import 'package:future_loading_dialog/future_loading_dialog.dart'; import 'package:go_router/go_router.dart'; import 'package:matrix/matrix.dart'; @@ -30,6 +30,7 @@ import 'package:receive_sharing_intent/receive_sharing_intent.dart'; import 'package:uni_links/uni_links.dart'; import '../../../utils/account_bundles.dart'; +import '../../config/setting_keys.dart'; import '../../utils/matrix_sdk_extensions/matrix_file_extension.dart'; import '../../utils/url_launcher.dart'; import '../../utils/voip/callkeep_manager.dart'; @@ -281,12 +282,34 @@ class ChatListController extends State } SearchUserDirectoryResponse? userSearchResult; QueryPublicRoomsResponse? roomSearchResult; + final searchQuery = searchController.text.trim(); try { roomSearchResult = await client.queryPublicRooms( server: searchServer, - filter: PublicRoomQueryFilter(genericSearchTerm: searchController.text), + filter: PublicRoomQueryFilter(genericSearchTerm: searchQuery), limit: 20, ); + + if (searchQuery.isValidMatrixId && + searchQuery.sigil == '#' && + roomSearchResult.chunk + .any((room) => room.canonicalAlias == searchQuery) == + false) { + final response = await client.getRoomIdByAlias(searchQuery); + final roomId = response.roomId; + if (roomId != null) { + roomSearchResult.chunk.add( + PublicRoomsChunk( + name: searchQuery, + guestCanJoin: false, + numJoinedMembers: 0, + roomId: roomId, + worldReadable: false, + canonicalAlias: searchQuery, + ), + ); + } + } userSearchResult = await client.searchUserDirectory( searchController.text, limit: 20, @@ -309,7 +332,7 @@ class ChatListController extends State }); } - void onSearchEnter(String text) { + void onSearchEnter(String text, {bool globalSearch = true}) { if (text.isEmpty) { cancelSearch(unfocus: false); return; @@ -319,7 +342,9 @@ class ChatListController extends State isSearchMode = true; }); _coolDown?.cancel(); - _coolDown = Timer(const Duration(milliseconds: 500), _search); + if (globalSearch) { + _coolDown = Timer(const Duration(milliseconds: 500), _search); + } } void startSearch() { @@ -445,6 +470,16 @@ class ChatListController extends State FluffyChatApp.gotInitialLink = true; getInitialLink().then(_processIncomingUris); } + + if (PlatformInfos.isAndroid) { + final shortcuts = FlutterShortcuts(); + shortcuts.initialize().then( + (_) => shortcuts.listenAction((action) { + if (!mounted) return; + UrlLauncher(context, action).launchUrl(); + }), + ); + } } //#Pangea @@ -620,6 +655,18 @@ class ChatListController extends State // Pangea# } + void dismissStatusList() async { + final result = await showOkCancelAlertDialog( + title: L10n.of(context)!.hidePresences, + context: context, + ); + if (result == OkCancelResult.ok) { + await Matrix.of(context).store.setBool(SettingKeys.showPresences, false); + AppConfig.showPresences = false; + setState(() {}); + } + } + void setStatus() async { final client = Matrix.of(context).client; final currentPresence = await client.fetchCurrentPresence(client.userID!); @@ -746,6 +793,7 @@ class ChatListController extends State final client = Matrix.of(context).client; await client.roomsLoading; await client.accountDataLoading; + await client.userDeviceKeysLoading; if (client.prevBatch == null) { await client.onSync.stream.first; // #Pangea @@ -770,6 +818,7 @@ class ChatListController extends State await pangeaController.subscriptionController.initialize(); pangeaController.afterSyncAndFirstLoginInitialization(context); await pangeaController.inviteBotToExistingSpaces(); + await pangeaController.setPangeaPushRules(); } else { ErrorHandler.logError( m: "didn't run afterSyncAndFirstLoginInitialization because not mounted", @@ -896,8 +945,7 @@ class ChatListController extends State isTorBrowser = isTor; } - Future dehydrate() => - SettingsSecurityController.dehydrateDevice(context); + Future dehydrate() => Matrix.of(context).dehydrateAction(); } enum EditBundleAction { addToBundle, removeFromBundle } diff --git a/lib/pages/chat_list/chat_list_body.dart b/lib/pages/chat_list/chat_list_body.dart index 20737b66f2..55161b9b6e 100644 --- a/lib/pages/chat_list/chat_list_body.dart +++ b/lib/pages/chat_list/chat_list_body.dart @@ -3,6 +3,7 @@ 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/utils/on_chat_tap.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'; @@ -130,10 +131,14 @@ class ChatListViewBody extends StatelessWidget { ], // #Pangea // if (!controller.isSearchMode && - // controller.activeFilter != ActiveFilter.groups) - // StatusMessageList( - // onStatusEdit: controller.setStatus, - // ), + // controller.activeFilter != ActiveFilter.groups && + // AppConfig.showPresences) + // GestureDetector( + // onLongPress: () => controller.dismissStatusList(), + // child: StatusMessageList( + // onStatusEdit: controller.setStatus, + // ), + // ), // Pangea# const ConnectionStatusHeader(), AnimatedContainer( @@ -253,6 +258,7 @@ class ChatListViewBody extends StatelessWidget { )) { return const SizedBox.shrink(); } + final activeChat = controller.activeChat == rooms[i].id; return ChatListItem( rooms[i], key: Key('chat_list_item_${rooms[i].id}'), @@ -260,10 +266,10 @@ class ChatListViewBody extends StatelessWidget { controller.selectedRoomIds.contains(rooms[i].id), onTap: controller.selectMode == SelectMode.select ? () => controller.toggleSelection(rooms[i].id) - : null, + : () => onChatTap(rooms[i], context), onLongPress: () => controller.toggleSelection(rooms[i].id), - activeChat: controller.activeChat == rooms[i].id, + activeChat: activeChat, ); }, childCount: rooms.length, diff --git a/lib/pages/chat_list/chat_list_header.dart b/lib/pages/chat_list/chat_list_header.dart index 98b323b6bd..c5973d8bbe 100644 --- a/lib/pages/chat_list/chat_list_header.dart +++ b/lib/pages/chat_list/chat_list_header.dart @@ -6,8 +6,13 @@ import 'package:flutter_gen/gen_l10n/l10n.dart'; class ChatListHeader extends StatelessWidget implements PreferredSizeWidget { final ChatListController controller; + final bool globalSearch; - const ChatListHeader({super.key, required this.controller}); + const ChatListHeader({ + super.key, + required this.controller, + this.globalSearch = true, + }); @override Widget build(BuildContext context) { @@ -140,8 +145,8 @@ class ChatListHeader extends StatelessWidget implements PreferredSizeWidget { tooltip: L10n.of(context)!.toggleUnread, icon: Icon( controller.anySelectedRoomNotMarkedUnread - ? Icons.mark_chat_read_outlined - : Icons.mark_chat_unread_outlined, + ? Icons.mark_chat_unread_outlined + : Icons.mark_chat_read_outlined, ), onPressed: controller.toggleUnread, ), @@ -149,8 +154,8 @@ class ChatListHeader extends StatelessWidget implements PreferredSizeWidget { tooltip: L10n.of(context)!.toggleFavorite, icon: Icon( controller.anySelectedRoomNotFavorite - ? Icons.push_pin_outlined - : Icons.push_pin, + ? Icons.push_pin + : Icons.push_pin_outlined, ), onPressed: controller.toggleFavouriteRoom, ), diff --git a/lib/pages/chat_list/chat_list_item.dart b/lib/pages/chat_list/chat_list_item.dart index a24fcd8fd8..680fe8dcf9 100644 --- a/lib/pages/chat_list/chat_list_item.dart +++ b/lib/pages/chat_list/chat_list_item.dart @@ -8,14 +8,12 @@ import 'package:fluffychat/widgets/hover_builder.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 '../../config/themes.dart'; import '../../utils/date_time_extension.dart'; import '../../widgets/avatar.dart'; import '../../widgets/matrix.dart'; -import '../chat/send_file_dialog.dart'; enum ArchivedRoomAction { delete, rejoin } @@ -23,142 +21,20 @@ class ChatListItem extends StatelessWidget { final Room room; final bool activeChat; final bool selected; - final void Function()? onTap; final void Function()? onLongPress; final void Function()? onForget; + final void Function() onTap; const ChatListItem( this.room, { this.activeChat = false, this.selected = false, - this.onTap, + required this.onTap, this.onLongPress, this.onForget, super.key, }); - void clickAction(BuildContext context) async { - if (onTap != null) return onTap!(); - if (activeChat) return; - if (room.membership == Membership.invite) { - final inviterId = - room.getState(EventTypes.RoomMember, room.client.userID!)?.senderId; - final inviteAction = await showModalActionSheet( - context: context, - message: room.isDirectChat - ? L10n.of(context)!.invitePrivateChat - : L10n.of(context)!.inviteGroupChat, - title: room.getLocalizedDisplayname(MatrixLocals(L10n.of(context)!)), - actions: [ - SheetAction( - key: InviteActions.accept, - label: L10n.of(context)!.accept, - icon: Icons.check_outlined, - isDefaultAction: true, - ), - SheetAction( - key: InviteActions.decline, - label: L10n.of(context)!.decline, - icon: Icons.close_outlined, - isDestructiveAction: true, - ), - SheetAction( - key: InviteActions.block, - label: L10n.of(context)!.block, - icon: Icons.block_outlined, - isDestructiveAction: true, - ), - ], - ); - if (inviteAction == null) return; - if (inviteAction == InviteActions.block) { - context.go('/rooms/settings/security/ignorelist', extra: inviterId); - return; - } - if (inviteAction == InviteActions.decline) { - await showFutureLoadingDialog( - context: context, - future: room.leave, - ); - return; - } - final joinResult = await showFutureLoadingDialog( - context: context, - future: () async { - final waitForRoom = room.client.waitForRoomInSync( - room.id, - join: true, - ); - await room.join(); - await waitForRoom; - }, - ); - if (joinResult.error != null) return; - } - - if (room.membership == Membership.ban) { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text(L10n.of(context)!.youHaveBeenBannedFromThisChat), - ), - ); - return; - } - - if (room.membership == Membership.leave) { - context.go('/rooms/archive/${room.id}'); - } - - if (room.membership == Membership.join) { - // Share content into this room - // #Pangea - // final shareContent = Matrix.of(context).shareContent; - Map? shareContent; - try { - shareContent = Matrix.of(context).shareContent; - } catch (e) { - shareContent = null; - } - // Pangea# - if (shareContent != null) { - final shareFile = shareContent.tryGet('file'); - if (shareContent.tryGet('msgtype') == - 'chat.fluffy.shared_file' && - shareFile != null) { - await showDialog( - context: context, - useRootNavigator: false, - builder: (c) => SendFileDialog( - files: [shareFile], - room: room, - ), - ); - Matrix.of(context).shareContent = null; - } else { - final consent = await showOkCancelAlertDialog( - context: context, - title: L10n.of(context)!.forward, - message: L10n.of(context)!.forwardMessageTo( - room.getLocalizedDisplayname(MatrixLocals(L10n.of(context)!)), - ), - okLabel: L10n.of(context)!.forward, - cancelLabel: L10n.of(context)!.cancel, - ); - if (consent == OkCancelResult.cancel) { - Matrix.of(context).shareContent = null; - return; - } - if (consent == OkCancelResult.ok) { - room.sendEvent(shareContent); - Matrix.of(context).shareContent = null; - } - } - } - - context.go('/rooms/${room.id}'); - } - } - Future archiveAction(BuildContext context) async { { if ([Membership.leave, Membership.ban].contains(room.membership)) { @@ -239,7 +115,7 @@ class ChatListItem extends StatelessWidget { maxLines: 1, overflow: TextOverflow.ellipsis, softWrap: false, - style: unread + style: unread || room.hasNewMessages ? const TextStyle(fontWeight: FontWeight.bold) : null, ), @@ -359,7 +235,9 @@ class ChatListItem extends StatelessWidget { maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle( - fontWeight: unread ? FontWeight.w600 : null, + fontWeight: unread || room.hasNewMessages + ? FontWeight.bold + : null, color: Theme.of(context) .colorScheme .onSurfaceVariant, @@ -424,7 +302,7 @@ class ChatListItem extends StatelessWidget { ), ], ), - onTap: () => clickAction(context), + onTap: onTap, trailing: onForget == null ? hovered || selected ? IconButton( @@ -450,9 +328,3 @@ class ChatListItem extends StatelessWidget { ); } } - -enum InviteActions { - accept, - decline, - block, -} diff --git a/lib/pages/chat_list/client_chooser_button.dart b/lib/pages/chat_list/client_chooser_button.dart index 74c3f34b70..1af1027687 100644 --- a/lib/pages/chat_list/client_chooser_button.dart +++ b/lib/pages/chat_list/client_chooser_button.dart @@ -1,5 +1,3 @@ -import 'dart:developer'; - import 'package:adaptive_dialog/adaptive_dialog.dart'; import 'package:fluffychat/pangea/constants/class_default_values.dart'; import 'package:fluffychat/pangea/extensions/client_extension.dart'; @@ -7,12 +5,10 @@ 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 '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:keyboard_shortcuts/keyboard_shortcuts.dart'; import 'package:matrix/matrix.dart'; import '../../utils/fluffy_share.dart'; @@ -113,17 +109,6 @@ class ClientChooserButton extends StatelessWidget { ], ), ), - 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, @@ -279,38 +264,40 @@ class ClientChooserButton extends StatelessWidget { builder: (context, snapshot) => Stack( alignment: Alignment.center, children: [ - ...List.generate( - clientCount, - (index) => KeyBoardShortcuts( - keysToPress: _buildKeyboardShortcut(index + 1), - helpLabel: L10n.of(context)!.switchToAccount(index + 1), - onKeysPressed: () => _handleKeyboardShortcut( - matrix, - index, - context, - ), - child: const SizedBox.shrink(), - ), - ), - KeyBoardShortcuts( - keysToPress: { - LogicalKeyboardKey.controlLeft, - LogicalKeyboardKey.tab, - }, - helpLabel: L10n.of(context)!.nextAccount, - onKeysPressed: () => _nextAccount(matrix, context), - child: const SizedBox.shrink(), - ), - KeyBoardShortcuts( - keysToPress: { - LogicalKeyboardKey.controlLeft, - LogicalKeyboardKey.shiftLeft, - LogicalKeyboardKey.tab, - }, - helpLabel: L10n.of(context)!.previousAccount, - onKeysPressed: () => _previousAccount(matrix, context), - child: const SizedBox.shrink(), - ), + // #Pangea + // ...List.generate( + // clientCount, + // (index) => KeyBoardShortcuts( + // keysToPress: _buildKeyboardShortcut(index + 1), + // helpLabel: L10n.of(context)!.switchToAccount(index + 1), + // onKeysPressed: () => _handleKeyboardShortcut( + // matrix, + // index, + // context, + // ), + // child: const SizedBox.shrink(), + // ), + // ), + // KeyBoardShortcuts( + // keysToPress: { + // LogicalKeyboardKey.controlLeft, + // LogicalKeyboardKey.tab, + // }, + // helpLabel: L10n.of(context)!.nextAccount, + // onKeysPressed: () => _nextAccount(matrix, context), + // child: const SizedBox.shrink(), + // ), + // KeyBoardShortcuts( + // keysToPress: { + // LogicalKeyboardKey.controlLeft, + // LogicalKeyboardKey.shiftLeft, + // LogicalKeyboardKey.tab, + // }, + // helpLabel: L10n.of(context)!.previousAccount, + // onKeysPressed: () => _previousAccount(matrix, context), + // child: const SizedBox.shrink(), + // ), + // Pangea# PopupMenuButton( onSelected: (o) => _clientSelected(o, context), itemBuilder: _bundleMenuItems, @@ -406,7 +393,6 @@ class ClientChooserButton extends StatelessWidget { ClassCodeUtil.joinWithClassCodeDialog( context, controller.pangeaController, - null, ); break; case SettingsAction.findAConversationPartner: @@ -421,9 +407,6 @@ class ClientChooserButton extends StatelessWidget { 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; @@ -514,7 +497,6 @@ enum SettingsAction { joinWithClassCode, classAnalytics, myAnalytics, - findAClass, findAConversationPartner, logout, newClass, diff --git a/lib/pages/chat_list/space_view.dart b/lib/pages/chat_list/space_view.dart index 906c3af71b..bc92ab4ef4 100644 --- a/lib/pages/chat_list/space_view.dart +++ b/lib/pages/chat_list/space_view.dart @@ -5,6 +5,7 @@ import 'package:collection/collection.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/pages/chat_list/utils/on_chat_tap.dart'; import 'package:fluffychat/pangea/constants/class_default_values.dart'; import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart'; import 'package:fluffychat/pangea/extensions/sync_update_extension.dart'; @@ -55,21 +56,25 @@ class _SpaceViewState extends State { // #Pangea @override void dispose() { - super.dispose(); _roomSubscription?.cancel(); + super.dispose(); } // Pangea# void _refresh() { // #Pangea // _lastResponse.remove(widget.controller.activseSpaceId); + if (mounted) { + // Pangea# + loadHierarchy(); + // #Pangea + } // Pangea# - loadHierarchy(); } Future loadHierarchy([String? prevBatch]) async { // #Pangea - if (widget.controller.activeSpaceId == null) { + if (widget.controller.activeSpaceId == null || loading) { return GetSpaceHierarchyResponse( rooms: [], nextBatch: null, @@ -371,6 +376,31 @@ class _SpaceViewState extends State { _refresh(); } + // #Pangea + void refreshOnUpdate(SyncUpdate event) { + /* refresh on leave, invite, and space child update + not join events, because there's already a listener on + onTapSpaceChild, and they interfere with each other */ + if (widget.controller.activeSpaceId == null || !mounted) { + return; + } + final client = Matrix.of(context).client; + if (event.isMembershipUpdateByType( + Membership.leave, + client.userID!, + ) || + event.isMembershipUpdateByType( + Membership.invite, + client.userID!, + ) || + event.isSpaceChildUpdate( + widget.controller.activeSpaceId!, + )) { + _refresh(); + } + } + // Pangea# + @override Widget build(BuildContext context) { final client = Matrix.of(context).client; @@ -385,11 +415,18 @@ class _SpaceViewState extends State { final rootSpaces = allSpaces // #Pangea // .where( - // (space) => !allSpaces.any( - // (parentSpace) => parentSpace.spaceChildren - // .any((child) => child.roomId == space.id), - // ), - // ) + // (space) => + // !allSpaces.any( + // (parentSpace) => parentSpace.spaceChildren + // .any((child) => child.roomId == space.id), + // ) && + // space + // .getLocalizedDisplayname(MatrixLocals(L10n.of(context)!)) + // .toLowerCase() + // .contains( + // widget.controller.searchController.text.toLowerCase(), + // ), + //) // Pangea# .toList(); @@ -468,23 +505,6 @@ class _SpaceViewState extends State { } // #Pangea - void refreshOnUpdate(SyncUpdate event) { - /* refresh on leave, invite, and space child update - not join events, because there's already a listener on - onTapSpaceChild, and they interfere with each other */ - if (event.isMembershipUpdateByType( - Membership.leave, - Matrix.of(context).client.userID!, - ) || - event.isMembershipUpdateByType( - Membership.invite, - Matrix.of(context).client.userID!, - ) || - event.isSpaceChildUpdate(activeSpaceId)) { - _refresh(); - } - } - _roomSubscription ??= client.onSync.stream .where((event) => event.hasRoomUpdate) .listen(refreshOnUpdate); @@ -506,7 +526,7 @@ class _SpaceViewState extends State { child: CustomScrollView( controller: widget.scrollController, slivers: [ - ChatListHeader(controller: widget.controller), + ChatListHeader(controller: widget.controller, globalSearch: false), SliverAppBar( automaticallyImplyLeading: false, primary: false, @@ -650,6 +670,7 @@ class _SpaceViewState extends State { onLongPress: () => _onSpaceChildContextMenu(spaceChild, room), activeChat: widget.controller.activeChat == room.id, + onTap: () => onChatTap(room, context), ); } final isSpace = spaceChild.roomType == 'm.space'; @@ -719,7 +740,8 @@ class _SpaceViewState extends State { L10n.of(context)!.chat; if (widget.controller.isSearchMode && !name.toLowerCase().contains( - widget.controller.searchController.text, + widget.controller.searchController.text + .toLowerCase(), )) { return const SizedBox.shrink(); } @@ -734,15 +756,20 @@ class _SpaceViewState extends State { ), title: Row( children: [ - Expanded( - child: Text( - name, - maxLines: 1, - style: const TextStyle( - fontWeight: FontWeight.bold, - ), + // #Pangea + // Expanded( + // child: + // Pangea# + Text( + name, + maxLines: 1, + style: const TextStyle( + fontWeight: FontWeight.bold, ), ), + // #Pangea + // ), + // Pangea# if (!isSpace) ...[ const Icon( Icons.people_outline, diff --git a/lib/pages/chat_list/status_msg_list.dart b/lib/pages/chat_list/status_msg_list.dart index 68bd9f26a9..db347292f8 100644 --- a/lib/pages/chat_list/status_msg_list.dart +++ b/lib/pages/chat_list/status_msg_list.dart @@ -125,7 +125,7 @@ class PresenceAvatar extends StatelessWidget { final statusMsgBubbleElevation = Theme.of(context).appBarTheme.scrolledUnderElevation ?? 4; final statusMsgBubbleShadowColor = - Theme.of(context).appBarTheme.shadowColor; + Theme.of(context).colorScheme.onBackground; final statusMsgBubbleColor = Colors.white.withAlpha(245); return Padding( padding: const EdgeInsets.symmetric(horizontal: 8.0), @@ -187,53 +187,57 @@ class PresenceAvatar extends StatelessWidget { left: 0, top: 0, right: 8, - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: - CrossAxisAlignment.stretch, - children: [ - Material( - elevation: statusMsgBubbleElevation, - shadowColor: statusMsgBubbleShadowColor, - borderRadius: BorderRadius.circular( - AppConfig.borderRadius / 2, - ), - color: statusMsgBubbleColor, - child: Padding( - padding: const EdgeInsets.all(2.0), - child: Text( - statusMsg, - maxLines: 2, - overflow: TextOverflow.ellipsis, - style: const TextStyle( - color: Colors.black, - fontSize: 10.5, - ), - ), - ), - ), - Padding( - padding: const EdgeInsets.only( - left: 26.0, - top: 4.0, - ), - child: Center( - child: SizedBox( - width: 12, - height: 12, - child: Material( - elevation: - statusMsgBubbleElevation, - shadowColor: - statusMsgBubbleShadowColor, - borderRadius: - BorderRadius.circular(99), - color: statusMsgBubbleColor, - ), - ), + child: Material( + elevation: statusMsgBubbleElevation, + shadowColor: statusMsgBubbleShadowColor, + borderRadius: BorderRadius.circular( + AppConfig.borderRadius / 2, + ), + color: statusMsgBubbleColor, + child: Padding( + padding: const EdgeInsets.all(2.0), + child: Text( + statusMsg, + maxLines: 2, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + color: Colors.black, + fontSize: 10.5, ), ), - ], + ), + ), + ), + Positioned( + left: 8, + top: 32, + child: Material( + color: statusMsgBubbleColor, + elevation: statusMsgBubbleElevation, + shadowColor: statusMsgBubbleShadowColor, + borderRadius: BorderRadius.circular( + AppConfig.borderRadius / 2, + ), + child: const SizedBox( + width: 8, + height: 8, + ), + ), + ), + Positioned( + left: 14, + top: 40, + child: Material( + color: statusMsgBubbleColor, + elevation: statusMsgBubbleElevation, + shadowColor: statusMsgBubbleShadowColor, + borderRadius: BorderRadius.circular( + AppConfig.borderRadius / 2, + ), + child: const SizedBox( + width: 4, + height: 4, + ), ), ), ], diff --git a/lib/pages/chat_list/utils/on_chat_tap.dart b/lib/pages/chat_list/utils/on_chat_tap.dart new file mode 100644 index 0000000000..d24af1fb42 --- /dev/null +++ b/lib/pages/chat_list/utils/on_chat_tap.dart @@ -0,0 +1,127 @@ +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:go_router/go_router.dart'; +import 'package:matrix/matrix.dart'; + +import 'package:fluffychat/pages/chat/send_file_dialog.dart'; +import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart'; +import 'package:fluffychat/widgets/matrix.dart'; + +void onChatTap(Room room, BuildContext context) async { + if (room.membership == Membership.invite) { + final inviterId = + room.getState(EventTypes.RoomMember, room.client.userID!)?.senderId; + final inviteAction = await showModalActionSheet( + context: context, + message: room.isDirectChat + ? L10n.of(context)!.invitePrivateChat + : L10n.of(context)!.inviteGroupChat, + title: room.getLocalizedDisplayname(MatrixLocals(L10n.of(context)!)), + actions: [ + SheetAction( + key: InviteActions.accept, + label: L10n.of(context)!.accept, + icon: Icons.check_outlined, + isDefaultAction: true, + ), + SheetAction( + key: InviteActions.decline, + label: L10n.of(context)!.decline, + icon: Icons.close_outlined, + isDestructiveAction: true, + ), + SheetAction( + key: InviteActions.block, + label: L10n.of(context)!.block, + icon: Icons.block_outlined, + isDestructiveAction: true, + ), + ], + ); + if (inviteAction == null) return; + if (inviteAction == InviteActions.block) { + context.go('/rooms/settings/security/ignorelist', extra: inviterId); + return; + } + if (inviteAction == InviteActions.decline) { + await showFutureLoadingDialog( + context: context, + future: room.leave, + ); + return; + } + final joinResult = await showFutureLoadingDialog( + context: context, + future: () async { + final waitForRoom = room.client.waitForRoomInSync( + room.id, + join: true, + ); + await room.join(); + await waitForRoom; + }, + ); + if (joinResult.error != null) return; + } + + if (room.membership == Membership.ban) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text(L10n.of(context)!.youHaveBeenBannedFromThisChat), + ), + ); + return; + } + + if (room.membership == Membership.leave) { + context.go('/rooms/archive/${room.id}'); + return; + } + + // Share content into this room + final shareContent = Matrix.of(context).shareContent; + if (shareContent != null) { + final shareFile = shareContent.tryGet('file'); + if (shareContent.tryGet('msgtype') == 'chat.fluffy.shared_file' && + shareFile != null) { + await showDialog( + context: context, + useRootNavigator: false, + builder: (c) => SendFileDialog( + files: [shareFile], + room: room, + ), + ); + Matrix.of(context).shareContent = null; + } else { + final consent = await showOkCancelAlertDialog( + context: context, + title: L10n.of(context)!.forward, + message: L10n.of(context)!.forwardMessageTo( + room.getLocalizedDisplayname(MatrixLocals(L10n.of(context)!)), + ), + okLabel: L10n.of(context)!.forward, + cancelLabel: L10n.of(context)!.cancel, + ); + if (consent == OkCancelResult.cancel) { + Matrix.of(context).shareContent = null; + return; + } + if (consent == OkCancelResult.ok) { + room.sendEvent(shareContent); + Matrix.of(context).shareContent = null; + } + } + } + + context.go('/rooms/${room.id}'); +} + +enum InviteActions { + accept, + decline, + block, +} 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 e8c34e2601..b88095b20c 100644 --- a/lib/pages/chat_permissions_settings/chat_permissions_settings_view.dart +++ b/lib/pages/chat_permissions_settings/chat_permissions_settings_view.dart @@ -31,14 +31,14 @@ class ChatPermissionsSettingsView extends StatelessWidget { if (room == null) { return Center(child: Text(L10n.of(context)!.noRoomsFound)); } - final powerLevelsContent = Map.from( - room.getState(EventTypes.RoomPowerLevels)!.content, + final powerLevelsContent = Map.from( + room.getState(EventTypes.RoomPowerLevels)?.content ?? {}, ); final powerLevels = Map.from(powerLevelsContent) ..removeWhere((k, v) => v is! int); - final eventsPowerLevels = - Map.from(powerLevelsContent['events'] ?? {}) - ..removeWhere((k, v) => v is! int); + final eventsPowerLevels = Map.from( + powerLevelsContent.tryGetMap('events') ?? {}, + )..removeWhere((k, v) => v is! int); return Column( children: [ Column( @@ -67,9 +67,12 @@ class ChatPermissionsSettingsView extends StatelessWidget { Builder( builder: (context) { const key = 'rooms'; - final int value = powerLevelsContent + final value = powerLevelsContent .containsKey('notifications') - ? powerLevelsContent['notifications']['rooms'] ?? 0 + ? powerLevelsContent + .tryGetMap('notifications') + ?.tryGet('rooms') ?? + 0 : 0; return PermissionsListTile( permissionKey: key, @@ -98,11 +101,11 @@ class ChatPermissionsSettingsView extends StatelessWidget { PermissionsListTile( permissionKey: entry.key, category: 'events', - permission: entry.value, + permission: entry.value ?? 0, onTap: () => controller.editPowerLevel( context, entry.key, - entry.value, + entry.value ?? 0, category: 'events', ), ), diff --git a/lib/pages/device_settings/device_settings.dart b/lib/pages/device_settings/device_settings.dart index 3e9f4d3236..83e26192e3 100644 --- a/lib/pages/device_settings/device_settings.dart +++ b/lib/pages/device_settings/device_settings.dart @@ -91,6 +91,15 @@ class DevicesSettingsController extends State { } void verifyDeviceAction(Device device) async { + final consent = await showOkCancelAlertDialog( + context: context, + title: L10n.of(context)!.verifyOtherDevice, + message: L10n.of(context)!.verifyOtherDeviceDescription, + okLabel: L10n.of(context)!.ok, + cancelLabel: L10n.of(context)!.cancel, + fullyCapitalizedForMaterial: false, + ); + if (consent != OkCancelResult.ok) return; final req = await Matrix.of(context) .client .userDeviceKeys[Matrix.of(context).client.userID!]! diff --git a/lib/pages/dialer/dialer.dart b/lib/pages/dialer/dialer.dart index a8e5a92020..b6c0a6da34 100644 --- a/lib/pages/dialer/dialer.dart +++ b/lib/pages/dialer/dialer.dart @@ -19,20 +19,19 @@ import 'dart:async'; import 'dart:math'; +import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart'; +import 'package:fluffychat/utils/platform_infos.dart'; +import 'package:fluffychat/widgets/avatar.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; - +import 'package:flutter/services.dart'; import 'package:flutter_foreground_task/flutter_foreground_task.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:flutter_webrtc/flutter_webrtc.dart'; import 'package:just_audio/just_audio.dart'; import 'package:matrix/matrix.dart'; -import 'package:vibration/vibration.dart'; import 'package:wakelock_plus/wakelock_plus.dart'; -import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart'; -import 'package:fluffychat/utils/platform_infos.dart'; -import 'package:fluffychat/widgets/avatar.dart'; import 'pip/pip_view.dart'; class _StreamView extends StatelessWidget { @@ -264,11 +263,7 @@ class MyCallingPage extends State { void _handleCallState(CallState state) { Logs().v('CallingPage::handleCallState: ${state.toString()}'); if ({CallState.kConnected, CallState.kEnded}.contains(state)) { - try { - Vibration.vibrate(duration: 200); - } catch (e) { - Logs().e('[Dialer] could not vibrate for call updates'); - } + HapticFeedback.heavyImpact(); } if (mounted) { diff --git a/lib/pages/homeserver_picker/homeserver_app_bar.dart b/lib/pages/homeserver_picker/homeserver_app_bar.dart index f7f6935158..060235beb1 100644 --- a/lib/pages/homeserver_picker/homeserver_app_bar.dart +++ b/lib/pages/homeserver_picker/homeserver_app_bar.dart @@ -1,12 +1,11 @@ -import 'package:flutter/material.dart'; - -import 'package:flutter_gen/gen_l10n/l10n.dart'; -import 'package:flutter_typeahead/flutter_typeahead.dart'; - import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/config/themes.dart'; import 'package:fluffychat/pages/homeserver_picker/public_homeserver.dart'; import 'package:fluffychat/utils/localized_exception_extension.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:flutter_typeahead/flutter_typeahead.dart'; + import 'homeserver_bottom_sheet.dart'; import 'homeserver_picker.dart'; @@ -18,13 +17,17 @@ class HomeserverAppBar extends StatelessWidget { @override Widget build(BuildContext context) { return TypeAheadField( - suggestionsBoxDecoration: SuggestionsBoxDecoration( - borderRadius: BorderRadius.circular(AppConfig.borderRadius), - elevation: Theme.of(context).appBarTheme.scrolledUnderElevation ?? 4, - shadowColor: Theme.of(context).appBarTheme.shadowColor ?? Colors.black, + decorationBuilder: (context, child) => ConstrainedBox( constraints: const BoxConstraints(maxHeight: 256), + child: Material( + borderRadius: BorderRadius.circular(AppConfig.borderRadius), + elevation: Theme.of(context).appBarTheme.scrolledUnderElevation ?? 4, + shadowColor: + Theme.of(context).appBarTheme.shadowColor ?? Colors.black, + child: child, + ), ), - noItemsFoundBuilder: (context) => ListTile( + emptyBuilder: (context) => ListTile( leading: const Icon(Icons.search_outlined), title: Text(L10n.of(context)!.nothingFound), ), @@ -35,8 +38,7 @@ class HomeserverAppBar extends StatelessWidget { errorBuilder: (context, error) => ListTile( leading: const Icon(Icons.error_outlined), title: Text( - error?.toLocalizedString(context) ?? - L10n.of(context)!.oopsSomethingWentWrong, + error.toLocalizedString(context), ), ), itemBuilder: (context, homeserver) => ListTile( @@ -72,13 +74,15 @@ class HomeserverAppBar extends StatelessWidget { } return matches; }, - onSuggestionSelected: (suggestion) { + onSelected: (suggestion) { controller.homeserverController.text = suggestion.name; controller.checkHomeserverAction(); }, - textFieldConfiguration: TextFieldConfiguration( + controller: controller.homeserverController, + builder: (context, textEditingController, focusNode) => TextField( enabled: !controller.isLoggingIn, - controller: controller.homeserverController, + controller: textEditingController, + focusNode: focusNode, decoration: InputDecoration( prefixIcon: Navigator.of(context).canPop() ? IconButton( diff --git a/lib/pages/homeserver_picker/homeserver_picker.dart b/lib/pages/homeserver_picker/homeserver_picker.dart index dd15538e20..4ad60ebb09 100644 --- a/lib/pages/homeserver_picker/homeserver_picker.dart +++ b/lib/pages/homeserver_picker/homeserver_picker.dart @@ -121,14 +121,15 @@ class HomeserverPickerController extends State { void ssoLoginAction(IdentityProvider provider) async { //Pangea# final redirectUrl = kIsWeb - // #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# + ? Uri.parse(html.window.location.href) + .resolveUri( + Uri(pathSegments: ['auth.html']), + ) + .toString() + : isDefaultPlatform + ? '${AppConfig.appOpenUrlScheme.toLowerCase()}://login' + : 'http://localhost:3001//login'; + final url = Matrix.of(context).getLoginClient().homeserver!.replace( // #Pangea // path: '/_matrix/client/v3/login/sso/redirect${id == null ? '' : '/$id'}', @@ -199,15 +200,16 @@ class HomeserverPickerController extends State { List? get identityProviders { final loginTypes = _rawLoginTypes; if (loginTypes == null) return null; - 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(); + final List? rawProviders = + loginTypes.tryGetList('flows')?.singleWhereOrNull( + (flow) => flow['type'] == AuthenticationTypes.sso, + )['identity_providers'] ?? + [ + {'id': null}, + ]; + if (rawProviders == null) return null; + final list = + rawProviders.map((json) => IdentityProvider.fromJson(json)).toList(); if (PlatformInfos.isCupertinoStyle) { list.sort((a, b) => a.brand == 'apple' ? -1 : 1); } diff --git a/lib/pages/new_group/new_group.dart b/lib/pages/new_group/new_group.dart index b4633ea7d9..16d4e2cdba 100644 --- a/lib/pages/new_group/new_group.dart +++ b/lib/pages/new_group/new_group.dart @@ -114,6 +114,10 @@ class NewGroupController extends State { // content: {'url': avatarUrl.toString()}, // ), // ], + initialState: [ + if (addConversationBotKey.currentState?.addBot ?? false) + addConversationBotKey.currentState!.botOptions.toStateEvent, + ], groupName: nameController.text, preset: sdk.CreateRoomPreset.publicChat, powerLevelContentOverride: 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 d1b61af0e7..80cc725fce 100644 --- a/lib/pages/new_private_chat/new_private_chat_view.dart +++ b/lib/pages/new_private_chat/new_private_chat_view.dart @@ -11,7 +11,7 @@ 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:qr_flutter/qr_flutter.dart'; +import 'package:pretty_qr_code/pretty_qr_code.dart'; class NewPrivateChatView extends StatelessWidget { final NewPrivateChatController controller; @@ -159,11 +159,23 @@ class NewPrivateChatView extends StatelessWidget { shadowColor: Theme.of(context).appBarTheme.shadowColor, clipBehavior: Clip.hardEdge, - child: QrImageView( - data: - 'https://matrix.to/#/${Matrix.of(context).client.userID}', - version: QrVersions.auto, - // size: qrCodeSize, + child: Padding( + padding: const EdgeInsets.all(8), + child: PrettyQrView.data( + data: + 'https://matrix.to/#/${Matrix.of(context).client.userID}', + decoration: PrettyQrDecoration( + shape: PrettyQrSmoothSymbol( + roundFactor: 1, + color: Theme.of(context).brightness == + Brightness.light + ? Theme.of(context).colorScheme.primary + : Theme.of(context) + .colorScheme + .onPrimary, + ), + ), + ), ), ), ), diff --git a/lib/pages/settings_security/settings_security.dart b/lib/pages/settings_security/settings_security.dart index 4482f764ea..3f488070b8 100644 --- a/lib/pages/settings_security/settings_security.dart +++ b/lib/pages/settings_security/settings_security.dart @@ -1,15 +1,10 @@ -import 'dart:convert'; -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:future_loading_dialog/future_loading_dialog.dart'; -import 'package:intl/intl.dart'; import 'package:matrix/matrix.dart'; -import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_file_extension.dart'; import 'package:fluffychat/widgets/app_lock.dart'; import 'package:fluffychat/widgets/matrix.dart'; import '../bootstrap/bootstrap_dialog.dart'; @@ -120,36 +115,7 @@ class SettingsSecurityController extends State { ).show(context); } - Future dehydrateAction() => dehydrateDevice(context); - - static Future dehydrateDevice(BuildContext context) async { - final response = await showOkCancelAlertDialog( - context: context, - isDestructiveAction: true, - title: L10n.of(context)!.dehydrate, - message: L10n.of(context)!.dehydrateWarning, - ); - if (response != OkCancelResult.ok) { - return; - } - final file = await showFutureLoadingDialog( - context: context, - future: () async { - final export = await Matrix.of(context).client.exportDump(); - if (export == null) throw Exception('Export data is null.'); - - final exportBytes = Uint8List.fromList( - const Utf8Codec().encode(export), - ); - - final exportFileName = - 'fluffychat-export-${DateFormat(DateFormat.YEAR_MONTH_DAY).format(DateTime.now())}.fluffybackup'; - - return MatrixFile(bytes: exportBytes, name: exportFileName); - }, - ); - file.result?.save(context); - } + Future dehydrateAction() => Matrix.of(context).dehydrateAction(); @override Widget build(BuildContext context) => SettingsSecurityView(this); diff --git a/lib/pages/settings_security/settings_security_view.dart b/lib/pages/settings_security/settings_security_view.dart index 7c3755e5e2..20328ade7c 100644 --- a/lib/pages/settings_security/settings_security_view.dart +++ b/lib/pages/settings_security/settings_security_view.dart @@ -1,8 +1,11 @@ +import 'package:fluffychat/config/app_config.dart'; +import 'package:fluffychat/config/setting_keys.dart'; import 'package:fluffychat/utils/beautify_string_extension.dart'; import 'package:fluffychat/utils/localized_exception_extension.dart'; import 'package:fluffychat/utils/platform_infos.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 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:go_router/go_router.dart'; @@ -49,7 +52,7 @@ class SettingsSecurityView extends StatelessWidget { style: const TextStyle(color: Colors.orange), ), ), - if (capabilities?.mChangePassword?.enabled == true || + if (capabilities?.mChangePassword?.enabled != false || error != null) ...[ ListTile( leading: const Icon(Icons.key_outlined), @@ -104,7 +107,6 @@ class SettingsSecurityView extends StatelessWidget { const Divider(height: 1), ListTile( leading: const Icon(Icons.tap_and_play), - trailing: const Icon(Icons.chevron_right_outlined), title: Text( L10n.of(context)!.dehydrate, style: const TextStyle(color: Colors.red), @@ -113,7 +115,6 @@ class SettingsSecurityView extends StatelessWidget { ), ListTile( leading: const Icon(Icons.delete_outlined), - trailing: const Icon(Icons.chevron_right_outlined), title: Text( L10n.of(context)!.deleteAccount, style: const TextStyle(color: Colors.red), @@ -128,6 +129,22 @@ class SettingsSecurityView extends StatelessWidget { ), leading: const Icon(Icons.vpn_key_outlined), ), + const Divider(height: 1), + SettingsSwitchListTile.adaptive( + title: L10n.of(context)!.sendTypingNotifications, + subtitle: + L10n.of(context)!.sendTypingNotificationsDescription, + onChanged: (b) => AppConfig.sendTypingNotifications = b, + storeKey: SettingKeys.sendTypingNotifications, + defaultValue: AppConfig.sendTypingNotifications, + ), + SettingsSwitchListTile.adaptive( + title: L10n.of(context)!.sendReadReceipts, + subtitle: L10n.of(context)!.sendReadReceiptsDescription, + onChanged: (b) => AppConfig.sendPublicReadReceipts = b, + storeKey: SettingKeys.sendPublicReadReceipts, + defaultValue: AppConfig.sendPublicReadReceipts, + ), ], ); }, diff --git a/lib/pages/settings_style/settings_style.dart b/lib/pages/settings_style/settings_style.dart index 267c69d947..58f8e2c1b7 100644 --- a/lib/pages/settings_style/settings_style.dart +++ b/lib/pages/settings_style/settings_style.dart @@ -1,7 +1,12 @@ import 'package:flutter/material.dart'; +import 'package:file_picker/file_picker.dart'; +import 'package:future_loading_dialog/future_loading_dialog.dart'; + import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/config/setting_keys.dart'; +import 'package:fluffychat/utils/account_config.dart'; +import 'package:fluffychat/widgets/app_lock.dart'; import 'package:fluffychat/widgets/theme_builder.dart'; import '../../widgets/matrix.dart'; import 'settings_style_view.dart'; @@ -19,6 +24,51 @@ class SettingsStyleController extends State { ThemeController.of(context).setPrimaryColor(color); } + void setWallpaper() async { + final client = Matrix.of(context).client; + final picked = await AppLock.of(context).pauseWhile( + FilePicker.platform.pickFiles( + type: FileType.image, + withData: true, + ), + ); + final pickedFile = picked?.files.firstOrNull; + if (pickedFile == null) return; + + await showFutureLoadingDialog( + context: context, + future: () async { + final url = await client.uploadContent( + pickedFile.bytes!, + filename: pickedFile.name, + ); + await client.updateApplicationAccountConfig( + ApplicationAccountConfig(wallpaperUrl: url), + ); + }, + ); + } + + void setChatWallpaperOpacity(double opacity) { + final client = Matrix.of(context).client; + showFutureLoadingDialog( + context: context, + future: () => client.updateApplicationAccountConfig( + ApplicationAccountConfig(wallpaperOpacity: opacity), + ), + ); + } + + void deleteChatWallpaper() => showFutureLoadingDialog( + context: context, + future: () => Matrix.of(context).client.setApplicationAccountConfig( + const ApplicationAccountConfig( + wallpaperUrl: null, + wallpaperOpacity: null, + ), + ), + ); + ThemeMode get currentTheme => ThemeController.of(context).themeMode; Color? get currentColor => ThemeController.of(context).primaryColor; diff --git a/lib/pages/settings_style/settings_style_view.dart b/lib/pages/settings_style/settings_style_view.dart index ac65d8cdde..ed80e82680 100644 --- a/lib/pages/settings_style/settings_style_view.dart +++ b/lib/pages/settings_style/settings_style_view.dart @@ -2,9 +2,15 @@ import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:fluffychat/config/setting_keys.dart'; import 'package:fluffychat/config/themes.dart'; +import 'package:fluffychat/utils/account_config.dart'; +import 'package:fluffychat/widgets/avatar.dart'; import 'package:fluffychat/widgets/layouts/max_width_body.dart'; +import 'package:fluffychat/widgets/matrix.dart'; +import 'package:fluffychat/widgets/mxc_image.dart'; import '../../config/app_config.dart'; +import '../../widgets/settings_switch_list_tile.dart'; import 'settings_style.dart'; class SettingsStyleView extends StatelessWidget { @@ -15,6 +21,7 @@ class SettingsStyleView extends StatelessWidget { @override Widget build(BuildContext context) { const colorPickerSize = 32.0; + final client = Matrix.of(context).client; return Scaffold( appBar: AppBar( leading: const Center(child: BackButton()), @@ -159,35 +166,125 @@ class SettingsStyleView extends StatelessWidget { const Divider(height: 1), ListTile( title: Text( - L10n.of(context)!.messagesStyle, + L10n.of(context)!.presenceStyle, style: TextStyle( color: Theme.of(context).colorScheme.secondary, fontWeight: FontWeight.bold, ), ), ), - Container( - alignment: Alignment.centerLeft, - padding: const EdgeInsets.symmetric(horizontal: 12), - child: Material( - color: Theme.of(context).colorScheme.primaryContainer, - borderRadius: BorderRadius.circular(AppConfig.borderRadius), - child: Padding( - padding: const EdgeInsets.symmetric( - horizontal: 16, - vertical: 8, - ), - child: Text( - 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor', - style: TextStyle( - color: Theme.of(context).colorScheme.onPrimaryContainer, - fontSize: - AppConfig.messageFontSize * AppConfig.fontSizeFactor, - ), - ), + SettingsSwitchListTile.adaptive( + title: L10n.of(context)!.presencesToggle, + onChanged: (b) => AppConfig.showPresences = b, + storeKey: SettingKeys.showPresences, + defaultValue: AppConfig.showPresences, + ), + const Divider(height: 1), + ListTile( + title: Text( + L10n.of(context)!.messagesStyle, + style: TextStyle( + color: Theme.of(context).colorScheme.secondary, + fontWeight: FontWeight.bold, ), ), ), + StreamBuilder( + stream: client.onAccountData.stream.where( + (data) => + data.type == + ApplicationAccountConfigExtension.accountDataKey, + ), + builder: (context, snapshot) { + final accountConfig = client.applicationAccountConfig; + final wallpaperOpacity = accountConfig.wallpaperOpacity ?? 1; + final wallpaperOpacityIsDefault = wallpaperOpacity == 1; + + return Column( + mainAxisSize: MainAxisSize.min, + children: [ + AnimatedContainer( + duration: FluffyThemes.animationDuration, + curve: FluffyThemes.animationCurve, + alignment: Alignment.centerLeft, + decoration: const BoxDecoration(), + clipBehavior: Clip.hardEdge, + child: Stack( + children: [ + if (accountConfig.wallpaperUrl != null) + Opacity( + opacity: wallpaperOpacity, + child: MxcImage( + uri: accountConfig.wallpaperUrl, + fit: BoxFit.cover, + isThumbnail: true, + width: FluffyThemes.columnWidth * 2, + height: 156, + ), + ), + Padding( + padding: EdgeInsets.only( + left: 12 + 12 + Avatar.defaultSize, + right: 12, + top: accountConfig.wallpaperUrl == null ? 0 : 12, + bottom: 12, + ), + child: Material( + color: Theme.of(context).colorScheme.primary, + borderRadius: BorderRadius.circular( + AppConfig.borderRadius, + ), + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 16, + vertical: 8, + ), + child: Text( + 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor', + style: TextStyle( + color: + Theme.of(context).colorScheme.onPrimary, + fontSize: AppConfig.messageFontSize * + AppConfig.fontSizeFactor, + ), + ), + ), + ), + ), + ], + ), + ), + ListTile( + title: Text(L10n.of(context)!.wallpaper), + leading: const Icon(Icons.photo_outlined), + trailing: accountConfig.wallpaperUrl == null + ? null + : IconButton( + icon: const Icon(Icons.delete_outlined), + color: Theme.of(context).colorScheme.error, + onPressed: controller.deleteChatWallpaper, + ), + onTap: controller.setWallpaper, + ), + AnimatedSize( + duration: FluffyThemes.animationDuration, + curve: FluffyThemes.animationCurve, + child: accountConfig.wallpaperUrl != null + ? SwitchListTile.adaptive( + title: Text(L10n.of(context)!.transparent), + secondary: const Icon(Icons.blur_linear_outlined), + value: !wallpaperOpacityIsDefault, + onChanged: (_) => + controller.setChatWallpaperOpacity( + wallpaperOpacityIsDefault ? 0.4 : 1, + ), + ) + : null, + ), + ], + ); + }, + ), ListTile( title: Text(L10n.of(context)!.fontSize), trailing: Text('× ${AppConfig.fontSizeFactor}'), diff --git a/lib/pangea/constants/pangea_event_types.dart b/lib/pangea/constants/pangea_event_types.dart index abd155460e..6494843c99 100644 --- a/lib/pangea/constants/pangea_event_types.dart +++ b/lib/pangea/constants/pangea_event_types.dart @@ -18,4 +18,5 @@ class PangeaEventTypes { static const botOptions = "pangea.bot_options"; static const userAge = "pangea.user_age"; + static const textToSpeechRule = "p.rule.text_to_speech"; } diff --git a/lib/pangea/controllers/class_controller.dart b/lib/pangea/controllers/class_controller.dart index f9c5b2ce14..a767036f7b 100644 --- a/lib/pangea/controllers/class_controller.dart +++ b/lib/pangea/controllers/class_controller.dart @@ -13,7 +13,6 @@ import 'package:fluffychat/pangea/utils/error_handler.dart'; 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 '../../widgets/matrix.dart'; @@ -132,15 +131,7 @@ class ClassController extends BaseController { 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? diff --git a/lib/pangea/controllers/message_data_controller.dart b/lib/pangea/controllers/message_data_controller.dart index b0759b108c..e227919698 100644 --- a/lib/pangea/controllers/message_data_controller.dart +++ b/lib/pangea/controllers/message_data_controller.dart @@ -18,8 +18,7 @@ class MessageDataController extends BaseController { late PangeaController _pangeaController; final List _cache = []; - - final Map _messageDataToSave = {}; + final List _representationCache = []; MessageDataController(PangeaController pangeaController) { _pangeaController = pangeaController; @@ -31,6 +30,14 @@ class MessageDataController extends BaseController { e.parentId == parentId && e.type == type && e.langCode == langCode, ); + RepresentationCacheItem? getRepresentationCacheItem( + String parentId, + String langCode, + ) => + _representationCache.firstWhereOrNull( + (e) => e.parentId == parentId && e.langCode == langCode, + ); + Future _getTokens( TokensRequestModel req, ) async { @@ -141,6 +148,32 @@ class MessageDataController extends BaseController { required String? source, required String target, required Room room, + }) async { + final RepresentationCacheItem? item = + getRepresentationCacheItem(text, target); + if (item != null) return item.data; + + _representationCache.add( + RepresentationCacheItem( + text, + target, + _getPangeaRepresentation( + text: text, + source: source, + target: target, + room: room, + ), + ), + ); + + return _representationCache.last.data; + } + + Future _getPangeaRepresentation({ + required String text, + required String? source, + required String target, + required Room room, }) async { final req = FullTextTranslationRequestModel( text: text, @@ -235,3 +268,11 @@ class CacheItem { CacheItem(this.parentId, this.type, this.langCode, this.data); } + +class RepresentationCacheItem { + String parentId; + String langCode; + Future data; + + RepresentationCacheItem(this.parentId, this.langCode, this.data); +} diff --git a/lib/pangea/controllers/my_analytics_controller.dart b/lib/pangea/controllers/my_analytics_controller.dart index a33748fdaf..4b7c8cc967 100644 --- a/lib/pangea/controllers/my_analytics_controller.dart +++ b/lib/pangea/controllers/my_analytics_controller.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'dart:developer'; import 'package:fluffychat/pangea/controllers/pangea_controller.dart'; +import 'package:fluffychat/pangea/enum/construct_type_enum.dart'; import 'package:fluffychat/pangea/models/student_analytics_summary_model.dart'; import 'package:fluffychat/pangea/utils/error_handler.dart'; import 'package:flutter/foundation.dart'; @@ -24,8 +25,9 @@ class MyAnalyticsController { //PTODO - locally cache and update periodically Future handleMessage( Room room, - RecentMessageRecord messageRecord, - ) async { + RecentMessageRecord messageRecord, { + bool isEdit = false, + }) async { try { debugPrint("in handle message with type ${messageRecord.useType}"); if (_userId == null) { @@ -48,7 +50,7 @@ class MyAnalyticsController { for (final event in events) { if (event != null) { - event.handleNewMessage(messageRecord); + event.handleNewMessage(messageRecord, isEdit: isEdit); } } } catch (err) { @@ -76,8 +78,9 @@ class MyAnalyticsController { Future saveConstructsMixed( List allUses, - String langCode, - ) async { + String langCode, { + bool isEdit = false, + }) async { try { final Map> aggregatedVocabUse = {}; for (final use in allUses) { @@ -94,8 +97,9 @@ class MyAnalyticsController { saveFutures.add( analyticsRoom.saveConstructUsesSameLemma( uses.key, - uses.value.first.constructType!, + uses.value.first.constructType ?? ConstructType.grammar, uses.value, + isEdit: isEdit, ), ); } diff --git a/lib/pangea/controllers/pangea_controller.dart b/lib/pangea/controllers/pangea_controller.dart index 86946f314b..0e495b501d 100644 --- a/lib/pangea/controllers/pangea_controller.dart +++ b/lib/pangea/controllers/pangea_controller.dart @@ -2,6 +2,7 @@ import 'dart:developer'; import 'dart:math'; import 'package:fluffychat/pangea/constants/class_default_values.dart'; +import 'package:fluffychat/pangea/constants/pangea_event_types.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'; @@ -218,6 +219,10 @@ class PangeaController { final List spaces = matrixState.client.rooms.where((room) => room.isSpace).toList(); for (final Room space in spaces) { + if (space.ownPowerLevel < ClassDefaultValues.powerLevelOfAdmin || + !space.canInvite) { + continue; + } List participants; try { participants = await space.requestParticipants(); @@ -228,9 +233,10 @@ class PangeaController { continue; } final List userIds = participants.map((user) => user.id).toList(); - if (space.canInvite && !userIds.contains(BotName.byEnvironment)) { + if (!userIds.contains(BotName.byEnvironment)) { try { await space.invite(BotName.byEnvironment); + await space.postLoad(); await space.setPower( BotName.byEnvironment, ClassDefaultValues.powerLevelOfAdmin, @@ -240,7 +246,51 @@ class PangeaController { e: "Failed to invite pangea bot to space ${space.id}", ); } + } else if (space.getPowerLevelByUserId(BotName.byEnvironment) < + ClassDefaultValues.powerLevelOfAdmin) { + try { + await space.postLoad(); + await space.setPower( + BotName.byEnvironment, + ClassDefaultValues.powerLevelOfAdmin, + ); + } catch (err) { + ErrorHandler.logError( + e: "Failed to reset power level for pangea bot in space ${space.id}", + ); + } } } } + + Future setPangeaPushRules() async { + if (!(matrixState.client.globalPushRules?.override?.any( + (element) => element.ruleId == PangeaEventTypes.textToSpeechRule, + ) ?? + false)) { + await matrixState.client.setPushRule( + 'global', + PushRuleKind.override, + PangeaEventTypes.textToSpeechRule, + [PushRuleAction.dontNotify], + conditions: [ + PushCondition( + kind: 'event_match', + key: 'content.msgtype', + pattern: MessageTypes.Audio, + ), + PushCondition( + kind: 'event_match', + key: 'content.transcription.lang_code', + pattern: '*', + ), + PushCondition( + kind: 'event_match', + key: 'content.transcription.text', + pattern: '*', + ), + ], + ); + } + } } diff --git a/lib/pangea/extensions/client_extension.dart b/lib/pangea/extensions/client_extension.dart index f5a32c95ee..730db5f7aa 100644 --- a/lib/pangea/extensions/client_extension.dart +++ b/lib/pangea/extensions/client_extension.dart @@ -117,7 +117,12 @@ extension PangeaClient on Client { // set description to let people know what the hell it is Future getMyAnalyticsRoom(String langCode) async { await roomsLoading; - + // ensure room state events (room create, + // to check for analytics type) are loaded + for (final room in rooms) { + if (room.partial) await room.postLoad(); + } + final Room? analyticsRoom = analyticsRoomLocal(langCode); if (analyticsRoom != null) return analyticsRoom; @@ -212,4 +217,31 @@ extension PangeaClient on Client { } return false; } + + Future> getEditHistory( + String roomId, + String eventId, + ) async { + final Room? room = getRoomById(roomId); + final Event? editEvent = await room?.getEventById(eventId); + final String? edittedEventId = + editEvent?.content.tryGetMap('m.relates_to')?['event_id']; + if (edittedEventId == null) return []; + + final Event? originalEvent = await room!.getEventById(edittedEventId); + if (originalEvent == null) return []; + + final Timeline timeline = await room.getTimeline(); + final List editEvents = originalEvent + .aggregatedEvents( + timeline, + RelationshipTypes.edit, + ) + .sorted( + (a, b) => b.originServerTs.compareTo(a.originServerTs), + ) + .toList(); + editEvents.add(originalEvent); + return editEvents.slice(1).map((e) => e.eventId).toList(); + } } diff --git a/lib/pangea/extensions/pangea_room_extension.dart b/lib/pangea/extensions/pangea_room_extension.dart index e617247ded..79e69e1fb7 100644 --- a/lib/pangea/extensions/pangea_room_extension.dart +++ b/lib/pangea/extensions/pangea_room_extension.dart @@ -514,7 +514,13 @@ extension PangeaRoom on Room { return; } - myAnalEvent.bulkUpdate(await _messageListForAllChildChats); + final updateMessages = await _messageListForAllChildChats; + updateMessages.removeWhere( + (element) => myAnalEvent.content.messages.any( + (e) => e.eventId == element.eventId, + ), + ); + myAnalEvent.bulkUpdate(updateMessages); storageService?.save(migratedAnalyticsKey, true); } catch (err, s) { @@ -692,16 +698,39 @@ extension PangeaRoom on Room { } } + Future> removeEdittedLemmas( + List lemmaUses, + ) async { + final List removeUses = []; + for (final use in lemmaUses) { + if (use.msgId == null) continue; + final List removeIds = await client.getEditHistory( + use.chatId, + use.msgId!, + ); + removeUses.addAll(removeIds); + } + lemmaUses.removeWhere((use) => removeUses.contains(use.msgId)); + final allEvents = await allConstructEvents; + for (final constructEvent in allEvents) { + await constructEvent.removeEdittedUses(removeUses, client); + } + return lemmaUses; + } + Future saveConstructUsesSameLemma( String lemma, ConstructType type, - List lemmaUses, - ) async { + List lemmaUses, { + bool isEdit = false, + }) async { final ConstructEvent? localEvent = _vocabEventLocal(lemma); + if (isEdit) { + lemmaUses = await removeEdittedLemmas(lemmaUses); + } + if (localEvent == null) { - final json = - ConstructUses(lemma: lemma, type: type, uses: lemmaUses).toJson(); await client.setRoomStateWithKey( id, PangeaEventTypes.vocab, @@ -943,14 +972,18 @@ extension PangeaRoom on Room { return (eventsDefaultPowerLevel ?? 0) >= ClassDefaultValues.powerLevelOfAdmin; } + int joinedRooms = 0; for (final child in spaceChildren) { if (child.roomId == null) continue; final Room? room = client.getRoomById(child.roomId!); if (room?.locked == false) { return false; } + if (room != null) { + joinedRooms += 1; + } } - return true; + return joinedRooms > 0 ? true : false; } Future suggestedInSpace(Room space) async { diff --git a/lib/pangea/models/construct_analytics_event.dart b/lib/pangea/models/construct_analytics_event.dart index 66921b8a23..176d84bbd8 100644 --- a/lib/pangea/models/construct_analytics_event.dart +++ b/lib/pangea/models/construct_analytics_event.dart @@ -1,6 +1,6 @@ +import 'package:fluffychat/pangea/models/constructs_analytics_model.dart'; import 'package:matrix/matrix.dart'; -import 'package:fluffychat/pangea/models/constructs_analytics_model.dart'; import '../constants/pangea_event_types.dart'; class ConstructEvent { @@ -30,4 +30,24 @@ class ConstructEvent { content.uses.addAll(uses); event.content = content.toJson(); } + + Future removeEdittedUses( + List removeIds, + Client client, + ) async { + _contentCache ??= ConstructUses.fromJson(event.content); + if (_contentCache == null || _event.stateKey == null) return; + final previousLength = _contentCache!.uses.length; + _contentCache!.uses.removeWhere( + (element) => removeIds.contains(element.msgId), + ); + if (previousLength > _contentCache!.uses.length) { + await client.setRoomStateWithKey( + _event.room.id, + _event.type, + _event.stateKey!, + _contentCache!.toJson(), + ); + } + } } diff --git a/lib/pangea/models/igc_text_data_model.dart b/lib/pangea/models/igc_text_data_model.dart index 390912fd5b..6a3eec96e0 100644 --- a/lib/pangea/models/igc_text_data_model.dart +++ b/lib/pangea/models/igc_text_data_model.dart @@ -5,6 +5,7 @@ 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 'package:fluffychat/pangea/utils/overlay.dart'; +import 'package:fluffychat/pangea/widgets/igc/span_card.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; @@ -12,7 +13,6 @@ import 'package:matrix/matrix.dart'; import 'package:sentry_flutter/sentry_flutter.dart'; import '../constants/model_keys.dart'; -import '../widgets/igc/span_card.dart'; import 'language_detection_model.dart'; // import 'package:language_tool/language_tool.dart'; @@ -285,10 +285,9 @@ class IGCTextData { String matchText; try { - matchText = originalInput.substring( - matchTokens[tokenIndex].token.text.offset, - matchTokens[nextTokenIndex - 1].token.end, - ); + final int start = matchTokens[tokenIndex].token.text.offset; + final int end = matchTokens[nextTokenIndex - 1].token.end; + matchText = originalInput.characters.getRange(start, end).toString(); } catch (err) { return [ TextSpan( @@ -318,12 +317,14 @@ class IGCTextData { ), ); - final String beforeNextToken = originalInput.substring( - matchTokens[nextTokenIndex - 1].token.end, - nextTokenIndex < matchTokens.length - ? matchTokens[nextTokenIndex].token.text.offset - : originalInput.length, - ); + final String beforeNextToken = originalInput.characters + .getRange( + matchTokens[nextTokenIndex - 1].token.end, + nextTokenIndex < matchTokens.length + ? matchTokens[nextTokenIndex].token.text.offset + : originalInput.length, + ) + .toString(); if (beforeNextToken.isNotEmpty) { items.add( diff --git a/lib/pangea/models/pangea_message_event.dart b/lib/pangea/models/pangea_message_event.dart index ebc8c2665d..61bcceb4ee 100644 --- a/lib/pangea/models/pangea_message_event.dart +++ b/lib/pangea/models/pangea_message_event.dart @@ -2,7 +2,6 @@ import 'dart:convert'; import 'package:collection/collection.dart'; import 'package:fluffychat/pangea/constants/model_keys.dart'; -import 'package:fluffychat/pangea/constants/pangea_message_types.dart'; import 'package:fluffychat/pangea/controllers/text_to_speech_controller.dart'; import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart'; import 'package:fluffychat/pangea/models/choreo_record.dart'; @@ -14,6 +13,7 @@ import 'package:fluffychat/pangea/utils/bot_name.dart'; import 'package:fluffychat/pangea/widgets/chat/message_audio_card.dart'; import 'package:flutter/material.dart'; import 'package:matrix/matrix.dart'; +import 'package:sentry_flutter/sentry_flutter.dart'; import '../../widgets/matrix.dart'; import '../constants/language_keys.dart'; @@ -69,6 +69,12 @@ class PangeaMessageEvent { .firstOrNull ?? _event; + Event updateLatestEdit() { + _latestEditCache = null; + _representations = null; + return _latestEdit; + } + bool showRichText(bool selected, bool highlighted) { if (!_isValidPangeaMessageEvent) { return false; @@ -270,32 +276,41 @@ class PangeaMessageEvent { 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, + final RepresentationEvent sent = 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, ); + if (_latestEdit.content[ModelKey.choreoRecord] == null) { + Sentry.addBreadcrumb( + Breadcrumb( + message: "originalSent created without _event or _choreo", + data: { + "eventId": _latestEdit.eventId, + "room": _latestEdit.room.id, + "sender": _latestEdit.senderId, + }, + ), + ); + } + _representations!.add(sent); } catch (err, s) { ErrorHandler.logError( m: "error parsing originalSent", @@ -456,7 +471,7 @@ class PangeaMessageEvent { _event.room.isSpaceAdmin && _event.senderId != BotName.byEnvironment && !room.isUserSpaceAdmin(_event.senderId) && - _event.messageType != PangeaMessageTypes.report; + _event.messageType == MessageTypes.Text; String get messageDisplayLangCode { final bool immersionMode = MatrixState diff --git a/lib/pangea/models/pangea_representation_event.dart b/lib/pangea/models/pangea_representation_event.dart index b79bdd0148..c581f93906 100644 --- a/lib/pangea/models/pangea_representation_event.dart +++ b/lib/pangea/models/pangea_representation_event.dart @@ -136,10 +136,10 @@ class RepresentationEvent { if (_choreo != null) return _choreo; if (_event == null) { - // debugger(when: kDebugMode); - ErrorHandler.logError( - m: '_event and _choreo both null', - s: StackTrace.current, + Sentry.addBreadcrumb( + Breadcrumb( + message: "_event and _choreo both null", + ), ); return null; } diff --git a/lib/pangea/models/student_analytics_event.dart b/lib/pangea/models/student_analytics_event.dart index 738014bb81..1884b43b4d 100644 --- a/lib/pangea/models/student_analytics_event.dart +++ b/lib/pangea/models/student_analytics_event.dart @@ -1,12 +1,12 @@ 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/extensions/client_extension.dart'; import 'package:fluffychat/pangea/models/student_analytics_summary_model.dart'; import 'package:fluffychat/pangea/utils/error_handler.dart'; +import 'package:flutter/foundation.dart'; +import 'package:matrix/matrix.dart'; + import '../constants/pangea_event_types.dart'; import 'chart_analytics_model.dart'; @@ -41,8 +41,27 @@ class StudentAnalyticsEvent { return _contentCache!; } - Future handleNewMessage(RecentMessageRecord message) async { - debugPrint("handle new message"); + Future removeEdittedMessages( + RecentMessageRecord message, + ) async { + final List removeIds = await classRoom.client.getEditHistory( + message.chatId, + message.eventId, + ); + if (removeIds.isEmpty) return; + _messagesToSave.removeWhere( + (msg) => removeIds.any((e) => e == msg.eventId), + ); + content.removeEdittedMessages( + classRoom.client, + removeIds, + ); + } + + Future handleNewMessage( + RecentMessageRecord message, { + isEdit = false, + }) async { if (classRoom.client.userID != _event.stateKey) { debugger(when: kDebugMode); ErrorHandler.logError( @@ -50,6 +69,10 @@ class StudentAnalyticsEvent { ); return; } + + if (isEdit) { + await removeEdittedMessages(message); + } _addMessage(message); if (DateTime.now().difference(content.lastUpdated).inMinutes > @@ -66,6 +89,10 @@ class StudentAnalyticsEvent { ); return; } + for (final message in messages) { + await removeEdittedMessages(message); + } + _messagesToSave.addAll(messages); _updateStudentAnalytics(); } @@ -75,6 +102,7 @@ class StudentAnalyticsEvent { content.addAll(_messagesToSave); debugPrint("updating student analytics"); _clearMessages(); + await classRoom.client.setRoomStateWithKey( classRoom.id, _event.type, diff --git a/lib/pangea/models/student_analytics_summary_model.dart b/lib/pangea/models/student_analytics_summary_model.dart index 682768b287..69d237ea95 100644 --- a/lib/pangea/models/student_analytics_summary_model.dart +++ b/lib/pangea/models/student_analytics_summary_model.dart @@ -1,8 +1,9 @@ import 'dart:convert'; +import 'package:fluffychat/pangea/utils/error_handler.dart'; import 'package:flutter/foundation.dart'; +import 'package:matrix/matrix.dart'; -import 'package:fluffychat/pangea/utils/error_handler.dart'; import '../enum/use_type.dart'; class RecentMessageRecord { @@ -78,6 +79,12 @@ class StudentAnalyticsSummary { } } + void removeEdittedMessages(Client client, List removeEventIds) { + _messages.removeWhere( + (element) => removeEventIds.contains(element.eventId), + ); + } + List get messages => _messages; static const _messagesKey = "msgs"; diff --git a/lib/pangea/pages/analytics/student_analytics/student_analytics.dart b/lib/pangea/pages/analytics/student_analytics/student_analytics.dart index fe0e796298..44843bd412 100644 --- a/lib/pangea/pages/analytics/student_analytics/student_analytics.dart +++ b/lib/pangea/pages/analytics/student_analytics/student_analytics.dart @@ -49,10 +49,6 @@ class StudentAnalyticsController extends State { } Future initialize() async { - await _pangeaController.matrixState.client - .updateMyLearningAnalyticsForAllClassesImIn( - _pangeaController.pStoreService, - ); await getClassAndChatAnalytics(context); stateSub = _pangeaController.matrixState.client.onRoomState.stream .where( diff --git a/lib/pangea/pages/sign_up/signup.dart b/lib/pangea/pages/sign_up/signup.dart index d860e442fa..7bbd055c02 100644 --- a/lib/pangea/pages/sign_up/signup.dart +++ b/lib/pangea/pages/sign_up/signup.dart @@ -139,9 +139,12 @@ class SignupPageController extends State { } } catch (e) { //#Pangea - ErrorHandler.logError(e: e); - //Pangea# - error = (e).toLocalizedString(context); + const cancelledString = "Exception: Request has been canceled"; + if (e.toString() != cancelledString) { + ErrorHandler.logError(e: e); + error = (e).toLocalizedString(context); + } + // Pangea# } finally { if (mounted) { setState(() => loading = false); diff --git a/lib/pangea/utils/class_code.dart b/lib/pangea/utils/class_code.dart index 6bd9c97643..b4e0671d67 100644 --- a/lib/pangea/utils/class_code.dart +++ b/lib/pangea/utils/class_code.dart @@ -1,12 +1,10 @@ import 'dart:math'; +import 'package:adaptive_dialog/adaptive_dialog.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:go_router/go_router.dart'; -import 'package:fluffychat/pangea/utils/error_handler.dart'; import '../controllers/pangea_controller.dart'; class ClassCodeUtil { @@ -23,59 +21,32 @@ class ClassCodeUtil { .join(); } - static void joinWithClassCodeDialog( - BuildContext outerContext, + static Future joinWithClassCodeDialog( + BuildContext context, PangeaController pangeaController, - String? classCode, - ) { - final TextEditingController textFieldController = TextEditingController( - text: classCode, + ) async { + final List? classCode = await showTextInputDialog( + context: context, + title: L10n.of(context)!.joinWithClassCode, + okLabel: L10n.of(context)!.ok, + cancelLabel: L10n.of(context)!.cancel, + textFields: [ + DialogTextField(hintText: L10n.of(context)!.joinWithClassCodeHint), + ], ); + if (classCode == null || classCode.single.isEmpty) return; - 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(); - } - }, - ), - ), - ], - ), - ), - ); + try { + await pangeaController.classController.joinClasswithCode( + context, + classCode.first, + ); + } catch (err) { + messageSnack( + context, + ErrorCopy(context, err).body, + ); + } } static messageDialog( diff --git a/lib/pangea/utils/get_chat_list_item_subtitle.dart b/lib/pangea/utils/get_chat_list_item_subtitle.dart index cddf31435c..e5b1388a91 100644 --- a/lib/pangea/utils/get_chat_list_item_subtitle.dart +++ b/lib/pangea/utils/get_chat_list_item_subtitle.dart @@ -43,6 +43,7 @@ class GetChatListItemSubtitle { } if (event.type != EventTypes.Message || + event.messageType != MessageTypes.Text || !pangeaController.permissionsController .isToolEnabled(ToolSetting.immersionMode, event.room)) { return event.calcLocalizedBody( diff --git a/lib/pangea/widgets/chat/message_toolbar.dart b/lib/pangea/widgets/chat/message_toolbar.dart index 2e9627c712..8e88d3a511 100644 --- a/lib/pangea/widgets/chat/message_toolbar.dart +++ b/lib/pangea/widgets/chat/message_toolbar.dart @@ -26,6 +26,8 @@ class ToolbarDisplayController { final bool immersionMode; final ChatController controller; final FocusNode focusNode = FocusNode(); + Event? nextEvent; + Event? previousEvent; MessageToolbar? toolbar; String? overlayId; @@ -38,6 +40,8 @@ class ToolbarDisplayController { required this.targetId, required this.immersionMode, required this.controller, + this.nextEvent, + this.previousEvent, }); void setToolbar() { @@ -86,6 +90,8 @@ class ToolbarDisplayController { ownMessage: pangeaMessageEvent.ownMessage, toolbarController: this, width: messageWidth, + nextEvent: nextEvent, + previousEvent: previousEvent, ), ], ); diff --git a/lib/pangea/widgets/chat/overlay_message.dart b/lib/pangea/widgets/chat/overlay_message.dart index e39ffe8278..630addc179 100644 --- a/lib/pangea/widgets/chat/overlay_message.dart +++ b/lib/pangea/widgets/chat/overlay_message.dart @@ -11,6 +11,8 @@ import '../../../config/app_config.dart'; class OverlayMessage extends StatelessWidget { final Event event; + final Event? nextEvent; + final Event? previousEvent; final bool selected; final Timeline timeline; // #Pangea @@ -24,6 +26,8 @@ class OverlayMessage extends StatelessWidget { const OverlayMessage( this.event, { + this.nextEvent, + this.previousEvent, this.selected = false, required this.timeline, // #Pangea @@ -44,19 +48,43 @@ class OverlayMessage extends StatelessWidget { var color = Theme.of(context).colorScheme.surfaceVariant; final textColor = ownMessage - ? Theme.of(context).colorScheme.onPrimaryContainer + ? Theme.of(context).colorScheme.onPrimary : Theme.of(context).colorScheme.onBackground; + const hardCorner = Radius.circular(4); + + final displayTime = event.type == EventTypes.RoomCreate || + nextEvent == null || + !event.originServerTs.sameEnvironment(nextEvent!.originServerTs); + + final nextEventSameSender = nextEvent != null && + { + EventTypes.Message, + EventTypes.Sticker, + EventTypes.Encrypted, + }.contains(nextEvent!.type) && + nextEvent!.senderId == event.senderId && + !displayTime; + + final previousEventSameSender = previousEvent != null && + { + EventTypes.Message, + EventTypes.Sticker, + EventTypes.Encrypted, + }.contains(previousEvent!.type) && + previousEvent!.senderId == event.senderId && + previousEvent!.originServerTs.sameEnvironment(event.originServerTs); + + const roundedCorner = Radius.circular(AppConfig.borderRadius); final borderRadius = BorderRadius.only( - topLeft: !ownMessage - ? const Radius.circular(4) - : const Radius.circular(AppConfig.borderRadius), - topRight: const Radius.circular(AppConfig.borderRadius), - bottomLeft: const Radius.circular(AppConfig.borderRadius), - bottomRight: ownMessage - ? const Radius.circular(4) - : const Radius.circular(AppConfig.borderRadius), + topLeft: !ownMessage && nextEventSameSender ? hardCorner : roundedCorner, + topRight: ownMessage && nextEventSameSender ? hardCorner : roundedCorner, + bottomLeft: + !ownMessage && previousEventSameSender ? hardCorner : roundedCorner, + bottomRight: + ownMessage && previousEventSameSender ? hardCorner : roundedCorner, ); + final noBubble = { MessageTypes.Video, MessageTypes.Image, @@ -69,7 +97,7 @@ class OverlayMessage extends StatelessWidget { }.contains(event.messageType); if (ownMessage) { - color = Theme.of(context).colorScheme.primaryContainer; + color = Theme.of(context).colorScheme.primary; } // #Pangea diff --git a/lib/pangea/widgets/class/add_space_toggles.dart b/lib/pangea/widgets/class/add_space_toggles.dart index 9103bad161..307db42ef1 100644 --- a/lib/pangea/widgets/class/add_space_toggles.dart +++ b/lib/pangea/widgets/class/add_space_toggles.dart @@ -2,6 +2,7 @@ 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:fluffychat/utils/localized_exception_extension.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:future_loading_dialog/future_loading_dialog.dart'; @@ -134,6 +135,13 @@ class AddToSpaceState extends State { future: () => add ? _addSingleSpace(room!.id, possibleParent) : possibleParent.removeSpaceChild(room!.id), + onError: (e) { + // if error occurs, do not change value of toggle + add = !add; + return (e as Object?)?.toLocalizedString(context) ?? + e?.toString() ?? + L10n.of(context)!.oopsSomethingWentWrong; + }, ); } diff --git a/lib/utils/account_config.dart b/lib/utils/account_config.dart new file mode 100644 index 0000000000..ee80e246e8 --- /dev/null +++ b/lib/utils/account_config.dart @@ -0,0 +1,65 @@ +import 'package:matrix/matrix.dart'; + +extension ApplicationAccountConfigExtension on Client { + static const String accountDataKey = 'im.fluffychat.account_config'; + + ApplicationAccountConfig get applicationAccountConfig => + ApplicationAccountConfig.fromJson( + accountData[accountDataKey]?.content ?? {}, + ); + + Future setApplicationAccountConfig( + ApplicationAccountConfig config, + ) => + setAccountData( + userID!, + accountDataKey, + config.toJson(), + ); + + /// Only updates the specified values in ApplicationAccountConfig + Future updateApplicationAccountConfig( + ApplicationAccountConfig config, + ) { + final currentConfig = applicationAccountConfig; + return setAccountData( + userID!, + accountDataKey, + ApplicationAccountConfig( + wallpaperUrl: config.wallpaperUrl ?? currentConfig.wallpaperUrl, + wallpaperOpacity: + config.wallpaperOpacity ?? currentConfig.wallpaperOpacity, + ).toJson(), + ); + } +} + +class ApplicationAccountConfig { + final Uri? wallpaperUrl; + final double? wallpaperOpacity; + + const ApplicationAccountConfig({ + this.wallpaperUrl, + this.wallpaperOpacity, + }); + + static double _sanitizedOpacity(double? opacity) { + if (opacity == null) return 1; + if (opacity > 1 || opacity < 0) return 1; + return opacity; + } + + factory ApplicationAccountConfig.fromJson(Map json) => + ApplicationAccountConfig( + wallpaperUrl: json['wallpaper_url'] is String + ? Uri.tryParse(json['wallpaper_url']) + : null, + wallpaperOpacity: + _sanitizedOpacity(json.tryGet('wallpaper_opacity')), + ); + + Map toJson() => { + 'wallpaper_url': wallpaperUrl?.toString(), + 'wallpaper_opacity': wallpaperOpacity, + }; +} diff --git a/lib/utils/adaptive_bottom_sheet.dart b/lib/utils/adaptive_bottom_sheet.dart index d2a9a8b6da..cfe487ffd4 100644 --- a/lib/utils/adaptive_bottom_sheet.dart +++ b/lib/utils/adaptive_bottom_sheet.dart @@ -2,7 +2,6 @@ import 'package:flutter/material.dart'; import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/config/themes.dart'; -import 'package:fluffychat/utils/platform_infos.dart'; Future showAdaptiveBottomSheet({ required BuildContext context, @@ -14,7 +13,8 @@ Future showAdaptiveBottomSheet({ showModalBottomSheet( context: context, builder: builder, - useRootNavigator: !PlatformInfos.isMobile, + // this sadly is ugly on desktops but otherwise breaks `.of(context)` calls + useRootNavigator: false, isDismissible: isDismissible, isScrollControlled: isScrollControlled, constraints: BoxConstraints( diff --git a/lib/utils/background_push.dart b/lib/utils/background_push.dart index fd24a1716d..00ebd3cb5e 100644 --- a/lib/utils/background_push.dart +++ b/lib/utils/background_push.dart @@ -82,9 +82,6 @@ class BackgroundPush { onLogin ??= client.onLoginStateChanged.stream.listen(handleLoginStateChanged); // Pangea# - onRoomSync ??= client.onSync.stream - .where((s) => s.hasRoomUpdate) - .listen((s) => _onClearingPush(getFromServer: false)); firebase?.setListeners( onMessage: (message) => pushHelper( PushNotification.fromJson( @@ -134,7 +131,6 @@ class BackgroundPush { void handleLoginStateChanged(_) => setupPush(); StreamSubscription? onLogin; - StreamSubscription? onRoomSync; void _newFcmToken(String token) { _fcmToken = token; @@ -145,8 +141,7 @@ class BackgroundPush { Future cancelNotification(String roomId) async { Logs().v('Cancel notification for room', roomId); - final id = await mapRoomIdToInt(roomId); - await FlutterLocalNotificationsPlugin().cancel(id); + await FlutterLocalNotificationsPlugin().cancel(roomId.hashCode); // Workaround for app icon badge not updating if (Platform.isIOS) { @@ -170,6 +165,11 @@ class BackgroundPush { }) async { if (PlatformInfos.isIOS) { await firebase?.requestPermission(); + } else if (PlatformInfos.isAndroid) { + _flutterLocalNotificationsPlugin + .resolvePlatformSpecificImplementation< + AndroidFlutterLocalNotificationsPlugin>() + ?.requestNotificationsPermission(); } final clientName = PlatformInfos.clientName; oldTokens ??= {}; @@ -269,7 +269,7 @@ class BackgroundPush { ? 'ios' : null; - bool _wentToRoomOnStartup = false; + static bool _wentToRoomOnStartup = false; Future setupPush() async { Logs().d("SetupPush"); @@ -451,97 +451,6 @@ 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 matrix?.store this number. - late Map idMap; - Future _loadIdMap() async { - idMap = Map.from( - json.decode( - (matrix?.store.getString(SettingKeys.notificationCurrentIds)) ?? '{}', - ), - ); - } - - bool _clearingPushLock = false; - Future _onClearingPush({bool getFromServer = true}) async { - if (_clearingPushLock) { - return; - } - try { - _clearingPushLock = true; - late Iterable emptyRooms; - if (getFromServer) { - Logs().v('[Push] Got new clearing push'); - var syncErrored = false; - if (client.syncPending) { - Logs().v('[Push] waiting for existing sync'); - // we need to catchError here as the Future might be in a different execution zone - await client.oneShotSync().catchError((e) { - syncErrored = true; - Logs().v('[Push] Error one-shot syncing', e); - }); - } - if (!syncErrored) { - Logs().v('[Push] single oneShotSync'); - // we need to catchError here as the Future might be in a different execution zone - await client.oneShotSync().catchError((e) { - syncErrored = true; - Logs().v('[Push] Error one-shot syncing', e); - }); - if (!syncErrored) { - emptyRooms = client.rooms - .where((r) => r.notificationCount == 0) - .map((r) => r.id); - } - } - if (syncErrored) { - try { - Logs().v( - '[Push] failed to sync for fallback push, fetching notifications endpoint...', - ); - final notifications = await client.getNotifications(limit: 20); - final notificationRooms = - notifications.notifications.map((n) => n.roomId).toSet(); - emptyRooms = client.rooms - .where((r) => !notificationRooms.contains(r.id)) - .map((r) => r.id); - } catch (e) { - Logs().v( - '[Push] failed to fetch pending notifications for clearing push, falling back...', - e, - ); - emptyRooms = client.rooms - .where((r) => r.notificationCount == 0) - .map((r) => r.id); - } - } - } else { - emptyRooms = client.rooms - .where((r) => r.notificationCount == 0) - .map((r) => r.id); - } - await _loadIdMap(); - var changed = false; - for (final roomId in emptyRooms) { - final id = idMap[roomId]; - if (id != null) { - idMap.remove(roomId); - changed = true; - await _flutterLocalNotificationsPlugin.cancel(id); - } - } - if (changed) { - await matrix?.store.setString( - SettingKeys.notificationCurrentIds, - json.encode(idMap), - ); - } - } finally { - _clearingPushLock = false; - } - } - // #Pangea Future _getToken() async { if (Platform.isAndroid) { diff --git a/lib/utils/client_manager.dart b/lib/utils/client_manager.dart index 0d9cbee902..cf8904d188 100644 --- a/lib/utils/client_manager.dart +++ b/lib/utils/client_manager.dart @@ -16,7 +16,7 @@ import 'package:path_provider/path_provider.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:universal_html/html.dart' as html; -import 'matrix_sdk_extensions/flutter_matrix_sdk_database_builder.dart'; +import 'matrix_sdk_extensions/flutter_matrix_dart_sdk_database/builder.dart'; abstract class ClientManager { static const String clientNamespace = 'im.fluffychat.store.clients'; @@ -169,12 +169,10 @@ abstract class ClientManager { body, const NotificationDetails( android: AndroidNotificationDetails( - AppConfig.pushNotificationsChannelId, - AppConfig.pushNotificationsChannelName, - channelDescription: AppConfig.pushNotificationsChannelDescription, - importance: Importance.max, + 'error_message', + 'Error Messages', + importance: Importance.high, priority: Priority.max, - fullScreenIntent: true, // To show notification popup ), iOS: DarwinNotificationDetails(sound: 'notification.caf'), ), diff --git a/lib/utils/init_with_restore.dart b/lib/utils/init_with_restore.dart index 04ed47db63..c99e2ba08b 100644 --- a/lib/utils/init_with_restore.dart +++ b/lib/utils/init_with_restore.dart @@ -99,7 +99,8 @@ extension InitWithRestoreExtension on Client { ); } } - } catch (e) { + } catch (e, s) { + Logs().wtf('Client init failed!', e, s); final l10n = lookupL10n(PlatformDispatcher.instance.locale); final sessionBackupString = await storage?.read(key: storageKey); if (sessionBackupString == null) { @@ -110,10 +111,6 @@ extension InitWithRestoreExtension on Client { rethrow; } - ClientManager.sendInitNotification( - l10n.initAppError, - l10n.restoreSessionBody(AppConfig.newIssueUrl.toString(), e.toString()), - ); try { final sessionBackup = SessionBackup.fromJsonString(sessionBackupString); await init( @@ -127,7 +124,15 @@ extension InitWithRestoreExtension on Client { waitUntilLoadCompletedLoaded: false, onMigration: onMigration, ); - } catch (e) { + ClientManager.sendInitNotification( + l10n.initAppError, + l10n.restoreSessionBody( + AppConfig.newIssueUrl.toString(), + e.toString(), + ), + ); + } catch (e, s) { + Logs().wtf('Restore client failed!', e, s); ClientManager.sendInitNotification( l10n.initAppError, l10n.sessionLostBody(AppConfig.newIssueUrl.toString(), e.toString()), diff --git a/lib/utils/matrix_sdk_extensions/flutter_matrix_dart_sdk_database/builder.dart b/lib/utils/matrix_sdk_extensions/flutter_matrix_dart_sdk_database/builder.dart new file mode 100644 index 0000000000..301d0c6ee9 --- /dev/null +++ b/lib/utils/matrix_sdk_extensions/flutter_matrix_dart_sdk_database/builder.dart @@ -0,0 +1,125 @@ +import 'dart:io'; + +import 'package:flutter/foundation.dart'; + +import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'package:matrix/matrix.dart'; +import 'package:path/path.dart'; +import 'package:path_provider/path_provider.dart'; +import 'package:sqflite_common_ffi/sqflite_ffi.dart'; +import 'package:universal_html/html.dart' as html; + +import 'package:fluffychat/config/app_config.dart'; +import 'package:fluffychat/utils/client_manager.dart'; +import 'package:fluffychat/utils/matrix_sdk_extensions/flutter_hive_collections_database.dart'; +import 'package:fluffychat/utils/platform_infos.dart'; +import 'cipher.dart'; + +import 'sqlcipher_stub.dart' + if (dart.library.io) 'package:sqlcipher_flutter_libs/sqlcipher_flutter_libs.dart'; + +Future flutterMatrixSdkDatabaseBuilder(Client client) async { + MatrixSdkDatabase? database; + try { + database = await _constructDatabase(client); + await database.open(); + return database; + } catch (e) { + // Try to delete database so that it can created again on next init: + database?.delete().catchError( + (e, s) => Logs().w( + 'Unable to delete database, after failed construction', + e, + s, + ), + ); + + // Send error notification: + final l10n = lookupL10n(PlatformDispatcher.instance.locale); + ClientManager.sendInitNotification( + l10n.initAppError, + l10n.databaseBuildErrorBody( + AppConfig.newIssueUrl.toString(), + e.toString(), + ), + ); + + return FlutterHiveCollectionsDatabase.databaseBuilder(client); + } +} + +Future _constructDatabase(Client client) async { + if (kIsWeb) { + html.window.navigator.storage?.persist(); + return MatrixSdkDatabase(client.clientName); + } + + final cipher = await getDatabaseCipher(); + + final fileStoragePath = PlatformInfos.isIOS || PlatformInfos.isMacOS + ? await getLibraryDirectory() + : await getApplicationSupportDirectory(); + + final path = join(fileStoragePath.path, '${client.clientName}.sqlite'); + + // fix dlopen for old Android + await applyWorkaroundToOpenSqlCipherOnOldAndroidVersions(); + // import the SQLite / SQLCipher shared objects / dynamic libraries + final factory = + createDatabaseFactoryFfi(ffiInit: SQfLiteEncryptionHelper.ffiInit); + + // migrate from potential previous SQLite database path to current one + await _migrateLegacyLocation(path, client.clientName); + + // required for [getDatabasesPath] + databaseFactory = factory; + + // in case we got a cipher, we use the encryption helper + // to manage SQLite encryption + final helper = SQfLiteEncryptionHelper( + factory: factory, + path: path, + cipher: cipher, + ); + + // check whether the DB is already encrypted and otherwise do so + await helper.ensureDatabaseFileEncrypted(); + + final database = await factory.openDatabase( + path, + options: OpenDatabaseOptions( + version: 1, + // most important : apply encryption when opening the DB + onConfigure: helper.applyPragmaKey, + ), + ); + + return MatrixSdkDatabase( + client.clientName, + database: database, + maxFileSize: 1024 * 1024 * 10, + fileStoragePath: fileStoragePath, + deleteFilesAfterDuration: const Duration(days: 30), + ); +} + +Future _migrateLegacyLocation( + String sqlFilePath, + String clientName, +) async { + final oldPath = PlatformInfos.isDesktop + ? (await getApplicationSupportDirectory()).path + : await getDatabasesPath(); + + final oldFilePath = join(oldPath, clientName); + if (oldFilePath == sqlFilePath) return; + + final maybeOldFile = File(oldFilePath); + if (await maybeOldFile.exists()) { + Logs().i( + 'Migrate legacy location for database from "$oldFilePath" to "$sqlFilePath"', + ); + await maybeOldFile.copy(sqlFilePath); + await maybeOldFile.delete(); + } +} diff --git a/lib/utils/matrix_sdk_extensions/flutter_matrix_dart_sdk_database/cipher.dart b/lib/utils/matrix_sdk_extensions/flutter_matrix_dart_sdk_database/cipher.dart new file mode 100644 index 0000000000..0c1163c4ab --- /dev/null +++ b/lib/utils/matrix_sdk_extensions/flutter_matrix_dart_sdk_database/cipher.dart @@ -0,0 +1,48 @@ +import 'dart:convert'; +import 'dart:math'; + +import 'package:flutter/services.dart'; + +import 'package:flutter_secure_storage/flutter_secure_storage.dart'; +import 'package:matrix/matrix.dart'; + +const _passwordStorageKey = 'database_password'; + +Future getDatabaseCipher() async { + String? password; + + try { + const secureStorage = FlutterSecureStorage(); + final containsEncryptionKey = + await secureStorage.read(key: _passwordStorageKey) != null; + if (!containsEncryptionKey) { + final rng = Random.secure(); + final list = Uint8List(32); + list.setAll(0, Iterable.generate(list.length, (i) => rng.nextInt(256))); + final newPassword = base64UrlEncode(list); + await secureStorage.write( + key: _passwordStorageKey, + value: newPassword, + ); + } + // workaround for if we just wrote to the key and it still doesn't exist + password = await secureStorage.read(key: _passwordStorageKey); + if (password == null) throw MissingPluginException(); + } on MissingPluginException catch (_) { + const FlutterSecureStorage() + .delete(key: _passwordStorageKey) + .catchError((_) {}); + Logs().i('Database encryption is not supported on this platform'); + } catch (e, s) { + const FlutterSecureStorage() + .delete(key: _passwordStorageKey) + .catchError((_) {}); + Logs().w('Unable to init database encryption', e, s); + } + + // with the new database, we should no longer allow unencrypted storage + // secure_storage now supports all platforms we support + assert(password != null); + + return password!; +} diff --git a/lib/utils/matrix_sdk_extensions/flutter_matrix_dart_sdk_database/sqlcipher_stub.dart b/lib/utils/matrix_sdk_extensions/flutter_matrix_dart_sdk_database/sqlcipher_stub.dart new file mode 100644 index 0000000000..b0f8b43dcd --- /dev/null +++ b/lib/utils/matrix_sdk_extensions/flutter_matrix_dart_sdk_database/sqlcipher_stub.dart @@ -0,0 +1 @@ +Future applyWorkaroundToOpenSqlCipherOnOldAndroidVersions() async {} diff --git a/lib/utils/matrix_sdk_extensions/flutter_matrix_sdk_database_builder.dart b/lib/utils/matrix_sdk_extensions/flutter_matrix_sdk_database_builder.dart deleted file mode 100644 index ff22abf5cc..0000000000 --- a/lib/utils/matrix_sdk_extensions/flutter_matrix_sdk_database_builder.dart +++ /dev/null @@ -1,117 +0,0 @@ -import 'dart:convert'; -import 'dart:math'; - -import 'package:fluffychat/pangea/utils/error_handler.dart'; -import 'package:fluffychat/utils/matrix_sdk_extensions/flutter_hive_collections_database.dart'; -import 'package:fluffychat/utils/platform_infos.dart'; -import 'package:flutter/foundation.dart'; -import 'package:flutter/services.dart'; -import 'package:flutter_secure_storage/flutter_secure_storage.dart'; -import 'package:matrix/matrix.dart'; -import 'package:path_provider/path_provider.dart'; -import 'package:sqflite_common_ffi/sqflite_ffi.dart' as ffi; -import 'package:sqflite_sqlcipher/sqflite.dart'; -import 'package:universal_html/html.dart' as html; - -Future flutterMatrixSdkDatabaseBuilder(Client client) async { - MatrixSdkDatabase? database; - try { - database = await _constructDatabase(client); - await database.open(); - return database; - } catch (e) { - // #Pangea - ErrorHandler.logError( - e: e, - m: 'Unable to init database', - s: StackTrace.current, - ); - // Try to delete database so that it can created again on next init: - // database?.delete().catchError( - // (e, s) => Logs().w( - // 'Unable to delete database, after failed construction', - // e, - // s, - // ), - // ); - - // Send error notification: - // final l10n = lookupL10n(PlatformDispatcher.instance.locale); - // ClientManager.sendInitNotification( - // l10n.initAppError, - // l10n.databaseBuildErrorBody( - // AppConfig.newIssueUrl.toString(), - // e.toString(), - // ), - // ); - // Pangea# - - return FlutterHiveCollectionsDatabase.databaseBuilder(client); - } -} - -Future _constructDatabase(Client client) async { - if (kIsWeb) { - html.window.navigator.storage?.persist(); - return MatrixSdkDatabase(client.clientName); - } - if (PlatformInfos.isDesktop) { - final path = await getApplicationSupportDirectory(); - return MatrixSdkDatabase( - client.clientName, - database: await ffi.databaseFactoryFfi.openDatabase( - '${path.path}/${client.clientName}', - ), - maxFileSize: 1024 * 1024 * 10, - fileStoragePath: path, - deleteFilesAfterDuration: const Duration(days: 30), - ); - } - - final path = await getDatabasesPath(); - const passwordStorageKey = 'database_password'; - String? password; - - try { - // Workaround for secure storage is calling Platform.operatingSystem on web - if (kIsWeb) throw MissingPluginException(); - - const secureStorage = FlutterSecureStorage(); - final containsEncryptionKey = - await secureStorage.read(key: passwordStorageKey) != null; - if (!containsEncryptionKey) { - final rng = Random.secure(); - final list = Uint8List(32); - list.setAll(0, Iterable.generate(list.length, (i) => rng.nextInt(256))); - final newPassword = base64UrlEncode(list); - await secureStorage.write( - key: passwordStorageKey, - value: newPassword, - ); - } - // workaround for if we just wrote to the key and it still doesn't exist - password = await secureStorage.read(key: passwordStorageKey); - if (password == null) throw MissingPluginException(); - } on MissingPluginException catch (_) { - const FlutterSecureStorage() - .delete(key: passwordStorageKey) - .catchError((_) {}); - Logs().i('Database encryption is not supported on this platform'); - } catch (e, s) { - const FlutterSecureStorage() - .delete(key: passwordStorageKey) - .catchError((_) {}); - Logs().w('Unable to init database encryption', e, s); - } - - return MatrixSdkDatabase( - client.clientName, - database: await openDatabase( - '$path/${client.clientName}', - password: password, - ), - maxFileSize: 1024 * 1024 * 10, - fileStoragePath: await getTemporaryDirectory(), - deleteFilesAfterDuration: const Duration(days: 30), - ); -} diff --git a/lib/utils/matrix_sdk_extensions/matrix_file_extension.dart b/lib/utils/matrix_sdk_extensions/matrix_file_extension.dart index 183fb753f3..97978ce023 100644 --- a/lib/utils/matrix_sdk_extensions/matrix_file_extension.dart +++ b/lib/utils/matrix_sdk_extensions/matrix_file_extension.dart @@ -3,10 +3,10 @@ import 'dart:io'; import 'package:flutter/material.dart'; import 'package:file_picker/file_picker.dart'; +import 'package:flutter_file_dialog/flutter_file_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:path_provider/path_provider.dart'; import 'package:share_plus/share_plus.dart'; import 'package:universal_html/html.dart' as html; @@ -15,8 +15,8 @@ import 'package:fluffychat/utils/size_string.dart'; extension MatrixFileExtension on MatrixFile { void save(BuildContext context) async { - if (PlatformInfos.isIOS) { - return share(context); + if (PlatformInfos.isIOS || PlatformInfos.isAndroid) { + _mobileDownload(context); } if (PlatformInfos.isWeb) { @@ -24,13 +24,11 @@ extension MatrixFileExtension on MatrixFile { return; } - final downloadPath = PlatformInfos.isAndroid - ? await getDownloadPathAndroid() - : await FilePicker.platform.saveFile( - dialogTitle: L10n.of(context)!.saveFile, - fileName: name, - type: filePickerFileType, - ); + final downloadPath = await FilePicker.platform.saveFile( + dialogTitle: L10n.of(context)!.saveFile, + fileName: name, + type: filePickerFileType, + ); if (downloadPath == null) return; final result = await showFutureLoadingDialog( @@ -48,24 +46,6 @@ extension MatrixFileExtension on MatrixFile { ); } - Future getDownloadPathAndroid() async { - final directory = await getDownloadDirectoryAndroid(); - var counter = 1; - var path = '${directory.path}/$name'; - while (await File(path).exists()) { - path = '${directory.path}/(${counter++})$name'; - } - return path; - } - - Future getDownloadDirectoryAndroid() async { - final defaultDownloadDirectory = Directory('/storage/emulated/0/Download'); - if (await defaultDownloadDirectory.exists()) { - return defaultDownloadDirectory; - } - return await getApplicationDocumentsDirectory(); - } - FileType get filePickerFileType { if (this is MatrixImageFile) return FileType.image; if (this is MatrixAudioFile) return FileType.audio; @@ -73,6 +53,25 @@ extension MatrixFileExtension on MatrixFile { return FileType.any; } + void _mobileDownload(BuildContext context) async { + final downloadPath = await FlutterFileDialog.saveFile( + params: SaveFileDialogParams( + fileName: name, + data: bytes, + ), + ); + if (downloadPath != null) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text( + L10n.of(context)!.fileHasBeenSavedAt(downloadPath), + ), + ), + ); + } + return; + } + void _webDownload() { html.AnchorElement( href: html.Url.createObjectUrlFromBlob( diff --git a/lib/utils/matrix_sdk_extensions/matrix_locals.dart b/lib/utils/matrix_sdk_extensions/matrix_locals.dart index 4eaec0d52e..c96fcac818 100644 --- a/lib/utils/matrix_sdk_extensions/matrix_locals.dart +++ b/lib/utils/matrix_sdk_extensions/matrix_locals.dart @@ -176,7 +176,7 @@ class MatrixLocals extends MatrixLocalizations { } @override - String get needPantalaimonWarning => l10n.needPantalaimonWarning; + String get needPantalaimonWarning => l10n.oopsSomethingWentWrong; @override String get noPermission => l10n.noKeyForThisMessage; diff --git a/lib/utils/push_helper.dart b/lib/utils/push_helper.dart index 76e0ff74f5..3290ae0869 100644 --- a/lib/utils/push_helper.dart +++ b/lib/utils/push_helper.dart @@ -1,22 +1,21 @@ -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'; -import 'package:matrix/matrix.dart'; -import 'package:shared_preferences/shared_preferences.dart'; - +import 'package:collection/collection.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'; import 'package:fluffychat/utils/voip/callkeep_manager.dart'; +import 'package:flutter/foundation.dart'; +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'; +import 'package:flutter_shortcuts/flutter_shortcuts.dart'; +import 'package:matrix/matrix.dart'; +import 'package:shared_preferences/shared_preferences.dart'; Future pushHelper( PushNotification notification, { @@ -34,7 +33,7 @@ Future pushHelper( onSelectNotification: onSelectNotification, ); } catch (e, s) { - Logs().wtf('Push Helper has crashed!', e, s); + Logs().v('Push Helper has crashed!', e, s); // Initialise the plugin. app_icon needs to be a added as a drawable resource to the Android head project final flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin(); @@ -52,20 +51,22 @@ Future pushHelper( // l10n ??= lookupL10n(const Locale('en')); // Pangea# flutterLocalNotificationsPlugin.show( - 0, + notification.roomId?.hashCode ?? 0, l10n?.newMessageInFluffyChat, l10n?.openAppToReadMessages, NotificationDetails( iOS: const DarwinNotificationDetails(), android: AndroidNotificationDetails( AppConfig.pushNotificationsChannelId, - AppConfig.pushNotificationsChannelName, - channelDescription: AppConfig.pushNotificationsChannelDescription, + l10n!.incomingMessages, number: notification.counts?.unread, - ticker: l10n?.unreadChats(notification.counts?.unread ?? 1), - importance: Importance.max, + ticker: l10n.unreadChatsInApp( + AppConfig.applicationName, + (notification.counts?.unread ?? 0).toString(), + ), + importance: Importance.high, priority: Priority.max, - fullScreenIntent: true, // To show notification popup + shortcutId: notification.roomId, ), ), ); @@ -116,14 +117,22 @@ Future _tryPushHelper( if (event == null) { Logs().v('Notification is a clearing indicator.'); - if (notification.counts?.unread == 0) { - if (notification.counts == null || notification.counts?.unread == 0) { - await flutterLocalNotificationsPlugin.cancelAll(); - final store = await SharedPreferences.getInstance(); - await store.setString( - SettingKeys.notificationCurrentIds, - json.encode({}), + if (notification.counts?.unread == null || + notification.counts?.unread == 0) { + await flutterLocalNotificationsPlugin.cancelAll(); + } else { + // Make sure client is fully loaded and synced before dismiss notifications: + await client.roomsLoading; + await client.oneShotSync(); + final activeNotifications = + await flutterLocalNotificationsPlugin.getActiveNotifications(); + for (final activeNotification in activeNotifications) { + final room = client.rooms.singleWhereOrNull( + (room) => room.id.hashCode == activeNotification.id, ); + if (room == null || !room.isUnreadOrInvited) { + flutterLocalNotificationsPlugin.cancel(activeNotification.id!); + } } } return; @@ -173,13 +182,23 @@ Future _tryPushHelper( final avatar = event.room.avatar ?.getThumbnail( client, - width: 126, - height: 126, + width: 256, + height: 256, ) .toString(); - File? avatarFile; + final senderAvatar = event.room.isDirectChat + ? avatar + : event.senderFromMemoryOrFallback.avatarUrl + ?.getThumbnail( + client, + width: 256, + height: 256, + ) + .toString(); + + File? roomAvatarFile, senderAvatarFile; try { - avatarFile = avatar == null + roomAvatarFile = avatar == null ? null : await DefaultCacheManager().getSingleFile(avatar); } catch (e, s) { @@ -188,19 +207,31 @@ Future _tryPushHelper( ErrorHandler.logError(e: e, s: s); // Pangea# } + try { + senderAvatarFile = event.room.isDirectChat + ? roomAvatarFile + : senderAvatar == null + ? null + : await DefaultCacheManager().getSingleFile(senderAvatar); + } catch (e, s) { + Logs().e('Unable to get avatar picture', e, s); + } - final id = await mapRoomIdToInt(event.room.id); + final id = notification.roomId.hashCode; // Show notification - final person = Person( - name: event.senderFromMemoryOrFallback.calcDisplayname(), - icon: - avatarFile == null ? null : BitmapFilePathAndroidIcon(avatarFile.path), - ); + final newMessage = Message( body, event.originServerTs, - person, + Person( + bot: event.messageType == MessageTypes.Notice, + key: event.senderId, + name: event.senderFromMemoryOrFallback.calcDisplayname(), + icon: senderAvatarFile == null + ? null + : BitmapFilePathAndroidIcon(senderAvatarFile.path), + ), ); final messagingStyleInformation = PlatformInfos.isAndroid @@ -235,23 +266,36 @@ Future _tryPushHelper( ?.createNotificationChannel(roomsChannel); final androidPlatformChannelSpecifics = AndroidNotificationDetails( - event.room.id, - roomName, - channelDescription: groupName, + AppConfig.pushNotificationsChannelId, + l10n.incomingMessages, number: notification.counts?.unread, category: AndroidNotificationCategory.message, + shortcutId: event.room.id, styleInformation: messagingStyleInformation ?? MessagingStyleInformation( - person, + Person( + name: event.senderFromMemoryOrFallback.calcDisplayname(), + icon: roomAvatarFile == null + ? null + : BitmapFilePathAndroidIcon(roomAvatarFile.path), + key: event.roomId, + important: event.room.isFavourite, + ), conversationTitle: roomName, groupConversation: !event.room.isDirectChat, messages: [newMessage], ), - ticker: l10n.unreadChats(notification.counts?.unread ?? 1), - importance: Importance.max, + ticker: event.calcLocalizedBodyFallback( + matrixLocals, + plaintextBody: true, + withSenderNamePrefix: true, + hideReply: true, + hideEdit: true, + removeMarkdown: true, + ), + importance: Importance.high, priority: Priority.max, groupKey: notificationGroupId, - fullScreenIntent: true, // To show notification popup ); const iOSPlatformChannelSpecifics = DarwinNotificationDetails(); final platformChannelSpecifics = NotificationDetails( @@ -259,11 +303,15 @@ Future _tryPushHelper( iOS: iOSPlatformChannelSpecifics, ); + final title = event.room.getLocalizedDisplayname(MatrixLocals(l10n)); + + if (PlatformInfos.isAndroid && messagingStyleInformation == null) { + await _setShortcut(event, l10n, title, roomAvatarFile); + } + await flutterLocalNotificationsPlugin.show( id, - event.room.getLocalizedDisplayname( - MatrixLocals(l10n), - ), + title, body, platformChannelSpecifics, payload: event.roomId, @@ -271,28 +319,31 @@ Future _tryPushHelper( Logs().v('Push helper has been completed!'); } -/// 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. -Future mapRoomIdToInt(String roomId) async { - final store = await SharedPreferences.getInstance(); - final idMap = Map.from( - jsonDecode(store.getString(SettingKeys.notificationCurrentIds) ?? '{}'), +/// Creates a shortcut for Android platform but does not block displaying the +/// notification. This is optional but provides a nicer view of the +/// notification popup. +Future _setShortcut( + Event event, + L10n l10n, + String title, + File? avatarFile, +) async { + final flutterShortcuts = FlutterShortcuts(); + await flutterShortcuts.initialize(debug: !kReleaseMode); + await flutterShortcuts.pushShortcutItem( + shortcut: ShortcutItem( + id: event.room.id, + action: AppConfig.inviteLinkPrefix + event.room.id, + shortLabel: title, + conversationShortcut: true, + icon: avatarFile == null + ? null + : ShortcutMemoryIcon(jpegImage: await avatarFile.readAsBytes()) + .toString(), + shortcutIconAsset: avatarFile == null + ? ShortcutIconAsset.androidAsset + : ShortcutIconAsset.memoryAsset, + isImportant: event.room.isFavourite, + ), ); - int? currentInt; - try { - currentInt = idMap[roomId]; - } catch (_) { - currentInt = null; - } - if (currentInt != null) { - return currentInt; - } - var nCurrentInt = 0; - while (idMap.values.contains(nCurrentInt)) { - nCurrentInt++; - } - idMap[roomId] = nCurrentInt; - await store.setString(SettingKeys.notificationCurrentIds, json.encode(idMap)); - return nCurrentInt; } diff --git a/lib/utils/url_launcher.dart b/lib/utils/url_launcher.dart index 808f64f65b..53de9b1385 100644 --- a/lib/utils/url_launcher.dart +++ b/lib/utils/url_launcher.dart @@ -169,10 +169,10 @@ class UrlLauncher { // we have the room, so....just open it if (event != null) { context.go( - Uri( + '/${Uri( pathSegments: ['rooms', room.id], queryParameters: {'event': event}, - ).toString(), + )}', ); } else { context.go('/rooms/${room.id}'); diff --git a/lib/widgets/app_lock.dart b/lib/widgets/app_lock.dart index ace02b2276..d337358d7c 100644 --- a/lib/widgets/app_lock.dart +++ b/lib/widgets/app_lock.dart @@ -104,6 +104,7 @@ class AppLock extends State with WidgetsBindingObserver { Widget build(BuildContext context) => Provider( create: (_) => this, child: Stack( + fit: StackFit.expand, children: [ widget.child, if (isLocked) const LockScreen(), diff --git a/lib/widgets/blur_hash.dart b/lib/widgets/blur_hash.dart new file mode 100644 index 0000000000..d4ad1dd47a --- /dev/null +++ b/lib/widgets/blur_hash.dart @@ -0,0 +1,104 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; + +import 'package:blurhash_dart/blurhash_dart.dart' as b; +import 'package:image/image.dart' as image; + +class BlurHash extends StatefulWidget { + final double width; + final double height; + final String blurhash; + final BoxFit fit; + + const BlurHash({ + super.key, + String? blurhash, + required this.width, + required this.height, + this.fit = BoxFit.cover, + }) : blurhash = blurhash ?? 'LEHV6nWB2yk8pyo0adR*.7kCMdnj'; + + @override + State createState() => _BlurHashState(); +} + +class _BlurHashState extends State { + Uint8List? _data; + + static Future getBlurhashData( + BlurhashData blurhashData, + ) async { + final blurhash = b.BlurHash.decode(blurhashData.hsh); + final img = blurhash.toImage(blurhashData.w, blurhashData.h); + return Uint8List.fromList(image.encodePng(img)); + } + + Future _computeBlurhashData() async { + if (_data != null) return _data!; + final ratio = widget.width / widget.height; + var width = 32; + var height = 32; + if (ratio > 1.0) { + height = (width / ratio).round(); + } else { + width = (height * ratio).round(); + } + + return _data ??= await compute( + getBlurhashData, + BlurhashData( + hsh: widget.blurhash, + w: width, + h: height, + ), + ); + } + + @override + Widget build(BuildContext context) { + return FutureBuilder( + future: _computeBlurhashData(), + initialData: _data, + builder: (context, snapshot) { + final data = snapshot.data; + if (data == null) { + return Container( + width: widget.width, + height: widget.height, + color: Theme.of(context).colorScheme.onInverseSurface, + ); + } + return Image.memory( + data, + fit: widget.fit, + width: widget.width, + height: widget.height, + ); + }, + ); + } +} + +class BlurhashData { + final String hsh; + final int w; + final int h; + + const BlurhashData({ + required this.hsh, + required this.w, + required this.h, + }); + + factory BlurhashData.fromJson(Map json) => BlurhashData( + hsh: json['hsh'], + w: json['w'], + h: json['h'], + ); + + Map toJson() => { + 'hsh': hsh, + 'w': w, + 'h': h, + }; +} diff --git a/lib/widgets/chat_settings_popup_menu.dart b/lib/widgets/chat_settings_popup_menu.dart index 92a4df4081..6c10781678 100644 --- a/lib/widgets/chat_settings_popup_menu.dart +++ b/lib/widgets/chat_settings_popup_menu.dart @@ -6,11 +6,9 @@ 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 'package:flutter/material.dart'; -import 'package:flutter/services.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:keyboard_shortcuts/keyboard_shortcuts.dart'; import 'package:matrix/matrix.dart'; import 'matrix.dart'; @@ -152,15 +150,17 @@ class ChatSettingsPopupMenuState extends State { return Stack( alignment: Alignment.center, children: [ - KeyBoardShortcuts( - keysToPress: { - LogicalKeyboardKey.controlLeft, - LogicalKeyboardKey.keyI, - }, - helpLabel: L10n.of(context)!.chatDetails, - onKeysPressed: _showChatDetails, - child: const SizedBox.shrink(), - ), + // #Pangea + // KeyBoardShortcuts( + // keysToPress: { + // LogicalKeyboardKey.controlLeft, + // LogicalKeyboardKey.keyI, + // }, + // helpLabel: L10n.of(context)!.chatDetails, + // onKeysPressed: _showChatDetails, + // child: const SizedBox.shrink(), + // ), + // Pangea# PopupMenuButton( onSelected: (String choice) async { switch (choice) { diff --git a/lib/widgets/connection_status_header.dart b/lib/widgets/connection_status_header.dart index 2283c41bf4..285ebb8bfc 100644 --- a/lib/widgets/connection_status_header.dart +++ b/lib/widgets/connection_status_header.dart @@ -47,7 +47,7 @@ class ConnectionStatusHeaderState extends State { curve: FluffyThemes.animationCurve, height: hide ? 0 : 36, clipBehavior: Clip.hardEdge, - decoration: BoxDecoration(color: Theme.of(context).colorScheme.surface), + decoration: const BoxDecoration(color: Colors.transparent), padding: const EdgeInsets.symmetric(horizontal: 12), child: Row( mainAxisAlignment: MainAxisAlignment.center, diff --git a/lib/widgets/local_notifications_extension.dart b/lib/widgets/local_notifications_extension.dart index 1be783d36d..e3d9ff3c44 100644 --- a/lib/widgets/local_notifications_extension.dart +++ b/lib/widgets/local_notifications_extension.dart @@ -111,7 +111,11 @@ extension LocalNotificationsExtension on MatrixState { .singleWhere((a) => a.name == actionStr); switch (action) { case DesktopNotificationActions.seen: - room.setReadMarker(event.eventId, mRead: event.eventId); + room.setReadMarker( + event.eventId, + mRead: event.eventId, + public: AppConfig.sendPublicReadReceipts, + ); break; case DesktopNotificationActions.openChat: context.go('/rooms/${room.id}'); diff --git a/lib/widgets/lock_screen.dart b/lib/widgets/lock_screen.dart index 8825f6cd8c..93c0b54fb6 100644 --- a/lib/widgets/lock_screen.dart +++ b/lib/widgets/lock_screen.dart @@ -4,10 +4,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; -import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/config/themes.dart'; import 'package:fluffychat/widgets/app_lock.dart'; -import 'package:fluffychat/widgets/theme_builder.dart'; class LockScreen extends StatefulWidget { const LockScreen({super.key}); @@ -62,63 +60,50 @@ class _LockScreenState extends State { @override Widget build(BuildContext context) { - return ThemeBuilder( - builder: (context, themeMode, primaryColor) => MaterialApp( - title: AppConfig.applicationName, - themeMode: themeMode, - theme: FluffyThemes.buildTheme(context, Brightness.light, primaryColor), - darkTheme: - FluffyThemes.buildTheme(context, Brightness.dark, primaryColor), - localizationsDelegates: L10n.localizationsDelegates, - supportedLocales: L10n.supportedLocales, - home: Builder( - builder: (context) => Scaffold( - appBar: AppBar( - title: Text(L10n.of(context)!.pleaseEnterYourPin), - centerTitle: true, + return Scaffold( + appBar: AppBar( + title: Text(L10n.of(context)!.pleaseEnterYourPin), + centerTitle: true, + ), + extendBodyBehindAppBar: true, + body: Center( + child: Padding( + padding: const EdgeInsets.all(16.0), + child: ConstrainedBox( + constraints: const BoxConstraints( + maxWidth: FluffyThemes.columnWidth, ), - extendBodyBehindAppBar: true, - body: Center( - child: Padding( - padding: const EdgeInsets.all(16.0), - child: ConstrainedBox( - constraints: const BoxConstraints( - maxWidth: FluffyThemes.columnWidth, + child: ListView( + shrinkWrap: true, + children: [ + Center( + child: Image.asset( + 'assets/info-logo.png', + width: 256, ), - child: ListView( - shrinkWrap: true, - children: [ - Center( - child: Image.asset( - 'assets/info-logo.png', - width: 256, - ), - ), - TextField( - controller: _textEditingController, - textInputAction: TextInputAction.done, - keyboardType: TextInputType.number, - obscureText: true, - autofocus: true, - textAlign: TextAlign.center, - readOnly: _inputBlocked, - onChanged: (_) => tryUnlock(context), - onSubmitted: (_) => tryUnlock(context), - style: const TextStyle(fontSize: 40), - decoration: InputDecoration( - errorText: _errorText, - hintText: '****', - ), - ), - if (_inputBlocked) - const Padding( - padding: EdgeInsets.all(8.0), - child: LinearProgressIndicator(), - ), - ], + ), + TextField( + controller: _textEditingController, + textInputAction: TextInputAction.done, + keyboardType: TextInputType.number, + obscureText: true, + autofocus: true, + textAlign: TextAlign.center, + readOnly: _inputBlocked, + onChanged: (_) => tryUnlock(context), + onSubmitted: (_) => tryUnlock(context), + style: const TextStyle(fontSize: 40), + decoration: InputDecoration( + errorText: _errorText, + hintText: '****', ), ), - ), + if (_inputBlocked) + const Padding( + padding: EdgeInsets.all(8.0), + child: LinearProgressIndicator(), + ), + ], ), ), ), diff --git a/lib/widgets/matrix.dart b/lib/widgets/matrix.dart index e6d47e13be..5aae2398bf 100644 --- a/lib/widgets/matrix.dart +++ b/lib/widgets/matrix.dart @@ -4,10 +4,12 @@ import 'dart:convert'; import 'package:adaptive_dialog/adaptive_dialog.dart'; import 'package:collection/collection.dart'; import 'package:desktop_notifications/desktop_notifications.dart'; +import 'package:fluffychat/pangea/constants/model_keys.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/matrix_sdk_extensions/matrix_file_extension.dart'; import 'package:fluffychat/utils/platform_infos.dart'; import 'package:fluffychat/utils/uia_request_manager.dart'; import 'package:fluffychat/utils/voip_plugin.dart'; @@ -18,6 +20,7 @@ import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:future_loading_dialog/future_loading_dialog.dart'; import 'package:http/http.dart' as http; import 'package:image_picker/image_picker.dart'; +import 'package:intl/intl.dart'; import 'package:matrix/encryption.dart'; import 'package:matrix/matrix.dart'; import 'package:provider/provider.dart'; @@ -191,26 +194,6 @@ class MatrixState extends State with WidgetsBindingObserver { final StreamController?> onShareContentChanged = StreamController.broadcast(); - void _initWithStore() async { - try { - if (client.isLogged()) { - // TODO: Figure out how this works in multi account - final statusMsg = store.getString(SettingKeys.ownStatusMessage); - if (statusMsg?.isNotEmpty ?? false) { - Logs().v('Send cached status message: "$statusMsg"'); - await client.setPresence( - client.userID!, - PresenceType.online, - statusMsg: statusMsg, - ); - } - } - } catch (e, s) { - client.onLoginStateChanged.addError(e, s); - rethrow; - } - } - final onRoomKeyRequestSub = {}; final onKeyVerificationRequestSub = {}; final onNotification = {}; @@ -267,8 +250,14 @@ class MatrixState extends State with WidgetsBindingObserver { WidgetsBinding.instance.addPostFrameCallback((_) { LoadingDialog.defaultTitle = L10n.of(context)!.loadingPleaseWait; LoadingDialog.defaultBackLabel = L10n.of(context)!.close; - LoadingDialog.defaultOnError = - (e) => (e as Object?)!.toLocalizedString(context); + // #Pangea + // LoadingDialog.defaultOnError = + // (e) => (e as Object?)!.toLocalizedString(context); + LoadingDialog.defaultOnError = (e) => + (e as Object?)?.toLocalizedString(context) ?? + e?.toString() ?? + L10n.of(context)!.oopsSomethingWentWrong; + // Pangea# }); } @@ -372,7 +361,11 @@ class MatrixState extends State with WidgetsBindingObserver { e.type == EventUpdateType.timeline && [EventTypes.Message, EventTypes.Sticker, EventTypes.Encrypted] .contains(e.content['type']) && - e.content['sender'] != c.userID, + e.content['sender'] != c.userID + // #Pangea + && + !e.content['content']?.containsKey(ModelKey.transcription), + // Pangea#, ) .listen(showLocalNotification); }); @@ -391,8 +384,6 @@ class MatrixState extends State with WidgetsBindingObserver { } void initMatrix() { - _initWithStore(); - for (final c in widget.clients) { _registerSubs(c.clientName); } @@ -474,6 +465,10 @@ class MatrixState extends State with WidgetsBindingObserver { store.getBool(SettingKeys.hideUnknownEvents) ?? AppConfig.hideUnknownEvents; + AppConfig.hideUnimportantStateEvents = + store.getBool(SettingKeys.hideUnimportantStateEvents) ?? + AppConfig.hideUnimportantStateEvents; + AppConfig.separateChatTypes = store.getBool(SettingKeys.separateChatTypes) ?? AppConfig.separateChatTypes; @@ -485,11 +480,18 @@ class MatrixState extends State with WidgetsBindingObserver { store.getBool(SettingKeys.sendTypingNotifications) ?? AppConfig.sendTypingNotifications; + AppConfig.sendPublicReadReceipts = + store.getBool(SettingKeys.sendPublicReadReceipts) ?? + AppConfig.sendPublicReadReceipts; + AppConfig.sendOnEnter = store.getBool(SettingKeys.sendOnEnter) ?? AppConfig.sendOnEnter; AppConfig.experimentalVoip = store.getBool(SettingKeys.experimentalVoip) ?? AppConfig.experimentalVoip; + + AppConfig.showPresences = + store.getBool(SettingKeys.showPresences) ?? AppConfig.showPresences; } @override @@ -503,7 +505,6 @@ class MatrixState extends State with WidgetsBindingObserver { client.httpClient.close(); onFocusSub?.cancel(); onBlurSub?.cancel(); - backgroundPush?.onRoomSync?.cancel(); linuxNotifications?.close(); @@ -517,6 +518,34 @@ class MatrixState extends State with WidgetsBindingObserver { child: widget.child, ); } + + Future dehydrateAction() async { + final response = await showOkCancelAlertDialog( + context: context, + isDestructiveAction: true, + title: L10n.of(context)!.dehydrate, + message: L10n.of(context)!.dehydrateWarning, + ); + if (response != OkCancelResult.ok) { + return; + } + final result = await showFutureLoadingDialog( + context: context, + future: client.exportDump, + ); + final export = result.result; + if (export == null) return; + + final exportBytes = Uint8List.fromList( + const Utf8Codec().encode(export), + ); + + final exportFileName = + 'fluffychat-export-${DateFormat(DateFormat.YEAR_MONTH_DAY).format(DateTime.now())}.fluffybackup'; + + final file = MatrixFile(bytes: exportBytes, name: exportFileName); + file.save(context); + } } class _AccountBundleWithClient { diff --git a/lib/widgets/mxc_image.dart b/lib/widgets/mxc_image.dart index 0aedd1e4ff..9290156bf7 100644 --- a/lib/widgets/mxc_image.dart +++ b/lib/widgets/mxc_image.dart @@ -131,7 +131,9 @@ class _MxcImageState extends State { } void _tryLoad(_) async { - if (_imageData != null) return; + if (_imageData != null) { + return; + } try { await _load(); } catch (_) { @@ -149,33 +151,41 @@ class _MxcImageState extends State { Widget placeholder(BuildContext context) => widget.placeholder?.call(context) ?? - const Center( - child: CircularProgressIndicator.adaptive(), + Container( + width: widget.width, + height: widget.height, + alignment: Alignment.center, + child: const CircularProgressIndicator.adaptive(strokeWidth: 2), ); @override Widget build(BuildContext context) { final data = _imageData; + final hasData = data != null && data.isNotEmpty; return AnimatedCrossFade( - duration: widget.animationDuration, crossFadeState: - data == null ? CrossFadeState.showFirst : CrossFadeState.showSecond, + hasData ? CrossFadeState.showSecond : CrossFadeState.showFirst, + duration: FluffyThemes.animationDuration, firstChild: placeholder(context), - secondChild: data == null || data.isEmpty - ? const SizedBox.shrink() - : Image.memory( + secondChild: hasData + ? Image.memory( data, width: widget.width, height: widget.height, fit: widget.fit, - filterQuality: FilterQuality.medium, + filterQuality: + widget.isThumbnail ? FilterQuality.low : FilterQuality.medium, errorBuilder: (context, __, ___) { _isCached = false; _imageData = null; WidgetsBinding.instance.addPostFrameCallback(_tryLoad); return placeholder(context); }, + ) + : SizedBox( + width: widget.width, + height: widget.height, ), ); } diff --git a/lib/widgets/public_room_bottom_sheet.dart b/lib/widgets/public_room_bottom_sheet.dart index baf59a030b..19932f5b98 100644 --- a/lib/widgets/public_room_bottom_sheet.dart +++ b/lib/widgets/public_room_bottom_sheet.dart @@ -82,7 +82,7 @@ class PublicRoomBottomSheet extends StatelessWidget { child: Scaffold( appBar: AppBar( title: Text( - chunk!.name ?? roomAlias ?? chunk!.roomId, + chunk?.name ?? roomAlias ?? chunk?.roomId ?? 'Unknown', overflow: TextOverflow.fade, ), leading: IconButton( @@ -148,7 +148,10 @@ class PublicRoomBottomSheet extends StatelessWidget { const SizedBox(height: 16), ListTile( title: Text( - profile?.name ?? chunk!.roomId.localpart ?? '', + profile?.name ?? + roomAlias?.localpart ?? + chunk?.roomId.localpart ?? + L10n.of(context)!.chat, ), subtitle: Text( '${L10n.of(context)!.participant}: ${profile?.numJoinedMembers ?? 0}', diff --git a/lib/widgets/settings_switch_list_tile.dart b/lib/widgets/settings_switch_list_tile.dart index 8f4285a4be..f49b97598b 100644 --- a/lib/widgets/settings_switch_list_tile.dart +++ b/lib/widgets/settings_switch_list_tile.dart @@ -6,6 +6,7 @@ class SettingsSwitchListTile extends StatefulWidget { final bool defaultValue; final String storeKey; final String title; + final String? subtitle; final Function(bool)? onChanged; const SettingsSwitchListTile.adaptive({ @@ -13,6 +14,7 @@ class SettingsSwitchListTile extends StatefulWidget { this.defaultValue = false, required this.storeKey, required this.title, + this.subtitle, this.onChanged, }); @@ -23,10 +25,12 @@ class SettingsSwitchListTile extends StatefulWidget { class SettingsSwitchListTileState extends State { @override Widget build(BuildContext context) { + final subtitle = widget.subtitle; return SwitchListTile.adaptive( value: Matrix.of(context).store.getBool(widget.storeKey) ?? widget.defaultValue, title: Text(widget.title), + subtitle: subtitle == null ? null : Text(subtitle), onChanged: (bool newValue) async { widget.onChanged?.call(newValue); await Matrix.of(context).store.setBool(widget.storeKey, newValue); diff --git a/licenses.yaml b/licenses.yaml new file mode 100644 index 0000000000..7b2f79bbfe --- /dev/null +++ b/licenses.yaml @@ -0,0 +1,38 @@ +# This is a config for a license compliance checker script. It runs in CI. +# +# To run locally: +# dart run license_checker check-licenses -c licenses.yaml --problematic +# +# SPDX license list: https://spdx.org/licenses/ + +# Before you add a license here: Is it free software? Is it compatible with AGPL-3.0? +permittedLicenses: + - AGPL-3.0 + - Apache-2.0 + - BSD-2-Clause + - BSD-3-Clause + - EUPL-1.2 + - MIT + - MPL-2.0 + - Zlib + +packageLicenseOverride: + dependency_validator: Apache-2.0 + flutter_gen: MIT + hive: Apache-2.0 + hive_flutter: Apache-2.0 + latlong2: Apache-2.0 + platform_detect: Apache-2.0 + rxdart: Apache-2.0 + + # flutter's internal packages + flutter_driver: BSD-3-Clause + flutter_localizations: BSD-3-Clause + flutter_test: BSD-3-Clause + flutter_web_plugins: BSD-3-Clause + fuchsia_remote_debug_protocol: BSD-3-Clause + integration_test: BSD-3-Clause + sky_engine: BSD-3-Clause + +rejectedLicenses: + - BUSL-1.1 diff --git a/linux/CMakeLists.txt b/linux/CMakeLists.txt index 5b46b21570..d6a3874b57 100644 --- a/linux/CMakeLists.txt +++ b/linux/CMakeLists.txt @@ -2,6 +2,8 @@ cmake_minimum_required(VERSION 3.10) project(runner LANGUAGES CXX) +# smth sqlcipher_flutter_libs static linking Hundreds +set(OPENSSL_USE_STATIC_LIBS OFF) # The name of the executable created for the application. Change this to change # the on-disk name of your application. set(BINARY_NAME "fluffychat") @@ -122,6 +124,12 @@ foreach(bundled_library ${PLUGIN_BUNDLED_LIBRARIES}) COMPONENT Runtime) endforeach(bundled_library) +# Copy the native assets provided by the build.dart from all packages. +set(NATIVE_ASSETS_DIR "${PROJECT_BUILD_DIR}native_assets/linux/") +install(DIRECTORY "${NATIVE_ASSETS_DIR}" + DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) + # Fully re-copy the assets directory on each build to avoid having stale files # from a previous install. set(FLUTTER_ASSET_DIR_NAME "flutter_assets") diff --git a/linux/flutter/generated_plugin_registrant.cc b/linux/flutter/generated_plugin_registrant.cc index 935db77358..f1b16b116c 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) sentry_flutter_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "SentryFlutterPlugin"); sentry_flutter_plugin_register_with_registrar(sentry_flutter_registrar); + g_autoptr(FlPluginRegistrar) sqlcipher_flutter_libs_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "Sqlite3FlutterLibsPlugin"); + sqlite3_flutter_libs_plugin_register_with_registrar(sqlcipher_flutter_libs_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 6c5e71b28d..26540a8d98 100644 --- a/linux/flutter/generated_plugins.cmake +++ b/linux/flutter/generated_plugins.cmake @@ -12,6 +12,7 @@ list(APPEND FLUTTER_PLUGIN_LIST pasteboard record_linux sentry_flutter + sqlcipher_flutter_libs url_launcher_linux window_to_front ) diff --git a/linux/my_application.cc b/linux/my_application.cc index 6dea055f26..c185bcd785 100644 --- a/linux/my_application.cc +++ b/linux/my_application.cc @@ -94,6 +94,24 @@ static gboolean my_application_local_command_line(GApplication* application, gch return TRUE; } +// Implements GApplication::startup. +static void my_application_startup(GApplication* application) { + //MyApplication* self = MY_APPLICATION(object); + + // Perform any actions required at application startup. + + G_APPLICATION_CLASS(my_application_parent_class)->startup(application); +} + +// Implements GApplication::shutdown. +static void my_application_shutdown(GApplication* application) { + //MyApplication* self = MY_APPLICATION(object); + + // Perform any actions required at application shutdown. + + G_APPLICATION_CLASS(my_application_parent_class)->shutdown(application); +} + // Implements GObject::dispose. static void my_application_dispose(GObject* object) { MyApplication* self = MY_APPLICATION(object); @@ -104,6 +122,8 @@ static void my_application_dispose(GObject* object) { static void my_application_class_init(MyApplicationClass* klass) { G_APPLICATION_CLASS(klass)->activate = my_application_activate; G_APPLICATION_CLASS(klass)->local_command_line = my_application_local_command_line; + G_APPLICATION_CLASS(klass)->startup = my_application_startup; + G_APPLICATION_CLASS(klass)->shutdown = my_application_shutdown; G_OBJECT_CLASS(klass)->dispose = my_application_dispose; } diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index fc58943dc4..ca9f6a1855 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -35,7 +35,7 @@ import sentry_flutter import share_plus import shared_preferences_foundation import sqflite -import sqflite_sqlcipher +import sqlcipher_flutter_libs import url_launcher_macos import video_compress import video_player_avfoundation @@ -73,7 +73,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin")) - SqfliteSqlCipherPlugin.register(with: registry.registrar(forPlugin: "SqfliteSqlCipherPlugin")) + Sqlite3FlutterLibsPlugin.register(with: registry.registrar(forPlugin: "Sqlite3FlutterLibsPlugin")) UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) VideoCompressPlugin.register(with: registry.registrar(forPlugin: "VideoCompressPlugin")) FVPVideoPlayerPlugin.register(with: registry.registrar(forPlugin: "FVPVideoPlayerPlugin")) diff --git a/needed-translations.txt b/needed-translations.txt index b5d0fb74ad..cbe3b2bfc4 100644 --- a/needed-translations.txt +++ b/needed-translations.txt @@ -709,7 +709,6 @@ "addToClassOrExchange", "addToClassOrExchangeDesc", "invitedToClassOrExchange", - "decline", "declinedInvitation", "acceptedInvitation", "youreInvited", @@ -770,26 +769,6 @@ "clickToManageSubscription", "emptyInviteWarning", "errorGettingAudio", - "nothingFound", - "leaveEmptyToClearStatus", - "select", - "searchForUsers", - "pleaseEnterYourCurrentPassword", - "newPassword", - "pleaseChooseAStrongPassword", - "passwordsDoNotMatch", - "passwordIsWrong", - "publicLink", - "joinSpace", - "publicSpaces", - "addChatOrSubSpace", - "subspace", - "thisDevice", - "initAppError", - "databaseBuildErrorBody", - "sessionLostBody", - "restoreSessionBody", - "forwardMessageTo", "signUp", "pleaseChooseAtLeastChars", "noEmailWarning", @@ -810,12 +789,6 @@ "enableModerationDesc", "conversationLanguageLevel", "showDefinition", - "acceptedKeyVerification", - "canceledKeyVerification", - "completedKeyVerification", - "isReadyForKeyVerification", - "requestedKeyVerification", - "startedKeyVerification", "subscriptionPopupTitle", "subscriptionPopupDesc", "seeOptions", @@ -834,29 +807,569 @@ "joinToView", "refresh", "autoPlayTitle", - "autoPlayDesc" + "autoPlayDesc", + "stickers", + "discover", + "commandHint_ignore", + "commandHint_unignore", + "unreadChatsInApp" ], - "bn": [ + "be": [ + "repeatPassword", + "notAnImage", + "remove", + "importNow", + "importEmojis", + "importFromZipFile", + "exportEmotePack", + "replace", + "about", + "accept", + "acceptedTheInvitation", + "account", "accountInformation", + "activatedEndToEndEncryption", + "addEmail", + "confirmMatrixId", + "supposedMxid", "addGroupDescription", "addNewFriend", + "addToSpace", + "admin", + "alias", + "all", + "allChats", "alreadyHaveAnAccount", + "commandHint_googly", + "commandHint_cuddle", + "commandHint_hug", + "googlyEyesContent", + "cuddleContent", + "hugContent", + "answeredTheCall", + "anyoneCanJoin", + "appLock", + "archive", + "areGuestsAllowedToJoin", + "areYouSure", + "areYouSureYouWantToLogout", + "askSSSSSign", + "askVerificationRequest", + "autoplayImages", + "badServerLoginTypesException", + "sendTypingNotifications", + "sendOnEnter", + "badServerVersionsException", + "banFromChat", + "banned", + "bannedUser", + "blockDevice", + "blocked", + "botMessages", + "cancel", + "cantOpenUri", + "changeDeviceName", + "changedTheChatAvatar", + "changedTheChatDescriptionTo", + "changedTheChatNameTo", + "changedTheChatPermissions", + "changedTheDisplaynameTo", + "changedTheGuestAccessRules", + "changedTheGuestAccessRulesTo", + "changedTheHistoryVisibility", + "changedTheHistoryVisibilityTo", + "changedTheJoinRules", + "changedTheJoinRulesTo", + "changedTheProfileAvatar", + "changedTheRoomAliases", + "changedTheRoomInvitationLink", + "changePassword", + "changeTheHomeserver", + "changeTheme", + "changeTheNameOfTheGroup", + "changeYourAvatar", + "channelCorruptedDecryptError", + "chat", + "yourChatBackupHasBeenSetUp", + "chatBackup", + "chatBackupDescription", + "chatDetails", + "chatHasBeenAddedToThisSpace", + "chats", "classes", + "chooseAStrongPassword", + "clearArchive", + "close", + "commandHint_markasdm", + "commandHint_markasgroup", + "commandHint_ban", + "commandHint_clearcache", + "commandHint_create", + "commandHint_discardsession", + "commandHint_dm", + "commandHint_html", + "commandHint_invite", + "commandHint_join", + "commandHint_kick", + "commandHint_leave", + "commandHint_me", + "commandHint_myroomavatar", + "commandHint_myroomnick", + "commandHint_op", + "commandHint_plain", + "commandHint_react", + "commandHint_send", + "commandHint_unban", + "commandInvalid", + "commandMissing", + "compareEmojiMatch", + "compareNumbersMatch", + "configureChat", + "confirm", + "connect", + "contactHasBeenInvitedToTheGroup", + "containsDisplayName", + "containsUserName", + "contentHasBeenReported", + "copiedToClipboard", + "copy", + "copyToClipboard", + "couldNotDecryptMessage", + "countParticipants", + "create", + "createdTheChat", + "createGroup", + "createNewSpace", "createNewGroup", + "currentlyActive", + "darkTheme", + "dateAndTimeOfDay", + "dateWithoutYear", + "dateWithYear", + "deactivateAccountWarning", + "defaultPermissionLevel", + "delete", + "deleteAccount", + "deleteMessage", + "device", + "deviceId", + "devices", + "directChats", + "allRooms", + "displaynameHasBeenChanged", + "downloadFile", + "edit", + "editBlockedServers", + "chatPermissions", "editChatPermissions", + "editDisplayname", + "editRoomAliases", + "editRoomAvatar", + "emoteExists", + "emoteInvalid", + "emoteKeyboardNoRecents", + "emotePacks", + "emoteSettings", + "emoteShortcode", + "emoteWarnNeedToPick", + "emptyChat", + "enableEmotesGlobally", + "enableEncryption", + "enableEncryptionWarning", + "encrypted", + "encryption", + "encryptionNotEnabled", + "endedTheCall", "enterAGroupName", + "enterAnEmailAddress", "enterASpacepName", + "homeserver", + "enterYourHomeserver", + "errorObtainingLocation", + "everythingReady", + "extremeOffensive", + "fileName", + "fluffychat", + "fontSize", + "forward", + "fromJoining", + "fromTheInvitation", + "goToTheNewRoom", + "group", + "chatDescription", + "chatDescriptionHasBeenChanged", + "groupIsPublic", "groupDescription", "groupDescriptionHasBeenChanged", + "groups", + "groupWith", + "guestsAreForbidden", + "guestsCanJoin", + "hasWithdrawnTheInvitationFor", + "help", + "hideRedactedEvents", + "hideUnknownEvents", + "howOffensiveIsThisContent", + "id", + "identity", + "ignore", + "ignoredUsers", "ignoreListDescription", "ignoreUsername", "block", "blockedUsers", "blockListDescription", "blockUsername", + "iHaveClickedOnLink", + "incorrectPassphraseOrKey", + "inoffensive", + "inviteContact", + "inviteContactToGroupQuestion", + "inviteContactToGroup", + "noChatDescriptionYet", + "tryAgain", + "invalidServerName", + "invited", + "redactMessageDescription", + "optionalRedactReason", + "invitedUser", + "invitedUsersOnly", + "inviteForMe", + "inviteText", + "isTyping", + "joinedTheChat", + "joinRoom", + "kicked", + "kickedAndBanned", + "kickFromChat", + "lastActiveAgo", + "leave", + "leftTheChat", + "license", + "lightTheme", + "loadCountMoreParticipants", + "dehydrate", + "dehydrateWarning", + "dehydrateTor", + "dehydrateTorLong", + "hydrateTor", + "hydrateTorLong", + "hydrate", + "loadingPleaseWait", + "loadMore", + "locationDisabledNotice", + "locationPermissionDeniedNotice", + "login", + "logInTo", + "logout", + "memberChanges", + "mention", + "messages", + "messagesStyle", + "moderator", + "muteChat", + "needPantalaimonWarning", + "newChat", + "newMessageInFluffyChat", + "newVerificationRequest", + "next", + "no", + "noConnectionToTheServer", + "noEmotesFound", + "noEncryptionForPublicRooms", + "noGoogleServicesWarning", + "noMatrixServer", + "shareInviteLink", + "scanQrCode", + "none", + "noPasswordRecoveryDescription", + "noPermission", + "noRoomsFound", + "notifications", + "notificationsEnabledForThisAccount", + "numUsersTyping", + "obtainingLocation", + "offensive", + "offline", + "ok", + "online", + "onlineKeyBackupEnabled", + "oopsPushError", + "oopsSomethingWentWrong", + "openAppToReadMessages", + "openCamera", + "openVideoCamera", + "oneClientLoggedOut", + "addAccount", + "editBundlesForAccount", + "addToBundle", + "removeFromBundle", + "bundleName", + "enableMultiAccounts", + "openInMaps", + "link", + "serverRequiresEmail", "optionalGroupName", + "or", + "participant", + "passphraseOrKey", + "password", + "passwordForgotten", + "passwordHasBeenChanged", + "passwordRecovery", + "people", + "pickImage", + "pin", + "play", + "pleaseChoose", + "pleaseChooseAPasscode", + "pleaseClickOnLink", + "pleaseEnter4Digits", + "pleaseEnterRecoveryKey", + "pleaseEnterYourPassword", + "pleaseEnterYourPin", + "pleaseEnterYourUsername", + "pleaseFollowInstructionsOnWeb", + "privacy", + "publicRooms", + "pushRules", + "reason", + "recording", + "redactedBy", + "directChat", + "redactedByBecause", + "redactedAnEvent", + "redactMessage", + "register", + "reject", + "rejectedTheInvitation", + "rejoin", + "removeAllOtherDevices", + "removedBy", + "removeDevice", + "unbanFromChat", + "removeYourAvatar", + "replaceRoomWithNewerVersion", + "reply", + "reportMessage", + "requestPermission", + "roomHasBeenUpgraded", + "roomVersion", + "saveFile", + "search", + "security", + "recoveryKey", + "recoveryKeyLost", + "seenByUser", + "send", + "sendAMessage", + "sendAsText", + "sendAudio", + "sendFile", + "sendImage", + "sendMessages", + "sendOriginal", + "sendSticker", + "sendVideo", + "sentAFile", + "sentAnAudio", + "sentAPicture", + "sentASticker", + "sentAVideo", + "sentCallInformations", + "separateChatTypes", + "setAsCanonicalAlias", + "setCustomEmotes", + "setChatDescription", + "setInvitationLink", + "setPermissionsLevel", + "setStatus", + "settings", + "share", + "sharedTheLocation", + "shareLocation", + "showPassword", + "presenceStyle", + "presencesToggle", + "singlesignon", + "skip", + "sourceCode", + "spaceIsPublic", + "spaceName", + "startedACall", + "startFirstChat", + "status", + "statusExampleMessage", + "submit", + "synchronizingPleaseWait", + "systemTheme", + "theyDontMatch", + "theyMatch", + "title", + "toggleFavorite", + "toggleMuted", + "toggleUnread", + "tooManyRequestsWarning", + "transferFromAnotherDevice", + "tryToSendAgain", + "unavailable", + "unbannedUser", + "unblockDevice", + "unknownDevice", + "unknownEncryptionAlgorithm", + "unknownEvent", + "unmuteChat", + "unpin", + "unreadChats", + "userAndOthersAreTyping", + "userAndUserAreTyping", + "userIsTyping", + "userLeftTheChat", + "username", + "userSentUnknownEvent", + "unverified", + "verified", + "verify", + "verifyStart", + "verifySuccess", + "verifyTitle", + "videoCall", + "visibilityOfTheChatHistory", + "visibleForAllParticipants", + "visibleForEveryone", + "voiceMessage", + "waitingPartnerAcceptRequest", + "waitingPartnerEmoji", + "waitingPartnerNumbers", + "wallpaper", + "warning", + "weSentYouAnEmail", + "whoCanPerformWhichAction", + "whoIsAllowedToJoinThisGroup", + "whyDoYouWantToReportThis", + "wipeChatBackup", + "withTheseAddressesRecoveryDescription", + "writeAMessage", + "yes", + "you", + "youAreNoLongerParticipatingInThisChat", + "youHaveBeenBannedFromThisChat", + "yourPublicKey", + "messageInfo", + "time", + "messageType", + "sender", + "openGallery", + "removeFromSpace", + "addToSpaceDescription", + "start", + "pleaseEnterRecoveryKeyDescription", + "publish", + "videoWithSize", + "openChat", + "markAsRead", + "reportUser", + "dismiss", + "reactedWith", + "pinMessage", + "confirmEventUnpin", + "emojis", + "placeCall", + "voiceCall", + "unsupportedAndroidVersion", + "unsupportedAndroidVersionLong", + "videoCallsBetaWarning", + "experimentalVideoCalls", + "emailOrUsername", + "indexedDbErrorTitle", + "indexedDbErrorLong", + "switchToAccount", + "nextAccount", + "previousAccount", + "addWidget", + "widgetVideo", + "widgetEtherpad", + "widgetJitsi", + "widgetCustom", + "widgetName", + "widgetUrlError", + "widgetNameError", + "errorAddingWidget", + "youRejectedTheInvitation", + "youJoinedTheChat", + "youAcceptedTheInvitation", + "youBannedUser", + "youHaveWithdrawnTheInvitationFor", + "youInvitedToBy", + "youInvitedBy", + "youInvitedUser", + "youKicked", + "youKickedAndBanned", + "youUnbannedUser", + "hasKnocked", + "users", + "unlockOldMessages", + "storeInSecureStorageDescription", + "saveKeyManuallyDescription", + "storeInAndroidKeystore", + "storeInAppleKeyChain", + "storeSecurlyOnThisDevice", + "countFiles", + "user", + "custom", + "foregroundServiceRunning", + "screenSharingTitle", + "screenSharingDetail", + "callingPermissions", + "callingAccount", + "callingAccountDetails", + "appearOnTop", + "appearOnTopDetails", + "otherCallingPermissions", + "whyIsThisMessageEncrypted", + "noKeyForThisMessage", + "newGroup", + "newSpace", + "enterSpace", + "enterRoom", + "allSpaces", + "numChats", + "hideUnimportantStateEvents", + "hidePresences", + "doNotShowAgain", + "wasDirectChatDisplayName", + "newSpaceDescription", + "encryptThisChat", + "disableEncryptionWarning", + "sorryThatsNotPossible", + "deviceKeys", + "reopenChat", + "noBackupWarning", + "noOtherDevicesFound", + "fileIsTooBigForServer", + "fileHasBeenSavedAt", + "jumpToLastReadMessage", + "readUpToHere", + "jump", + "openLinkInBrowser", + "reportErrorDescription", + "report", + "signInWithPassword", + "pleaseTryAgainLaterOrChooseDifferentServer", + "signInWith", + "profileNotFound", + "setTheme", + "setColorTheme", + "invite", "requests", + "inviteGroupChat", + "invitePrivateChat", + "invalidInput", + "wrongPinEntered", + "pleaseEnterANumber", + "archiveRoomDescription", + "roomUpgradeDescription", "allCorrect", "newWayAllGood", "othersAreBetter", @@ -1601,6 +2114,13 @@ "reportMessageTitle", "reportMessageBody", "noTeachersFound", + "pushNotificationsNotAvailable", + "learnMore", + "banUserDescription", + "unbanUserDescription", + "kickUserDescription", + "makeAdminDescription", + "removeDevicesDescription", "yourGlobalUserIdIs", "noUsersFoundWithQuery", "searchChatsRooms", @@ -1664,6 +2184,15 @@ "conversationLanguageLevel", "showDefinition", "acceptedKeyVerification", + "sendReadReceipts", + "sendTypingNotificationsDescription", + "sendReadReceiptsDescription", + "formattedMessages", + "formattedMessagesDescription", + "verifyOtherUser", + "verifyOtherUserDescription", + "verifyOtherDevice", + "verifyOtherDeviceDescription", "canceledKeyVerification", "completedKeyVerification", "isReadyForKeyVerification", @@ -1687,10 +2216,17 @@ "joinToView", "refresh", "autoPlayTitle", - "autoPlayDesc" + "autoPlayDesc", + "transparent", + "incomingMessages", + "stickers", + "discover", + "commandHint_ignore", + "commandHint_unignore", + "unreadChatsInApp" ], - "bo": [ + "bn": [ "accountInformation", "addGroupDescription", "addNewFriend", @@ -1709,6 +2245,10 @@ "blockListDescription", "blockUsername", "optionalGroupName", + "presenceStyle", + "presencesToggle", + "youInvitedToBy", + "hidePresences", "requests", "allCorrect", "newWayAllGood", @@ -2517,6 +3057,15 @@ "conversationLanguageLevel", "showDefinition", "acceptedKeyVerification", + "sendReadReceipts", + "sendTypingNotificationsDescription", + "sendReadReceiptsDescription", + "formattedMessages", + "formattedMessagesDescription", + "verifyOtherUser", + "verifyOtherUserDescription", + "verifyOtherDevice", + "verifyOtherDeviceDescription", "canceledKeyVerification", "completedKeyVerification", "isReadyForKeyVerification", @@ -2540,10 +3089,17 @@ "joinToView", "refresh", "autoPlayTitle", - "autoPlayDesc" + "autoPlayDesc", + "transparent", + "incomingMessages", + "stickers", + "discover", + "commandHint_ignore", + "commandHint_unignore", + "unreadChatsInApp" ], - "ca": [ + "bo": [ "accountInformation", "addGroupDescription", "addNewFriend", @@ -2562,6 +3118,10 @@ "blockListDescription", "blockUsername", "optionalGroupName", + "presenceStyle", + "presencesToggle", + "youInvitedToBy", + "hidePresences", "requests", "allCorrect", "newWayAllGood", @@ -3370,6 +3930,15 @@ "conversationLanguageLevel", "showDefinition", "acceptedKeyVerification", + "sendReadReceipts", + "sendTypingNotificationsDescription", + "sendReadReceiptsDescription", + "formattedMessages", + "formattedMessagesDescription", + "verifyOtherUser", + "verifyOtherUserDescription", + "verifyOtherDevice", + "verifyOtherDeviceDescription", "canceledKeyVerification", "completedKeyVerification", "isReadyForKeyVerification", @@ -3393,10 +3962,17 @@ "joinToView", "refresh", "autoPlayTitle", - "autoPlayDesc" + "autoPlayDesc", + "transparent", + "incomingMessages", + "stickers", + "discover", + "commandHint_ignore", + "commandHint_unignore", + "unreadChatsInApp" ], - "cs": [ + "ca": [ "accountInformation", "addGroupDescription", "addNewFriend", @@ -3415,6 +3991,10 @@ "blockListDescription", "blockUsername", "optionalGroupName", + "presenceStyle", + "presencesToggle", + "youInvitedToBy", + "hidePresences", "requests", "allCorrect", "newWayAllGood", @@ -4223,6 +4803,15 @@ "conversationLanguageLevel", "showDefinition", "acceptedKeyVerification", + "sendReadReceipts", + "sendTypingNotificationsDescription", + "sendReadReceiptsDescription", + "formattedMessages", + "formattedMessagesDescription", + "verifyOtherUser", + "verifyOtherUserDescription", + "verifyOtherDevice", + "verifyOtherDeviceDescription", "canceledKeyVerification", "completedKeyVerification", "isReadyForKeyVerification", @@ -4246,10 +4835,17 @@ "joinToView", "refresh", "autoPlayTitle", - "autoPlayDesc" + "autoPlayDesc", + "transparent", + "incomingMessages", + "stickers", + "discover", + "commandHint_ignore", + "commandHint_unignore", + "unreadChatsInApp" ], - "de": [ + "cs": [ "accountInformation", "addGroupDescription", "addNewFriend", @@ -4263,7 +4859,15 @@ "groupDescriptionHasBeenChanged", "ignoreListDescription", "ignoreUsername", + "block", + "blockedUsers", + "blockListDescription", + "blockUsername", "optionalGroupName", + "presenceStyle", + "presencesToggle", + "youInvitedToBy", + "hidePresences", "requests", "allCorrect", "newWayAllGood", @@ -4959,6 +5563,7 @@ "addToClassOrExchange", "addToClassOrExchangeDesc", "invitedToClassOrExchange", + "decline", "declinedInvitation", "acceptedInvitation", "youreInvited", @@ -5008,6 +5613,12 @@ "reportMessageTitle", "reportMessageBody", "noTeachersFound", + "yourGlobalUserIdIs", + "noUsersFoundWithQuery", + "searchChatsRooms", + "groupName", + "createGroupAndInviteUsers", + "groupCanBeFoundViaSearch", "inNoSpaces", "createClass", "createExchange", @@ -5019,6 +5630,26 @@ "clickToManageSubscription", "emptyInviteWarning", "errorGettingAudio", + "nothingFound", + "wrongRecoveryKey", + "startConversation", + "commandHint_sendraw", + "databaseMigrationTitle", + "databaseMigrationBody", + "leaveEmptyToClearStatus", + "select", + "searchForUsers", + "pleaseEnterYourCurrentPassword", + "newPassword", + "pleaseChooseAStrongPassword", + "passwordsDoNotMatch", + "passwordIsWrong", + "publicLink", + "joinSpace", + "publicSpaces", + "addChatOrSubSpace", + "subspace", + "thisDevice", "initAppError", "databaseBuildErrorBody", "sessionLostBody", @@ -5045,6 +5676,15 @@ "conversationLanguageLevel", "showDefinition", "acceptedKeyVerification", + "sendReadReceipts", + "sendTypingNotificationsDescription", + "sendReadReceiptsDescription", + "formattedMessages", + "formattedMessagesDescription", + "verifyOtherUser", + "verifyOtherUserDescription", + "verifyOtherDevice", + "verifyOtherDeviceDescription", "canceledKeyVerification", "completedKeyVerification", "isReadyForKeyVerification", @@ -5068,10 +5708,17 @@ "joinToView", "refresh", "autoPlayTitle", - "autoPlayDesc" + "autoPlayDesc", + "transparent", + "incomingMessages", + "stickers", + "discover", + "commandHint_ignore", + "commandHint_unignore", + "unreadChatsInApp" ], - "el": [ + "de": [ "accountInformation", "addGroupDescription", "addNewFriend", @@ -5085,11 +5732,10 @@ "groupDescriptionHasBeenChanged", "ignoreListDescription", "ignoreUsername", - "block", - "blockedUsers", - "blockListDescription", - "blockUsername", "optionalGroupName", + "presenceStyle", + "presencesToggle", + "hidePresences", "requests", "allCorrect", "newWayAllGood", @@ -5785,7 +6431,6 @@ "addToClassOrExchange", "addToClassOrExchangeDesc", "invitedToClassOrExchange", - "decline", "declinedInvitation", "acceptedInvitation", "youreInvited", @@ -5835,12 +6480,6 @@ "reportMessageTitle", "reportMessageBody", "noTeachersFound", - "yourGlobalUserIdIs", - "noUsersFoundWithQuery", - "searchChatsRooms", - "groupName", - "createGroupAndInviteUsers", - "groupCanBeFoundViaSearch", "inNoSpaces", "createClass", "createExchange", @@ -5852,31 +6491,6 @@ "clickToManageSubscription", "emptyInviteWarning", "errorGettingAudio", - "nothingFound", - "wrongRecoveryKey", - "startConversation", - "commandHint_sendraw", - "databaseMigrationTitle", - "databaseMigrationBody", - "leaveEmptyToClearStatus", - "select", - "searchForUsers", - "pleaseEnterYourCurrentPassword", - "newPassword", - "pleaseChooseAStrongPassword", - "passwordsDoNotMatch", - "passwordIsWrong", - "publicLink", - "joinSpace", - "publicSpaces", - "addChatOrSubSpace", - "subspace", - "thisDevice", - "initAppError", - "databaseBuildErrorBody", - "sessionLostBody", - "restoreSessionBody", - "forwardMessageTo", "signUp", "pleaseChooseAtLeastChars", "noEmailWarning", @@ -5897,12 +6511,6 @@ "enableModerationDesc", "conversationLanguageLevel", "showDefinition", - "acceptedKeyVerification", - "canceledKeyVerification", - "completedKeyVerification", - "isReadyForKeyVerification", - "requestedKeyVerification", - "startedKeyVerification", "subscriptionPopupTitle", "subscriptionPopupDesc", "seeOptions", @@ -5921,10 +6529,16 @@ "joinToView", "refresh", "autoPlayTitle", - "autoPlayDesc" + "autoPlayDesc", + "incomingMessages", + "stickers", + "discover", + "commandHint_ignore", + "commandHint_unignore", + "unreadChatsInApp" ], - "eo": [ + "el": [ "accountInformation", "addGroupDescription", "addNewFriend", @@ -5943,6 +6557,10 @@ "blockListDescription", "blockUsername", "optionalGroupName", + "presenceStyle", + "presencesToggle", + "youInvitedToBy", + "hidePresences", "requests", "allCorrect", "newWayAllGood", @@ -6751,6 +7369,15 @@ "conversationLanguageLevel", "showDefinition", "acceptedKeyVerification", + "sendReadReceipts", + "sendTypingNotificationsDescription", + "sendReadReceiptsDescription", + "formattedMessages", + "formattedMessagesDescription", + "verifyOtherUser", + "verifyOtherUserDescription", + "verifyOtherDevice", + "verifyOtherDeviceDescription", "canceledKeyVerification", "completedKeyVerification", "isReadyForKeyVerification", @@ -6774,10 +7401,17 @@ "joinToView", "refresh", "autoPlayTitle", - "autoPlayDesc" + "autoPlayDesc", + "transparent", + "incomingMessages", + "stickers", + "discover", + "commandHint_ignore", + "commandHint_unignore", + "unreadChatsInApp" ], - "et": [ + "eo": [ "accountInformation", "addGroupDescription", "addNewFriend", @@ -6791,7 +7425,15 @@ "groupDescriptionHasBeenChanged", "ignoreListDescription", "ignoreUsername", + "block", + "blockedUsers", + "blockListDescription", + "blockUsername", "optionalGroupName", + "presenceStyle", + "presencesToggle", + "youInvitedToBy", + "hidePresences", "requests", "allCorrect", "newWayAllGood", @@ -7537,6 +8179,12 @@ "reportMessageTitle", "reportMessageBody", "noTeachersFound", + "yourGlobalUserIdIs", + "noUsersFoundWithQuery", + "searchChatsRooms", + "groupName", + "createGroupAndInviteUsers", + "groupCanBeFoundViaSearch", "inNoSpaces", "createClass", "createExchange", @@ -7549,6 +8197,11 @@ "emptyInviteWarning", "errorGettingAudio", "nothingFound", + "wrongRecoveryKey", + "startConversation", + "commandHint_sendraw", + "databaseMigrationTitle", + "databaseMigrationBody", "leaveEmptyToClearStatus", "select", "searchForUsers", @@ -7589,6 +8242,15 @@ "conversationLanguageLevel", "showDefinition", "acceptedKeyVerification", + "sendReadReceipts", + "sendTypingNotificationsDescription", + "sendReadReceiptsDescription", + "formattedMessages", + "formattedMessagesDescription", + "verifyOtherUser", + "verifyOtherUserDescription", + "verifyOtherDevice", + "verifyOtherDeviceDescription", "canceledKeyVerification", "completedKeyVerification", "isReadyForKeyVerification", @@ -7612,10 +8274,39 @@ "joinToView", "refresh", "autoPlayTitle", - "autoPlayDesc" + "autoPlayDesc", + "transparent", + "incomingMessages", + "stickers", + "discover", + "commandHint_ignore", + "commandHint_unignore", + "unreadChatsInApp" ], - "eu": [ + "es": [ + "presenceStyle", + "presencesToggle", + "youInvitedToBy", + "hidePresences", + "sendReadReceipts", + "sendTypingNotificationsDescription", + "sendReadReceiptsDescription", + "formattedMessages", + "formattedMessagesDescription", + "verifyOtherUser", + "verifyOtherUserDescription", + "verifyOtherDevice", + "verifyOtherDeviceDescription", + "transparent", + "incomingMessages", + "stickers", + "commandHint_ignore", + "commandHint_unignore", + "unreadChatsInApp" + ], + + "et": [ "accountInformation", "addGroupDescription", "addNewFriend", @@ -8385,11 +9076,6 @@ "clickToManageSubscription", "emptyInviteWarning", "errorGettingAudio", - "initAppError", - "databaseBuildErrorBody", - "sessionLostBody", - "restoreSessionBody", - "forwardMessageTo", "signUp", "pleaseChooseAtLeastChars", "noEmailWarning", @@ -8410,12 +9096,6 @@ "enableModerationDesc", "conversationLanguageLevel", "showDefinition", - "acceptedKeyVerification", - "canceledKeyVerification", - "completedKeyVerification", - "isReadyForKeyVerification", - "requestedKeyVerification", - "startedKeyVerification", "subscriptionPopupTitle", "subscriptionPopupDesc", "seeOptions", @@ -8434,10 +9114,15 @@ "joinToView", "refresh", "autoPlayTitle", - "autoPlayDesc" + "autoPlayDesc", + "stickers", + "discover", + "commandHint_ignore", + "commandHint_unignore", + "unreadChatsInApp" ], - "fa": [ + "eu": [ "accountInformation", "addGroupDescription", "addNewFriend", @@ -8451,10 +9136,6 @@ "groupDescriptionHasBeenChanged", "ignoreListDescription", "ignoreUsername", - "block", - "blockedUsers", - "blockListDescription", - "blockUsername", "optionalGroupName", "requests", "allCorrect", @@ -9151,7 +9832,6 @@ "addToClassOrExchange", "addToClassOrExchangeDesc", "invitedToClassOrExchange", - "decline", "declinedInvitation", "acceptedInvitation", "youreInvited", @@ -9201,12 +9881,6 @@ "reportMessageTitle", "reportMessageBody", "noTeachersFound", - "yourGlobalUserIdIs", - "noUsersFoundWithQuery", - "searchChatsRooms", - "groupName", - "createGroupAndInviteUsers", - "groupCanBeFoundViaSearch", "inNoSpaces", "createClass", "createExchange", @@ -9218,31 +9892,6 @@ "clickToManageSubscription", "emptyInviteWarning", "errorGettingAudio", - "nothingFound", - "wrongRecoveryKey", - "startConversation", - "commandHint_sendraw", - "databaseMigrationTitle", - "databaseMigrationBody", - "leaveEmptyToClearStatus", - "select", - "searchForUsers", - "pleaseEnterYourCurrentPassword", - "newPassword", - "pleaseChooseAStrongPassword", - "passwordsDoNotMatch", - "passwordIsWrong", - "publicLink", - "joinSpace", - "publicSpaces", - "addChatOrSubSpace", - "subspace", - "thisDevice", - "initAppError", - "databaseBuildErrorBody", - "sessionLostBody", - "restoreSessionBody", - "forwardMessageTo", "signUp", "pleaseChooseAtLeastChars", "noEmailWarning", @@ -9263,12 +9912,6 @@ "enableModerationDesc", "conversationLanguageLevel", "showDefinition", - "acceptedKeyVerification", - "canceledKeyVerification", - "completedKeyVerification", - "isReadyForKeyVerification", - "requestedKeyVerification", - "startedKeyVerification", "subscriptionPopupTitle", "subscriptionPopupDesc", "seeOptions", @@ -9287,10 +9930,15 @@ "joinToView", "refresh", "autoPlayTitle", - "autoPlayDesc" + "autoPlayDesc", + "stickers", + "discover", + "commandHint_ignore", + "commandHint_unignore", + "unreadChatsInApp" ], - "fi": [ + "fa": [ "accountInformation", "addGroupDescription", "addNewFriend", @@ -9309,6 +9957,10 @@ "blockListDescription", "blockUsername", "optionalGroupName", + "presenceStyle", + "presencesToggle", + "youInvitedToBy", + "hidePresences", "requests", "allCorrect", "newWayAllGood", @@ -10117,6 +10769,15 @@ "conversationLanguageLevel", "showDefinition", "acceptedKeyVerification", + "sendReadReceipts", + "sendTypingNotificationsDescription", + "sendReadReceiptsDescription", + "formattedMessages", + "formattedMessagesDescription", + "verifyOtherUser", + "verifyOtherUserDescription", + "verifyOtherDevice", + "verifyOtherDeviceDescription", "canceledKeyVerification", "completedKeyVerification", "isReadyForKeyVerification", @@ -10140,10 +10801,17 @@ "joinToView", "refresh", "autoPlayTitle", - "autoPlayDesc" + "autoPlayDesc", + "transparent", + "incomingMessages", + "stickers", + "discover", + "commandHint_ignore", + "commandHint_unignore", + "unreadChatsInApp" ], - "fr": [ + "fi": [ "accountInformation", "addGroupDescription", "addNewFriend", @@ -10162,6 +10830,10 @@ "blockListDescription", "blockUsername", "optionalGroupName", + "presenceStyle", + "presencesToggle", + "youInvitedToBy", + "hidePresences", "requests", "allCorrect", "newWayAllGood", @@ -10970,6 +11642,15 @@ "conversationLanguageLevel", "showDefinition", "acceptedKeyVerification", + "sendReadReceipts", + "sendTypingNotificationsDescription", + "sendReadReceiptsDescription", + "formattedMessages", + "formattedMessagesDescription", + "verifyOtherUser", + "verifyOtherUserDescription", + "verifyOtherDevice", + "verifyOtherDeviceDescription", "canceledKeyVerification", "completedKeyVerification", "isReadyForKeyVerification", @@ -10993,10 +11674,17 @@ "joinToView", "refresh", "autoPlayTitle", - "autoPlayDesc" + "autoPlayDesc", + "transparent", + "incomingMessages", + "stickers", + "discover", + "commandHint_ignore", + "commandHint_unignore", + "unreadChatsInApp" ], - "ga": [ + "fr": [ "accountInformation", "addGroupDescription", "addNewFriend", @@ -11015,6 +11703,10 @@ "blockListDescription", "blockUsername", "optionalGroupName", + "presenceStyle", + "presencesToggle", + "youInvitedToBy", + "hidePresences", "requests", "allCorrect", "newWayAllGood", @@ -11823,6 +12515,15 @@ "conversationLanguageLevel", "showDefinition", "acceptedKeyVerification", + "sendReadReceipts", + "sendTypingNotificationsDescription", + "sendReadReceiptsDescription", + "formattedMessages", + "formattedMessagesDescription", + "verifyOtherUser", + "verifyOtherUserDescription", + "verifyOtherDevice", + "verifyOtherDeviceDescription", "canceledKeyVerification", "completedKeyVerification", "isReadyForKeyVerification", @@ -11846,10 +12547,17 @@ "joinToView", "refresh", "autoPlayTitle", - "autoPlayDesc" + "autoPlayDesc", + "transparent", + "incomingMessages", + "stickers", + "discover", + "commandHint_ignore", + "commandHint_unignore", + "unreadChatsInApp" ], - "gl": [ + "ga": [ "accountInformation", "addGroupDescription", "addNewFriend", @@ -11863,7 +12571,15 @@ "groupDescriptionHasBeenChanged", "ignoreListDescription", "ignoreUsername", + "block", + "blockedUsers", + "blockListDescription", + "blockUsername", "optionalGroupName", + "presenceStyle", + "presencesToggle", + "youInvitedToBy", + "hidePresences", "requests", "allCorrect", "newWayAllGood", @@ -12559,6 +13275,7 @@ "addToClassOrExchange", "addToClassOrExchangeDesc", "invitedToClassOrExchange", + "decline", "declinedInvitation", "acceptedInvitation", "youreInvited", @@ -12608,6 +13325,12 @@ "reportMessageTitle", "reportMessageBody", "noTeachersFound", + "yourGlobalUserIdIs", + "noUsersFoundWithQuery", + "searchChatsRooms", + "groupName", + "createGroupAndInviteUsers", + "groupCanBeFoundViaSearch", "inNoSpaces", "createClass", "createExchange", @@ -12619,6 +13342,26 @@ "clickToManageSubscription", "emptyInviteWarning", "errorGettingAudio", + "nothingFound", + "wrongRecoveryKey", + "startConversation", + "commandHint_sendraw", + "databaseMigrationTitle", + "databaseMigrationBody", + "leaveEmptyToClearStatus", + "select", + "searchForUsers", + "pleaseEnterYourCurrentPassword", + "newPassword", + "pleaseChooseAStrongPassword", + "passwordsDoNotMatch", + "passwordIsWrong", + "publicLink", + "joinSpace", + "publicSpaces", + "addChatOrSubSpace", + "subspace", + "thisDevice", "initAppError", "databaseBuildErrorBody", "sessionLostBody", @@ -12645,6 +13388,15 @@ "conversationLanguageLevel", "showDefinition", "acceptedKeyVerification", + "sendReadReceipts", + "sendTypingNotificationsDescription", + "sendReadReceiptsDescription", + "formattedMessages", + "formattedMessagesDescription", + "verifyOtherUser", + "verifyOtherUserDescription", + "verifyOtherDevice", + "verifyOtherDeviceDescription", "canceledKeyVerification", "completedKeyVerification", "isReadyForKeyVerification", @@ -12668,10 +13420,17 @@ "joinToView", "refresh", "autoPlayTitle", - "autoPlayDesc" + "autoPlayDesc", + "transparent", + "incomingMessages", + "stickers", + "discover", + "commandHint_ignore", + "commandHint_unignore", + "unreadChatsInApp" ], - "he": [ + "gl": [ "accountInformation", "addGroupDescription", "addNewFriend", @@ -12685,10 +13444,6 @@ "groupDescriptionHasBeenChanged", "ignoreListDescription", "ignoreUsername", - "block", - "blockedUsers", - "blockListDescription", - "blockUsername", "optionalGroupName", "requests", "allCorrect", @@ -13385,7 +14140,6 @@ "addToClassOrExchange", "addToClassOrExchangeDesc", "invitedToClassOrExchange", - "decline", "declinedInvitation", "acceptedInvitation", "youreInvited", @@ -13435,12 +14189,6 @@ "reportMessageTitle", "reportMessageBody", "noTeachersFound", - "yourGlobalUserIdIs", - "noUsersFoundWithQuery", - "searchChatsRooms", - "groupName", - "createGroupAndInviteUsers", - "groupCanBeFoundViaSearch", "inNoSpaces", "createClass", "createExchange", @@ -13452,31 +14200,6 @@ "clickToManageSubscription", "emptyInviteWarning", "errorGettingAudio", - "nothingFound", - "wrongRecoveryKey", - "startConversation", - "commandHint_sendraw", - "databaseMigrationTitle", - "databaseMigrationBody", - "leaveEmptyToClearStatus", - "select", - "searchForUsers", - "pleaseEnterYourCurrentPassword", - "newPassword", - "pleaseChooseAStrongPassword", - "passwordsDoNotMatch", - "passwordIsWrong", - "publicLink", - "joinSpace", - "publicSpaces", - "addChatOrSubSpace", - "subspace", - "thisDevice", - "initAppError", - "databaseBuildErrorBody", - "sessionLostBody", - "restoreSessionBody", - "forwardMessageTo", "signUp", "pleaseChooseAtLeastChars", "noEmailWarning", @@ -13497,12 +14220,6 @@ "enableModerationDesc", "conversationLanguageLevel", "showDefinition", - "acceptedKeyVerification", - "canceledKeyVerification", - "completedKeyVerification", - "isReadyForKeyVerification", - "requestedKeyVerification", - "startedKeyVerification", "subscriptionPopupTitle", "subscriptionPopupDesc", "seeOptions", @@ -13521,10 +14238,15 @@ "joinToView", "refresh", "autoPlayTitle", - "autoPlayDesc" + "autoPlayDesc", + "stickers", + "discover", + "commandHint_ignore", + "commandHint_unignore", + "unreadChatsInApp" ], - "hi": [ + "he": [ "accountInformation", "addGroupDescription", "addNewFriend", @@ -13543,6 +14265,10 @@ "blockListDescription", "blockUsername", "optionalGroupName", + "presenceStyle", + "presencesToggle", + "youInvitedToBy", + "hidePresences", "requests", "allCorrect", "newWayAllGood", @@ -14351,6 +15077,15 @@ "conversationLanguageLevel", "showDefinition", "acceptedKeyVerification", + "sendReadReceipts", + "sendTypingNotificationsDescription", + "sendReadReceiptsDescription", + "formattedMessages", + "formattedMessagesDescription", + "verifyOtherUser", + "verifyOtherUserDescription", + "verifyOtherDevice", + "verifyOtherDeviceDescription", "canceledKeyVerification", "completedKeyVerification", "isReadyForKeyVerification", @@ -14374,10 +15109,17 @@ "joinToView", "refresh", "autoPlayTitle", - "autoPlayDesc" + "autoPlayDesc", + "transparent", + "incomingMessages", + "stickers", + "discover", + "commandHint_ignore", + "commandHint_unignore", + "unreadChatsInApp" ], - "hr": [ + "hi": [ "accountInformation", "addGroupDescription", "addNewFriend", @@ -14391,8 +15133,15 @@ "groupDescriptionHasBeenChanged", "ignoreListDescription", "ignoreUsername", + "block", + "blockedUsers", "blockListDescription", + "blockUsername", "optionalGroupName", + "presenceStyle", + "presencesToggle", + "youInvitedToBy", + "hidePresences", "requests", "allCorrect", "newWayAllGood", @@ -15138,7 +15887,12 @@ "reportMessageTitle", "reportMessageBody", "noTeachersFound", + "yourGlobalUserIdIs", "noUsersFoundWithQuery", + "searchChatsRooms", + "groupName", + "createGroupAndInviteUsers", + "groupCanBeFoundViaSearch", "inNoSpaces", "createClass", "createExchange", @@ -15151,6 +15905,11 @@ "emptyInviteWarning", "errorGettingAudio", "nothingFound", + "wrongRecoveryKey", + "startConversation", + "commandHint_sendraw", + "databaseMigrationTitle", + "databaseMigrationBody", "leaveEmptyToClearStatus", "select", "searchForUsers", @@ -15191,6 +15950,15 @@ "conversationLanguageLevel", "showDefinition", "acceptedKeyVerification", + "sendReadReceipts", + "sendTypingNotificationsDescription", + "sendReadReceiptsDescription", + "formattedMessages", + "formattedMessagesDescription", + "verifyOtherUser", + "verifyOtherUserDescription", + "verifyOtherDevice", + "verifyOtherDeviceDescription", "canceledKeyVerification", "completedKeyVerification", "isReadyForKeyVerification", @@ -15214,10 +15982,17 @@ "joinToView", "refresh", "autoPlayTitle", - "autoPlayDesc" + "autoPlayDesc", + "transparent", + "incomingMessages", + "stickers", + "discover", + "commandHint_ignore", + "commandHint_unignore", + "unreadChatsInApp" ], - "hu": [ + "hr": [ "accountInformation", "addGroupDescription", "addNewFriend", @@ -15231,11 +16006,12 @@ "groupDescriptionHasBeenChanged", "ignoreListDescription", "ignoreUsername", - "block", - "blockedUsers", "blockListDescription", - "blockUsername", "optionalGroupName", + "presenceStyle", + "presencesToggle", + "youInvitedToBy", + "hidePresences", "requests", "allCorrect", "newWayAllGood", @@ -15981,12 +16757,7 @@ "reportMessageTitle", "reportMessageBody", "noTeachersFound", - "yourGlobalUserIdIs", "noUsersFoundWithQuery", - "searchChatsRooms", - "groupName", - "createGroupAndInviteUsers", - "groupCanBeFoundViaSearch", "inNoSpaces", "createClass", "createExchange", @@ -15999,11 +16770,6 @@ "emptyInviteWarning", "errorGettingAudio", "nothingFound", - "wrongRecoveryKey", - "startConversation", - "commandHint_sendraw", - "databaseMigrationTitle", - "databaseMigrationBody", "leaveEmptyToClearStatus", "select", "searchForUsers", @@ -16044,6 +16810,15 @@ "conversationLanguageLevel", "showDefinition", "acceptedKeyVerification", + "sendReadReceipts", + "sendTypingNotificationsDescription", + "sendReadReceiptsDescription", + "formattedMessages", + "formattedMessagesDescription", + "verifyOtherUser", + "verifyOtherUserDescription", + "verifyOtherDevice", + "verifyOtherDeviceDescription", "canceledKeyVerification", "completedKeyVerification", "isReadyForKeyVerification", @@ -16067,10 +16842,17 @@ "joinToView", "refresh", "autoPlayTitle", - "autoPlayDesc" + "autoPlayDesc", + "transparent", + "incomingMessages", + "stickers", + "discover", + "commandHint_ignore", + "commandHint_unignore", + "unreadChatsInApp" ], - "id": [ + "hu": [ "accountInformation", "addGroupDescription", "addNewFriend", @@ -16089,6 +16871,10 @@ "blockListDescription", "blockUsername", "optionalGroupName", + "presenceStyle", + "presencesToggle", + "youInvitedToBy", + "hidePresences", "requests", "allCorrect", "newWayAllGood", @@ -16897,6 +17683,15 @@ "conversationLanguageLevel", "showDefinition", "acceptedKeyVerification", + "sendReadReceipts", + "sendTypingNotificationsDescription", + "sendReadReceiptsDescription", + "formattedMessages", + "formattedMessagesDescription", + "verifyOtherUser", + "verifyOtherUserDescription", + "verifyOtherDevice", + "verifyOtherDeviceDescription", "canceledKeyVerification", "completedKeyVerification", "isReadyForKeyVerification", @@ -16920,29 +17715,557 @@ "joinToView", "refresh", "autoPlayTitle", - "autoPlayDesc" + "autoPlayDesc", + "transparent", + "incomingMessages", + "stickers", + "discover", + "commandHint_ignore", + "commandHint_unignore", + "unreadChatsInApp" ], - "ie": [ + "ia": [ "accountInformation", + "activatedEndToEndEncryption", + "confirmMatrixId", "addGroupDescription", "addNewFriend", + "addToSpace", + "admin", + "alias", + "all", + "allChats", "alreadyHaveAnAccount", + "commandHint_googly", + "commandHint_cuddle", + "commandHint_hug", + "googlyEyesContent", + "cuddleContent", + "hugContent", + "answeredTheCall", + "anyoneCanJoin", + "appLock", + "archive", + "areGuestsAllowedToJoin", + "areYouSure", + "areYouSureYouWantToLogout", + "askSSSSSign", + "askVerificationRequest", + "autoplayImages", + "badServerLoginTypesException", + "sendTypingNotifications", + "sendOnEnter", + "badServerVersionsException", + "banFromChat", + "banned", + "bannedUser", + "blockDevice", + "blocked", + "botMessages", + "cancel", + "cantOpenUri", + "changeDeviceName", + "changedTheChatAvatar", + "changedTheChatDescriptionTo", + "changedTheChatNameTo", + "changedTheChatPermissions", + "changedTheDisplaynameTo", + "changedTheGuestAccessRules", + "changedTheGuestAccessRulesTo", + "changedTheHistoryVisibility", + "changedTheHistoryVisibilityTo", + "changedTheJoinRules", + "changedTheJoinRulesTo", + "changedTheProfileAvatar", + "changedTheRoomAliases", + "changedTheRoomInvitationLink", + "changePassword", + "changeTheHomeserver", + "changeTheme", + "changeTheNameOfTheGroup", + "changeYourAvatar", + "channelCorruptedDecryptError", + "chat", + "yourChatBackupHasBeenSetUp", + "chatBackup", + "chatBackupDescription", + "chatDetails", + "chatHasBeenAddedToThisSpace", + "chats", "classes", + "chooseAStrongPassword", + "clearArchive", + "close", + "commandHint_markasdm", + "commandHint_markasgroup", + "commandHint_ban", + "commandHint_clearcache", + "commandHint_create", + "commandHint_discardsession", + "commandHint_dm", + "commandHint_html", + "commandHint_invite", + "commandHint_join", + "commandHint_kick", + "commandHint_leave", + "commandHint_me", + "commandHint_myroomavatar", + "commandHint_myroomnick", + "commandHint_op", + "commandHint_plain", + "commandHint_react", + "commandHint_send", + "commandHint_unban", + "commandInvalid", + "commandMissing", + "compareEmojiMatch", + "compareNumbersMatch", + "configureChat", + "confirm", + "connect", + "contactHasBeenInvitedToTheGroup", + "containsDisplayName", + "containsUserName", + "contentHasBeenReported", + "copiedToClipboard", + "copy", + "copyToClipboard", + "couldNotDecryptMessage", + "countParticipants", + "create", + "createdTheChat", + "createGroup", + "createNewSpace", "createNewGroup", + "currentlyActive", + "darkTheme", + "dateAndTimeOfDay", + "dateWithoutYear", + "dateWithYear", + "deactivateAccountWarning", + "defaultPermissionLevel", + "delete", + "deleteAccount", + "deleteMessage", + "device", + "deviceId", + "devices", + "directChats", + "allRooms", + "displaynameHasBeenChanged", + "downloadFile", + "edit", + "editBlockedServers", + "chatPermissions", "editChatPermissions", + "editDisplayname", + "editRoomAliases", + "editRoomAvatar", + "emoteExists", + "emoteInvalid", + "emoteKeyboardNoRecents", + "emotePacks", + "emoteSettings", + "emoteShortcode", + "emoteWarnNeedToPick", + "emptyChat", + "enableEmotesGlobally", + "enableEncryption", + "enableEncryptionWarning", + "encrypted", + "encryption", + "encryptionNotEnabled", + "endedTheCall", "enterAGroupName", + "enterAnEmailAddress", "enterASpacepName", + "homeserver", + "enterYourHomeserver", + "errorObtainingLocation", + "everythingReady", + "extremeOffensive", + "fileName", + "fluffychat", + "fontSize", + "forward", + "fromJoining", + "fromTheInvitation", + "goToTheNewRoom", + "group", + "chatDescription", + "chatDescriptionHasBeenChanged", + "groupIsPublic", "groupDescription", "groupDescriptionHasBeenChanged", + "groups", + "groupWith", + "guestsAreForbidden", + "guestsCanJoin", + "hasWithdrawnTheInvitationFor", + "help", + "hideRedactedEvents", + "hideUnknownEvents", + "howOffensiveIsThisContent", + "id", + "identity", + "ignore", + "ignoredUsers", "ignoreListDescription", "ignoreUsername", "block", "blockedUsers", "blockListDescription", "blockUsername", + "iHaveClickedOnLink", + "incorrectPassphraseOrKey", + "inoffensive", + "inviteContact", + "inviteContactToGroupQuestion", + "inviteContactToGroup", + "noChatDescriptionYet", + "tryAgain", + "invalidServerName", + "invited", + "redactMessageDescription", + "optionalRedactReason", + "invitedUser", + "invitedUsersOnly", + "inviteForMe", + "inviteText", + "isTyping", + "joinedTheChat", + "joinRoom", + "kicked", + "kickedAndBanned", + "kickFromChat", + "lastActiveAgo", + "leave", + "leftTheChat", + "license", + "lightTheme", + "loadCountMoreParticipants", + "dehydrate", + "dehydrateWarning", + "dehydrateTor", + "dehydrateTorLong", + "hydrateTor", + "hydrateTorLong", + "hydrate", + "loadingPleaseWait", + "loadMore", + "locationDisabledNotice", + "locationPermissionDeniedNotice", + "login", + "logInTo", + "logout", + "memberChanges", + "mention", + "messages", + "messagesStyle", + "moderator", + "muteChat", + "needPantalaimonWarning", + "newChat", + "newMessageInFluffyChat", + "newVerificationRequest", + "next", + "no", + "noConnectionToTheServer", + "noEmotesFound", + "noEncryptionForPublicRooms", + "noGoogleServicesWarning", + "noMatrixServer", + "shareInviteLink", + "scanQrCode", + "none", + "noPasswordRecoveryDescription", + "noPermission", + "noRoomsFound", + "notifications", + "notificationsEnabledForThisAccount", + "numUsersTyping", + "obtainingLocation", + "offensive", + "offline", + "ok", + "online", + "onlineKeyBackupEnabled", + "oopsPushError", + "oopsSomethingWentWrong", + "openAppToReadMessages", + "openCamera", + "openVideoCamera", + "oneClientLoggedOut", + "addAccount", + "editBundlesForAccount", + "addToBundle", + "removeFromBundle", + "bundleName", + "enableMultiAccounts", + "openInMaps", + "link", + "serverRequiresEmail", "optionalGroupName", + "or", + "participant", + "passphraseOrKey", + "password", + "passwordForgotten", + "passwordHasBeenChanged", + "passwordRecovery", + "people", + "pickImage", + "pin", + "play", + "pleaseChoose", + "pleaseChooseAPasscode", + "pleaseClickOnLink", + "pleaseEnter4Digits", + "pleaseEnterRecoveryKey", + "pleaseEnterYourPassword", + "pleaseEnterYourPin", + "pleaseEnterYourUsername", + "pleaseFollowInstructionsOnWeb", + "privacy", + "publicRooms", + "pushRules", + "reason", + "recording", + "redactedBy", + "directChat", + "redactedByBecause", + "redactedAnEvent", + "redactMessage", + "register", + "reject", + "rejectedTheInvitation", + "rejoin", + "removeAllOtherDevices", + "removedBy", + "removeDevice", + "unbanFromChat", + "removeYourAvatar", + "replaceRoomWithNewerVersion", + "reply", + "reportMessage", + "requestPermission", + "roomHasBeenUpgraded", + "roomVersion", + "saveFile", + "search", + "security", + "recoveryKey", + "recoveryKeyLost", + "seenByUser", + "send", + "sendAMessage", + "sendAsText", + "sendAudio", + "sendFile", + "sendImage", + "sendMessages", + "sendOriginal", + "sendSticker", + "sendVideo", + "sentAFile", + "sentAnAudio", + "sentAPicture", + "sentASticker", + "sentAVideo", + "sentCallInformations", + "separateChatTypes", + "setAsCanonicalAlias", + "setCustomEmotes", + "setChatDescription", + "setInvitationLink", + "setPermissionsLevel", + "setStatus", + "settings", + "share", + "sharedTheLocation", + "shareLocation", + "showPassword", + "presenceStyle", + "presencesToggle", + "singlesignon", + "skip", + "sourceCode", + "spaceIsPublic", + "spaceName", + "startedACall", + "startFirstChat", + "status", + "statusExampleMessage", + "submit", + "synchronizingPleaseWait", + "systemTheme", + "theyDontMatch", + "theyMatch", + "title", + "toggleFavorite", + "toggleMuted", + "toggleUnread", + "tooManyRequestsWarning", + "transferFromAnotherDevice", + "tryToSendAgain", + "unavailable", + "unbannedUser", + "unblockDevice", + "unknownDevice", + "unknownEncryptionAlgorithm", + "unknownEvent", + "unmuteChat", + "unpin", + "unreadChats", + "userAndOthersAreTyping", + "userAndUserAreTyping", + "userIsTyping", + "userLeftTheChat", + "username", + "userSentUnknownEvent", + "unverified", + "verified", + "verify", + "verifyStart", + "verifySuccess", + "verifyTitle", + "videoCall", + "visibilityOfTheChatHistory", + "visibleForAllParticipants", + "visibleForEveryone", + "voiceMessage", + "waitingPartnerAcceptRequest", + "waitingPartnerEmoji", + "waitingPartnerNumbers", + "wallpaper", + "warning", + "weSentYouAnEmail", + "whoCanPerformWhichAction", + "whoIsAllowedToJoinThisGroup", + "whyDoYouWantToReportThis", + "wipeChatBackup", + "withTheseAddressesRecoveryDescription", + "writeAMessage", + "yes", + "you", + "youAreNoLongerParticipatingInThisChat", + "youHaveBeenBannedFromThisChat", + "yourPublicKey", + "messageInfo", + "time", + "messageType", + "sender", + "openGallery", + "removeFromSpace", + "addToSpaceDescription", + "start", + "pleaseEnterRecoveryKeyDescription", + "publish", + "videoWithSize", + "openChat", + "markAsRead", + "reportUser", + "dismiss", + "reactedWith", + "pinMessage", + "confirmEventUnpin", + "emojis", + "placeCall", + "voiceCall", + "unsupportedAndroidVersion", + "unsupportedAndroidVersionLong", + "videoCallsBetaWarning", + "experimentalVideoCalls", + "emailOrUsername", + "indexedDbErrorTitle", + "indexedDbErrorLong", + "switchToAccount", + "nextAccount", + "previousAccount", + "addWidget", + "widgetVideo", + "widgetEtherpad", + "widgetJitsi", + "widgetCustom", + "widgetName", + "widgetUrlError", + "widgetNameError", + "errorAddingWidget", + "youRejectedTheInvitation", + "youJoinedTheChat", + "youAcceptedTheInvitation", + "youBannedUser", + "youHaveWithdrawnTheInvitationFor", + "youInvitedToBy", + "youInvitedBy", + "youInvitedUser", + "youKicked", + "youKickedAndBanned", + "youUnbannedUser", + "hasKnocked", + "users", + "unlockOldMessages", + "storeInSecureStorageDescription", + "saveKeyManuallyDescription", + "storeInAndroidKeystore", + "storeInAppleKeyChain", + "storeSecurlyOnThisDevice", + "countFiles", + "user", + "custom", + "foregroundServiceRunning", + "screenSharingTitle", + "screenSharingDetail", + "callingPermissions", + "callingAccount", + "callingAccountDetails", + "appearOnTop", + "appearOnTopDetails", + "otherCallingPermissions", + "whyIsThisMessageEncrypted", + "noKeyForThisMessage", + "newGroup", + "newSpace", + "enterSpace", + "enterRoom", + "allSpaces", + "numChats", + "hideUnimportantStateEvents", + "hidePresences", + "doNotShowAgain", + "wasDirectChatDisplayName", + "newSpaceDescription", + "encryptThisChat", + "disableEncryptionWarning", + "sorryThatsNotPossible", + "deviceKeys", + "reopenChat", + "noBackupWarning", + "noOtherDevicesFound", + "fileIsTooBigForServer", + "fileHasBeenSavedAt", + "jumpToLastReadMessage", + "readUpToHere", + "jump", + "openLinkInBrowser", + "reportErrorDescription", + "report", + "signInWithPassword", + "pleaseTryAgainLaterOrChooseDifferentServer", + "signInWith", + "profileNotFound", + "setTheme", + "setColorTheme", + "invite", "requests", + "inviteGroupChat", + "invitePrivateChat", + "invalidInput", + "wrongPinEntered", + "pleaseEnterANumber", + "archiveRoomDescription", + "roomUpgradeDescription", "allCorrect", "newWayAllGood", "othersAreBetter", @@ -17687,6 +19010,13 @@ "reportMessageTitle", "reportMessageBody", "noTeachersFound", + "pushNotificationsNotAvailable", + "learnMore", + "banUserDescription", + "unbanUserDescription", + "kickUserDescription", + "makeAdminDescription", + "removeDevicesDescription", "yourGlobalUserIdIs", "noUsersFoundWithQuery", "searchChatsRooms", @@ -17750,6 +19080,15 @@ "conversationLanguageLevel", "showDefinition", "acceptedKeyVerification", + "sendReadReceipts", + "sendTypingNotificationsDescription", + "sendReadReceiptsDescription", + "formattedMessages", + "formattedMessagesDescription", + "verifyOtherUser", + "verifyOtherUserDescription", + "verifyOtherDevice", + "verifyOtherDeviceDescription", "canceledKeyVerification", "completedKeyVerification", "isReadyForKeyVerification", @@ -17773,10 +19112,17 @@ "joinToView", "refresh", "autoPlayTitle", - "autoPlayDesc" + "autoPlayDesc", + "transparent", + "incomingMessages", + "stickers", + "discover", + "commandHint_ignore", + "commandHint_unignore", + "unreadChatsInApp" ], - "it": [ + "id": [ "accountInformation", "addGroupDescription", "addNewFriend", @@ -17790,7 +19136,15 @@ "groupDescriptionHasBeenChanged", "ignoreListDescription", "ignoreUsername", + "block", + "blockedUsers", + "blockListDescription", + "blockUsername", "optionalGroupName", + "presenceStyle", + "presencesToggle", + "youInvitedToBy", + "hidePresences", "requests", "allCorrect", "newWayAllGood", @@ -18536,6 +19890,12 @@ "reportMessageTitle", "reportMessageBody", "noTeachersFound", + "yourGlobalUserIdIs", + "noUsersFoundWithQuery", + "searchChatsRooms", + "groupName", + "createGroupAndInviteUsers", + "groupCanBeFoundViaSearch", "inNoSpaces", "createClass", "createExchange", @@ -18548,6 +19908,11 @@ "emptyInviteWarning", "errorGettingAudio", "nothingFound", + "wrongRecoveryKey", + "startConversation", + "commandHint_sendraw", + "databaseMigrationTitle", + "databaseMigrationBody", "leaveEmptyToClearStatus", "select", "searchForUsers", @@ -18588,6 +19953,15 @@ "conversationLanguageLevel", "showDefinition", "acceptedKeyVerification", + "sendReadReceipts", + "sendTypingNotificationsDescription", + "sendReadReceiptsDescription", + "formattedMessages", + "formattedMessagesDescription", + "verifyOtherUser", + "verifyOtherUserDescription", + "verifyOtherDevice", + "verifyOtherDeviceDescription", "canceledKeyVerification", "completedKeyVerification", "isReadyForKeyVerification", @@ -18611,10 +19985,17 @@ "joinToView", "refresh", "autoPlayTitle", - "autoPlayDesc" + "autoPlayDesc", + "transparent", + "incomingMessages", + "stickers", + "discover", + "commandHint_ignore", + "commandHint_unignore", + "unreadChatsInApp" ], - "ja": [ + "ie": [ "accountInformation", "addGroupDescription", "addNewFriend", @@ -18633,6 +20014,10 @@ "blockListDescription", "blockUsername", "optionalGroupName", + "presenceStyle", + "presencesToggle", + "youInvitedToBy", + "hidePresences", "requests", "allCorrect", "newWayAllGood", @@ -19441,6 +20826,15 @@ "conversationLanguageLevel", "showDefinition", "acceptedKeyVerification", + "sendReadReceipts", + "sendTypingNotificationsDescription", + "sendReadReceiptsDescription", + "formattedMessages", + "formattedMessagesDescription", + "verifyOtherUser", + "verifyOtherUserDescription", + "verifyOtherDevice", + "verifyOtherDeviceDescription", "canceledKeyVerification", "completedKeyVerification", "isReadyForKeyVerification", @@ -19464,10 +20858,17 @@ "joinToView", "refresh", "autoPlayTitle", - "autoPlayDesc" + "autoPlayDesc", + "transparent", + "incomingMessages", + "stickers", + "discover", + "commandHint_ignore", + "commandHint_unignore", + "unreadChatsInApp" ], - "ko": [ + "it": [ "accountInformation", "addGroupDescription", "addNewFriend", @@ -19481,11 +20882,11 @@ "groupDescriptionHasBeenChanged", "ignoreListDescription", "ignoreUsername", - "block", - "blockedUsers", - "blockListDescription", - "blockUsername", "optionalGroupName", + "presenceStyle", + "presencesToggle", + "youInvitedToBy", + "hidePresences", "requests", "allCorrect", "newWayAllGood", @@ -20231,12 +21632,6 @@ "reportMessageTitle", "reportMessageBody", "noTeachersFound", - "yourGlobalUserIdIs", - "noUsersFoundWithQuery", - "searchChatsRooms", - "groupName", - "createGroupAndInviteUsers", - "groupCanBeFoundViaSearch", "inNoSpaces", "createClass", "createExchange", @@ -20249,11 +21644,6 @@ "emptyInviteWarning", "errorGettingAudio", "nothingFound", - "wrongRecoveryKey", - "startConversation", - "commandHint_sendraw", - "databaseMigrationTitle", - "databaseMigrationBody", "leaveEmptyToClearStatus", "select", "searchForUsers", @@ -20294,6 +21684,15 @@ "conversationLanguageLevel", "showDefinition", "acceptedKeyVerification", + "sendReadReceipts", + "sendTypingNotificationsDescription", + "sendReadReceiptsDescription", + "formattedMessages", + "formattedMessagesDescription", + "verifyOtherUser", + "verifyOtherUserDescription", + "verifyOtherDevice", + "verifyOtherDeviceDescription", "canceledKeyVerification", "completedKeyVerification", "isReadyForKeyVerification", @@ -20317,10 +21716,17 @@ "joinToView", "refresh", "autoPlayTitle", - "autoPlayDesc" + "autoPlayDesc", + "transparent", + "incomingMessages", + "stickers", + "discover", + "commandHint_ignore", + "commandHint_unignore", + "unreadChatsInApp" ], - "lt": [ + "ja": [ "accountInformation", "addGroupDescription", "addNewFriend", @@ -20339,6 +21745,10 @@ "blockListDescription", "blockUsername", "optionalGroupName", + "presenceStyle", + "presencesToggle", + "youInvitedToBy", + "hidePresences", "requests", "allCorrect", "newWayAllGood", @@ -21147,6 +22557,15 @@ "conversationLanguageLevel", "showDefinition", "acceptedKeyVerification", + "sendReadReceipts", + "sendTypingNotificationsDescription", + "sendReadReceiptsDescription", + "formattedMessages", + "formattedMessagesDescription", + "verifyOtherUser", + "verifyOtherUserDescription", + "verifyOtherDevice", + "verifyOtherDeviceDescription", "canceledKeyVerification", "completedKeyVerification", "isReadyForKeyVerification", @@ -21170,10 +22589,17 @@ "joinToView", "refresh", "autoPlayTitle", - "autoPlayDesc" + "autoPlayDesc", + "transparent", + "incomingMessages", + "stickers", + "discover", + "commandHint_ignore", + "commandHint_unignore", + "unreadChatsInApp" ], - "lv": [ + "ko": [ "accountInformation", "addGroupDescription", "addNewFriend", @@ -21192,6 +22618,10 @@ "blockListDescription", "blockUsername", "optionalGroupName", + "presenceStyle", + "presencesToggle", + "youInvitedToBy", + "hidePresences", "requests", "allCorrect", "newWayAllGood", @@ -22000,6 +23430,15 @@ "conversationLanguageLevel", "showDefinition", "acceptedKeyVerification", + "sendReadReceipts", + "sendTypingNotificationsDescription", + "sendReadReceiptsDescription", + "formattedMessages", + "formattedMessagesDescription", + "verifyOtherUser", + "verifyOtherUserDescription", + "verifyOtherDevice", + "verifyOtherDeviceDescription", "canceledKeyVerification", "completedKeyVerification", "isReadyForKeyVerification", @@ -22023,10 +23462,17 @@ "joinToView", "refresh", "autoPlayTitle", - "autoPlayDesc" + "autoPlayDesc", + "transparent", + "incomingMessages", + "stickers", + "discover", + "commandHint_ignore", + "commandHint_unignore", + "unreadChatsInApp" ], - "nb": [ + "lt": [ "accountInformation", "addGroupDescription", "addNewFriend", @@ -22045,6 +23491,10 @@ "blockListDescription", "blockUsername", "optionalGroupName", + "presenceStyle", + "presencesToggle", + "youInvitedToBy", + "hidePresences", "requests", "allCorrect", "newWayAllGood", @@ -22853,6 +24303,15 @@ "conversationLanguageLevel", "showDefinition", "acceptedKeyVerification", + "sendReadReceipts", + "sendTypingNotificationsDescription", + "sendReadReceiptsDescription", + "formattedMessages", + "formattedMessagesDescription", + "verifyOtherUser", + "verifyOtherUserDescription", + "verifyOtherDevice", + "verifyOtherDeviceDescription", "canceledKeyVerification", "completedKeyVerification", "isReadyForKeyVerification", @@ -22876,10 +24335,17 @@ "joinToView", "refresh", "autoPlayTitle", - "autoPlayDesc" + "autoPlayDesc", + "transparent", + "incomingMessages", + "stickers", + "discover", + "commandHint_ignore", + "commandHint_unignore", + "unreadChatsInApp" ], - "nl": [ + "lv": [ "accountInformation", "addGroupDescription", "addNewFriend", @@ -22898,6 +24364,10 @@ "blockListDescription", "blockUsername", "optionalGroupName", + "presenceStyle", + "presencesToggle", + "youInvitedToBy", + "hidePresences", "requests", "allCorrect", "newWayAllGood", @@ -23706,6 +25176,15 @@ "conversationLanguageLevel", "showDefinition", "acceptedKeyVerification", + "sendReadReceipts", + "sendTypingNotificationsDescription", + "sendReadReceiptsDescription", + "formattedMessages", + "formattedMessagesDescription", + "verifyOtherUser", + "verifyOtherUserDescription", + "verifyOtherDevice", + "verifyOtherDeviceDescription", "canceledKeyVerification", "completedKeyVerification", "isReadyForKeyVerification", @@ -23729,10 +25208,17 @@ "joinToView", "refresh", "autoPlayTitle", - "autoPlayDesc" + "autoPlayDesc", + "transparent", + "incomingMessages", + "stickers", + "discover", + "commandHint_ignore", + "commandHint_unignore", + "unreadChatsInApp" ], - "pl": [ + "nb": [ "accountInformation", "addGroupDescription", "addNewFriend", @@ -23751,6 +25237,10 @@ "blockListDescription", "blockUsername", "optionalGroupName", + "presenceStyle", + "presencesToggle", + "youInvitedToBy", + "hidePresences", "requests", "allCorrect", "newWayAllGood", @@ -24559,6 +26049,15 @@ "conversationLanguageLevel", "showDefinition", "acceptedKeyVerification", + "sendReadReceipts", + "sendTypingNotificationsDescription", + "sendReadReceiptsDescription", + "formattedMessages", + "formattedMessagesDescription", + "verifyOtherUser", + "verifyOtherUserDescription", + "verifyOtherDevice", + "verifyOtherDeviceDescription", "canceledKeyVerification", "completedKeyVerification", "isReadyForKeyVerification", @@ -24582,10 +26081,17 @@ "joinToView", "refresh", "autoPlayTitle", - "autoPlayDesc" + "autoPlayDesc", + "transparent", + "incomingMessages", + "stickers", + "discover", + "commandHint_ignore", + "commandHint_unignore", + "unreadChatsInApp" ], - "pt": [ + "nl": [ "accountInformation", "addGroupDescription", "addNewFriend", @@ -24604,6 +26110,10 @@ "blockListDescription", "blockUsername", "optionalGroupName", + "presenceStyle", + "presencesToggle", + "youInvitedToBy", + "hidePresences", "requests", "allCorrect", "newWayAllGood", @@ -25412,6 +26922,15 @@ "conversationLanguageLevel", "showDefinition", "acceptedKeyVerification", + "sendReadReceipts", + "sendTypingNotificationsDescription", + "sendReadReceiptsDescription", + "formattedMessages", + "formattedMessagesDescription", + "verifyOtherUser", + "verifyOtherUserDescription", + "verifyOtherDevice", + "verifyOtherDeviceDescription", "canceledKeyVerification", "completedKeyVerification", "isReadyForKeyVerification", @@ -25435,10 +26954,17 @@ "joinToView", "refresh", "autoPlayTitle", - "autoPlayDesc" + "autoPlayDesc", + "transparent", + "incomingMessages", + "stickers", + "discover", + "commandHint_ignore", + "commandHint_unignore", + "unreadChatsInApp" ], - "pt_BR": [ + "pl": [ "accountInformation", "addGroupDescription", "addNewFriend", @@ -25452,7 +26978,15 @@ "groupDescriptionHasBeenChanged", "ignoreListDescription", "ignoreUsername", + "block", + "blockedUsers", + "blockListDescription", + "blockUsername", "optionalGroupName", + "presenceStyle", + "presencesToggle", + "youInvitedToBy", + "hidePresences", "requests", "allCorrect", "newWayAllGood", @@ -26148,6 +27682,7 @@ "addToClassOrExchange", "addToClassOrExchangeDesc", "invitedToClassOrExchange", + "decline", "declinedInvitation", "acceptedInvitation", "youreInvited", @@ -26197,6 +27732,12 @@ "reportMessageTitle", "reportMessageBody", "noTeachersFound", + "yourGlobalUserIdIs", + "noUsersFoundWithQuery", + "searchChatsRooms", + "groupName", + "createGroupAndInviteUsers", + "groupCanBeFoundViaSearch", "inNoSpaces", "createClass", "createExchange", @@ -26208,6 +27749,26 @@ "clickToManageSubscription", "emptyInviteWarning", "errorGettingAudio", + "nothingFound", + "wrongRecoveryKey", + "startConversation", + "commandHint_sendraw", + "databaseMigrationTitle", + "databaseMigrationBody", + "leaveEmptyToClearStatus", + "select", + "searchForUsers", + "pleaseEnterYourCurrentPassword", + "newPassword", + "pleaseChooseAStrongPassword", + "passwordsDoNotMatch", + "passwordIsWrong", + "publicLink", + "joinSpace", + "publicSpaces", + "addChatOrSubSpace", + "subspace", + "thisDevice", "initAppError", "databaseBuildErrorBody", "sessionLostBody", @@ -26234,6 +27795,15 @@ "conversationLanguageLevel", "showDefinition", "acceptedKeyVerification", + "sendReadReceipts", + "sendTypingNotificationsDescription", + "sendReadReceiptsDescription", + "formattedMessages", + "formattedMessagesDescription", + "verifyOtherUser", + "verifyOtherUserDescription", + "verifyOtherDevice", + "verifyOtherDeviceDescription", "canceledKeyVerification", "completedKeyVerification", "isReadyForKeyVerification", @@ -26257,10 +27827,17 @@ "joinToView", "refresh", "autoPlayTitle", - "autoPlayDesc" + "autoPlayDesc", + "transparent", + "incomingMessages", + "stickers", + "discover", + "commandHint_ignore", + "commandHint_unignore", + "unreadChatsInApp" ], - "pt_PT": [ + "pt": [ "accountInformation", "addGroupDescription", "addNewFriend", @@ -26279,6 +27856,10 @@ "blockListDescription", "blockUsername", "optionalGroupName", + "presenceStyle", + "presencesToggle", + "youInvitedToBy", + "hidePresences", "requests", "allCorrect", "newWayAllGood", @@ -27087,6 +28668,15 @@ "conversationLanguageLevel", "showDefinition", "acceptedKeyVerification", + "sendReadReceipts", + "sendTypingNotificationsDescription", + "sendReadReceiptsDescription", + "formattedMessages", + "formattedMessagesDescription", + "verifyOtherUser", + "verifyOtherUserDescription", + "verifyOtherDevice", + "verifyOtherDeviceDescription", "canceledKeyVerification", "completedKeyVerification", "isReadyForKeyVerification", @@ -27110,10 +28700,17 @@ "joinToView", "refresh", "autoPlayTitle", - "autoPlayDesc" + "autoPlayDesc", + "transparent", + "incomingMessages", + "stickers", + "discover", + "commandHint_ignore", + "commandHint_unignore", + "unreadChatsInApp" ], - "ro": [ + "pt_BR": [ "accountInformation", "addGroupDescription", "addNewFriend", @@ -27127,11 +28724,11 @@ "groupDescriptionHasBeenChanged", "ignoreListDescription", "ignoreUsername", - "block", - "blockedUsers", - "blockListDescription", - "blockUsername", "optionalGroupName", + "presenceStyle", + "presencesToggle", + "youInvitedToBy", + "hidePresences", "requests", "allCorrect", "newWayAllGood", @@ -27827,7 +29424,6 @@ "addToClassOrExchange", "addToClassOrExchangeDesc", "invitedToClassOrExchange", - "decline", "declinedInvitation", "acceptedInvitation", "youreInvited", @@ -27877,12 +29473,6 @@ "reportMessageTitle", "reportMessageBody", "noTeachersFound", - "yourGlobalUserIdIs", - "noUsersFoundWithQuery", - "searchChatsRooms", - "groupName", - "createGroupAndInviteUsers", - "groupCanBeFoundViaSearch", "inNoSpaces", "createClass", "createExchange", @@ -27894,26 +29484,6 @@ "clickToManageSubscription", "emptyInviteWarning", "errorGettingAudio", - "nothingFound", - "wrongRecoveryKey", - "startConversation", - "commandHint_sendraw", - "databaseMigrationTitle", - "databaseMigrationBody", - "leaveEmptyToClearStatus", - "select", - "searchForUsers", - "pleaseEnterYourCurrentPassword", - "newPassword", - "pleaseChooseAStrongPassword", - "passwordsDoNotMatch", - "passwordIsWrong", - "publicLink", - "joinSpace", - "publicSpaces", - "addChatOrSubSpace", - "subspace", - "thisDevice", "initAppError", "databaseBuildErrorBody", "sessionLostBody", @@ -27940,6 +29510,15 @@ "conversationLanguageLevel", "showDefinition", "acceptedKeyVerification", + "sendReadReceipts", + "sendTypingNotificationsDescription", + "sendReadReceiptsDescription", + "formattedMessages", + "formattedMessagesDescription", + "verifyOtherUser", + "verifyOtherUserDescription", + "verifyOtherDevice", + "verifyOtherDeviceDescription", "canceledKeyVerification", "completedKeyVerification", "isReadyForKeyVerification", @@ -27963,10 +29542,17 @@ "joinToView", "refresh", "autoPlayTitle", - "autoPlayDesc" + "autoPlayDesc", + "transparent", + "incomingMessages", + "stickers", + "discover", + "commandHint_ignore", + "commandHint_unignore", + "unreadChatsInApp" ], - "ru": [ + "pt_PT": [ "accountInformation", "addGroupDescription", "addNewFriend", @@ -27980,7 +29566,15 @@ "groupDescriptionHasBeenChanged", "ignoreListDescription", "ignoreUsername", + "block", + "blockedUsers", + "blockListDescription", + "blockUsername", "optionalGroupName", + "presenceStyle", + "presencesToggle", + "youInvitedToBy", + "hidePresences", "requests", "allCorrect", "newWayAllGood", @@ -28726,6 +30320,12 @@ "reportMessageTitle", "reportMessageBody", "noTeachersFound", + "yourGlobalUserIdIs", + "noUsersFoundWithQuery", + "searchChatsRooms", + "groupName", + "createGroupAndInviteUsers", + "groupCanBeFoundViaSearch", "inNoSpaces", "createClass", "createExchange", @@ -28737,6 +30337,23 @@ "clickToManageSubscription", "emptyInviteWarning", "errorGettingAudio", + "nothingFound", + "wrongRecoveryKey", + "startConversation", + "commandHint_sendraw", + "databaseMigrationTitle", + "databaseMigrationBody", + "leaveEmptyToClearStatus", + "select", + "searchForUsers", + "pleaseEnterYourCurrentPassword", + "newPassword", + "pleaseChooseAStrongPassword", + "passwordsDoNotMatch", + "passwordIsWrong", + "publicLink", + "joinSpace", + "publicSpaces", "addChatOrSubSpace", "subspace", "thisDevice", @@ -28766,6 +30383,15 @@ "conversationLanguageLevel", "showDefinition", "acceptedKeyVerification", + "sendReadReceipts", + "sendTypingNotificationsDescription", + "sendReadReceiptsDescription", + "formattedMessages", + "formattedMessagesDescription", + "verifyOtherUser", + "verifyOtherUserDescription", + "verifyOtherDevice", + "verifyOtherDeviceDescription", "canceledKeyVerification", "completedKeyVerification", "isReadyForKeyVerification", @@ -28789,10 +30415,17 @@ "joinToView", "refresh", "autoPlayTitle", - "autoPlayDesc" + "autoPlayDesc", + "transparent", + "incomingMessages", + "stickers", + "discover", + "commandHint_ignore", + "commandHint_unignore", + "unreadChatsInApp" ], - "sk": [ + "ro": [ "accountInformation", "addGroupDescription", "addNewFriend", @@ -28811,6 +30444,10 @@ "blockListDescription", "blockUsername", "optionalGroupName", + "presenceStyle", + "presencesToggle", + "youInvitedToBy", + "hidePresences", "requests", "allCorrect", "newWayAllGood", @@ -29619,6 +31256,15 @@ "conversationLanguageLevel", "showDefinition", "acceptedKeyVerification", + "sendReadReceipts", + "sendTypingNotificationsDescription", + "sendReadReceiptsDescription", + "formattedMessages", + "formattedMessagesDescription", + "verifyOtherUser", + "verifyOtherUserDescription", + "verifyOtherDevice", + "verifyOtherDeviceDescription", "canceledKeyVerification", "completedKeyVerification", "isReadyForKeyVerification", @@ -29642,10 +31288,17 @@ "joinToView", "refresh", "autoPlayTitle", - "autoPlayDesc" + "autoPlayDesc", + "transparent", + "incomingMessages", + "stickers", + "discover", + "commandHint_ignore", + "commandHint_unignore", + "unreadChatsInApp" ], - "sl": [ + "ru": [ "accountInformation", "addGroupDescription", "addNewFriend", @@ -29659,10 +31312,6 @@ "groupDescriptionHasBeenChanged", "ignoreListDescription", "ignoreUsername", - "block", - "blockedUsers", - "blockListDescription", - "blockUsername", "optionalGroupName", "requests", "allCorrect", @@ -30359,7 +32008,6 @@ "addToClassOrExchange", "addToClassOrExchangeDesc", "invitedToClassOrExchange", - "decline", "declinedInvitation", "acceptedInvitation", "youreInvited", @@ -30409,12 +32057,6 @@ "reportMessageTitle", "reportMessageBody", "noTeachersFound", - "yourGlobalUserIdIs", - "noUsersFoundWithQuery", - "searchChatsRooms", - "groupName", - "createGroupAndInviteUsers", - "groupCanBeFoundViaSearch", "inNoSpaces", "createClass", "createExchange", @@ -30426,31 +32068,6 @@ "clickToManageSubscription", "emptyInviteWarning", "errorGettingAudio", - "nothingFound", - "wrongRecoveryKey", - "startConversation", - "commandHint_sendraw", - "databaseMigrationTitle", - "databaseMigrationBody", - "leaveEmptyToClearStatus", - "select", - "searchForUsers", - "pleaseEnterYourCurrentPassword", - "newPassword", - "pleaseChooseAStrongPassword", - "passwordsDoNotMatch", - "passwordIsWrong", - "publicLink", - "joinSpace", - "publicSpaces", - "addChatOrSubSpace", - "subspace", - "thisDevice", - "initAppError", - "databaseBuildErrorBody", - "sessionLostBody", - "restoreSessionBody", - "forwardMessageTo", "signUp", "pleaseChooseAtLeastChars", "noEmailWarning", @@ -30471,12 +32088,6 @@ "enableModerationDesc", "conversationLanguageLevel", "showDefinition", - "acceptedKeyVerification", - "canceledKeyVerification", - "completedKeyVerification", - "isReadyForKeyVerification", - "requestedKeyVerification", - "startedKeyVerification", "subscriptionPopupTitle", "subscriptionPopupDesc", "seeOptions", @@ -30495,10 +32106,15 @@ "joinToView", "refresh", "autoPlayTitle", - "autoPlayDesc" + "autoPlayDesc", + "stickers", + "discover", + "commandHint_ignore", + "commandHint_unignore", + "unreadChatsInApp" ], - "sr": [ + "sk": [ "accountInformation", "addGroupDescription", "addNewFriend", @@ -30517,6 +32133,10 @@ "blockListDescription", "blockUsername", "optionalGroupName", + "presenceStyle", + "presencesToggle", + "youInvitedToBy", + "hidePresences", "requests", "allCorrect", "newWayAllGood", @@ -31325,6 +32945,15 @@ "conversationLanguageLevel", "showDefinition", "acceptedKeyVerification", + "sendReadReceipts", + "sendTypingNotificationsDescription", + "sendReadReceiptsDescription", + "formattedMessages", + "formattedMessagesDescription", + "verifyOtherUser", + "verifyOtherUserDescription", + "verifyOtherDevice", + "verifyOtherDeviceDescription", "canceledKeyVerification", "completedKeyVerification", "isReadyForKeyVerification", @@ -31348,10 +32977,17 @@ "joinToView", "refresh", "autoPlayTitle", - "autoPlayDesc" + "autoPlayDesc", + "transparent", + "incomingMessages", + "stickers", + "discover", + "commandHint_ignore", + "commandHint_unignore", + "unreadChatsInApp" ], - "sv": [ + "sl": [ "accountInformation", "addGroupDescription", "addNewFriend", @@ -31370,6 +33006,10 @@ "blockListDescription", "blockUsername", "optionalGroupName", + "presenceStyle", + "presencesToggle", + "youInvitedToBy", + "hidePresences", "requests", "allCorrect", "newWayAllGood", @@ -32178,6 +33818,15 @@ "conversationLanguageLevel", "showDefinition", "acceptedKeyVerification", + "sendReadReceipts", + "sendTypingNotificationsDescription", + "sendReadReceiptsDescription", + "formattedMessages", + "formattedMessagesDescription", + "verifyOtherUser", + "verifyOtherUserDescription", + "verifyOtherDevice", + "verifyOtherDeviceDescription", "canceledKeyVerification", "completedKeyVerification", "isReadyForKeyVerification", @@ -32201,10 +33850,17 @@ "joinToView", "refresh", "autoPlayTitle", - "autoPlayDesc" + "autoPlayDesc", + "transparent", + "incomingMessages", + "stickers", + "discover", + "commandHint_ignore", + "commandHint_unignore", + "unreadChatsInApp" ], - "ta": [ + "sr": [ "accountInformation", "addGroupDescription", "addNewFriend", @@ -32223,6 +33879,10 @@ "blockListDescription", "blockUsername", "optionalGroupName", + "presenceStyle", + "presencesToggle", + "youInvitedToBy", + "hidePresences", "requests", "allCorrect", "newWayAllGood", @@ -33031,6 +34691,15 @@ "conversationLanguageLevel", "showDefinition", "acceptedKeyVerification", + "sendReadReceipts", + "sendTypingNotificationsDescription", + "sendReadReceiptsDescription", + "formattedMessages", + "formattedMessagesDescription", + "verifyOtherUser", + "verifyOtherUserDescription", + "verifyOtherDevice", + "verifyOtherDeviceDescription", "canceledKeyVerification", "completedKeyVerification", "isReadyForKeyVerification", @@ -33054,10 +34723,17 @@ "joinToView", "refresh", "autoPlayTitle", - "autoPlayDesc" + "autoPlayDesc", + "transparent", + "incomingMessages", + "stickers", + "discover", + "commandHint_ignore", + "commandHint_unignore", + "unreadChatsInApp" ], - "th": [ + "sv": [ "accountInformation", "addGroupDescription", "addNewFriend", @@ -33071,11 +34747,11 @@ "groupDescriptionHasBeenChanged", "ignoreListDescription", "ignoreUsername", - "block", - "blockedUsers", - "blockListDescription", - "blockUsername", "optionalGroupName", + "presenceStyle", + "presencesToggle", + "youInvitedToBy", + "hidePresences", "requests", "allCorrect", "newWayAllGood", @@ -33771,7 +35447,6 @@ "addToClassOrExchange", "addToClassOrExchangeDesc", "invitedToClassOrExchange", - "decline", "declinedInvitation", "acceptedInvitation", "youreInvited", @@ -33821,12 +35496,6 @@ "reportMessageTitle", "reportMessageBody", "noTeachersFound", - "yourGlobalUserIdIs", - "noUsersFoundWithQuery", - "searchChatsRooms", - "groupName", - "createGroupAndInviteUsers", - "groupCanBeFoundViaSearch", "inNoSpaces", "createClass", "createExchange", @@ -33838,30 +35507,6 @@ "clickToManageSubscription", "emptyInviteWarning", "errorGettingAudio", - "nothingFound", - "wrongRecoveryKey", - "startConversation", - "commandHint_sendraw", - "databaseMigrationTitle", - "databaseMigrationBody", - "leaveEmptyToClearStatus", - "select", - "searchForUsers", - "pleaseEnterYourCurrentPassword", - "newPassword", - "pleaseChooseAStrongPassword", - "passwordsDoNotMatch", - "passwordIsWrong", - "publicLink", - "joinSpace", - "publicSpaces", - "addChatOrSubSpace", - "subspace", - "thisDevice", - "initAppError", - "databaseBuildErrorBody", - "sessionLostBody", - "restoreSessionBody", "forwardMessageTo", "signUp", "pleaseChooseAtLeastChars", @@ -33884,6 +35529,15 @@ "conversationLanguageLevel", "showDefinition", "acceptedKeyVerification", + "sendReadReceipts", + "sendTypingNotificationsDescription", + "sendReadReceiptsDescription", + "formattedMessages", + "formattedMessagesDescription", + "verifyOtherUser", + "verifyOtherUserDescription", + "verifyOtherDevice", + "verifyOtherDeviceDescription", "canceledKeyVerification", "completedKeyVerification", "isReadyForKeyVerification", @@ -33907,10 +35561,17 @@ "joinToView", "refresh", "autoPlayTitle", - "autoPlayDesc" + "autoPlayDesc", + "transparent", + "incomingMessages", + "stickers", + "discover", + "commandHint_ignore", + "commandHint_unignore", + "unreadChatsInApp" ], - "tr": [ + "ta": [ "accountInformation", "addGroupDescription", "addNewFriend", @@ -33924,7 +35585,15 @@ "groupDescriptionHasBeenChanged", "ignoreListDescription", "ignoreUsername", + "block", + "blockedUsers", + "blockListDescription", + "blockUsername", "optionalGroupName", + "presenceStyle", + "presencesToggle", + "youInvitedToBy", + "hidePresences", "requests", "allCorrect", "newWayAllGood", @@ -34670,6 +36339,12 @@ "reportMessageTitle", "reportMessageBody", "noTeachersFound", + "yourGlobalUserIdIs", + "noUsersFoundWithQuery", + "searchChatsRooms", + "groupName", + "createGroupAndInviteUsers", + "groupCanBeFoundViaSearch", "inNoSpaces", "createClass", "createExchange", @@ -34682,6 +36357,11 @@ "emptyInviteWarning", "errorGettingAudio", "nothingFound", + "wrongRecoveryKey", + "startConversation", + "commandHint_sendraw", + "databaseMigrationTitle", + "databaseMigrationBody", "leaveEmptyToClearStatus", "select", "searchForUsers", @@ -34722,6 +36402,15 @@ "conversationLanguageLevel", "showDefinition", "acceptedKeyVerification", + "sendReadReceipts", + "sendTypingNotificationsDescription", + "sendReadReceiptsDescription", + "formattedMessages", + "formattedMessagesDescription", + "verifyOtherUser", + "verifyOtherUserDescription", + "verifyOtherDevice", + "verifyOtherDeviceDescription", "canceledKeyVerification", "completedKeyVerification", "isReadyForKeyVerification", @@ -34745,10 +36434,17 @@ "joinToView", "refresh", "autoPlayTitle", - "autoPlayDesc" + "autoPlayDesc", + "transparent", + "incomingMessages", + "stickers", + "discover", + "commandHint_ignore", + "commandHint_unignore", + "unreadChatsInApp" ], - "uk": [ + "th": [ "accountInformation", "addGroupDescription", "addNewFriend", @@ -34762,7 +36458,15 @@ "groupDescriptionHasBeenChanged", "ignoreListDescription", "ignoreUsername", + "block", + "blockedUsers", + "blockListDescription", + "blockUsername", "optionalGroupName", + "presenceStyle", + "presencesToggle", + "youInvitedToBy", + "hidePresences", "requests", "allCorrect", "newWayAllGood", @@ -35508,6 +37212,12 @@ "reportMessageTitle", "reportMessageBody", "noTeachersFound", + "yourGlobalUserIdIs", + "noUsersFoundWithQuery", + "searchChatsRooms", + "groupName", + "createGroupAndInviteUsers", + "groupCanBeFoundViaSearch", "inNoSpaces", "createClass", "createExchange", @@ -35520,6 +37230,11 @@ "emptyInviteWarning", "errorGettingAudio", "nothingFound", + "wrongRecoveryKey", + "startConversation", + "commandHint_sendraw", + "databaseMigrationTitle", + "databaseMigrationBody", "leaveEmptyToClearStatus", "select", "searchForUsers", @@ -35560,6 +37275,15 @@ "conversationLanguageLevel", "showDefinition", "acceptedKeyVerification", + "sendReadReceipts", + "sendTypingNotificationsDescription", + "sendReadReceiptsDescription", + "formattedMessages", + "formattedMessagesDescription", + "verifyOtherUser", + "verifyOtherUserDescription", + "verifyOtherDevice", + "verifyOtherDeviceDescription", "canceledKeyVerification", "completedKeyVerification", "isReadyForKeyVerification", @@ -35583,10 +37307,17 @@ "joinToView", "refresh", "autoPlayTitle", - "autoPlayDesc" + "autoPlayDesc", + "transparent", + "incomingMessages", + "stickers", + "discover", + "commandHint_ignore", + "commandHint_unignore", + "unreadChatsInApp" ], - "vi": [ + "tr": [ "accountInformation", "addGroupDescription", "addNewFriend", @@ -35600,11 +37331,11 @@ "groupDescriptionHasBeenChanged", "ignoreListDescription", "ignoreUsername", - "block", - "blockedUsers", - "blockListDescription", - "blockUsername", "optionalGroupName", + "presenceStyle", + "presencesToggle", + "youInvitedToBy", + "hidePresences", "requests", "allCorrect", "newWayAllGood", @@ -36350,12 +38081,6 @@ "reportMessageTitle", "reportMessageBody", "noTeachersFound", - "yourGlobalUserIdIs", - "noUsersFoundWithQuery", - "searchChatsRooms", - "groupName", - "createGroupAndInviteUsers", - "groupCanBeFoundViaSearch", "inNoSpaces", "createClass", "createExchange", @@ -36368,11 +38093,6 @@ "emptyInviteWarning", "errorGettingAudio", "nothingFound", - "wrongRecoveryKey", - "startConversation", - "commandHint_sendraw", - "databaseMigrationTitle", - "databaseMigrationBody", "leaveEmptyToClearStatus", "select", "searchForUsers", @@ -36413,6 +38133,15 @@ "conversationLanguageLevel", "showDefinition", "acceptedKeyVerification", + "sendReadReceipts", + "sendTypingNotificationsDescription", + "sendReadReceiptsDescription", + "formattedMessages", + "formattedMessagesDescription", + "verifyOtherUser", + "verifyOtherUserDescription", + "verifyOtherDevice", + "verifyOtherDeviceDescription", "canceledKeyVerification", "completedKeyVerification", "isReadyForKeyVerification", @@ -36436,10 +38165,1706 @@ "joinToView", "refresh", "autoPlayTitle", - "autoPlayDesc" + "autoPlayDesc", + "transparent", + "incomingMessages", + "stickers", + "discover", + "commandHint_ignore", + "commandHint_unignore", + "unreadChatsInApp" ], - "zh": [ + "uk": [ + "accountInformation", + "addGroupDescription", + "addNewFriend", + "alreadyHaveAnAccount", + "classes", + "createNewGroup", + "editChatPermissions", + "enterAGroupName", + "enterASpacepName", + "groupDescription", + "groupDescriptionHasBeenChanged", + "ignoreListDescription", + "ignoreUsername", + "optionalGroupName", + "requests", + "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", + "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", + "inNoSpaces", + "createClass", + "createExchange", + "viewArchive", + "trialExpiration", + "freeTrialDesc", + "activateTrial", + "successfullySubscribed", + "clickToManageSubscription", + "emptyInviteWarning", + "errorGettingAudio", + "signUp", + "pleaseChooseAtLeastChars", + "noEmailWarning", + "pleaseEnterValidEmail", + "noAddToSpacePermissions", + "alreadyInSpace", + "pleaseChooseAUsername", + "chooseAUsername", + "define", + "listen", + "addConversationBot", + "addConversationBotDesc", + "convoBotSettingsTitle", + "convoBotSettingsDescription", + "enterAConversationTopic", + "conversationTopic", + "enableModeration", + "enableModerationDesc", + "conversationLanguageLevel", + "showDefinition", + "subscriptionPopupTitle", + "subscriptionPopupDesc", + "seeOptions", + "continuedWithoutSubscription", + "trialPeriodExpired", + "selectToDefine", + "translations", + "messageAudio", + "definitions", + "subscribedToUnlockTools", + "more", + "translationTooltip", + "audioTooltip", + "certifyAge", + "kickBotWarning", + "joinToView", + "refresh", + "autoPlayTitle", + "autoPlayDesc", + "stickers", + "discover", + "commandHint_ignore", + "commandHint_unignore", + "unreadChatsInApp" + ], + + "vi": [ + "accountInformation", + "addGroupDescription", + "addNewFriend", + "alreadyHaveAnAccount", + "classes", + "createNewGroup", + "editChatPermissions", + "enterAGroupName", + "enterASpacepName", + "groupDescription", + "groupDescriptionHasBeenChanged", + "ignoreListDescription", + "ignoreUsername", + "block", + "blockedUsers", + "blockListDescription", + "blockUsername", + "optionalGroupName", + "presenceStyle", + "presencesToggle", + "youInvitedToBy", + "hidePresences", + "requests", + "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", + "yourGlobalUserIdIs", + "noUsersFoundWithQuery", + "searchChatsRooms", + "groupName", + "createGroupAndInviteUsers", + "groupCanBeFoundViaSearch", + "inNoSpaces", + "createClass", + "createExchange", + "viewArchive", + "trialExpiration", + "freeTrialDesc", + "activateTrial", + "successfullySubscribed", + "clickToManageSubscription", + "emptyInviteWarning", + "errorGettingAudio", + "nothingFound", + "wrongRecoveryKey", + "startConversation", + "commandHint_sendraw", + "databaseMigrationTitle", + "databaseMigrationBody", + "leaveEmptyToClearStatus", + "select", + "searchForUsers", + "pleaseEnterYourCurrentPassword", + "newPassword", + "pleaseChooseAStrongPassword", + "passwordsDoNotMatch", + "passwordIsWrong", + "publicLink", + "joinSpace", + "publicSpaces", + "addChatOrSubSpace", + "subspace", + "thisDevice", + "initAppError", + "databaseBuildErrorBody", + "sessionLostBody", + "restoreSessionBody", + "forwardMessageTo", + "signUp", + "pleaseChooseAtLeastChars", + "noEmailWarning", + "pleaseEnterValidEmail", + "noAddToSpacePermissions", + "alreadyInSpace", + "pleaseChooseAUsername", + "chooseAUsername", + "define", + "listen", + "addConversationBot", + "addConversationBotDesc", + "convoBotSettingsTitle", + "convoBotSettingsDescription", + "enterAConversationTopic", + "conversationTopic", + "enableModeration", + "enableModerationDesc", + "conversationLanguageLevel", + "showDefinition", + "acceptedKeyVerification", + "sendReadReceipts", + "sendTypingNotificationsDescription", + "sendReadReceiptsDescription", + "formattedMessages", + "formattedMessagesDescription", + "verifyOtherUser", + "verifyOtherUserDescription", + "verifyOtherDevice", + "verifyOtherDeviceDescription", + "canceledKeyVerification", + "completedKeyVerification", + "isReadyForKeyVerification", + "requestedKeyVerification", + "startedKeyVerification", + "subscriptionPopupTitle", + "subscriptionPopupDesc", + "seeOptions", + "continuedWithoutSubscription", + "trialPeriodExpired", + "selectToDefine", + "translations", + "messageAudio", + "definitions", + "subscribedToUnlockTools", + "more", + "translationTooltip", + "audioTooltip", + "certifyAge", + "kickBotWarning", + "joinToView", + "refresh", + "autoPlayTitle", + "autoPlayDesc", + "transparent", + "incomingMessages", + "stickers", + "discover", + "commandHint_ignore", + "commandHint_unignore", + "unreadChatsInApp" + ], + + "zh": [ "accountInformation", "addGroupDescription", "addNewFriend", @@ -37149,7 +40574,6 @@ "addToClassOrExchange", "addToClassOrExchangeDesc", "invitedToClassOrExchange", - "decline", "declinedInvitation", "acceptedInvitation", "youreInvited", @@ -37210,26 +40634,6 @@ "clickToManageSubscription", "emptyInviteWarning", "errorGettingAudio", - "nothingFound", - "leaveEmptyToClearStatus", - "select", - "searchForUsers", - "pleaseEnterYourCurrentPassword", - "newPassword", - "pleaseChooseAStrongPassword", - "passwordsDoNotMatch", - "passwordIsWrong", - "publicLink", - "joinSpace", - "publicSpaces", - "addChatOrSubSpace", - "subspace", - "thisDevice", - "initAppError", - "databaseBuildErrorBody", - "sessionLostBody", - "restoreSessionBody", - "forwardMessageTo", "signUp", "pleaseChooseAtLeastChars", "noEmailWarning", @@ -37250,12 +40654,6 @@ "enableModerationDesc", "conversationLanguageLevel", "showDefinition", - "acceptedKeyVerification", - "canceledKeyVerification", - "completedKeyVerification", - "isReadyForKeyVerification", - "requestedKeyVerification", - "startedKeyVerification", "subscriptionPopupTitle", "subscriptionPopupDesc", "seeOptions", @@ -37274,7 +40672,12 @@ "joinToView", "refresh", "autoPlayTitle", - "autoPlayDesc" + "autoPlayDesc", + "stickers", + "discover", + "commandHint_ignore", + "commandHint_unignore", + "unreadChatsInApp" ], "zh_Hant": [ @@ -37296,6 +40699,10 @@ "blockListDescription", "blockUsername", "optionalGroupName", + "presenceStyle", + "presencesToggle", + "youInvitedToBy", + "hidePresences", "requests", "allCorrect", "newWayAllGood", @@ -38104,6 +41511,15 @@ "conversationLanguageLevel", "showDefinition", "acceptedKeyVerification", + "sendReadReceipts", + "sendTypingNotificationsDescription", + "sendReadReceiptsDescription", + "formattedMessages", + "formattedMessagesDescription", + "verifyOtherUser", + "verifyOtherUserDescription", + "verifyOtherDevice", + "verifyOtherDeviceDescription", "canceledKeyVerification", "completedKeyVerification", "isReadyForKeyVerification", @@ -38127,6 +41543,13 @@ "joinToView", "refresh", "autoPlayTitle", - "autoPlayDesc" + "autoPlayDesc", + "transparent", + "incomingMessages", + "stickers", + "discover", + "commandHint_ignore", + "commandHint_unignore", + "unreadChatsInApp" ] } diff --git a/pubspec.lock b/pubspec.lock index 2263313e78..366feffadf 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -21,10 +21,10 @@ packages: dependency: "direct main" description: name: adaptive_dialog - sha256: "30dc6deee139cde31e5d10a1d05e1a2a1bb6d592cf0eea27b978884b1ff03405" + sha256: "817ff9b4bb441434d1fcb39a8d4492e50be456cd3507e4f19c5c7455c9e279e0" url: "https://pub.dev" source: hosted - version: "2.0.0" + version: "2.1.0" analyzer: dependency: transitive description: @@ -33,14 +33,6 @@ packages: url: "https://pub.dev" source: hosted version: "5.13.0" - analyzer_plugin: - dependency: transitive - description: - name: analyzer_plugin - sha256: c1d5f167683de03d5ab6c3b53fc9aeefc5d59476e7810ba7bbddff50c6f4392d - url: "https://pub.dev" - source: hosted - version: "0.11.2" animations: dependency: "direct main" description: @@ -105,6 +97,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.1.2" + barbecue: + dependency: transitive + description: + name: barbecue + sha256: e3a0afaf9005e466887d6c87411a2ddd8d72fc46db3caabf278ee600f1e2f92c + url: "https://pub.dev" + source: hosted + version: "0.4.0" base58check: dependency: transitive description: @@ -209,6 +209,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.18.0" + colorize: + dependency: transitive + description: + name: colorize + sha256: "584746cd6ba1cba0633b6720f494fe6f9601c4170f0666c1579d2aa2a61071ba" + url: "https://pub.dev" + source: hosted + version: "3.0.0" connectivity_plus: dependency: "direct main" description: @@ -289,30 +297,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.6" - dart_code_metrics: - dependency: "direct dev" - description: - name: dart_code_metrics - sha256: "3dede3f7abc077a4181ec7445448a289a9ce08e2981e6a4d49a3fb5099d47e1f" - url: "https://pub.dev" - source: hosted - version: "5.7.6" - dart_code_metrics_presets: - dependency: transitive - description: - name: dart_code_metrics_presets - sha256: b71eadf02a3787ebd5c887623f83f6fdc204d45c75a081bd636c4104b3fd8b73 - url: "https://pub.dev" - source: hosted - version: "1.8.0" - dart_style: - dependency: transitive - description: - name: dart_style - sha256: "1efa911ca7086affd35f463ca2fc1799584fb6aa89883cf0af8e3664d6a02d55" - url: "https://pub.dev" - source: hosted - version: "2.3.2" dart_webrtc: dependency: transitive description: @@ -381,10 +365,10 @@ packages: dependency: "direct main" description: name: emoji_picker_flutter - sha256: "009c51efc763d5a6ba05a5628b8b2184c327cd117d66ea9c3e7edf2ff269c423" + sha256: "8506341d62efd116d6fb1481450bffdbac659d3d90d46d9cc610bfae5f33cc54" url: "https://pub.dev" source: hosted - version: "1.6.3" + version: "1.6.4" emoji_proposal: dependency: "direct main" description: @@ -444,10 +428,10 @@ packages: dependency: transitive description: name: file - sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d" + sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" url: "https://pub.dev" source: hosted - version: "6.1.4" + version: "7.0.0" file_picker: dependency: "direct main" description: @@ -589,14 +573,6 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.0" - flutter_blurhash: - dependency: "direct main" - description: - name: flutter_blurhash - sha256: "5e67678e479ac639069d7af1e133f4a4702311491188ff3e0227486430db0c06" - url: "https://pub.dev" - source: hosted - version: "0.8.2" flutter_cache_manager: dependency: "direct main" description: @@ -618,6 +594,14 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_file_dialog: + dependency: "direct main" + description: + name: flutter_file_dialog + sha256: "9344b8f07be6a1b6f9854b723fb0cf84a8094ba94761af1d213589d3cb087488" + url: "https://pub.dev" + source: hosted + version: "3.0.2" flutter_foreground_task: dependency: "direct main" description: @@ -654,10 +638,10 @@ packages: dependency: transitive description: name: flutter_keyboard_visibility - sha256: "4983655c26ab5b959252ee204c2fffa4afeb4413cd030455194ec0caa3b8e7cb" + sha256: "98664be7be0e3ffca00de50f7f6a287ab62c763fc8c762e0a21584584a3ff4f8" url: "https://pub.dev" source: hosted - version: "5.4.1" + version: "6.0.0" flutter_keyboard_visibility_linux: dependency: transitive description: @@ -726,10 +710,10 @@ packages: dependency: "direct main" description: name: flutter_local_notifications - sha256: "892ada16046d641263f30c72e7432397088810a84f34479f6677494802a2b535" + sha256: c18f1de98fe0bb9dd5ba91e1330d4febc8b6a7de6aae3ffe475ef423723e72f3 url: "https://pub.dev" source: hosted - version: "16.3.0" + version: "16.3.2" flutter_local_notifications_linux: dependency: transitive description: @@ -855,6 +839,15 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.0" + flutter_shortcuts: + dependency: "direct main" + description: + path: "." + ref: HEAD + resolved-ref: "930c51d56c87a7f8cefdf8c1db52c194baddc37d" + url: "https://github.com/krille-chan/flutter_shortcuts.git" + source: git + version: "1.4.0" flutter_svg: dependency: "direct main" description: @@ -872,10 +865,10 @@ packages: dependency: "direct main" description: name: flutter_typeahead - sha256: b9942bd5b7611a6ec3f0730c477146cffa4cd4b051077983ba67ddfc9e7ee818 + sha256: d64712c65db240b1057559b952398ebb6e498077baeebf9b0731dade62438a6d url: "https://pub.dev" source: hosted - version: "4.8.0" + version: "5.2.0" flutter_web_auth_2: dependency: "direct main" description: @@ -1002,10 +995,10 @@ packages: dependency: "direct main" description: name: go_router - sha256: c5fa45fa502ee880839e3b2152d987c44abae26d064a2376d4aad434cf0f7b15 + sha256: "07ee2436909f749d606f53521dc1725dd738dc5196e5ff815bc254253c594075" url: "https://pub.dev" source: hosted - version: "12.1.3" + version: "13.1.0" gradient_borders: dependency: transitive description: @@ -1071,13 +1064,13 @@ packages: source: hosted version: "4.0.2" image: - dependency: transitive + dependency: "direct main" description: name: image - sha256: "004a2e90ce080f8627b5a04aecb4cdfac87d2c3f3b520aa291260be5a32c033d" + sha256: "4c68bfd5ae83e700b5204c1e74451e7bf3cf750e6843c6e158289cf56bda018e" url: "https://pub.dev" source: hosted - version: "4.1.4" + version: "4.1.7" image_picker: dependency: "direct main" description: @@ -1292,6 +1285,38 @@ packages: url: "https://pub.dev" source: hosted version: "0.8.2" + leak_tracker: + dependency: transitive + description: + name: leak_tracker + sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa" + url: "https://pub.dev" + source: hosted + version: "10.0.0" + leak_tracker_flutter_testing: + dependency: transitive + description: + name: leak_tracker_flutter_testing + sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0 + url: "https://pub.dev" + source: hosted + version: "2.0.1" + leak_tracker_testing: + dependency: transitive + description: + name: leak_tracker_testing + sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47 + url: "https://pub.dev" + source: hosted + version: "2.0.1" + license_checker: + dependency: "direct dev" + description: + name: license_checker + sha256: eea27638e42bc98fd91a6a8187eb57e5617e2c3c8b313a5d51b14bec7a8685e1 + url: "https://pub.dev" + source: hosted + version: "1.6.0" linkify: dependency: "direct main" description: @@ -1360,27 +1385,26 @@ packages: dependency: transitive description: name: matcher - sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e" + sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb url: "https://pub.dev" source: hosted - version: "0.12.16" + version: "0.12.16+1" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41" + sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" url: "https://pub.dev" source: hosted - version: "0.5.0" + version: "0.8.0" matrix: dependency: "direct main" description: - path: "." - ref: "ggurdin/indexeddb-clear-fix" - resolved-ref: e9abfd041283595d38134410abeba71b6cf978f8 - url: "https://github.com/ggurdin/matrix-dart-sdk.git" - source: git - version: "0.25.9" + name: matrix + sha256: f829dd542f354e5073e3b43aaed3adc2829e762a9ec50a3f186ffd7dddc36d5e + url: "https://pub.dev" + source: hosted + version: "0.26.1" matrix_api_lite: dependency: transitive description: @@ -1401,10 +1425,10 @@ packages: dependency: transitive description: name: meta - sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e + sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 url: "https://pub.dev" source: hosted - version: "1.10.0" + version: "1.11.0" mgrs_dart: dependency: transitive description: @@ -1445,14 +1469,6 @@ 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: @@ -1489,10 +1505,10 @@ packages: dependency: "direct main" description: name: package_info_plus - sha256: "7e76fad405b3e4016cd39d08f455a4eb5199723cf594cd1b8916d47140d93017" + sha256: "88bc797f44a94814f2213db1c9bd5badebafdfb8290ca9f78d4b9ee2a3db4d79" url: "https://pub.dev" source: hosted - version: "4.2.0" + version: "5.0.1" package_info_plus_platform_interface: dependency: transitive description: @@ -1501,6 +1517,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.1" + pana: + dependency: transitive + description: + name: pana + sha256: "098eecfb7f80aecfff2395f9de1f19e31e7dc9a190708b75a1e708e6c2993c36" + url: "https://pub.dev" + source: hosted + version: "0.21.32" pasteboard: dependency: "direct main" description: @@ -1510,13 +1534,13 @@ packages: source: hosted version: "0.2.0" path: - dependency: transitive + dependency: "direct main" description: name: path - sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" url: "https://pub.dev" source: hosted - version: "1.8.3" + version: "1.9.0" path_parsing: dependency: transitive description: @@ -1633,10 +1657,10 @@ packages: dependency: transitive description: name: platform - sha256: ae68c7bfcd7383af3629daafb32fb4e8681c7154428da4febcff06200585f102 + sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec" url: "https://pub.dev" source: hosted - version: "3.1.2" + version: "3.1.4" platform_detect: dependency: transitive description: @@ -1657,10 +1681,34 @@ packages: dependency: transitive description: name: pointer_interceptor - sha256: adf7a637f97c077041d36801b43be08559fd4322d2127b3f20bb7be1b9eebc22 + sha256: bd18321519718678d5fa98ad3a3359cbc7a31f018554eab80b73d08a7f0c165a url: "https://pub.dev" source: hosted - version: "0.9.3+7" + version: "0.10.1" + pointer_interceptor_ios: + dependency: transitive + description: + name: pointer_interceptor_ios + sha256: "2e73c39452830adc4695757130676a39412a3b7f3c34e3f752791b5384770877" + url: "https://pub.dev" + source: hosted + version: "0.10.0+2" + pointer_interceptor_platform_interface: + dependency: transitive + description: + name: pointer_interceptor_platform_interface + sha256: "0597b0560e14354baeb23f8375cd612e8bd4841bf8306ecb71fcd0bb78552506" + url: "https://pub.dev" + source: hosted + version: "0.10.0+1" + pointer_interceptor_web: + dependency: transitive + description: + name: pointer_interceptor_web + sha256: "9386e064097fd16419e935c23f08f35b58e6aaec155dd39bd6a003b88f9c14b4" + url: "https://pub.dev" + source: hosted + version: "0.10.1+2" pointycastle: dependency: transitive description: @@ -1677,14 +1725,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.1" + pretty_qr_code: + dependency: "direct main" + description: + name: pretty_qr_code + sha256: "47a0fde3967e01ea31985d1a11a998fab1ab900becdba592e9abb0a4034b807e" + url: "https://pub.dev" + source: hosted + version: "3.2.1" process: dependency: transitive description: name: process - sha256: "53fd8db9cec1d37b0574e12f07520d582019cb6c44abf5479a01505099a34a09" + sha256: "21e54fd2faf1b5bdd5102afd25012184a6793927648ea81eea80552ac9405b32" url: "https://pub.dev" source: hosted - version: "4.2.4" + version: "5.0.2" proj4dart: dependency: transitive description: @@ -1709,14 +1765,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.4" - pub_updater: - dependency: transitive - description: - name: pub_updater - sha256: "05ae70703e06f7fdeb05f7f02dd680b8aad810e87c756a618f33e1794635115c" - url: "https://pub.dev" - source: hosted - version: "0.3.0" pubspec_parse: dependency: transitive description: @@ -1757,14 +1805,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.1" - qr_flutter: - dependency: "direct main" - description: - name: qr_flutter - sha256: "5095f0fc6e3f71d08adef8feccc8cea4f12eec18a2e31c2e8d82cb6019f4b097" - url: "https://pub.dev" - source: hosted - version: "4.1.0" quiver: dependency: transitive description: @@ -1853,6 +1893,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.0.10" + retry: + dependency: transitive + description: + name: retry + sha256: "822e118d5b3aafed083109c72d5f484c6dc66707885e07c0fbcb8b986bba7efc" + url: "https://pub.dev" + source: hosted + version: "3.1.2" rxdart: dependency: transitive description: @@ -1861,6 +1909,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.27.7" + safe_url_check: + dependency: transitive + description: + name: safe_url_check + sha256: "49a3e060a7869cbafc8f4845ca1ecbbaaa53179980a32f4fdfeab1607e90f41d" + url: "https://pub.dev" + source: hosted + version: "1.1.2" scroll_to_index: dependency: "direct main" description: @@ -2003,7 +2059,7 @@ packages: source: hosted version: "1.10.0" sqflite: - dependency: "direct main" + dependency: transitive description: name: sqflite sha256: "591f1602816e9c31377d5f008c2d9ef7b8aca8941c3f89cc5fd9d84da0c38a9a" @@ -2022,18 +2078,18 @@ packages: dependency: "direct main" description: name: sqflite_common_ffi - sha256: d0e3f0d04fdf668e57db8db1df758f56c4193cb429092c708e7bfcc6ab04b27e + sha256: "35d2fce1e971707c227cc4775cc017d5eafe06c2654c3435ebd5c3ad6c170f5f" url: "https://pub.dev" source: hosted - version: "2.3.2" - sqflite_sqlcipher: + version: "2.3.0+4" + sqlcipher_flutter_libs: dependency: "direct main" description: - name: sqflite_sqlcipher - sha256: e1dfb55bf21ee5a18c43f28faa4291272a801da4ab34a6ba9973b6c0e1ed77da + name: sqlcipher_flutter_libs + sha256: "60fe3444ff5b1b298a9ca3003c6c7f1f7ee4c90aa6035a8647f3aeaf05a073e2" url: "https://pub.dev" source: hosted - version: "2.2.1" + version: "0.6.1" sqlite3: dependency: transitive description: @@ -2066,6 +2122,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.2.0" + string_validator: + dependency: transitive + description: + name: string_validator + sha256: "50dd8ecf91db6a732f4a851eeae81ee12406eedc62d0da72f2d91a04a2d10dd8" + url: "https://pub.dev" + source: hosted + version: "0.3.0" swipe_to_action: dependency: "direct main" description: @@ -2118,10 +2182,18 @@ packages: dependency: transitive description: name: synchronized - sha256: "539ef412b170d65ecdafd780f924e5be3f60032a1128df156adad6c5b373d558" + sha256: "5fcbd27688af6082f5abd611af56ee575342c30e87541d0245f7ff99faa02c60" url: "https://pub.dev" source: hosted - version: "3.1.0+1" + version: "3.1.0" + tar: + dependency: transitive + description: + name: tar + sha256: "85ffd53e277f2bac8afa2885e6b195e26937e9c402424c3d88d92fd920b56de9" + url: "https://pub.dev" + source: hosted + version: "0.5.6" term_glyph: dependency: transitive description: @@ -2438,10 +2510,10 @@ packages: dependency: transitive description: name: vm_service - sha256: c538be99af830f478718b51630ec1b6bee5e74e52c8a802d328d9e71d35d2583 + sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957 url: "https://pub.dev" source: hosted - version: "11.10.0" + version: "13.0.0" wakelock_platform_interface: dependency: transitive description: @@ -2487,18 +2559,18 @@ packages: dependency: transitive description: name: web - sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152 + sha256: edc8a9573dd8c5a83a183dae1af2b6fd4131377404706ca4e5420474784906fa url: "https://pub.dev" source: hosted - version: "0.3.0" + version: "0.4.0" webdriver: dependency: transitive description: name: webdriver - sha256: "3c923e918918feeb90c4c9fdf1fe39220fa4c0e8e2c0fffaded174498ef86c49" + sha256: "003d7da9519e1e5f329422b36c4dcdf18d7d2978d1ba099ea4e45ba490ed845e" url: "https://pub.dev" source: hosted - version: "3.0.2" + version: "3.0.3" webrtc_interface: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 4c9fde2eaf..54cf24972e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -5,29 +5,30 @@ description: Learn a language while texting your friends. # !!!!!! flutter version: 3.16.9 !!!!!! # Pangea# publish_to: none -version: 1.11.2+3453 +# On version bump also increase the build number for F-Droid +version: 1.19.2+3531 environment: sdk: ">=3.0.0 <4.0.0" dependencies: - adaptive_dialog: ^2.0.0 - animations: ^2.0.8 - archive: ^3.4.9 + adaptive_dialog: ^2.1.0 + animations: ^2.0.11 + archive: ^3.4.10 async: ^2.11.0 badges: ^3.1.2 blurhash_dart: ^1.2.1 callkeep: ^0.3.2 - chewie: ^1.7.1 - collection: ^1.17.2 + chewie: ^1.8.1 + collection: ^1.18.0 cupertino_icons: any # #Pangea # desktop_drop: ^0.4.4 # Pangea# desktop_notifications: ^0.6.3 - device_info_plus: ^9.1.0 - dynamic_color: ^1.6.8 - emoji_picker_flutter: ^1.6.3 + device_info_plus: ^10.0.1 + dynamic_color: ^1.7.0 + emoji_picker_flutter: ^2.1.1 emoji_proposal: ^0.0.1 emojis: ^0.9.9 #fcm_shared_isolate: ^0.1.0 @@ -35,104 +36,90 @@ dependencies: flutter: sdk: flutter flutter_app_badger: ^1.5.0 - flutter_blurhash: ^0.8.2 - flutter_cache_manager: ^3.3.0 - flutter_foreground_task: ^6.0.0+1 + flutter_cache_manager: ^3.3.1 + flutter_file_dialog: ^3.0.2 + flutter_foreground_task: ^6.1.3 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: ^16.1.0 + flutter_local_notifications: ^17.0.0 flutter_localizations: sdk: flutter - flutter_map: ^4.0.0 + flutter_map: ^6.1.0 flutter_math_fork: ^0.7.2 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.3.0 flutter_ringtone_player: ^4.0.0+2 flutter_secure_storage: ^9.0.0 - flutter_typeahead: ^4.8.0 + flutter_shortcuts: + git: https://github.com/krille-chan/flutter_shortcuts.git + flutter_typeahead: ^5.2.0 flutter_web_auth_2: ^3.1.1 flutter_webrtc: ^0.9.46 future_loading_dialog: ^0.3.0 geolocator: ^7.6.2 - go_router: ^12.1.1 + go_router: ^13.2.2 hive: ^2.2.3 hive_flutter: ^1.1.0 html: ^0.15.4 - http: ^0.13.6 - image_picker: ^1.0.0 + http: ^1.2.0 + image: ^4.1.7 + image_picker: ^1.0.7 intl: any - # #Pangea - # just_audio: ^0.9.0 - just_audio: ^0.9.36 - # Pangea# + just_audio: ^0.9.37 keyboard_shortcuts: ^0.1.4 - latlong2: ^0.8.1 + latlong2: ^0.9.1 linkify: ^5.0.0 - # #Pangea - # matrix: ^0.25.7 - matrix: ^0.25.11 - # until https://github.com/famedly/matrix-dart-sdk/pull/1712 - # Pangea# + matrix: ^0.26.1 native_imaging: ^0.1.0 - package_info_plus: ^4.0.0 + package_info_plus: ^6.0.0 pasteboard: ^0.2.0 - path_provider: ^2.0.9 + path: ^1.9.0 + path_provider: ^2.1.2 permission_handler: ^11.0.1 + pretty_qr_code: ^3.2.1 provider: ^6.0.2 punycode: ^1.0.0 - qr_code_scanner: ^1.0.0 - qr_flutter: ^4.0.0 + qr_code_scanner: ^1.0.1 receive_sharing_intent: ^1.4.5 - # #Pangea - # record: 4.4.4 # Upgrade to 5 currently breaks playing on iOS - record: ^5.0.4 - # Pangea# + record: 4.4.4 # Upgrade to 5 currently breaks playing on iOS scroll_to_index: ^3.0.1 - share_plus: ^7.2.1 + share_plus: ^8.0.2 shared_preferences: ^2.2.0 # Pinned because https://github.com/flutter/flutter/issues/118401 slugify: ^2.0.0 - sqflite: ^2.3.0 - sqflite_common_ffi: ^2.3.0+4 - sqflite_sqlcipher: ^2.2.1 + sqflite_common_ffi: ^2.3.3 + sqlcipher_flutter_libs: ^0.6.1 swipe_to_action: ^0.2.0 tor_detector_web: ^1.1.0 uni_links: ^0.5.1 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.8.1 - wakelock_plus: ^1.1.3 + url_launcher: ^6.2.5 + video_compress: ^3.1.2 + video_player: ^2.8.5 + wakelock_plus: ^1.2.2 webrtc_interface: ^1.0.13 # #Pangea - connectivity_plus: ^3.0.2 - country_picker: ^2.0.20 - csv: ^5.0.2 - desktop_lifecycle: ^0.1.0 - fl_chart: ^0.61.0 - firebase_analytics: ^10.2.1 - firebase_core: ^2.10.0 - firebase_messaging: ^14.4.1 - flutter_app_lock: ^3.0.0 - flutter_dotenv: ^5.0.2 + country_picker: ^2.0.25 + csv: ^6.0.0 + fl_chart: ^0.67.0 + firebase_analytics: ^10.10.2 + firebase_core: ^2.30.0 + firebase_messaging: ^14.8.2 + flutter_dotenv: ^5.1.0 fcm_shared_isolate: path: pangea_packages/fcm_shared_isolate - flutter_svg: ^2.0.0+1 + flutter_svg: ^2.0.10+1 get_storage: ^2.1.1 - in_app_purchase: ^3.1.5 + in_app_purchase: ^3.1.13 jwt_decode: ^0.3.1 - language_tool: ^2.1.1 - matrix_homeserver_recommendations: ^0.3.0 - new_version_plus: ^0.0.10 + language_tool: ^2.2.0 open_file: ^3.3.2 - purchases_flutter: ^5.6.0 - sentry_flutter: ^7.4.0 + purchases_flutter: ^6.26.0 + sentry_flutter: ^7.19.0 shimmer: ^3.0.0 - syncfusion_flutter_datepicker: ^23.2.7 - syncfusion_flutter_xlsio: ^23.2.7 + syncfusion_flutter_xlsio: ^25.1.40 # Pangea# dev_dependencies: @@ -143,6 +130,7 @@ dev_dependencies: import_sorter: ^4.6.0 integration_test: sdk: flutter + license_checker: ^1.6.0 msix: ^3.6.2 translations_cleaner: ^0.0.5 @@ -220,11 +208,4 @@ dependency_overrides: keyboard_shortcuts: git: url: https://github.com/TheOneWithTheBraid/keyboard_shortcuts.git - ref: null-safety - # blocked upgrade of package_info_plus for null safety - # https://github.com/creativecreatorormaybenot/wakelock/pull/203 - wakelock_windows: - git: - url: https://github.com/chandrabezzo/wakelock.git - ref: main - path: wakelock_windows/ + ref: null-safety \ No newline at end of file diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml new file mode 100644 index 0000000000..86b7eb2411 --- /dev/null +++ b/snap/snapcraft.yaml @@ -0,0 +1,112 @@ +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 + - libssl-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/web/index.html b/web/index.html index 4e6f28e708..59ba23f0e1 100644 --- a/web/index.html +++ b/web/index.html @@ -19,7 +19,10 @@ - + + + + @@ -62,7 +65,7 @@ serviceWorkerVersion: serviceWorkerVersion, }, onEntrypointLoaded: function (engineInitializer) { - engineInitializer.initializeEngine().then(function (appRunner) { + engineInitializer.initializeEngine({ useColorEmoji: true }).then(function (appRunner) { appRunner.runApp(); }); } diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index 2e0327735e..83c63ff603 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -49,6 +50,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) { registry->GetRegistrarForPlugin("SentryFlutterPlugin")); SharePlusWindowsPluginCApiRegisterWithRegistrar( registry->GetRegistrarForPlugin("SharePlusWindowsPluginCApi")); + Sqlite3FlutterLibsPluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("Sqlite3FlutterLibsPlugin")); UrlLauncherWindowsRegisterWithRegistrar( registry->GetRegistrarForPlugin("UrlLauncherWindows")); WindowToFrontPluginRegisterWithRegistrar( diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index 98f992b447..e4a58181ec 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -16,6 +16,7 @@ list(APPEND FLUTTER_PLUGIN_LIST record_windows sentry_flutter share_plus + sqlcipher_flutter_libs url_launcher_windows window_to_front )