merge inn fluffychat changes
This commit is contained in:
commit
33b5de0afb
87 changed files with 65795 additions and 37064 deletions
2
.github/ISSUE_TEMPLATE/test_report.md
vendored
2
.github/ISSUE_TEMPLATE/test_report.md
vendored
|
|
@ -2,7 +2,7 @@
|
|||
name: 📝 Test
|
||||
about: A detailed protocol for testing all features
|
||||
title: 'Test Report'
|
||||
label: test
|
||||
labels: test
|
||||
---
|
||||
|
||||
1. App receives push notifications over Firebase Cloud Messaging when it is in background/terminated:
|
||||
|
|
|
|||
4
.github/workflows/main_deploy.yaml
vendored
4
.github/workflows/main_deploy.yaml
vendored
|
|
@ -60,6 +60,10 @@ jobs:
|
|||
run: gem install fastlane -NV
|
||||
- name: Apply Google Services Patch
|
||||
run: git apply ./scripts/enable-android-google-services.patch
|
||||
- name: Remove Emoji Font
|
||||
run: |
|
||||
rm -rf fonts/NotoEmoji
|
||||
yq -i 'del( .flutter.fonts[] | select(.family == "NotoEmoji") )' pubspec.yaml
|
||||
- run: flutter pub get
|
||||
- name: Prepare Android Release Build
|
||||
env:
|
||||
|
|
|
|||
28
.github/workflows/process_tags.yaml
vendored
Normal file
28
.github/workflows/process_tags.yaml
vendored
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
on:
|
||||
push:
|
||||
tags:
|
||||
- "v*"
|
||||
- "rc*"
|
||||
|
||||
name: Process Tags
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Create Release
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Get Changelog Entry
|
||||
id: changelog_reader
|
||||
uses: mindsers/changelog-reader-action@v2
|
||||
- name: Create Release
|
||||
id: create_release
|
||||
uses: actions/create-release@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
tag_name: ${{ github.ref }}
|
||||
release_name: Release ${{ github.ref }}
|
||||
body: ${{ steps.changelog_reader.outputs.changes }}
|
||||
draft: false
|
||||
prerelease: ${{ startsWith(github.ref, 'rc') }}
|
||||
8
.github/workflows/release.yaml
vendored
8
.github/workflows/release.yaml
vendored
|
|
@ -57,6 +57,10 @@ jobs:
|
|||
cache: true
|
||||
- name: Apply Google Services Patch
|
||||
run: git apply ./scripts/enable-android-google-services.patch
|
||||
- name: Remove Emoji Font
|
||||
run: |
|
||||
rm -rf fonts/NotoEmoji
|
||||
yq -i 'del( .flutter.fonts[] | select(.family == "NotoEmoji") )' pubspec.yaml
|
||||
- run: flutter pub get
|
||||
- name: Prepare Android Release Build
|
||||
env:
|
||||
|
|
@ -120,6 +124,10 @@ jobs:
|
|||
run: gem install fastlane -NV
|
||||
- name: Apply Google Services Patch
|
||||
run: git apply ./scripts/enable-android-google-services.patch
|
||||
- name: Remove Emoji Font
|
||||
run: |
|
||||
rm -rf fonts/NotoEmoji
|
||||
yq -i 'del( .flutter.fonts[] | select(.family == "NotoEmoji") )' pubspec.yaml
|
||||
- run: flutter pub get
|
||||
- name: Prepare Android Release Build
|
||||
env:
|
||||
|
|
|
|||
2
.github/workflows/versions.env
vendored
2
.github/workflows/versions.env
vendored
|
|
@ -1,2 +1,2 @@
|
|||
FLUTTER_VERSION=3.13.9
|
||||
FLUTTER_VERSION=3.16.0
|
||||
JAVA_VERSION=17
|
||||
25
CHANGELOG.md
25
CHANGELOG.md
|
|
@ -1,3 +1,28 @@
|
|||
## v1.15.1
|
||||
- feat: Make all text in chat selectable on desktop (krille-chan)
|
||||
- chore: Add border to images in timeline (krille-chan)
|
||||
- chore: added android audio sharing intent (Aryan Arora)
|
||||
- fix: Dockerfile: install jq in the builder image (David Douard)
|
||||
- fix: Cannot pin messages of other users (Krille)
|
||||
- fix: Emojipicker flickering because noRecent (krille-chan)
|
||||
- fix: LoadProfileBottomSheet accessing disposed outerContext (Aryan Arora)
|
||||
- fix: More stable scroll up to event (krille-chan)
|
||||
- fix: Properly capitalize Linux window title (kramo)
|
||||
- fix: Remove failed to sent events (krille-chan)
|
||||
- fix: Routing glitch when using SSO on desktop (krille-chan)
|
||||
- fix: SSO with no identity providers (krille-chan)
|
||||
- refactor: Do not init client in background mode on Android (krille-chan)
|
||||
- refactor: Store and fix missing persistence of some values (krille-chan)
|
||||
- Translated using Weblate (Arabic) (Rex_sa)
|
||||
- Translated using Weblate (Basque) (xabirequejo)
|
||||
- Translated using Weblate (Chinese (Simplified)) (Eric)
|
||||
- Translated using Weblate (Czech) (Vojtěch Fošnár)
|
||||
- Translated using Weblate (Dutch) (Jelv)
|
||||
- Translated using Weblate (Estonian) (Priit Jõerüüt)
|
||||
- Translated using Weblate (Finnish) (Aminda Suomalainen)
|
||||
- Translated using Weblate (German) (Haui)
|
||||
- Translated using Weblate (Ukrainian) (Ihor Hordiichuk)
|
||||
|
||||
## v1.15.0
|
||||
- feat: Add experimental todo list for rooms (krille-chan)
|
||||
- feat: better scroll to last read message handling (krille-chan)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
FROM ghcr.io/cirruslabs/flutter as builder
|
||||
RUN sudo apt update && sudo apt install curl -y
|
||||
RUN sudo apt update && sudo apt install curl jq -y
|
||||
COPY . /app
|
||||
WORKDIR /app
|
||||
RUN ./scripts/prepare-web.sh
|
||||
|
|
@ -8,4 +8,4 @@ RUN flutter build web --dart-define=FLUTTER_WEB_CANVASKIT_URL=canvaskit/ --relea
|
|||
|
||||
FROM docker.io/nginx:alpine
|
||||
RUN rm -rf /usr/share/nginx/html
|
||||
COPY --from=builder /app/build/web /usr/share/nginx/html
|
||||
COPY --from=builder /app/build/web /usr/share/nginx/html
|
||||
|
|
|
|||
|
|
@ -66,4 +66,4 @@ Please visit the [Wiki](https://github.com/krille-chan/fluffychat/wiki) for buil
|
|||
|
||||
* <a href="https://github.com/madsrh/WoodenBeaver">WoodenBeaver</a> sound theme for the notification sound.
|
||||
|
||||
* The Matrix Foundation for making and maintaining the [emoji translations](https://github.com/matrix-org/matrix-doc/blob/main/data-definitions/sas-emoji.json) used for emoji verification, licensed Apache 2.0
|
||||
* The Matrix Foundation for making and maintaining the [emoji translations](https://github.com/matrix-org/matrix-spec/blob/main/data-definitions/sas-emoji.json) used for emoji verification, licensed Apache 2.0
|
||||
|
|
|
|||
|
|
@ -73,6 +73,13 @@ android {
|
|||
signingConfig signingConfigs.release
|
||||
}
|
||||
}
|
||||
// https://stackoverflow.com/a/77494454/8222484
|
||||
packagingOptions {
|
||||
pickFirst 'lib/x86/libc++_shared.so'
|
||||
pickFirst 'lib/x86_64/libc++_shared.so'
|
||||
pickFirst 'lib/armeabi-v7a/libc++_shared.so'
|
||||
pickFirst 'lib/arm64-v8a/libc++_shared.so'
|
||||
}
|
||||
}
|
||||
|
||||
flutter {
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -2343,7 +2343,7 @@
|
|||
"@notAnImage": {},
|
||||
"importNow": "Importovat nyní",
|
||||
"@importNow": {},
|
||||
"redactedByBecause": "Redigováno uživatelem {username} s důvodem: \"{reason}\"",
|
||||
"redactedByBecause": "Smazáno uživatelem {username} s důvodem: \"{reason}\"",
|
||||
"@redactedByBecause": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
|
|
@ -2415,7 +2415,7 @@
|
|||
"@jumpToLastReadMessage": {},
|
||||
"signInWithPassword": "Přihlásit se pomocí hesla",
|
||||
"@signInWithPassword": {},
|
||||
"redactedBy": "Redigováno uživatelem {username}",
|
||||
"redactedBy": "Smazáno uživatelem {username}",
|
||||
"@redactedBy": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
|
|
@ -2432,9 +2432,9 @@
|
|||
"@noOneCanJoin": {},
|
||||
"tryAgain": "Zkuste to znovu",
|
||||
"@tryAgain": {},
|
||||
"redactMessageDescription": "Tato zpráva bude skryta pro všechny účastníky konverzace. Tuto akci nelze vzít zpět.",
|
||||
"redactMessageDescription": "Tato zpráva bude smazána pro všechny účastníky konverzace. Tuto akci nelze vzít zpět.",
|
||||
"@redactMessageDescription": {},
|
||||
"optionalRedactReason": "(Nepovinné) Důvod redakce této zprávy…",
|
||||
"optionalRedactReason": "(Nepovinné) Důvod smazání této zprávy…",
|
||||
"@optionalRedactReason": {},
|
||||
"messagesStyle": "Zprávy:",
|
||||
"@messagesStyle": {},
|
||||
|
|
@ -2566,5 +2566,96 @@
|
|||
}
|
||||
},
|
||||
"requests": "Žádosti",
|
||||
"@requests": {}
|
||||
"@requests": {},
|
||||
"reportErrorDescription": "",
|
||||
"@reportErrorDescription": {},
|
||||
"banUserDescription": "",
|
||||
"@banUserDescription": {},
|
||||
"removeDevicesDescription": "",
|
||||
"@removeDevicesDescription": {},
|
||||
"unbanUserDescription": "",
|
||||
"@unbanUserDescription": {},
|
||||
"todoLists": "",
|
||||
"@todoLists": {},
|
||||
"editTodo": "",
|
||||
"@editTodo": {},
|
||||
"pushNotificationsNotAvailable": "",
|
||||
"@pushNotificationsNotAvailable": {},
|
||||
"pleaseAddATitle": "",
|
||||
"@pleaseAddATitle": {},
|
||||
"makeAdminDescription": "",
|
||||
"@makeAdminDescription": {},
|
||||
"noTodosYet": "",
|
||||
"@noTodosYet": {},
|
||||
"archiveRoomDescription": "",
|
||||
"@archiveRoomDescription": {},
|
||||
"savedEmotePack": "",
|
||||
"@savedEmotePack": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"path": {}
|
||||
}
|
||||
},
|
||||
"invalidInput": "",
|
||||
"@invalidInput": {},
|
||||
"todosUnencrypted": "",
|
||||
"@todosUnencrypted": {},
|
||||
"report": "",
|
||||
"@report": {},
|
||||
"hasKnocked": "",
|
||||
"@hasKnocked": {
|
||||
"placeholders": {
|
||||
"user": {}
|
||||
}
|
||||
},
|
||||
"wrongPinEntered": "",
|
||||
"@wrongPinEntered": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"seconds": {}
|
||||
}
|
||||
},
|
||||
"inviteGroupChat": "",
|
||||
"@inviteGroupChat": {},
|
||||
"invitePrivateChat": "",
|
||||
"@invitePrivateChat": {},
|
||||
"newTodo": "",
|
||||
"@newTodo": {},
|
||||
"learnMore": "",
|
||||
"@learnMore": {},
|
||||
"todoListChangedError": "",
|
||||
"@todoListChangedError": {},
|
||||
"roomUpgradeDescription": "",
|
||||
"@roomUpgradeDescription": {},
|
||||
"pleaseEnterANumber": "",
|
||||
"@pleaseEnterANumber": {},
|
||||
"emoteKeyboardNoRecents": "",
|
||||
"@emoteKeyboardNoRecents": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"kickUserDescription": "",
|
||||
"@kickUserDescription": {},
|
||||
"invite": "",
|
||||
"@invite": {},
|
||||
"indexedDbErrorLong": "",
|
||||
"@indexedDbErrorLong": {},
|
||||
"callingAccount": "",
|
||||
"@callingAccount": {},
|
||||
"enterSpace": "",
|
||||
"@enterSpace": {},
|
||||
"noKeyForThisMessage": "",
|
||||
"@noKeyForThisMessage": {},
|
||||
"readUpToHere": "",
|
||||
"@readUpToHere": {},
|
||||
"appearOnTopDetails": "",
|
||||
"@appearOnTopDetails": {},
|
||||
"enterRoom": "",
|
||||
"@enterRoom": {},
|
||||
"hideUnimportantStateEvents": "",
|
||||
"@hideUnimportantStateEvents": {},
|
||||
"noBackupWarning": "",
|
||||
"@noBackupWarning": {},
|
||||
"indexedDbErrorTitle": "",
|
||||
"@indexedDbErrorTitle": {}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -3925,5 +3925,17 @@
|
|||
"todoListChangedError": "Oops... The todo list has been changed while you edited it.",
|
||||
"todosUnencrypted": "Please notice that todos are visible by everyone in the chat and are not end to end encrypted.",
|
||||
"noAddToSpacePermissions": "You can't add a chat to this space",
|
||||
"alreadyInSpace": "The chat is already in this space"
|
||||
"alreadyInSpace": "The chat is already in this space",
|
||||
"yourGlobalUserIdIs": "Your global user-ID is: ",
|
||||
"noUsersFoundWithQuery": "Unfortunately no user could be found with \"{query}\". Please check whether you made a typo.",
|
||||
"@noUsersFoundWithQuery": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"query": {}
|
||||
}
|
||||
},
|
||||
"searchChatsRooms": "Search for #chats, @users...",
|
||||
"groupName": "Group name",
|
||||
"createGroupAndInviteUsers": "Create a group and invite users",
|
||||
"groupCanBeFoundViaSearch": "Group can be found via search"
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -3618,11 +3618,358 @@
|
|||
"placeholders": {}
|
||||
},
|
||||
"commandHint_create": "Crear un chat grupal vacío\nUse --no-encryption para deshabilitar el cifrado",
|
||||
"replace": "Reemplazar",
|
||||
"@replace": {},
|
||||
"unsupportedAndroidVersionLong": "",
|
||||
"@unsupportedAndroidVersionLong": {},
|
||||
"storeSecurlyOnThisDevice": "",
|
||||
"@storeSecurlyOnThisDevice": {},
|
||||
"iUnderstand": "",
|
||||
"@iUnderstand": {},
|
||||
"encryptThisChat": "",
|
||||
"@encryptThisChat": {},
|
||||
"letsStart": "",
|
||||
"@letsStart": {},
|
||||
"endToEndEncryption": "",
|
||||
"@endToEndEncryption": {},
|
||||
"openChat": "",
|
||||
"@openChat": {},
|
||||
"screenSharingDetail": "",
|
||||
"@screenSharingDetail": {},
|
||||
"jumpToLastReadMessage": "",
|
||||
"@jumpToLastReadMessage": {},
|
||||
"allRooms": "",
|
||||
"@allRooms": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"widgetVideo": "",
|
||||
"@widgetVideo": {},
|
||||
"dismiss": "",
|
||||
"@dismiss": {},
|
||||
"reportErrorDescription": "",
|
||||
"@reportErrorDescription": {},
|
||||
"unsupportedAndroidVersion": "",
|
||||
"@unsupportedAndroidVersion": {},
|
||||
"noEmailWarning": "",
|
||||
"@noEmailWarning": {},
|
||||
"indexedDbErrorLong": "",
|
||||
"@indexedDbErrorLong": {},
|
||||
"startFirstChat": "",
|
||||
"@startFirstChat": {},
|
||||
"callingAccount": "",
|
||||
"@callingAccount": {},
|
||||
"setColorTheme": "",
|
||||
"@setColorTheme": {},
|
||||
"commandHint_create": "",
|
||||
"@commandHint_create": {
|
||||
"type": "text",
|
||||
"description": "Usage hint for the command /create"
|
||||
},
|
||||
"commandHint_dm": "Empezar un chat privado\nUse --no-encryption para deshabilitar el cifrado",
|
||||
"user": "",
|
||||
"@user": {},
|
||||
"banUserDescription": "",
|
||||
"@banUserDescription": {},
|
||||
"requests": "",
|
||||
"@requests": {},
|
||||
"addToStory": "",
|
||||
"@addToStory": {},
|
||||
"removeDevicesDescription": "",
|
||||
"@removeDevicesDescription": {},
|
||||
"separateChatTypes": "",
|
||||
"@separateChatTypes": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"tryAgain": "",
|
||||
"@tryAgain": {},
|
||||
"youKickedAndBanned": "",
|
||||
"@youKickedAndBanned": {
|
||||
"placeholders": {
|
||||
"user": {}
|
||||
}
|
||||
},
|
||||
"showDirectChatsInSpaces": "",
|
||||
"@showDirectChatsInSpaces": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"unbanUserDescription": "",
|
||||
"@unbanUserDescription": {},
|
||||
"todoLists": "",
|
||||
"@todoLists": {},
|
||||
"messagesStyle": "",
|
||||
"@messagesStyle": {},
|
||||
"newSpaceDescription": "",
|
||||
"@newSpaceDescription": {},
|
||||
"chatDescription": "",
|
||||
"@chatDescription": {},
|
||||
"callingAccountDetails": "",
|
||||
"@callingAccountDetails": {},
|
||||
"enterSpace": "",
|
||||
"@enterSpace": {},
|
||||
"reopenChat": "",
|
||||
"@reopenChat": {},
|
||||
"pleaseEnterRecoveryKey": "",
|
||||
"@pleaseEnterRecoveryKey": {},
|
||||
"widgetNameError": "",
|
||||
"@widgetNameError": {},
|
||||
"addWidget": "",
|
||||
"@addWidget": {},
|
||||
"noKeyForThisMessage": "",
|
||||
"@noKeyForThisMessage": {},
|
||||
"editTodo": "",
|
||||
"@editTodo": {},
|
||||
"hydrateTor": "",
|
||||
"@hydrateTor": {},
|
||||
"pushNotificationsNotAvailable": "",
|
||||
"@pushNotificationsNotAvailable": {},
|
||||
"storeInAppleKeyChain": "",
|
||||
"@storeInAppleKeyChain": {},
|
||||
"hydrate": "",
|
||||
"@hydrate": {},
|
||||
"invalidServerName": "",
|
||||
"@invalidServerName": {},
|
||||
"chatPermissions": "",
|
||||
"@chatPermissions": {},
|
||||
"sender": "",
|
||||
"@sender": {},
|
||||
"storeInAndroidKeystore": "",
|
||||
"@storeInAndroidKeystore": {},
|
||||
"signInWithPassword": "",
|
||||
"@signInWithPassword": {},
|
||||
"pleaseAddATitle": "",
|
||||
"@pleaseAddATitle": {},
|
||||
"makeAdminDescription": "",
|
||||
"@makeAdminDescription": {},
|
||||
"saveKeyManuallyDescription": "",
|
||||
"@saveKeyManuallyDescription": {},
|
||||
"whyIsThisMessageEncrypted": "",
|
||||
"@whyIsThisMessageEncrypted": {},
|
||||
"setChatDescription": "",
|
||||
"@setChatDescription": {},
|
||||
"dehydrateWarning": "",
|
||||
"@dehydrateWarning": {},
|
||||
"noOtherDevicesFound": "",
|
||||
"@noOtherDevicesFound": {},
|
||||
"redactedBy": "",
|
||||
"@redactedBy": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"username": {}
|
||||
}
|
||||
},
|
||||
"videoCallsBetaWarning": "",
|
||||
"@videoCallsBetaWarning": {},
|
||||
"storyPrivacyWarning": "",
|
||||
"@storyPrivacyWarning": {},
|
||||
"matrixWidgets": "",
|
||||
"@matrixWidgets": {},
|
||||
"signInWith": "",
|
||||
"@signInWith": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"provider": {}
|
||||
}
|
||||
},
|
||||
"fileIsTooBigForServer": "",
|
||||
"@fileIsTooBigForServer": {},
|
||||
"noTodosYet": "",
|
||||
"@noTodosYet": {},
|
||||
"callingPermissions": "",
|
||||
"@callingPermissions": {},
|
||||
"readUpToHere": "",
|
||||
"@readUpToHere": {},
|
||||
"unlockOldMessages": "",
|
||||
"@unlockOldMessages": {},
|
||||
"numChats": "",
|
||||
"@numChats": {
|
||||
"type": "number",
|
||||
"placeholders": {
|
||||
"number": {}
|
||||
}
|
||||
},
|
||||
"optionalRedactReason": "",
|
||||
"@optionalRedactReason": {},
|
||||
"dehydrate": "",
|
||||
"@dehydrate": {},
|
||||
"archiveRoomDescription": "",
|
||||
"@archiveRoomDescription": {},
|
||||
"switchToAccount": "",
|
||||
"@switchToAccount": {
|
||||
"type": "number",
|
||||
"placeholders": {
|
||||
"number": {}
|
||||
}
|
||||
},
|
||||
"experimentalVideoCalls": "",
|
||||
"@experimentalVideoCalls": {},
|
||||
"pleaseEnterRecoveryKeyDescription": "",
|
||||
"@pleaseEnterRecoveryKeyDescription": {},
|
||||
"inviteContactToGroupQuestion": "",
|
||||
"@inviteContactToGroupQuestion": {},
|
||||
"redactedByBecause": "",
|
||||
"@redactedByBecause": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"username": {},
|
||||
"reason": {}
|
||||
}
|
||||
},
|
||||
"youHaveWithdrawnTheInvitationFor": "",
|
||||
"@youHaveWithdrawnTheInvitationFor": {
|
||||
"placeholders": {
|
||||
"user": {}
|
||||
}
|
||||
},
|
||||
"appearOnTopDetails": "",
|
||||
"@appearOnTopDetails": {},
|
||||
"enterRoom": "",
|
||||
"@enterRoom": {},
|
||||
"confirmEventUnpin": "",
|
||||
"@confirmEventUnpin": {},
|
||||
"youInvitedUser": "",
|
||||
"@youInvitedUser": {
|
||||
"placeholders": {
|
||||
"user": {}
|
||||
}
|
||||
},
|
||||
"fileHasBeenSavedAt": "",
|
||||
"@fileHasBeenSavedAt": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"path": {}
|
||||
}
|
||||
},
|
||||
"anyoneCanKnock": "",
|
||||
"@anyoneCanKnock": {},
|
||||
"redactMessageDescription": "",
|
||||
"@redactMessageDescription": {},
|
||||
"recoveryKey": "",
|
||||
"@recoveryKey": {},
|
||||
"invalidInput": "",
|
||||
"@invalidInput": {},
|
||||
"todosUnencrypted": "",
|
||||
"@todosUnencrypted": {},
|
||||
"dehydrateTorLong": "",
|
||||
"@dehydrateTorLong": {},
|
||||
"doNotShowAgain": "",
|
||||
"@doNotShowAgain": {},
|
||||
"report": "",
|
||||
"@report": {},
|
||||
"hideUnimportantStateEvents": "",
|
||||
"@hideUnimportantStateEvents": {},
|
||||
"screenSharingTitle": "",
|
||||
"@screenSharingTitle": {},
|
||||
"widgetCustom": "",
|
||||
"@widgetCustom": {},
|
||||
"whoCanSeeMyStoriesDesc": "",
|
||||
"@whoCanSeeMyStoriesDesc": {},
|
||||
"youBannedUser": "",
|
||||
"@youBannedUser": {
|
||||
"placeholders": {
|
||||
"user": {}
|
||||
}
|
||||
},
|
||||
"unsubscribeStories": "",
|
||||
"@unsubscribeStories": {},
|
||||
"hasKnocked": "",
|
||||
"@hasKnocked": {
|
||||
"placeholders": {
|
||||
"user": {}
|
||||
}
|
||||
},
|
||||
"openLinkInBrowser": "",
|
||||
"@openLinkInBrowser": {},
|
||||
"disableEncryptionWarning": "",
|
||||
"@disableEncryptionWarning": {},
|
||||
"directChat": "",
|
||||
"@directChat": {},
|
||||
"noOneCanJoin": "",
|
||||
"@noOneCanJoin": {},
|
||||
"wrongPinEntered": "",
|
||||
"@wrongPinEntered": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"seconds": {}
|
||||
}
|
||||
},
|
||||
"inviteGroupChat": "",
|
||||
"@inviteGroupChat": {},
|
||||
"appearOnTop": "",
|
||||
"@appearOnTop": {},
|
||||
"invitePrivateChat": "",
|
||||
"@invitePrivateChat": {},
|
||||
"foregroundServiceRunning": "",
|
||||
"@foregroundServiceRunning": {},
|
||||
"wasDirectChatDisplayName": "",
|
||||
"@wasDirectChatDisplayName": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"oldDisplayName": {}
|
||||
}
|
||||
},
|
||||
"noChatDescriptionYet": "",
|
||||
"@noChatDescriptionYet": {},
|
||||
"newTodo": "",
|
||||
"@newTodo": {},
|
||||
"learnMore": "",
|
||||
"@learnMore": {},
|
||||
"chatDescriptionHasBeenChanged": "",
|
||||
"@chatDescriptionHasBeenChanged": {},
|
||||
"dehydrateTor": "",
|
||||
"@dehydrateTor": {},
|
||||
"todoListChangedError": "",
|
||||
"@todoListChangedError": {},
|
||||
"enterInviteLinkOrMatrixId": "",
|
||||
"@enterInviteLinkOrMatrixId": {},
|
||||
"roomUpgradeDescription": "",
|
||||
"@roomUpgradeDescription": {},
|
||||
"pleaseEnterANumber": "",
|
||||
"@pleaseEnterANumber": {},
|
||||
"youKicked": "",
|
||||
"@youKicked": {
|
||||
"placeholders": {
|
||||
"user": {}
|
||||
}
|
||||
},
|
||||
"profileNotFound": "",
|
||||
"@profileNotFound": {},
|
||||
"jump": "",
|
||||
"@jump": {},
|
||||
"sorryThatsNotPossible": "",
|
||||
"@sorryThatsNotPossible": {},
|
||||
"storyFrom": "",
|
||||
"@storyFrom": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"date": {},
|
||||
"body": {}
|
||||
}
|
||||
},
|
||||
"shareInviteLink": "",
|
||||
"@shareInviteLink": {},
|
||||
"commandHint_markasdm": "",
|
||||
"@commandHint_markasdm": {},
|
||||
"recoveryKeyLost": "",
|
||||
"@recoveryKeyLost": {},
|
||||
"deviceKeys": "",
|
||||
"@deviceKeys": {},
|
||||
"emoteKeyboardNoRecents": "",
|
||||
"@emoteKeyboardNoRecents": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"setTheme": "",
|
||||
"@setTheme": {},
|
||||
"youJoinedTheChat": "",
|
||||
"@youJoinedTheChat": {},
|
||||
"thisUserHasNotPostedAnythingYet": "",
|
||||
"@thisUserHasNotPostedAnythingYet": {},
|
||||
"errorAddingWidget": "",
|
||||
"@errorAddingWidget": {},
|
||||
"commandHint_dm": "",
|
||||
"@commandHint_dm": {
|
||||
"type": "text",
|
||||
"description": "Usage hint for the command /dm"
|
||||
|
|
@ -4262,5 +4609,55 @@
|
|||
"why": "¿Por qué?",
|
||||
"definition": "Definición",
|
||||
"exampleSentence": "Ejemplo de frase",
|
||||
"addToClassTitle": "Añadir intercambio a la clase"
|
||||
"addToClassTitle": "Añadir intercambio a la clase",
|
||||
"youUnbannedUser": "",
|
||||
"@youUnbannedUser": {
|
||||
"placeholders": {
|
||||
"user": {}
|
||||
}
|
||||
},
|
||||
"emojis": "",
|
||||
"@emojis": {},
|
||||
"pleaseTryAgainLaterOrChooseDifferentServer": "",
|
||||
"@pleaseTryAgainLaterOrChooseDifferentServer": {},
|
||||
"createGroup": "",
|
||||
"@createGroup": {},
|
||||
"hydrateTorLong": "",
|
||||
"@hydrateTorLong": {},
|
||||
"custom": "",
|
||||
"@custom": {},
|
||||
"noBackupWarning": "",
|
||||
"@noBackupWarning": {},
|
||||
"editWidgets": "",
|
||||
"@editWidgets": {},
|
||||
"storeInSecureStorageDescription": "",
|
||||
"@storeInSecureStorageDescription": {},
|
||||
"kickUserDescription": "",
|
||||
"@kickUserDescription": {},
|
||||
"pinMessage": "",
|
||||
"@pinMessage": {},
|
||||
"invite": "",
|
||||
"@invite": {},
|
||||
"continueWith": "",
|
||||
"@continueWith": {},
|
||||
"indexedDbErrorTitle": "",
|
||||
"@indexedDbErrorTitle": {},
|
||||
"googlyEyesContent": "",
|
||||
"@googlyEyesContent": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"senderName": {}
|
||||
}
|
||||
},
|
||||
"cuddleContent": "",
|
||||
"@cuddleContent": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"senderName": {}
|
||||
}
|
||||
},
|
||||
"commandHint_googly": "",
|
||||
"@commandHint_googly": {},
|
||||
"placeCall": "",
|
||||
"@placeCall": {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -746,7 +746,7 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"noGoogleServicesWarning": "Dirudienez Firebase Cloud Messaging ez dago erabilgarri zure mugikorrean. Jakinarazpenak jasotzeko MicroG edo Unified Push instalatzea gomendatzen dugu.",
|
||||
"noGoogleServicesWarning": "Ez dirudi Firebase Cloud Messaging zure mugikorrean erabilgarri dagoenik. Jakinarazpenak jasotzeko ntfy instalatzea gomendatzen dugu. ntfy edo beste Unified Push hornitzaileren batekin, push jakinarazpenak jaso ditzazkezu datuentzako segurua den modu batean. ntfy PlayStore edo F-Droid dendetatik deskarga dezakezu.",
|
||||
"@noGoogleServicesWarning": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
|
|
@ -2504,7 +2504,7 @@
|
|||
"@continueWith": {},
|
||||
"pleaseTryAgainLaterOrChooseDifferentServer": "Saiatu geroago edo aukeratu beste zerbitzari bat.",
|
||||
"@pleaseTryAgainLaterOrChooseDifferentServer": {},
|
||||
"signInWith": "Hasi saioa {provider}(e)kin",
|
||||
"signInWith": "Hasi saioa {provider}(r)ekin",
|
||||
"@signInWith": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
|
|
|
|||
|
|
@ -2502,5 +2502,152 @@
|
|||
"continueWith": "ادامه دادن با:",
|
||||
"@continueWith": {},
|
||||
"pleaseTryAgainLaterOrChooseDifferentServer": "لطفا بعدا تلاش کنید یا سرور دیگری انتخاب کنید.",
|
||||
"@pleaseTryAgainLaterOrChooseDifferentServer": {}
|
||||
"@pleaseTryAgainLaterOrChooseDifferentServer": {},
|
||||
"setColorTheme": "",
|
||||
"@setColorTheme": {},
|
||||
"banUserDescription": "",
|
||||
"@banUserDescription": {},
|
||||
"requests": "",
|
||||
"@requests": {},
|
||||
"removeDevicesDescription": "",
|
||||
"@removeDevicesDescription": {},
|
||||
"tryAgain": "",
|
||||
"@tryAgain": {},
|
||||
"unbanUserDescription": "",
|
||||
"@unbanUserDescription": {},
|
||||
"todoLists": "",
|
||||
"@todoLists": {},
|
||||
"messagesStyle": "",
|
||||
"@messagesStyle": {},
|
||||
"chatDescription": "",
|
||||
"@chatDescription": {},
|
||||
"editTodo": "",
|
||||
"@editTodo": {},
|
||||
"pushNotificationsNotAvailable": "",
|
||||
"@pushNotificationsNotAvailable": {},
|
||||
"invalidServerName": "",
|
||||
"@invalidServerName": {},
|
||||
"chatPermissions": "",
|
||||
"@chatPermissions": {},
|
||||
"pleaseAddATitle": "",
|
||||
"@pleaseAddATitle": {},
|
||||
"makeAdminDescription": "",
|
||||
"@makeAdminDescription": {},
|
||||
"setChatDescription": "",
|
||||
"@setChatDescription": {},
|
||||
"importFromZipFile": "",
|
||||
"@importFromZipFile": {},
|
||||
"redactedBy": "",
|
||||
"@redactedBy": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"username": {}
|
||||
}
|
||||
},
|
||||
"signInWith": "",
|
||||
"@signInWith": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"provider": {}
|
||||
}
|
||||
},
|
||||
"noTodosYet": "",
|
||||
"@noTodosYet": {},
|
||||
"optionalRedactReason": "",
|
||||
"@optionalRedactReason": {},
|
||||
"archiveRoomDescription": "",
|
||||
"@archiveRoomDescription": {},
|
||||
"exportEmotePack": "",
|
||||
"@exportEmotePack": {},
|
||||
"savedEmotePack": "",
|
||||
"@savedEmotePack": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"path": {}
|
||||
}
|
||||
},
|
||||
"inviteContactToGroupQuestion": "",
|
||||
"@inviteContactToGroupQuestion": {},
|
||||
"redactedByBecause": "",
|
||||
"@redactedByBecause": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"username": {},
|
||||
"reason": {}
|
||||
}
|
||||
},
|
||||
"importZipFile": "",
|
||||
"@importZipFile": {},
|
||||
"anyoneCanKnock": "",
|
||||
"@anyoneCanKnock": {},
|
||||
"redactMessageDescription": "",
|
||||
"@redactMessageDescription": {},
|
||||
"invalidInput": "",
|
||||
"@invalidInput": {},
|
||||
"todosUnencrypted": "",
|
||||
"@todosUnencrypted": {},
|
||||
"addChatDescription": "",
|
||||
"@addChatDescription": {},
|
||||
"hasKnocked": "",
|
||||
"@hasKnocked": {
|
||||
"placeholders": {
|
||||
"user": {}
|
||||
}
|
||||
},
|
||||
"directChat": "",
|
||||
"@directChat": {},
|
||||
"noOneCanJoin": "",
|
||||
"@noOneCanJoin": {},
|
||||
"wrongPinEntered": "",
|
||||
"@wrongPinEntered": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"seconds": {}
|
||||
}
|
||||
},
|
||||
"sendTypingNotifications": "",
|
||||
"@sendTypingNotifications": {},
|
||||
"inviteGroupChat": "",
|
||||
"@inviteGroupChat": {},
|
||||
"invitePrivateChat": "",
|
||||
"@invitePrivateChat": {},
|
||||
"importEmojis": "",
|
||||
"@importEmojis": {},
|
||||
"noChatDescriptionYet": "",
|
||||
"@noChatDescriptionYet": {},
|
||||
"newTodo": "",
|
||||
"@newTodo": {},
|
||||
"learnMore": "",
|
||||
"@learnMore": {},
|
||||
"notAnImage": "",
|
||||
"@notAnImage": {},
|
||||
"chatDescriptionHasBeenChanged": "",
|
||||
"@chatDescriptionHasBeenChanged": {},
|
||||
"todoListChangedError": "",
|
||||
"@todoListChangedError": {},
|
||||
"roomUpgradeDescription": "",
|
||||
"@roomUpgradeDescription": {},
|
||||
"pleaseEnterANumber": "",
|
||||
"@pleaseEnterANumber": {},
|
||||
"profileNotFound": "",
|
||||
"@profileNotFound": {},
|
||||
"shareInviteLink": "",
|
||||
"@shareInviteLink": {},
|
||||
"emoteKeyboardNoRecents": "",
|
||||
"@emoteKeyboardNoRecents": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"setTheme": "",
|
||||
"@setTheme": {},
|
||||
"replace": "",
|
||||
"@replace": {},
|
||||
"createGroup": "",
|
||||
"@createGroup": {},
|
||||
"kickUserDescription": "",
|
||||
"@kickUserDescription": {},
|
||||
"importNow": "",
|
||||
"@importNow": {},
|
||||
"invite": "",
|
||||
"@invite": {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2620,5 +2620,33 @@
|
|||
"importNow": "Tuo nyt",
|
||||
"@importNow": {},
|
||||
"invite": "Kutsu",
|
||||
"@invite": {}
|
||||
"@invite": {},
|
||||
"banUserDescription": "",
|
||||
"@banUserDescription": {},
|
||||
"removeDevicesDescription": "",
|
||||
"@removeDevicesDescription": {},
|
||||
"unbanUserDescription": "",
|
||||
"@unbanUserDescription": {},
|
||||
"todoLists": "",
|
||||
"@todoLists": {},
|
||||
"editTodo": "",
|
||||
"@editTodo": {},
|
||||
"pushNotificationsNotAvailable": "",
|
||||
"@pushNotificationsNotAvailable": {},
|
||||
"pleaseAddATitle": "",
|
||||
"@pleaseAddATitle": {},
|
||||
"makeAdminDescription": "",
|
||||
"@makeAdminDescription": {},
|
||||
"noTodosYet": "",
|
||||
"@noTodosYet": {},
|
||||
"todosUnencrypted": "",
|
||||
"@todosUnencrypted": {},
|
||||
"newTodo": "",
|
||||
"@newTodo": {},
|
||||
"learnMore": "",
|
||||
"@learnMore": {},
|
||||
"todoListChangedError": "",
|
||||
"@todoListChangedError": {},
|
||||
"kickUserDescription": "",
|
||||
"@kickUserDescription": {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2514,5 +2514,148 @@
|
|||
"createGroup": "Créer un groupe",
|
||||
"@createGroup": {},
|
||||
"importNow": "Importer maintenant",
|
||||
"@importNow": {}
|
||||
"@importNow": {},
|
||||
"reportErrorDescription": "",
|
||||
"@reportErrorDescription": {},
|
||||
"setColorTheme": "",
|
||||
"@setColorTheme": {},
|
||||
"banUserDescription": "",
|
||||
"@banUserDescription": {},
|
||||
"requests": "",
|
||||
"@requests": {},
|
||||
"removeDevicesDescription": "",
|
||||
"@removeDevicesDescription": {},
|
||||
"tryAgain": "",
|
||||
"@tryAgain": {},
|
||||
"unbanUserDescription": "",
|
||||
"@unbanUserDescription": {},
|
||||
"todoLists": "",
|
||||
"@todoLists": {},
|
||||
"messagesStyle": "",
|
||||
"@messagesStyle": {},
|
||||
"chatDescription": "",
|
||||
"@chatDescription": {},
|
||||
"editTodo": "",
|
||||
"@editTodo": {},
|
||||
"pushNotificationsNotAvailable": "",
|
||||
"@pushNotificationsNotAvailable": {},
|
||||
"invalidServerName": "",
|
||||
"@invalidServerName": {},
|
||||
"signInWithPassword": "",
|
||||
"@signInWithPassword": {},
|
||||
"pleaseAddATitle": "",
|
||||
"@pleaseAddATitle": {},
|
||||
"makeAdminDescription": "",
|
||||
"@makeAdminDescription": {},
|
||||
"setChatDescription": "",
|
||||
"@setChatDescription": {},
|
||||
"redactedBy": "",
|
||||
"@redactedBy": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"username": {}
|
||||
}
|
||||
},
|
||||
"signInWith": "",
|
||||
"@signInWith": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"provider": {}
|
||||
}
|
||||
},
|
||||
"noTodosYet": "",
|
||||
"@noTodosYet": {},
|
||||
"optionalRedactReason": "",
|
||||
"@optionalRedactReason": {},
|
||||
"archiveRoomDescription": "",
|
||||
"@archiveRoomDescription": {},
|
||||
"exportEmotePack": "",
|
||||
"@exportEmotePack": {},
|
||||
"savedEmotePack": "",
|
||||
"@savedEmotePack": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"path": {}
|
||||
}
|
||||
},
|
||||
"redactedByBecause": "",
|
||||
"@redactedByBecause": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"username": {},
|
||||
"reason": {}
|
||||
}
|
||||
},
|
||||
"anyoneCanKnock": "",
|
||||
"@anyoneCanKnock": {},
|
||||
"redactMessageDescription": "",
|
||||
"@redactMessageDescription": {},
|
||||
"invalidInput": "",
|
||||
"@invalidInput": {},
|
||||
"todosUnencrypted": "",
|
||||
"@todosUnencrypted": {},
|
||||
"report": "",
|
||||
"@report": {},
|
||||
"addChatDescription": "",
|
||||
"@addChatDescription": {},
|
||||
"hasKnocked": "",
|
||||
"@hasKnocked": {
|
||||
"placeholders": {
|
||||
"user": {}
|
||||
}
|
||||
},
|
||||
"directChat": "",
|
||||
"@directChat": {},
|
||||
"noOneCanJoin": "",
|
||||
"@noOneCanJoin": {},
|
||||
"wrongPinEntered": "",
|
||||
"@wrongPinEntered": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"seconds": {}
|
||||
}
|
||||
},
|
||||
"sendTypingNotifications": "",
|
||||
"@sendTypingNotifications": {},
|
||||
"inviteGroupChat": "",
|
||||
"@inviteGroupChat": {},
|
||||
"invitePrivateChat": "",
|
||||
"@invitePrivateChat": {},
|
||||
"noChatDescriptionYet": "",
|
||||
"@noChatDescriptionYet": {},
|
||||
"newTodo": "",
|
||||
"@newTodo": {},
|
||||
"learnMore": "",
|
||||
"@learnMore": {},
|
||||
"todoListChangedError": "",
|
||||
"@todoListChangedError": {},
|
||||
"roomUpgradeDescription": "",
|
||||
"@roomUpgradeDescription": {},
|
||||
"pleaseEnterANumber": "",
|
||||
"@pleaseEnterANumber": {},
|
||||
"profileNotFound": "",
|
||||
"@profileNotFound": {},
|
||||
"jump": "",
|
||||
"@jump": {},
|
||||
"shareInviteLink": "",
|
||||
"@shareInviteLink": {},
|
||||
"emoteKeyboardNoRecents": "",
|
||||
"@emoteKeyboardNoRecents": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"setTheme": "",
|
||||
"@setTheme": {},
|
||||
"replace": "",
|
||||
"@replace": {},
|
||||
"pleaseTryAgainLaterOrChooseDifferentServer": "",
|
||||
"@pleaseTryAgainLaterOrChooseDifferentServer": {},
|
||||
"kickUserDescription": "",
|
||||
"@kickUserDescription": {},
|
||||
"invite": "",
|
||||
"@invite": {},
|
||||
"continueWith": "",
|
||||
"@continueWith": {},
|
||||
"openLinkInBrowser": "",
|
||||
"@openLinkInBrowser": {}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -2657,5 +2657,7 @@
|
|||
"pleaseEnterANumber": "Escribe un número maior de cero",
|
||||
"@pleaseEnterANumber": {},
|
||||
"kickUserDescription": "A usuaria foi expulsada pero non vetada. En conversas públicas a usuaria pode volver cando queira.",
|
||||
"@kickUserDescription": {}
|
||||
"@kickUserDescription": {},
|
||||
"todosUnencrypted": "",
|
||||
"@todosUnencrypted": {}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -2625,5 +2625,37 @@
|
|||
}
|
||||
},
|
||||
"pleaseEnterANumber": "Upiši broj veći od 0",
|
||||
"@pleaseEnterANumber": {}
|
||||
"@pleaseEnterANumber": {},
|
||||
"banUserDescription": "",
|
||||
"@banUserDescription": {},
|
||||
"removeDevicesDescription": "",
|
||||
"@removeDevicesDescription": {},
|
||||
"unbanUserDescription": "",
|
||||
"@unbanUserDescription": {},
|
||||
"todoLists": "",
|
||||
"@todoLists": {},
|
||||
"editTodo": "",
|
||||
"@editTodo": {},
|
||||
"pushNotificationsNotAvailable": "",
|
||||
"@pushNotificationsNotAvailable": {},
|
||||
"pleaseAddATitle": "",
|
||||
"@pleaseAddATitle": {},
|
||||
"makeAdminDescription": "",
|
||||
"@makeAdminDescription": {},
|
||||
"noTodosYet": "",
|
||||
"@noTodosYet": {},
|
||||
"archiveRoomDescription": "",
|
||||
"@archiveRoomDescription": {},
|
||||
"todosUnencrypted": "",
|
||||
"@todosUnencrypted": {},
|
||||
"newTodo": "",
|
||||
"@newTodo": {},
|
||||
"learnMore": "",
|
||||
"@learnMore": {},
|
||||
"todoListChangedError": "",
|
||||
"@todoListChangedError": {},
|
||||
"roomUpgradeDescription": "",
|
||||
"@roomUpgradeDescription": {},
|
||||
"kickUserDescription": "",
|
||||
"@kickUserDescription": {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2004,5 +2004,651 @@
|
|||
"placeholders": {}
|
||||
},
|
||||
"notAnImage": "Nem kép fájl.",
|
||||
"@notAnImage": {}
|
||||
"@notAnImage": {},
|
||||
"showPassword": "",
|
||||
"@showPassword": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"hugContent": "",
|
||||
"@hugContent": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"senderName": {}
|
||||
}
|
||||
},
|
||||
"jumpToLastReadMessage": "",
|
||||
"@jumpToLastReadMessage": {},
|
||||
"allRooms": "",
|
||||
"@allRooms": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"whoCanSeeMyStories": "",
|
||||
"@whoCanSeeMyStories": {},
|
||||
"widgetVideo": "",
|
||||
"@widgetVideo": {},
|
||||
"dismiss": "",
|
||||
"@dismiss": {},
|
||||
"reportErrorDescription": "",
|
||||
"@reportErrorDescription": {},
|
||||
"setPermissionsLevel": "",
|
||||
"@setPermissionsLevel": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"removeYourAvatar": "",
|
||||
"@removeYourAvatar": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"unsupportedAndroidVersion": "",
|
||||
"@unsupportedAndroidVersion": {},
|
||||
"widgetJitsi": "",
|
||||
"@widgetJitsi": {},
|
||||
"messageType": "",
|
||||
"@messageType": {},
|
||||
"noEmailWarning": "",
|
||||
"@noEmailWarning": {},
|
||||
"indexedDbErrorLong": "",
|
||||
"@indexedDbErrorLong": {},
|
||||
"oneClientLoggedOut": "",
|
||||
"@oneClientLoggedOut": {},
|
||||
"toggleMuted": "",
|
||||
"@toggleMuted": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"startFirstChat": "",
|
||||
"@startFirstChat": {},
|
||||
"callingAccount": "",
|
||||
"@callingAccount": {},
|
||||
"setColorTheme": "",
|
||||
"@setColorTheme": {},
|
||||
"nextAccount": "",
|
||||
"@nextAccount": {},
|
||||
"singlesignon": "",
|
||||
"@singlesignon": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"allSpaces": "",
|
||||
"@allSpaces": {},
|
||||
"supposedMxid": "",
|
||||
"@supposedMxid": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"mxid": {}
|
||||
}
|
||||
},
|
||||
"user": "",
|
||||
"@user": {},
|
||||
"youAcceptedTheInvitation": "",
|
||||
"@youAcceptedTheInvitation": {},
|
||||
"youInvitedBy": "",
|
||||
"@youInvitedBy": {
|
||||
"placeholders": {
|
||||
"user": {}
|
||||
}
|
||||
},
|
||||
"banUserDescription": "",
|
||||
"@banUserDescription": {},
|
||||
"requests": "",
|
||||
"@requests": {},
|
||||
"widgetEtherpad": "",
|
||||
"@widgetEtherpad": {},
|
||||
"stories": "",
|
||||
"@stories": {},
|
||||
"addToStory": "",
|
||||
"@addToStory": {},
|
||||
"removeDevicesDescription": "",
|
||||
"@removeDevicesDescription": {},
|
||||
"separateChatTypes": "",
|
||||
"@separateChatTypes": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"tryAgain": "",
|
||||
"@tryAgain": {},
|
||||
"youKickedAndBanned": "",
|
||||
"@youKickedAndBanned": {
|
||||
"placeholders": {
|
||||
"user": {}
|
||||
}
|
||||
},
|
||||
"showDirectChatsInSpaces": "",
|
||||
"@showDirectChatsInSpaces": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"unbanUserDescription": "",
|
||||
"@unbanUserDescription": {},
|
||||
"todoLists": "",
|
||||
"@todoLists": {},
|
||||
"pleaseClickOnLink": "",
|
||||
"@pleaseClickOnLink": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"youRejectedTheInvitation": "",
|
||||
"@youRejectedTheInvitation": {},
|
||||
"otherCallingPermissions": "",
|
||||
"@otherCallingPermissions": {},
|
||||
"messagesStyle": "",
|
||||
"@messagesStyle": {},
|
||||
"widgetUrlError": "",
|
||||
"@widgetUrlError": {},
|
||||
"emailOrUsername": "",
|
||||
"@emailOrUsername": {},
|
||||
"newSpaceDescription": "",
|
||||
"@newSpaceDescription": {},
|
||||
"chatDescription": "",
|
||||
"@chatDescription": {},
|
||||
"callingAccountDetails": "",
|
||||
"@callingAccountDetails": {},
|
||||
"pleaseFollowInstructionsOnWeb": "",
|
||||
"@pleaseFollowInstructionsOnWeb": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"enterSpace": "",
|
||||
"@enterSpace": {},
|
||||
"encryptThisChat": "",
|
||||
"@encryptThisChat": {},
|
||||
"previousAccount": "",
|
||||
"@previousAccount": {},
|
||||
"reopenChat": "",
|
||||
"@reopenChat": {},
|
||||
"pleaseEnterRecoveryKey": "",
|
||||
"@pleaseEnterRecoveryKey": {},
|
||||
"toggleFavorite": "",
|
||||
"@toggleFavorite": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"widgetNameError": "",
|
||||
"@widgetNameError": {},
|
||||
"addToBundle": "",
|
||||
"@addToBundle": {},
|
||||
"spaceIsPublic": "",
|
||||
"@spaceIsPublic": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"addWidget": "",
|
||||
"@addWidget": {},
|
||||
"countFiles": "",
|
||||
"@countFiles": {
|
||||
"placeholders": {
|
||||
"count": {}
|
||||
}
|
||||
},
|
||||
"noKeyForThisMessage": "",
|
||||
"@noKeyForThisMessage": {},
|
||||
"shareLocation": "",
|
||||
"@shareLocation": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"editTodo": "",
|
||||
"@editTodo": {},
|
||||
"pushNotificationsNotAvailable": "",
|
||||
"@pushNotificationsNotAvailable": {},
|
||||
"storeInAppleKeyChain": "",
|
||||
"@storeInAppleKeyChain": {},
|
||||
"replaceRoomWithNewerVersion": "",
|
||||
"@replaceRoomWithNewerVersion": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"invalidServerName": "",
|
||||
"@invalidServerName": {},
|
||||
"chatPermissions": "",
|
||||
"@chatPermissions": {},
|
||||
"wipeChatBackup": "",
|
||||
"@wipeChatBackup": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"sender": "",
|
||||
"@sender": {},
|
||||
"storeInAndroidKeystore": "",
|
||||
"@storeInAndroidKeystore": {},
|
||||
"signInWithPassword": "",
|
||||
"@signInWithPassword": {},
|
||||
"pleaseAddATitle": "",
|
||||
"@pleaseAddATitle": {},
|
||||
"makeAdminDescription": "",
|
||||
"@makeAdminDescription": {},
|
||||
"synchronizingPleaseWait": "",
|
||||
"@synchronizingPleaseWait": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"transferFromAnotherDevice": "",
|
||||
"@transferFromAnotherDevice": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"pushRules": "",
|
||||
"@pushRules": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"saveKeyManuallyDescription": "",
|
||||
"@saveKeyManuallyDescription": {},
|
||||
"editBundlesForAccount": "",
|
||||
"@editBundlesForAccount": {},
|
||||
"whyIsThisMessageEncrypted": "",
|
||||
"@whyIsThisMessageEncrypted": {},
|
||||
"setChatDescription": "",
|
||||
"@setChatDescription": {},
|
||||
"spaceName": "",
|
||||
"@spaceName": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"importFromZipFile": "",
|
||||
"@importFromZipFile": {},
|
||||
"toggleUnread": "",
|
||||
"@toggleUnread": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"noOtherDevicesFound": "",
|
||||
"@noOtherDevicesFound": {},
|
||||
"addDescription": "",
|
||||
"@addDescription": {},
|
||||
"redactedBy": "",
|
||||
"@redactedBy": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"username": {}
|
||||
}
|
||||
},
|
||||
"videoCallsBetaWarning": "",
|
||||
"@videoCallsBetaWarning": {},
|
||||
"storyPrivacyWarning": "",
|
||||
"@storyPrivacyWarning": {},
|
||||
"matrixWidgets": "",
|
||||
"@matrixWidgets": {},
|
||||
"signInWith": "",
|
||||
"@signInWith": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"provider": {}
|
||||
}
|
||||
},
|
||||
"fileIsTooBigForServer": "",
|
||||
"@fileIsTooBigForServer": {},
|
||||
"noTodosYet": "",
|
||||
"@noTodosYet": {},
|
||||
"verified": "",
|
||||
"@verified": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"callingPermissions": "",
|
||||
"@callingPermissions": {},
|
||||
"readUpToHere": "",
|
||||
"@readUpToHere": {},
|
||||
"start": "",
|
||||
"@start": {},
|
||||
"unlockOldMessages": "",
|
||||
"@unlockOldMessages": {},
|
||||
"numChats": "",
|
||||
"@numChats": {
|
||||
"type": "number",
|
||||
"placeholders": {
|
||||
"number": {}
|
||||
}
|
||||
},
|
||||
"whatIsGoingOn": "",
|
||||
"@whatIsGoingOn": {},
|
||||
"optionalRedactReason": "",
|
||||
"@optionalRedactReason": {},
|
||||
"sendAsText": "",
|
||||
"@sendAsText": {
|
||||
"type": "text"
|
||||
},
|
||||
"archiveRoomDescription": "",
|
||||
"@archiveRoomDescription": {},
|
||||
"exportEmotePack": "",
|
||||
"@exportEmotePack": {},
|
||||
"switchToAccount": "",
|
||||
"@switchToAccount": {
|
||||
"type": "number",
|
||||
"placeholders": {
|
||||
"number": {}
|
||||
}
|
||||
},
|
||||
"setAsCanonicalAlias": "",
|
||||
"@setAsCanonicalAlias": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"whyDoYouWantToReportThis": "",
|
||||
"@whyDoYouWantToReportThis": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"letsStart": "",
|
||||
"@letsStart": {},
|
||||
"experimentalVideoCalls": "",
|
||||
"@experimentalVideoCalls": {},
|
||||
"savedEmotePack": "",
|
||||
"@savedEmotePack": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"path": {}
|
||||
}
|
||||
},
|
||||
"pleaseEnterRecoveryKeyDescription": "",
|
||||
"@pleaseEnterRecoveryKeyDescription": {},
|
||||
"inviteContactToGroupQuestion": "",
|
||||
"@inviteContactToGroupQuestion": {},
|
||||
"redactedByBecause": "",
|
||||
"@redactedByBecause": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"username": {},
|
||||
"reason": {}
|
||||
}
|
||||
},
|
||||
"youHaveWithdrawnTheInvitationFor": "",
|
||||
"@youHaveWithdrawnTheInvitationFor": {
|
||||
"placeholders": {
|
||||
"user": {}
|
||||
}
|
||||
},
|
||||
"appearOnTopDetails": "",
|
||||
"@appearOnTopDetails": {},
|
||||
"enterRoom": "",
|
||||
"@enterRoom": {},
|
||||
"pleaseChooseAPasscode": "",
|
||||
"@pleaseChooseAPasscode": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"reportUser": "",
|
||||
"@reportUser": {},
|
||||
"confirmEventUnpin": "",
|
||||
"@confirmEventUnpin": {},
|
||||
"youInvitedUser": "",
|
||||
"@youInvitedUser": {
|
||||
"placeholders": {
|
||||
"user": {}
|
||||
}
|
||||
},
|
||||
"fileHasBeenSavedAt": "",
|
||||
"@fileHasBeenSavedAt": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"path": {}
|
||||
}
|
||||
},
|
||||
"importZipFile": "",
|
||||
"@importZipFile": {},
|
||||
"anyoneCanKnock": "",
|
||||
"@anyoneCanKnock": {},
|
||||
"redactMessageDescription": "",
|
||||
"@redactMessageDescription": {},
|
||||
"recoveryKey": "",
|
||||
"@recoveryKey": {},
|
||||
"invalidInput": "",
|
||||
"@invalidInput": {},
|
||||
"todosUnencrypted": "",
|
||||
"@todosUnencrypted": {},
|
||||
"yourPublicKey": "",
|
||||
"@yourPublicKey": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"tooManyRequestsWarning": "",
|
||||
"@tooManyRequestsWarning": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"replyHasBeenSent": "",
|
||||
"@replyHasBeenSent": {},
|
||||
"doNotShowAgain": "",
|
||||
"@doNotShowAgain": {},
|
||||
"report": "",
|
||||
"@report": {},
|
||||
"status": "",
|
||||
"@status": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"yourStory": "",
|
||||
"@yourStory": {},
|
||||
"unverified": "",
|
||||
"@unverified": {},
|
||||
"serverRequiresEmail": "",
|
||||
"@serverRequiresEmail": {},
|
||||
"hideUnimportantStateEvents": "",
|
||||
"@hideUnimportantStateEvents": {},
|
||||
"screenSharingTitle": "",
|
||||
"@screenSharingTitle": {},
|
||||
"widgetCustom": "",
|
||||
"@widgetCustom": {},
|
||||
"addToSpaceDescription": "",
|
||||
"@addToSpaceDescription": {},
|
||||
"whoCanSeeMyStoriesDesc": "",
|
||||
"@whoCanSeeMyStoriesDesc": {},
|
||||
"youBannedUser": "",
|
||||
"@youBannedUser": {
|
||||
"placeholders": {
|
||||
"user": {}
|
||||
}
|
||||
},
|
||||
"unsubscribeStories": "",
|
||||
"@unsubscribeStories": {},
|
||||
"addChatDescription": "",
|
||||
"@addChatDescription": {},
|
||||
"hasKnocked": "",
|
||||
"@hasKnocked": {
|
||||
"placeholders": {
|
||||
"user": {}
|
||||
}
|
||||
},
|
||||
"publish": "",
|
||||
"@publish": {},
|
||||
"openLinkInBrowser": "",
|
||||
"@openLinkInBrowser": {},
|
||||
"messageInfo": "",
|
||||
"@messageInfo": {},
|
||||
"disableEncryptionWarning": "",
|
||||
"@disableEncryptionWarning": {},
|
||||
"directChat": "",
|
||||
"@directChat": {},
|
||||
"noOneCanJoin": "",
|
||||
"@noOneCanJoin": {},
|
||||
"wrongPinEntered": "",
|
||||
"@wrongPinEntered": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"seconds": {}
|
||||
}
|
||||
},
|
||||
"sendTypingNotifications": "",
|
||||
"@sendTypingNotifications": {},
|
||||
"inviteGroupChat": "",
|
||||
"@inviteGroupChat": {},
|
||||
"appearOnTop": "",
|
||||
"@appearOnTop": {},
|
||||
"invitePrivateChat": "",
|
||||
"@invitePrivateChat": {},
|
||||
"foregroundServiceRunning": "",
|
||||
"@foregroundServiceRunning": {},
|
||||
"voiceCall": "",
|
||||
"@voiceCall": {},
|
||||
"importEmojis": "",
|
||||
"@importEmojis": {},
|
||||
"wasDirectChatDisplayName": "",
|
||||
"@wasDirectChatDisplayName": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"oldDisplayName": {}
|
||||
}
|
||||
},
|
||||
"noChatDescriptionYet": "",
|
||||
"@noChatDescriptionYet": {},
|
||||
"newTodo": "",
|
||||
"@newTodo": {},
|
||||
"removeFromBundle": "",
|
||||
"@removeFromBundle": {},
|
||||
"whoCanPerformWhichAction": "",
|
||||
"@whoCanPerformWhichAction": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"learnMore": "",
|
||||
"@learnMore": {},
|
||||
"users": "",
|
||||
"@users": {},
|
||||
"openGallery": "",
|
||||
"@openGallery": {},
|
||||
"chatDescriptionHasBeenChanged": "",
|
||||
"@chatDescriptionHasBeenChanged": {},
|
||||
"newGroup": "",
|
||||
"@newGroup": {},
|
||||
"bundleName": "",
|
||||
"@bundleName": {},
|
||||
"todoListChangedError": "",
|
||||
"@todoListChangedError": {},
|
||||
"removeFromSpace": "",
|
||||
"@removeFromSpace": {},
|
||||
"enterInviteLinkOrMatrixId": "",
|
||||
"@enterInviteLinkOrMatrixId": {},
|
||||
"roomUpgradeDescription": "",
|
||||
"@roomUpgradeDescription": {},
|
||||
"pleaseEnterANumber": "",
|
||||
"@pleaseEnterANumber": {},
|
||||
"youKicked": "",
|
||||
"@youKicked": {
|
||||
"placeholders": {
|
||||
"user": {}
|
||||
}
|
||||
},
|
||||
"profileNotFound": "",
|
||||
"@profileNotFound": {},
|
||||
"jump": "",
|
||||
"@jump": {},
|
||||
"reactedWith": "",
|
||||
"@reactedWith": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"sender": {},
|
||||
"reaction": {}
|
||||
}
|
||||
},
|
||||
"sorryThatsNotPossible": "",
|
||||
"@sorryThatsNotPossible": {},
|
||||
"storyFrom": "",
|
||||
"@storyFrom": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"date": {},
|
||||
"body": {}
|
||||
}
|
||||
},
|
||||
"videoWithSize": "",
|
||||
"@videoWithSize": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"size": {}
|
||||
}
|
||||
},
|
||||
"shareInviteLink": "",
|
||||
"@shareInviteLink": {},
|
||||
"commandHint_markasdm": "",
|
||||
"@commandHint_markasdm": {},
|
||||
"recoveryKeyLost": "",
|
||||
"@recoveryKeyLost": {},
|
||||
"deviceKeys": "",
|
||||
"@deviceKeys": {},
|
||||
"emoteKeyboardNoRecents": "",
|
||||
"@emoteKeyboardNoRecents": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"setCustomEmotes": "",
|
||||
"@setCustomEmotes": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"endToEndEncryption": "",
|
||||
"@endToEndEncryption": {},
|
||||
"setTheme": "",
|
||||
"@setTheme": {},
|
||||
"youJoinedTheChat": "",
|
||||
"@youJoinedTheChat": {},
|
||||
"thisUserHasNotPostedAnythingYet": "",
|
||||
"@thisUserHasNotPostedAnythingYet": {},
|
||||
"markAsRead": "",
|
||||
"@markAsRead": {},
|
||||
"widgetName": "",
|
||||
"@widgetName": {},
|
||||
"errorAddingWidget": "",
|
||||
"@errorAddingWidget": {},
|
||||
"replace": "",
|
||||
"@replace": {},
|
||||
"youUnbannedUser": "",
|
||||
"@youUnbannedUser": {
|
||||
"placeholders": {
|
||||
"user": {}
|
||||
}
|
||||
},
|
||||
"newSpace": "",
|
||||
"@newSpace": {},
|
||||
"emojis": "",
|
||||
"@emojis": {},
|
||||
"pleaseTryAgainLaterOrChooseDifferentServer": "",
|
||||
"@pleaseTryAgainLaterOrChooseDifferentServer": {},
|
||||
"createGroup": "",
|
||||
"@createGroup": {},
|
||||
"hydrateTorLong": "",
|
||||
"@hydrateTorLong": {},
|
||||
"time": "",
|
||||
"@time": {},
|
||||
"custom": "",
|
||||
"@custom": {},
|
||||
"noBackupWarning": "",
|
||||
"@noBackupWarning": {},
|
||||
"editWidgets": "",
|
||||
"@editWidgets": {},
|
||||
"storeInSecureStorageDescription": "",
|
||||
"@storeInSecureStorageDescription": {},
|
||||
"openChat": "",
|
||||
"@openChat": {},
|
||||
"kickUserDescription": "",
|
||||
"@kickUserDescription": {},
|
||||
"importNow": "",
|
||||
"@importNow": {},
|
||||
"pinMessage": "",
|
||||
"@pinMessage": {},
|
||||
"invite": "",
|
||||
"@invite": {},
|
||||
"enableMultiAccounts": "",
|
||||
"@enableMultiAccounts": {},
|
||||
"continueWith": "",
|
||||
"@continueWith": {},
|
||||
"indexedDbErrorTitle": "",
|
||||
"@indexedDbErrorTitle": {},
|
||||
"discover": "",
|
||||
"@discover": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"unsupportedAndroidVersionLong": "",
|
||||
"@unsupportedAndroidVersionLong": {},
|
||||
"storeSecurlyOnThisDevice": "",
|
||||
"@storeSecurlyOnThisDevice": {},
|
||||
"iUnderstand": "",
|
||||
"@iUnderstand": {},
|
||||
"screenSharingDetail": "",
|
||||
"@screenSharingDetail": {},
|
||||
"placeCall": "",
|
||||
"@placeCall": {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2616,5 +2616,45 @@
|
|||
"placeholders": {
|
||||
"seconds": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"banUserDescription": "",
|
||||
"@banUserDescription": {},
|
||||
"removeDevicesDescription": "",
|
||||
"@removeDevicesDescription": {},
|
||||
"unbanUserDescription": "",
|
||||
"@unbanUserDescription": {},
|
||||
"todoLists": "",
|
||||
"@todoLists": {},
|
||||
"editTodo": "",
|
||||
"@editTodo": {},
|
||||
"pushNotificationsNotAvailable": "",
|
||||
"@pushNotificationsNotAvailable": {},
|
||||
"pleaseAddATitle": "",
|
||||
"@pleaseAddATitle": {},
|
||||
"makeAdminDescription": "",
|
||||
"@makeAdminDescription": {},
|
||||
"noTodosYet": "",
|
||||
"@noTodosYet": {},
|
||||
"archiveRoomDescription": "",
|
||||
"@archiveRoomDescription": {},
|
||||
"todosUnencrypted": "",
|
||||
"@todosUnencrypted": {},
|
||||
"hasKnocked": "",
|
||||
"@hasKnocked": {
|
||||
"placeholders": {
|
||||
"user": {}
|
||||
}
|
||||
},
|
||||
"newTodo": "",
|
||||
"@newTodo": {},
|
||||
"learnMore": "",
|
||||
"@learnMore": {},
|
||||
"todoListChangedError": "",
|
||||
"@todoListChangedError": {},
|
||||
"roomUpgradeDescription": "",
|
||||
"@roomUpgradeDescription": {},
|
||||
"pleaseEnterANumber": "",
|
||||
"@pleaseEnterANumber": {},
|
||||
"kickUserDescription": "",
|
||||
"@kickUserDescription": {}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -2395,5 +2395,260 @@
|
|||
}
|
||||
},
|
||||
"signInWithPassword": "パスワードでログイン",
|
||||
"@signInWithPassword": {}
|
||||
"@signInWithPassword": {},
|
||||
"discover": "",
|
||||
"@discover": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"hugContent": "",
|
||||
"@hugContent": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"senderName": {}
|
||||
}
|
||||
},
|
||||
"jumpToLastReadMessage": "",
|
||||
"@jumpToLastReadMessage": {},
|
||||
"allRooms": "",
|
||||
"@allRooms": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"whoCanSeeMyStories": "",
|
||||
"@whoCanSeeMyStories": {},
|
||||
"commandHint_cuddle": "",
|
||||
"@commandHint_cuddle": {},
|
||||
"dismiss": "",
|
||||
"@dismiss": {},
|
||||
"reportErrorDescription": "",
|
||||
"@reportErrorDescription": {},
|
||||
"indexedDbErrorLong": "",
|
||||
"@indexedDbErrorLong": {},
|
||||
"setColorTheme": "",
|
||||
"@setColorTheme": {},
|
||||
"supposedMxid": "",
|
||||
"@supposedMxid": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"mxid": {}
|
||||
}
|
||||
},
|
||||
"banUserDescription": "",
|
||||
"@banUserDescription": {},
|
||||
"requests": "",
|
||||
"@requests": {},
|
||||
"widgetEtherpad": "",
|
||||
"@widgetEtherpad": {},
|
||||
"removeDevicesDescription": "",
|
||||
"@removeDevicesDescription": {},
|
||||
"separateChatTypes": "",
|
||||
"@separateChatTypes": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"tryAgain": "",
|
||||
"@tryAgain": {},
|
||||
"unbanUserDescription": "",
|
||||
"@unbanUserDescription": {},
|
||||
"todoLists": "",
|
||||
"@todoLists": {},
|
||||
"messagesStyle": "",
|
||||
"@messagesStyle": {},
|
||||
"newSpaceDescription": "",
|
||||
"@newSpaceDescription": {},
|
||||
"chatDescription": "",
|
||||
"@chatDescription": {},
|
||||
"callingAccountDetails": "",
|
||||
"@callingAccountDetails": {},
|
||||
"noKeyForThisMessage": "",
|
||||
"@noKeyForThisMessage": {},
|
||||
"editTodo": "",
|
||||
"@editTodo": {},
|
||||
"pushNotificationsNotAvailable": "",
|
||||
"@pushNotificationsNotAvailable": {},
|
||||
"invalidServerName": "",
|
||||
"@invalidServerName": {},
|
||||
"chatPermissions": "",
|
||||
"@chatPermissions": {},
|
||||
"pleaseAddATitle": "",
|
||||
"@pleaseAddATitle": {},
|
||||
"makeAdminDescription": "",
|
||||
"@makeAdminDescription": {},
|
||||
"saveKeyManuallyDescription": "",
|
||||
"@saveKeyManuallyDescription": {},
|
||||
"setChatDescription": "",
|
||||
"@setChatDescription": {},
|
||||
"importFromZipFile": "",
|
||||
"@importFromZipFile": {},
|
||||
"redactedBy": "",
|
||||
"@redactedBy": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"username": {}
|
||||
}
|
||||
},
|
||||
"fileIsTooBigForServer": "",
|
||||
"@fileIsTooBigForServer": {},
|
||||
"noTodosYet": "",
|
||||
"@noTodosYet": {},
|
||||
"readUpToHere": "",
|
||||
"@readUpToHere": {},
|
||||
"whatIsGoingOn": "",
|
||||
"@whatIsGoingOn": {},
|
||||
"optionalRedactReason": "",
|
||||
"@optionalRedactReason": {},
|
||||
"archiveRoomDescription": "",
|
||||
"@archiveRoomDescription": {},
|
||||
"exportEmotePack": "",
|
||||
"@exportEmotePack": {},
|
||||
"savedEmotePack": "",
|
||||
"@savedEmotePack": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"path": {}
|
||||
}
|
||||
},
|
||||
"openInMaps": "",
|
||||
"@openInMaps": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"inviteContactToGroupQuestion": "",
|
||||
"@inviteContactToGroupQuestion": {},
|
||||
"redactedByBecause": "",
|
||||
"@redactedByBecause": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"username": {},
|
||||
"reason": {}
|
||||
}
|
||||
},
|
||||
"fileHasBeenSavedAt": "",
|
||||
"@fileHasBeenSavedAt": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"path": {}
|
||||
}
|
||||
},
|
||||
"importZipFile": "",
|
||||
"@importZipFile": {},
|
||||
"anyoneCanKnock": "",
|
||||
"@anyoneCanKnock": {},
|
||||
"redactMessageDescription": "",
|
||||
"@redactMessageDescription": {},
|
||||
"invalidInput": "",
|
||||
"@invalidInput": {},
|
||||
"todosUnencrypted": "",
|
||||
"@todosUnencrypted": {},
|
||||
"report": "",
|
||||
"@report": {},
|
||||
"googlyEyesContent": "",
|
||||
"@googlyEyesContent": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"senderName": {}
|
||||
}
|
||||
},
|
||||
"addChatDescription": "",
|
||||
"@addChatDescription": {},
|
||||
"hasKnocked": "",
|
||||
"@hasKnocked": {
|
||||
"placeholders": {
|
||||
"user": {}
|
||||
}
|
||||
},
|
||||
"openLinkInBrowser": "",
|
||||
"@openLinkInBrowser": {},
|
||||
"commandHint_me": "",
|
||||
"@commandHint_me": {
|
||||
"type": "text",
|
||||
"description": "Usage hint for the command /me"
|
||||
},
|
||||
"directChat": "",
|
||||
"@directChat": {},
|
||||
"noOneCanJoin": "",
|
||||
"@noOneCanJoin": {},
|
||||
"wrongPinEntered": "",
|
||||
"@wrongPinEntered": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"seconds": {}
|
||||
}
|
||||
},
|
||||
"sendTypingNotifications": "",
|
||||
"@sendTypingNotifications": {},
|
||||
"inviteGroupChat": "",
|
||||
"@inviteGroupChat": {},
|
||||
"appearOnTop": "",
|
||||
"@appearOnTop": {},
|
||||
"invitePrivateChat": "",
|
||||
"@invitePrivateChat": {},
|
||||
"commandHint_kick": "",
|
||||
"@commandHint_kick": {
|
||||
"type": "text",
|
||||
"description": "Usage hint for the command /kick"
|
||||
},
|
||||
"commandHint_unban": "",
|
||||
"@commandHint_unban": {
|
||||
"type": "text",
|
||||
"description": "Usage hint for the command /unban"
|
||||
},
|
||||
"importEmojis": "",
|
||||
"@importEmojis": {},
|
||||
"noChatDescriptionYet": "",
|
||||
"@noChatDescriptionYet": {},
|
||||
"newTodo": "",
|
||||
"@newTodo": {},
|
||||
"learnMore": "",
|
||||
"@learnMore": {},
|
||||
"notAnImage": "",
|
||||
"@notAnImage": {},
|
||||
"chatDescriptionHasBeenChanged": "",
|
||||
"@chatDescriptionHasBeenChanged": {},
|
||||
"todoListChangedError": "",
|
||||
"@todoListChangedError": {},
|
||||
"commandHint_op": "",
|
||||
"@commandHint_op": {
|
||||
"type": "text",
|
||||
"description": "Usage hint for the command /op"
|
||||
},
|
||||
"roomUpgradeDescription": "",
|
||||
"@roomUpgradeDescription": {},
|
||||
"pleaseEnterANumber": "",
|
||||
"@pleaseEnterANumber": {},
|
||||
"profileNotFound": "",
|
||||
"@profileNotFound": {},
|
||||
"jump": "",
|
||||
"@jump": {},
|
||||
"shareInviteLink": "",
|
||||
"@shareInviteLink": {},
|
||||
"cuddleContent": "",
|
||||
"@cuddleContent": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"senderName": {}
|
||||
}
|
||||
},
|
||||
"emoteKeyboardNoRecents": "",
|
||||
"@emoteKeyboardNoRecents": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"setTheme": "",
|
||||
"@setTheme": {},
|
||||
"replace": "",
|
||||
"@replace": {},
|
||||
"pleaseTryAgainLaterOrChooseDifferentServer": "",
|
||||
"@pleaseTryAgainLaterOrChooseDifferentServer": {},
|
||||
"createGroup": "",
|
||||
"@createGroup": {},
|
||||
"kickUserDescription": "",
|
||||
"@kickUserDescription": {},
|
||||
"importNow": "",
|
||||
"@importNow": {},
|
||||
"invite": "",
|
||||
"@invite": {},
|
||||
"continueWith": "",
|
||||
"@continueWith": {}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -1167,7 +1167,7 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"noGoogleServicesWarning": "Het lijkt erop dat je geen Google-services op je telefoon hebt. Dat is een goede beslissing voor je privacy! Om pushmeldingen in FluffyChat te ontvangen raden we je https://microg.org/ of https://unifiedpush.org aan.",
|
||||
"noGoogleServicesWarning": "Firebase Cloud Messaging lijkt niet beschikbaar op je apparaat. Om nog steeds meldingen te krijgen, adviseren we om ntfy te installeren. Met ntfy of een andere Unified Push provider kun je meldingen ontvangen op een veilige manier. Je kunt ntfy downloaden van de PlayStore of van F-Droid.",
|
||||
"@noGoogleServicesWarning": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
|
|
@ -2616,5 +2616,45 @@
|
|||
"placeholders": {
|
||||
"seconds": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"banUserDescription": "De persoon zal worden verbannen van de chat en kan niet meer toetreden totdat de verbanning is opgeheven.",
|
||||
"@banUserDescription": {},
|
||||
"removeDevicesDescription": "Je wordt op dit apparaat uitgelogd en zal niet langer in staat zijn om berichten te ontvangen.",
|
||||
"@removeDevicesDescription": {},
|
||||
"unbanUserDescription": "De persoon zal weer in staat zijn om de chat te betreden als ze het proberen.",
|
||||
"@unbanUserDescription": {},
|
||||
"todoLists": "(Beta) Todo's",
|
||||
"@todoLists": {},
|
||||
"editTodo": "Wijzig todo",
|
||||
"@editTodo": {},
|
||||
"pushNotificationsNotAvailable": "Meldingen zijn niet beschikbaar",
|
||||
"@pushNotificationsNotAvailable": {},
|
||||
"pleaseAddATitle": "Voeg een titel toe",
|
||||
"@pleaseAddATitle": {},
|
||||
"makeAdminDescription": "Wanneer je deze persoon beheerder maakt kun je dit niet ongedaan maken als jullie dezelfde rechten hebben.",
|
||||
"@makeAdminDescription": {},
|
||||
"noTodosYet": "Er zijn nog geen todo's toegevoegd aan deze chat. Maak je eerste todo en start met samenwerken met anderen. 📝",
|
||||
"@noTodosYet": {},
|
||||
"archiveRoomDescription": "De chat zal naar het archief worden verplaatst. Andere personen zullen in staat zijn te zien dat je de chat hebt verlaten.",
|
||||
"@archiveRoomDescription": {},
|
||||
"todosUnencrypted": "Let op dat todo's zichtbaar zijn voor iedereen in de chat en niet zijn versleuteld.",
|
||||
"@todosUnencrypted": {},
|
||||
"hasKnocked": "{user} heeft geklopt",
|
||||
"@hasKnocked": {
|
||||
"placeholders": {
|
||||
"user": {}
|
||||
}
|
||||
},
|
||||
"newTodo": "Nieuwe todo",
|
||||
"@newTodo": {},
|
||||
"learnMore": "Lees meer",
|
||||
"@learnMore": {},
|
||||
"todoListChangedError": "Oeps... De todo's zijn aangepast terwijl je aan het bewerken was.",
|
||||
"@todoListChangedError": {},
|
||||
"roomUpgradeDescription": "De chat zal dan opnieuw gemaakt worden met de nieuwe kamerversie. Alle deelnemers worden geïnformeerd dat ze moeten overstappen naar de nieuwe chat. Je kan meer lezen over kamerversies op https://spec.matrix.org/latest/rooms/",
|
||||
"@roomUpgradeDescription": {},
|
||||
"pleaseEnterANumber": "Vul een getal in groter dan 0",
|
||||
"@pleaseEnterANumber": {},
|
||||
"kickUserDescription": "De persoon is verwijderd uit de chat, maar is niet verbannen. In publieke chats kan de persoon op elk moment opnieuw deelnemen.",
|
||||
"@kickUserDescription": {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2610,5 +2610,45 @@
|
|||
"invite": "Zaproszenie",
|
||||
"@invite": {},
|
||||
"continueWith": "Kontynuuj z:",
|
||||
"@continueWith": {}
|
||||
"@continueWith": {},
|
||||
"banUserDescription": "",
|
||||
"@banUserDescription": {},
|
||||
"removeDevicesDescription": "",
|
||||
"@removeDevicesDescription": {},
|
||||
"unbanUserDescription": "",
|
||||
"@unbanUserDescription": {},
|
||||
"todoLists": "",
|
||||
"@todoLists": {},
|
||||
"editTodo": "",
|
||||
"@editTodo": {},
|
||||
"pushNotificationsNotAvailable": "",
|
||||
"@pushNotificationsNotAvailable": {},
|
||||
"pleaseAddATitle": "",
|
||||
"@pleaseAddATitle": {},
|
||||
"makeAdminDescription": "",
|
||||
"@makeAdminDescription": {},
|
||||
"noTodosYet": "",
|
||||
"@noTodosYet": {},
|
||||
"archiveRoomDescription": "",
|
||||
"@archiveRoomDescription": {},
|
||||
"todosUnencrypted": "",
|
||||
"@todosUnencrypted": {},
|
||||
"hasKnocked": "",
|
||||
"@hasKnocked": {
|
||||
"placeholders": {
|
||||
"user": {}
|
||||
}
|
||||
},
|
||||
"newTodo": "",
|
||||
"@newTodo": {},
|
||||
"learnMore": "",
|
||||
"@learnMore": {},
|
||||
"todoListChangedError": "",
|
||||
"@todoListChangedError": {},
|
||||
"roomUpgradeDescription": "",
|
||||
"@roomUpgradeDescription": {},
|
||||
"pleaseEnterANumber": "",
|
||||
"@pleaseEnterANumber": {},
|
||||
"kickUserDescription": "",
|
||||
"@kickUserDescription": {}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -2476,5 +2476,185 @@
|
|||
"exportEmotePack": "Exportar pacote de Emotes como .zip",
|
||||
"@exportEmotePack": {},
|
||||
"replace": "Substituir",
|
||||
"@replace": {}
|
||||
"@replace": {},
|
||||
"jumpToLastReadMessage": "",
|
||||
"@jumpToLastReadMessage": {},
|
||||
"reportErrorDescription": "",
|
||||
"@reportErrorDescription": {},
|
||||
"setColorTheme": "",
|
||||
"@setColorTheme": {},
|
||||
"banUserDescription": "",
|
||||
"@banUserDescription": {},
|
||||
"requests": "",
|
||||
"@requests": {},
|
||||
"removeDevicesDescription": "",
|
||||
"@removeDevicesDescription": {},
|
||||
"tryAgain": "",
|
||||
"@tryAgain": {},
|
||||
"unbanUserDescription": "",
|
||||
"@unbanUserDescription": {},
|
||||
"todoLists": "",
|
||||
"@todoLists": {},
|
||||
"messagesStyle": "",
|
||||
"@messagesStyle": {},
|
||||
"newSpaceDescription": "",
|
||||
"@newSpaceDescription": {},
|
||||
"chatDescription": "",
|
||||
"@chatDescription": {},
|
||||
"encryptThisChat": "",
|
||||
"@encryptThisChat": {},
|
||||
"reopenChat": "",
|
||||
"@reopenChat": {},
|
||||
"editTodo": "",
|
||||
"@editTodo": {},
|
||||
"pushNotificationsNotAvailable": "",
|
||||
"@pushNotificationsNotAvailable": {},
|
||||
"invalidServerName": "",
|
||||
"@invalidServerName": {},
|
||||
"chatPermissions": "",
|
||||
"@chatPermissions": {},
|
||||
"signInWithPassword": "",
|
||||
"@signInWithPassword": {},
|
||||
"pleaseAddATitle": "",
|
||||
"@pleaseAddATitle": {},
|
||||
"makeAdminDescription": "",
|
||||
"@makeAdminDescription": {},
|
||||
"setChatDescription": "",
|
||||
"@setChatDescription": {},
|
||||
"noOtherDevicesFound": "",
|
||||
"@noOtherDevicesFound": {},
|
||||
"redactedBy": "",
|
||||
"@redactedBy": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"username": {}
|
||||
}
|
||||
},
|
||||
"signInWith": "",
|
||||
"@signInWith": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"provider": {}
|
||||
}
|
||||
},
|
||||
"fileIsTooBigForServer": "",
|
||||
"@fileIsTooBigForServer": {},
|
||||
"noTodosYet": "",
|
||||
"@noTodosYet": {},
|
||||
"readUpToHere": "",
|
||||
"@readUpToHere": {},
|
||||
"optionalRedactReason": "",
|
||||
"@optionalRedactReason": {},
|
||||
"archiveRoomDescription": "",
|
||||
"@archiveRoomDescription": {},
|
||||
"letsStart": "",
|
||||
"@letsStart": {},
|
||||
"inviteContactToGroupQuestion": "",
|
||||
"@inviteContactToGroupQuestion": {},
|
||||
"redactedByBecause": "",
|
||||
"@redactedByBecause": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"username": {},
|
||||
"reason": {}
|
||||
}
|
||||
},
|
||||
"fileHasBeenSavedAt": "",
|
||||
"@fileHasBeenSavedAt": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"path": {}
|
||||
}
|
||||
},
|
||||
"anyoneCanKnock": "",
|
||||
"@anyoneCanKnock": {},
|
||||
"redactMessageDescription": "",
|
||||
"@redactMessageDescription": {},
|
||||
"invalidInput": "",
|
||||
"@invalidInput": {},
|
||||
"todosUnencrypted": "",
|
||||
"@todosUnencrypted": {},
|
||||
"report": "",
|
||||
"@report": {},
|
||||
"addChatDescription": "",
|
||||
"@addChatDescription": {},
|
||||
"hasKnocked": "",
|
||||
"@hasKnocked": {
|
||||
"placeholders": {
|
||||
"user": {}
|
||||
}
|
||||
},
|
||||
"openLinkInBrowser": "",
|
||||
"@openLinkInBrowser": {},
|
||||
"disableEncryptionWarning": "",
|
||||
"@disableEncryptionWarning": {},
|
||||
"directChat": "",
|
||||
"@directChat": {},
|
||||
"noOneCanJoin": "",
|
||||
"@noOneCanJoin": {},
|
||||
"wrongPinEntered": "",
|
||||
"@wrongPinEntered": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"seconds": {}
|
||||
}
|
||||
},
|
||||
"inviteGroupChat": "",
|
||||
"@inviteGroupChat": {},
|
||||
"invitePrivateChat": "",
|
||||
"@invitePrivateChat": {},
|
||||
"wasDirectChatDisplayName": "",
|
||||
"@wasDirectChatDisplayName": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"oldDisplayName": {}
|
||||
}
|
||||
},
|
||||
"noChatDescriptionYet": "",
|
||||
"@noChatDescriptionYet": {},
|
||||
"newTodo": "",
|
||||
"@newTodo": {},
|
||||
"learnMore": "",
|
||||
"@learnMore": {},
|
||||
"chatDescriptionHasBeenChanged": "",
|
||||
"@chatDescriptionHasBeenChanged": {},
|
||||
"todoListChangedError": "",
|
||||
"@todoListChangedError": {},
|
||||
"enterInviteLinkOrMatrixId": "",
|
||||
"@enterInviteLinkOrMatrixId": {},
|
||||
"roomUpgradeDescription": "",
|
||||
"@roomUpgradeDescription": {},
|
||||
"pleaseEnterANumber": "",
|
||||
"@pleaseEnterANumber": {},
|
||||
"profileNotFound": "",
|
||||
"@profileNotFound": {},
|
||||
"jump": "",
|
||||
"@jump": {},
|
||||
"sorryThatsNotPossible": "",
|
||||
"@sorryThatsNotPossible": {},
|
||||
"shareInviteLink": "",
|
||||
"@shareInviteLink": {},
|
||||
"deviceKeys": "",
|
||||
"@deviceKeys": {},
|
||||
"emoteKeyboardNoRecents": "",
|
||||
"@emoteKeyboardNoRecents": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"endToEndEncryption": "",
|
||||
"@endToEndEncryption": {},
|
||||
"setTheme": "",
|
||||
"@setTheme": {},
|
||||
"pleaseTryAgainLaterOrChooseDifferentServer": "",
|
||||
"@pleaseTryAgainLaterOrChooseDifferentServer": {},
|
||||
"createGroup": "",
|
||||
"@createGroup": {},
|
||||
"noBackupWarning": "",
|
||||
"@noBackupWarning": {},
|
||||
"kickUserDescription": "",
|
||||
"@kickUserDescription": {},
|
||||
"invite": "",
|
||||
"@invite": {},
|
||||
"continueWith": "",
|
||||
"@continueWith": {}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -2502,5 +2502,152 @@
|
|||
"pleaseTryAgainLaterOrChooseDifferentServer": "Vă rugăm să încercați din nou mai târziu sau să alegeți un server diferit.",
|
||||
"@pleaseTryAgainLaterOrChooseDifferentServer": {},
|
||||
"signInWithPassword": "Conectați-vă cu parolă",
|
||||
"@signInWithPassword": {}
|
||||
"@signInWithPassword": {},
|
||||
"setColorTheme": "",
|
||||
"@setColorTheme": {},
|
||||
"banUserDescription": "",
|
||||
"@banUserDescription": {},
|
||||
"requests": "",
|
||||
"@requests": {},
|
||||
"removeDevicesDescription": "",
|
||||
"@removeDevicesDescription": {},
|
||||
"tryAgain": "",
|
||||
"@tryAgain": {},
|
||||
"unbanUserDescription": "",
|
||||
"@unbanUserDescription": {},
|
||||
"todoLists": "",
|
||||
"@todoLists": {},
|
||||
"messagesStyle": "",
|
||||
"@messagesStyle": {},
|
||||
"chatDescription": "",
|
||||
"@chatDescription": {},
|
||||
"editTodo": "",
|
||||
"@editTodo": {},
|
||||
"pushNotificationsNotAvailable": "",
|
||||
"@pushNotificationsNotAvailable": {},
|
||||
"invalidServerName": "",
|
||||
"@invalidServerName": {},
|
||||
"chatPermissions": "",
|
||||
"@chatPermissions": {},
|
||||
"pleaseAddATitle": "",
|
||||
"@pleaseAddATitle": {},
|
||||
"makeAdminDescription": "",
|
||||
"@makeAdminDescription": {},
|
||||
"setChatDescription": "",
|
||||
"@setChatDescription": {},
|
||||
"importFromZipFile": "",
|
||||
"@importFromZipFile": {},
|
||||
"redactedBy": "",
|
||||
"@redactedBy": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"username": {}
|
||||
}
|
||||
},
|
||||
"signInWith": "",
|
||||
"@signInWith": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"provider": {}
|
||||
}
|
||||
},
|
||||
"noTodosYet": "",
|
||||
"@noTodosYet": {},
|
||||
"optionalRedactReason": "",
|
||||
"@optionalRedactReason": {},
|
||||
"archiveRoomDescription": "",
|
||||
"@archiveRoomDescription": {},
|
||||
"exportEmotePack": "",
|
||||
"@exportEmotePack": {},
|
||||
"savedEmotePack": "",
|
||||
"@savedEmotePack": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"path": {}
|
||||
}
|
||||
},
|
||||
"inviteContactToGroupQuestion": "",
|
||||
"@inviteContactToGroupQuestion": {},
|
||||
"redactedByBecause": "",
|
||||
"@redactedByBecause": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"username": {},
|
||||
"reason": {}
|
||||
}
|
||||
},
|
||||
"importZipFile": "",
|
||||
"@importZipFile": {},
|
||||
"anyoneCanKnock": "",
|
||||
"@anyoneCanKnock": {},
|
||||
"redactMessageDescription": "",
|
||||
"@redactMessageDescription": {},
|
||||
"invalidInput": "",
|
||||
"@invalidInput": {},
|
||||
"todosUnencrypted": "",
|
||||
"@todosUnencrypted": {},
|
||||
"addChatDescription": "",
|
||||
"@addChatDescription": {},
|
||||
"hasKnocked": "",
|
||||
"@hasKnocked": {
|
||||
"placeholders": {
|
||||
"user": {}
|
||||
}
|
||||
},
|
||||
"directChat": "",
|
||||
"@directChat": {},
|
||||
"noOneCanJoin": "",
|
||||
"@noOneCanJoin": {},
|
||||
"wrongPinEntered": "",
|
||||
"@wrongPinEntered": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"seconds": {}
|
||||
}
|
||||
},
|
||||
"sendTypingNotifications": "",
|
||||
"@sendTypingNotifications": {},
|
||||
"inviteGroupChat": "",
|
||||
"@inviteGroupChat": {},
|
||||
"invitePrivateChat": "",
|
||||
"@invitePrivateChat": {},
|
||||
"importEmojis": "",
|
||||
"@importEmojis": {},
|
||||
"noChatDescriptionYet": "",
|
||||
"@noChatDescriptionYet": {},
|
||||
"newTodo": "",
|
||||
"@newTodo": {},
|
||||
"learnMore": "",
|
||||
"@learnMore": {},
|
||||
"notAnImage": "",
|
||||
"@notAnImage": {},
|
||||
"chatDescriptionHasBeenChanged": "",
|
||||
"@chatDescriptionHasBeenChanged": {},
|
||||
"todoListChangedError": "",
|
||||
"@todoListChangedError": {},
|
||||
"roomUpgradeDescription": "",
|
||||
"@roomUpgradeDescription": {},
|
||||
"pleaseEnterANumber": "",
|
||||
"@pleaseEnterANumber": {},
|
||||
"profileNotFound": "",
|
||||
"@profileNotFound": {},
|
||||
"shareInviteLink": "",
|
||||
"@shareInviteLink": {},
|
||||
"emoteKeyboardNoRecents": "",
|
||||
"@emoteKeyboardNoRecents": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"setTheme": "",
|
||||
"@setTheme": {},
|
||||
"replace": "",
|
||||
"@replace": {},
|
||||
"createGroup": "",
|
||||
"@createGroup": {},
|
||||
"kickUserDescription": "",
|
||||
"@kickUserDescription": {},
|
||||
"importNow": "",
|
||||
"@importNow": {},
|
||||
"invite": "",
|
||||
"@invite": {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2617,5 +2617,45 @@
|
|||
"@emoteKeyboardNoRecents": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
}
|
||||
},
|
||||
"banUserDescription": "",
|
||||
"@banUserDescription": {},
|
||||
"removeDevicesDescription": "",
|
||||
"@removeDevicesDescription": {},
|
||||
"unbanUserDescription": "",
|
||||
"@unbanUserDescription": {},
|
||||
"todoLists": "",
|
||||
"@todoLists": {},
|
||||
"editTodo": "",
|
||||
"@editTodo": {},
|
||||
"pushNotificationsNotAvailable": "",
|
||||
"@pushNotificationsNotAvailable": {},
|
||||
"pleaseAddATitle": "",
|
||||
"@pleaseAddATitle": {},
|
||||
"makeAdminDescription": "",
|
||||
"@makeAdminDescription": {},
|
||||
"noTodosYet": "",
|
||||
"@noTodosYet": {},
|
||||
"archiveRoomDescription": "",
|
||||
"@archiveRoomDescription": {},
|
||||
"todosUnencrypted": "",
|
||||
"@todosUnencrypted": {},
|
||||
"hasKnocked": "",
|
||||
"@hasKnocked": {
|
||||
"placeholders": {
|
||||
"user": {}
|
||||
}
|
||||
},
|
||||
"newTodo": "",
|
||||
"@newTodo": {},
|
||||
"learnMore": "",
|
||||
"@learnMore": {},
|
||||
"todoListChangedError": "",
|
||||
"@todoListChangedError": {},
|
||||
"roomUpgradeDescription": "",
|
||||
"@roomUpgradeDescription": {},
|
||||
"pleaseEnterANumber": "",
|
||||
"@pleaseEnterANumber": {},
|
||||
"kickUserDescription": "",
|
||||
"@kickUserDescription": {}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -2617,5 +2617,45 @@
|
|||
"placeholders": {
|
||||
"seconds": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"banUserDescription": "",
|
||||
"@banUserDescription": {},
|
||||
"removeDevicesDescription": "",
|
||||
"@removeDevicesDescription": {},
|
||||
"unbanUserDescription": "",
|
||||
"@unbanUserDescription": {},
|
||||
"todoLists": "",
|
||||
"@todoLists": {},
|
||||
"editTodo": "",
|
||||
"@editTodo": {},
|
||||
"pushNotificationsNotAvailable": "",
|
||||
"@pushNotificationsNotAvailable": {},
|
||||
"pleaseAddATitle": "",
|
||||
"@pleaseAddATitle": {},
|
||||
"makeAdminDescription": "",
|
||||
"@makeAdminDescription": {},
|
||||
"noTodosYet": "",
|
||||
"@noTodosYet": {},
|
||||
"archiveRoomDescription": "",
|
||||
"@archiveRoomDescription": {},
|
||||
"todosUnencrypted": "",
|
||||
"@todosUnencrypted": {},
|
||||
"hasKnocked": "",
|
||||
"@hasKnocked": {
|
||||
"placeholders": {
|
||||
"user": {}
|
||||
}
|
||||
},
|
||||
"newTodo": "",
|
||||
"@newTodo": {},
|
||||
"learnMore": "",
|
||||
"@learnMore": {},
|
||||
"todoListChangedError": "",
|
||||
"@todoListChangedError": {},
|
||||
"roomUpgradeDescription": "",
|
||||
"@roomUpgradeDescription": {},
|
||||
"pleaseEnterANumber": "",
|
||||
"@pleaseEnterANumber": {},
|
||||
"kickUserDescription": "",
|
||||
"@kickUserDescription": {}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -2625,5 +2625,37 @@
|
|||
}
|
||||
},
|
||||
"pleaseEnterANumber": "请输入大于 0 的数",
|
||||
"@pleaseEnterANumber": {}
|
||||
"@pleaseEnterANumber": {},
|
||||
"banUserDescription": "",
|
||||
"@banUserDescription": {},
|
||||
"removeDevicesDescription": "",
|
||||
"@removeDevicesDescription": {},
|
||||
"unbanUserDescription": "",
|
||||
"@unbanUserDescription": {},
|
||||
"todoLists": "",
|
||||
"@todoLists": {},
|
||||
"editTodo": "",
|
||||
"@editTodo": {},
|
||||
"pushNotificationsNotAvailable": "",
|
||||
"@pushNotificationsNotAvailable": {},
|
||||
"pleaseAddATitle": "",
|
||||
"@pleaseAddATitle": {},
|
||||
"makeAdminDescription": "",
|
||||
"@makeAdminDescription": {},
|
||||
"noTodosYet": "",
|
||||
"@noTodosYet": {},
|
||||
"archiveRoomDescription": "",
|
||||
"@archiveRoomDescription": {},
|
||||
"todosUnencrypted": "",
|
||||
"@todosUnencrypted": {},
|
||||
"newTodo": "",
|
||||
"@newTodo": {},
|
||||
"learnMore": "",
|
||||
"@learnMore": {},
|
||||
"todoListChangedError": "",
|
||||
"@todoListChangedError": {},
|
||||
"roomUpgradeDescription": "",
|
||||
"@roomUpgradeDescription": {},
|
||||
"kickUserDescription": "",
|
||||
"@kickUserDescription": {}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -94,16 +94,16 @@
|
|||
code</a>
|
||||
-
|
||||
<a class="text-slate-700 dark:text-slate-200 no-underline hover:text-purple-800"
|
||||
href="https://github.com/krille-chan/fluffychat/-/blob/main/PRIVACY.md">Privacy</a>
|
||||
href="https://github.com/krille-chan/fluffychat/blob/main/PRIVACY.md">Privacy</a>
|
||||
-
|
||||
<a class="text-slate-700 dark:text-slate-200 no-underline hover:text-purple-800"
|
||||
href="https://github.com/krille-chan/fluffychat/-/blob/main/CHANGELOG.md">Changelog</a>
|
||||
href="https://github.com/krille-chan/fluffychat/blob/main/CHANGELOG.md">Changelog</a>
|
||||
-
|
||||
<a class="text-slate-700 dark:text-slate-200 no-underline hover:text-purple-800"
|
||||
href="https://hosted.weblate.org/projects/fluffychat/">Translations</a>
|
||||
-
|
||||
<a class="text-slate-700 dark:text-slate-200 no-underline hover:text-purple-800"
|
||||
href="https://github.com/krille-chan/fluffychat/-/blob/main/docs/fdroid_repo.md">FluffyChat F-Droid
|
||||
href="https://github.com/krille-chan/fluffychat/blob/main/docs/fdroid_repo.md">FluffyChat F-Droid
|
||||
repository</a>
|
||||
-
|
||||
<a class="text-slate-700 dark:text-slate-200 no-underline hover:text-purple-800"
|
||||
|
|
|
|||
|
|
@ -38,6 +38,8 @@ abstract class AppConfig {
|
|||
'https://github.com/krille-chan/fluffychat/wiki/Push-Notifications-without-Google-Services';
|
||||
static const String encryptionTutorial =
|
||||
'https://github.com/krille-chan/fluffychat/wiki/How-to-use-end-to-end-encryption-in-FluffyChat';
|
||||
static const String startChatTutorial =
|
||||
'https://github.com/krille-chan/fluffychat/wiki/How-to-Find-Users-in-FluffyChat';
|
||||
static const String appId = 'im.fluffychat.FluffyChat';
|
||||
// #Pangea
|
||||
// static const String appOpenUrlScheme = 'im.fluffychat';
|
||||
|
|
|
|||
|
|
@ -52,6 +52,11 @@ void main() async {
|
|||
// currently only supported on Android.
|
||||
if (PlatformInfos.isAndroid &&
|
||||
AppLifecycleState.detached == WidgetsBinding.instance.lifecycleState) {
|
||||
// Do not send online presences when app is in background fetch mode.
|
||||
for (final client in clients) {
|
||||
client.syncPresence = PresenceType.offline;
|
||||
}
|
||||
|
||||
// In the background fetch mode we do not want to waste ressources with
|
||||
// starting the Flutter engine but process incoming push notifications.
|
||||
BackgroundPush.clientOnly(clients.first);
|
||||
|
|
@ -109,6 +114,10 @@ class AppStarter with WidgetsBindingObserver {
|
|||
Logs().i(
|
||||
'${AppConfig.applicationName} switches from the detached background-fetch mode to ${state.name} mode. Rendering GUI...',
|
||||
);
|
||||
// Switching to foreground mode needs to reenable send online sync presence.
|
||||
for (final client in clients) {
|
||||
client.syncPresence = PresenceType.online;
|
||||
}
|
||||
startGui(clients, store);
|
||||
// We must make sure that the GUI is only started once.
|
||||
guiStarted = true;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
import 'package:fluffychat/config/themes.dart';
|
||||
import 'package:fluffychat/pages/chat/chat.dart';
|
||||
import 'package:fluffychat/utils/date_time_extension.dart';
|
||||
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
|
||||
import 'package:fluffychat/widgets/avatar.dart';
|
||||
import 'package:fluffychat/widgets/presence_builder.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
|
@ -32,17 +35,48 @@ class ChatAppBarTitle extends StatelessWidget {
|
|||
MatrixLocals(L10n.of(context)!),
|
||||
),
|
||||
size: 32,
|
||||
presenceUserId: room.directChatMatrixID,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
Expanded(
|
||||
child: Text(
|
||||
room.getLocalizedDisplayname(MatrixLocals(L10n.of(context)!)),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: const TextStyle(
|
||||
fontSize: 16,
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
room.getLocalizedDisplayname(MatrixLocals(L10n.of(context)!)),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: const TextStyle(
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
AnimatedSize(
|
||||
duration: FluffyThemes.animationDuration,
|
||||
child: PresenceBuilder(
|
||||
userId: room.directChatMatrixID,
|
||||
builder: (context, presence) {
|
||||
final lastActiveTimestamp = presence?.lastActiveTimestamp;
|
||||
final style = Theme.of(context).textTheme.bodySmall;
|
||||
if (presence?.currentlyActive == true) {
|
||||
return Text(
|
||||
L10n.of(context)!.currentlyActive,
|
||||
style: style,
|
||||
);
|
||||
}
|
||||
if (lastActiveTimestamp != null) {
|
||||
return Text(
|
||||
L10n.of(context)!.lastActiveAgo(
|
||||
lastActiveTimestamp.localizedTimeShort(context),
|
||||
),
|
||||
style: style,
|
||||
);
|
||||
}
|
||||
return const SizedBox.shrink();
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
|
|
|
|||
|
|
@ -149,16 +149,15 @@ class ChatView extends StatelessWidget {
|
|||
final bottomSheetPadding = FluffyThemes.isColumnMode(context) ? 16.0 : 8.0;
|
||||
final scrollUpBannerEventId = controller.scrollUpBannerEventId;
|
||||
|
||||
return WillPopScope(
|
||||
onWillPop: () async {
|
||||
return PopScope(
|
||||
canPop: controller.selectedEvents.isEmpty && !controller.showEmojiPicker,
|
||||
onPopInvoked: (pop) async {
|
||||
if (pop) return;
|
||||
if (controller.selectedEvents.isNotEmpty) {
|
||||
controller.clearSelectedEvents();
|
||||
return false;
|
||||
} else if (controller.showEmojiPicker) {
|
||||
controller.emojiPickerAction();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
child: GestureDetector(
|
||||
onTapDown: (_) => controller.setReadMarker(),
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@ class EventInfoDialog extends StatelessWidget {
|
|||
leading: Avatar(
|
||||
mxContent: event.senderFromMemoryOrFallback.avatarUrl,
|
||||
name: event.senderFromMemoryOrFallback.calcDisplayname(),
|
||||
client: event.room.client,
|
||||
presenceUserId: event.senderId,
|
||||
),
|
||||
title: Text(L10n.of(context)!.sender),
|
||||
subtitle: Text(
|
||||
|
|
|
|||
|
|
@ -140,7 +140,11 @@ class HtmlMessage extends StatelessWidget {
|
|||
const ImageExtension(),
|
||||
FontColorExtension(),
|
||||
],
|
||||
onLinkTap: (url, _, __) => UrlLauncher(context, url).launchUrl(),
|
||||
onLinkTap: (url, _, element) => UrlLauncher(
|
||||
context,
|
||||
url,
|
||||
element?.text,
|
||||
).launchUrl(),
|
||||
onlyRenderTheseTags: const {
|
||||
...allowedHtmlTags,
|
||||
// Needed to make it work properly
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import 'package:fluffychat/config/app_config.dart';
|
||||
import 'package:fluffychat/pages/image_viewer/image_viewer.dart';
|
||||
import 'package:fluffychat/widgets/mxc_image.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
|
@ -15,6 +16,7 @@ class ImageBubble extends StatelessWidget {
|
|||
final double width;
|
||||
final double height;
|
||||
final void Function()? onTap;
|
||||
final BorderRadius? borderRadius;
|
||||
|
||||
const ImageBubble(
|
||||
this.event, {
|
||||
|
|
@ -27,6 +29,7 @@ class ImageBubble extends StatelessWidget {
|
|||
this.height = 300,
|
||||
this.animated = false,
|
||||
this.onTap,
|
||||
this.borderRadius,
|
||||
super.key,
|
||||
});
|
||||
|
||||
|
|
@ -47,8 +50,10 @@ class ImageBubble extends StatelessWidget {
|
|||
var height = 32;
|
||||
if (ratio > 1.0) {
|
||||
height = (width / ratio).round();
|
||||
if (height <= 0) height = 1;
|
||||
} else {
|
||||
width = (height * ratio).round();
|
||||
if (width <= 0) width = 1;
|
||||
}
|
||||
return SizedBox(
|
||||
width: this.width,
|
||||
|
|
@ -77,19 +82,25 @@ class ImageBubble extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return InkWell(
|
||||
onTap: () => _onTap(context),
|
||||
child: Hero(
|
||||
tag: event.eventId,
|
||||
child: AnimatedSwitcher(
|
||||
duration: const Duration(seconds: 1),
|
||||
child: Container(
|
||||
final borderRadius =
|
||||
this.borderRadius ?? BorderRadius.circular(AppConfig.borderRadius);
|
||||
return Material(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: borderRadius,
|
||||
side: BorderSide(color: Theme.of(context).dividerColor),
|
||||
),
|
||||
child: InkWell(
|
||||
onTap: () => _onTap(context),
|
||||
borderRadius: borderRadius,
|
||||
child: Hero(
|
||||
tag: event.eventId,
|
||||
child: ConstrainedBox(
|
||||
constraints: maxSize
|
||||
? BoxConstraints(
|
||||
maxWidth: width,
|
||||
maxHeight: height,
|
||||
)
|
||||
: null,
|
||||
: const BoxConstraints.expand(),
|
||||
child: MxcImage(
|
||||
event: event,
|
||||
width: width,
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ import 'package:matrix/matrix.dart';
|
|||
import 'package:swipe_to_action/swipe_to_action.dart';
|
||||
|
||||
import '../../../config/app_config.dart';
|
||||
import '../../../widgets/hover_builder.dart';
|
||||
import 'message_content.dart';
|
||||
import 'message_reactions.dart';
|
||||
import 'reply_content.dart';
|
||||
|
|
@ -23,10 +22,10 @@ class Message extends StatelessWidget {
|
|||
final Event event;
|
||||
final Event? nextEvent;
|
||||
final bool displayReadMarker;
|
||||
final void Function(Event)? onSelect;
|
||||
final void Function(Event)? onAvatarTab;
|
||||
final void Function(Event)? onInfoTab;
|
||||
final void Function(String)? scrollToEventId;
|
||||
final void Function(Event) onSelect;
|
||||
final void Function(Event) onAvatarTab;
|
||||
final void Function(Event) onInfoTab;
|
||||
final void Function(String) scrollToEventId;
|
||||
final void Function() onSwipe;
|
||||
final bool longPressSelect;
|
||||
final bool selected;
|
||||
|
|
@ -35,17 +34,17 @@ class Message extends StatelessWidget {
|
|||
final LanguageModel? selectedDisplayLang;
|
||||
final bool immersionMode;
|
||||
final bool definitions;
|
||||
// #Pangea
|
||||
// Pangea#
|
||||
|
||||
const Message(
|
||||
this.event, {
|
||||
this.nextEvent,
|
||||
this.displayReadMarker = false,
|
||||
this.longPressSelect = false,
|
||||
this.onSelect,
|
||||
this.onInfoTab,
|
||||
this.onAvatarTab,
|
||||
this.scrollToEventId,
|
||||
required this.onSelect,
|
||||
required this.onInfoTab,
|
||||
required this.onAvatarTab,
|
||||
required this.scrollToEventId,
|
||||
required this.onSwipe,
|
||||
this.selected = false,
|
||||
required this.timeline,
|
||||
|
|
@ -53,7 +52,7 @@ class Message extends StatelessWidget {
|
|||
required this.selectedDisplayLang,
|
||||
required this.immersionMode,
|
||||
required this.definitions,
|
||||
// #Pangea
|
||||
// Pangea#
|
||||
super.key,
|
||||
});
|
||||
|
||||
|
|
@ -129,231 +128,218 @@ class Message extends StatelessWidget {
|
|||
: Theme.of(context).colorScheme.primaryContainer;
|
||||
}
|
||||
|
||||
//#Pangea
|
||||
// #Pangea
|
||||
final pangeaMessageEvent = PangeaMessageEvent(
|
||||
event: event,
|
||||
timeline: timeline,
|
||||
ownMessage: ownMessage,
|
||||
selected: selected,
|
||||
);
|
||||
//#Pangea
|
||||
// Pangea#
|
||||
|
||||
final row = HoverBuilder(
|
||||
builder: (context, hovered) => Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: rowMainAxisAlignment,
|
||||
children: [
|
||||
if (hovered || selected)
|
||||
SizedBox(
|
||||
width: Avatar.defaultSize,
|
||||
height: Avatar.defaultSize - 8,
|
||||
child: Checkbox.adaptive(
|
||||
value: selected,
|
||||
onChanged: (_) => onSelect?.call(event),
|
||||
final row = Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: rowMainAxisAlignment,
|
||||
children: [
|
||||
if (sameSender || ownMessage)
|
||||
SizedBox(
|
||||
width: Avatar.defaultSize,
|
||||
child: Center(
|
||||
child: SizedBox(
|
||||
width: 16,
|
||||
height: 16,
|
||||
child: event.status == EventStatus.sending
|
||||
? const CircularProgressIndicator.adaptive(
|
||||
strokeWidth: 2,
|
||||
)
|
||||
: event.status == EventStatus.error
|
||||
? const Icon(Icons.error, color: Colors.red)
|
||||
: null,
|
||||
),
|
||||
)
|
||||
else if (sameSender || ownMessage)
|
||||
SizedBox(
|
||||
width: Avatar.defaultSize,
|
||||
child: Center(
|
||||
child: SizedBox(
|
||||
width: 16,
|
||||
height: 16,
|
||||
child: event.status == EventStatus.sending
|
||||
? const CircularProgressIndicator.adaptive(
|
||||
strokeWidth: 2,
|
||||
)
|
||||
: event.status == EventStatus.error
|
||||
? const Icon(Icons.error, color: Colors.red)
|
||||
: null,
|
||||
),
|
||||
),
|
||||
)
|
||||
else
|
||||
FutureBuilder<User?>(
|
||||
future: event.fetchSenderUser(),
|
||||
builder: (context, snapshot) {
|
||||
final user = snapshot.data ?? event.senderFromMemoryOrFallback;
|
||||
return Avatar(
|
||||
mxContent: user.avatarUrl,
|
||||
name: user.calcDisplayname(),
|
||||
onTap: () => onAvatarTab!(event),
|
||||
);
|
||||
},
|
||||
),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
if (!sameSender)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 8.0, bottom: 4),
|
||||
child: ownMessage || event.room.isDirectChat
|
||||
? const SizedBox(height: 12)
|
||||
: FutureBuilder<User?>(
|
||||
future: event.fetchSenderUser(),
|
||||
builder: (context, snapshot) {
|
||||
final displayname =
|
||||
snapshot.data?.calcDisplayname() ??
|
||||
event.senderFromMemoryOrFallback
|
||||
.calcDisplayname();
|
||||
return Text(
|
||||
displayname,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: (Theme.of(context).brightness ==
|
||||
Brightness.light
|
||||
? displayname.color
|
||||
: displayname.lightColorText),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
Container(
|
||||
alignment: alignment,
|
||||
padding: const EdgeInsets.only(left: 8),
|
||||
child: Material(
|
||||
color: noBubble ? Colors.transparent : color,
|
||||
borderRadius: borderRadius,
|
||||
clipBehavior: Clip.antiAlias,
|
||||
// #Pangea
|
||||
child: CompositedTransformTarget(
|
||||
link: MatrixState.pAnyState
|
||||
.layerLinkAndKey(event.eventId)
|
||||
.link,
|
||||
child: Container(
|
||||
key: MatrixState.pAnyState
|
||||
.layerLinkAndKey(event.eventId)
|
||||
.key,
|
||||
// #Pangea
|
||||
decoration: BoxDecoration(
|
||||
borderRadius:
|
||||
BorderRadius.circular(AppConfig.borderRadius),
|
||||
),
|
||||
padding: noBubble || noPadding
|
||||
? EdgeInsets.zero
|
||||
: const EdgeInsets.symmetric(
|
||||
horizontal: 16,
|
||||
vertical: 8,
|
||||
)
|
||||
else
|
||||
FutureBuilder<User?>(
|
||||
future: event.fetchSenderUser(),
|
||||
builder: (context, snapshot) {
|
||||
final user = snapshot.data ?? event.senderFromMemoryOrFallback;
|
||||
return Avatar(
|
||||
mxContent: user.avatarUrl,
|
||||
name: user.calcDisplayname(),
|
||||
presenceUserId: user.stateKey,
|
||||
onTap: () => onAvatarTab(event),
|
||||
);
|
||||
},
|
||||
),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
if (!sameSender)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 8.0, bottom: 4),
|
||||
child: ownMessage || event.room.isDirectChat
|
||||
? const SizedBox(height: 12)
|
||||
: FutureBuilder<User?>(
|
||||
future: event.fetchSenderUser(),
|
||||
builder: (context, snapshot) {
|
||||
final displayname =
|
||||
snapshot.data?.calcDisplayname() ??
|
||||
event.senderFromMemoryOrFallback
|
||||
.calcDisplayname();
|
||||
return Text(
|
||||
displayname,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: (Theme.of(context).brightness ==
|
||||
Brightness.light
|
||||
? displayname.color
|
||||
: displayname.lightColorText),
|
||||
),
|
||||
constraints: const BoxConstraints(
|
||||
maxWidth: FluffyThemes.columnWidth * 1.5,
|
||||
);
|
||||
},
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
if (event.relationshipType ==
|
||||
RelationshipTypes.reply)
|
||||
FutureBuilder<Event?>(
|
||||
future: event.getReplyEvent(timeline),
|
||||
builder: (BuildContext context, snapshot) {
|
||||
final replyEvent = snapshot.hasData
|
||||
? snapshot.data!
|
||||
: Event(
|
||||
eventId: event.relationshipEventId!,
|
||||
content: {
|
||||
'msgtype': 'm.text',
|
||||
'body': '...',
|
||||
},
|
||||
senderId: event.senderId,
|
||||
type: 'm.room.message',
|
||||
room: event.room,
|
||||
status: EventStatus.sent,
|
||||
originServerTs: DateTime.now(),
|
||||
);
|
||||
return InkWell(
|
||||
onTap: () {
|
||||
if (scrollToEventId != null) {
|
||||
scrollToEventId!(replyEvent.eventId);
|
||||
}
|
||||
},
|
||||
child: AbsorbPointer(
|
||||
child: Container(
|
||||
margin: const EdgeInsets.symmetric(
|
||||
vertical: 4.0,
|
||||
),
|
||||
child: ReplyContent(
|
||||
replyEvent,
|
||||
ownMessage: ownMessage,
|
||||
timeline: timeline,
|
||||
),
|
||||
),
|
||||
Container(
|
||||
alignment: alignment,
|
||||
padding: const EdgeInsets.only(left: 8),
|
||||
child: Material(
|
||||
color: noBubble ? Colors.transparent : color,
|
||||
borderRadius: borderRadius,
|
||||
clipBehavior: Clip.antiAlias,
|
||||
// #Pangea
|
||||
child: CompositedTransformTarget(
|
||||
link: MatrixState.pAnyState
|
||||
.layerLinkAndKey(event.eventId)
|
||||
.link,
|
||||
child: Container(
|
||||
key: MatrixState.pAnyState
|
||||
.layerLinkAndKey(event.eventId)
|
||||
.key,
|
||||
// Pangea#
|
||||
decoration: BoxDecoration(
|
||||
borderRadius:
|
||||
BorderRadius.circular(AppConfig.borderRadius),
|
||||
),
|
||||
padding: noBubble || noPadding
|
||||
? EdgeInsets.zero
|
||||
: const EdgeInsets.symmetric(
|
||||
horizontal: 16,
|
||||
vertical: 8,
|
||||
),
|
||||
constraints: const BoxConstraints(
|
||||
maxWidth: FluffyThemes.columnWidth * 1.5,
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
if (event.relationshipType == RelationshipTypes.reply)
|
||||
FutureBuilder<Event?>(
|
||||
future: event.getReplyEvent(timeline),
|
||||
builder: (BuildContext context, snapshot) {
|
||||
final replyEvent = snapshot.hasData
|
||||
? snapshot.data!
|
||||
: Event(
|
||||
eventId: event.relationshipEventId!,
|
||||
content: {
|
||||
'msgtype': 'm.text',
|
||||
'body': '...',
|
||||
},
|
||||
senderId: event.senderId,
|
||||
type: 'm.room.message',
|
||||
room: event.room,
|
||||
status: EventStatus.sent,
|
||||
originServerTs: DateTime.now(),
|
||||
);
|
||||
return InkWell(
|
||||
onTap: () =>
|
||||
scrollToEventId(replyEvent.eventId),
|
||||
child: AbsorbPointer(
|
||||
child: Container(
|
||||
margin: const EdgeInsets.symmetric(
|
||||
vertical: 4.0,
|
||||
),
|
||||
child: ReplyContent(
|
||||
replyEvent,
|
||||
ownMessage: ownMessage,
|
||||
timeline: timeline,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
MessageContent(
|
||||
displayEvent,
|
||||
textColor: textColor,
|
||||
onInfoTab: onInfoTab,
|
||||
// #Pangea
|
||||
selected: selected,
|
||||
pangeaMessageEvent: pangeaMessageEvent,
|
||||
selectedDisplayLang: selectedDisplayLang,
|
||||
immersionMode: immersionMode,
|
||||
definitions: definitions,
|
||||
// Pangea#
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
if (event.hasAggregatedEvents(
|
||||
timeline,
|
||||
RelationshipTypes.edit,
|
||||
)
|
||||
// #Pangea
|
||||
||
|
||||
(pangeaMessageEvent.showUseType)
|
||||
// #Pangea
|
||||
)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
top: 4.0,
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
// #Pangea
|
||||
if (pangeaMessageEvent.showUseType) ...[
|
||||
pangeaMessageEvent.useType.iconView(
|
||||
context,
|
||||
textColor.withAlpha(164),
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
],
|
||||
if (event.hasAggregatedEvents(
|
||||
timeline,
|
||||
RelationshipTypes.edit,
|
||||
)) ...[
|
||||
// #Pangea
|
||||
Icon(
|
||||
Icons.edit_outlined,
|
||||
color: textColor.withAlpha(164),
|
||||
size: 14,
|
||||
),
|
||||
Text(
|
||||
' - ${displayEvent.originServerTs.localizedTimeShort(context)}',
|
||||
style: TextStyle(
|
||||
color: textColor.withAlpha(164),
|
||||
fontSize: 12,
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
MessageContent(
|
||||
displayEvent,
|
||||
textColor: textColor,
|
||||
onInfoTab: onInfoTab,
|
||||
borderRadius: borderRadius,
|
||||
// #Pangea
|
||||
selected: selected,
|
||||
pangeaMessageEvent: pangeaMessageEvent,
|
||||
selectedDisplayLang: selectedDisplayLang,
|
||||
immersionMode: immersionMode,
|
||||
definitions: definitions,
|
||||
// Pangea#
|
||||
),
|
||||
if (event.hasAggregatedEvents(
|
||||
timeline,
|
||||
RelationshipTypes.edit,
|
||||
)
|
||||
// #Pangea
|
||||
||
|
||||
(pangeaMessageEvent.showUseType)
|
||||
// Pangea#
|
||||
)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
top: 4.0,
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
// #Pangea
|
||||
if (pangeaMessageEvent.showUseType) ...[
|
||||
pangeaMessageEvent.useType.iconView(
|
||||
context,
|
||||
textColor.withAlpha(164),
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
],
|
||||
if (event.hasAggregatedEvents(
|
||||
timeline,
|
||||
RelationshipTypes.edit,
|
||||
)) ...[
|
||||
// Pangea#
|
||||
Icon(
|
||||
Icons.edit_outlined,
|
||||
color: textColor.withAlpha(164),
|
||||
size: 14,
|
||||
),
|
||||
Text(
|
||||
' - ${displayEvent.originServerTs.localizedTimeShort(context)}',
|
||||
style: TextStyle(
|
||||
color: textColor.withAlpha(164),
|
||||
fontSize: 12,
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
Widget container;
|
||||
if (event.hasAggregatedEvents(timeline, RelationshipTypes.reaction) ||
|
||||
|
|
@ -452,23 +438,20 @@ class Message extends StatelessWidget {
|
|||
),
|
||||
direction: SwipeDirection.endToStart,
|
||||
onSwipe: (_) => onSwipe(),
|
||||
child: Center(
|
||||
child: InkWell(
|
||||
onTap: longPressSelect ? () => onSelect!(event) : null,
|
||||
onLongPress: () => onSelect!(event),
|
||||
child: Container(
|
||||
color: selected
|
||||
? Theme.of(context).primaryColor.withAlpha(100)
|
||||
: Theme.of(context).primaryColor.withAlpha(0),
|
||||
constraints: const BoxConstraints(
|
||||
maxWidth: FluffyThemes.columnWidth * 2.5,
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 8.0,
|
||||
vertical: 4.0,
|
||||
),
|
||||
child: container,
|
||||
child: InkWell(
|
||||
onTap: () => onSelect(event),
|
||||
child: Container(
|
||||
color: selected
|
||||
? Theme.of(context).primaryColor.withAlpha(100)
|
||||
: Theme.of(context).primaryColor.withAlpha(0),
|
||||
constraints: const BoxConstraints(
|
||||
maxWidth: FluffyThemes.columnWidth * 2.5,
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 8.0,
|
||||
vertical: 4.0,
|
||||
),
|
||||
child: container,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ class MessageContent extends StatelessWidget {
|
|||
final Event event;
|
||||
final Color textColor;
|
||||
final void Function(Event)? onInfoTab;
|
||||
final BorderRadius borderRadius;
|
||||
// #Pangea
|
||||
final bool selected;
|
||||
final PangeaMessageEvent pangeaMessageEvent;
|
||||
|
|
@ -49,6 +50,7 @@ class MessageContent extends StatelessWidget {
|
|||
required this.immersionMode,
|
||||
required this.definitions,
|
||||
// Pangea#
|
||||
required this.borderRadius,
|
||||
});
|
||||
|
||||
void _verifyOrRequestKey(BuildContext context) async {
|
||||
|
|
@ -97,6 +99,7 @@ class MessageContent extends StatelessWidget {
|
|||
leading: Avatar(
|
||||
mxContent: sender.avatarUrl,
|
||||
name: sender.calcDisplayname(),
|
||||
presenceUserId: sender.stateKey,
|
||||
),
|
||||
title: Text(sender.calcDisplayname()),
|
||||
subtitle: Text(event.originServerTs.localizedTime(context)),
|
||||
|
|
@ -130,6 +133,7 @@ class MessageContent extends StatelessWidget {
|
|||
width: 400,
|
||||
height: 300,
|
||||
fit: BoxFit.cover,
|
||||
borderRadius: borderRadius,
|
||||
);
|
||||
case MessageTypes.Sticker:
|
||||
if (event.redacted) continue textmessage;
|
||||
|
|
|
|||
|
|
@ -208,6 +208,7 @@ class _AdaptableReactorsDialog extends StatelessWidget {
|
|||
mxContent: reactor.avatarUrl,
|
||||
name: reactor.displayName,
|
||||
client: client,
|
||||
presenceUserId: reactor.stateKey,
|
||||
),
|
||||
label: Text(reactor.displayName!),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ class EventVideoPlayerState extends State<EventVideoPlayer> {
|
|||
);
|
||||
} else if (!kIsWeb && tmpFile != null && _chewieManager == null) {
|
||||
_chewieManager ??= ChewieController(
|
||||
useRootNavigator: false,
|
||||
videoPlayerController: VideoPlayerController.file(tmpFile),
|
||||
autoPlay: true,
|
||||
autoInitialize: true,
|
||||
|
|
|
|||
|
|
@ -103,8 +103,11 @@ class ParticipantListItem extends StatelessWidget {
|
|||
],
|
||||
),
|
||||
subtitle: Text(user.id),
|
||||
leading:
|
||||
Avatar(mxContent: user.avatarUrl, name: user.calcDisplayname()),
|
||||
leading: Avatar(
|
||||
mxContent: user.avatarUrl,
|
||||
name: user.calcDisplayname(),
|
||||
presenceUserId: user.stateKey,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ class ChatListHeader extends StatelessWidget implements PreferredSizeWidget {
|
|||
// borderSide: BorderSide.none,
|
||||
// borderRadius: BorderRadius.circular(99),
|
||||
// ),
|
||||
// hintText: L10n.of(context)!.search,
|
||||
// hintText: L10n.of(context)!.searchChatsRooms,
|
||||
// floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
// prefixIcon: controller.isSearchMode
|
||||
// ? IconButton(
|
||||
|
|
|
|||
|
|
@ -159,6 +159,11 @@ class ChatListItem extends StatelessWidget {
|
|||
: 14.0
|
||||
: 0.0;
|
||||
final hasNotifications = room.notificationCount > 0;
|
||||
final backgroundColor = selected
|
||||
? Theme.of(context).colorScheme.primaryContainer
|
||||
: activeChat
|
||||
? Theme.of(context).colorScheme.secondaryContainer
|
||||
: null;
|
||||
final displayname = room.getLocalizedDisplayname(
|
||||
MatrixLocals(L10n.of(context)!),
|
||||
);
|
||||
|
|
@ -170,11 +175,7 @@ class ChatListItem extends StatelessWidget {
|
|||
child: Material(
|
||||
borderRadius: BorderRadius.circular(AppConfig.borderRadius),
|
||||
clipBehavior: Clip.hardEdge,
|
||||
color: selected
|
||||
? Theme.of(context).colorScheme.primaryContainer
|
||||
: activeChat
|
||||
? Theme.of(context).colorScheme.secondaryContainer
|
||||
: Colors.transparent,
|
||||
color: backgroundColor,
|
||||
child: ListTile(
|
||||
visualDensity: const VisualDensity(vertical: -0.5),
|
||||
contentPadding: const EdgeInsets.symmetric(horizontal: 8),
|
||||
|
|
@ -196,6 +197,8 @@ class ChatListItem extends StatelessWidget {
|
|||
//#Pangea
|
||||
littleIcon: room.roomTypeIcon,
|
||||
// Pangea#
|
||||
presenceUserId: room.directChatMatrixID,
|
||||
presenceBackgroundColor: backgroundColor,
|
||||
),
|
||||
title: Row(
|
||||
children: <Widget>[
|
||||
|
|
|
|||
|
|
@ -98,16 +98,23 @@ class ChatListView extends StatelessWidget {
|
|||
stream: Matrix.of(context).onShareContentChanged.stream,
|
||||
builder: (_, __) {
|
||||
final selectMode = controller.selectMode;
|
||||
return WillPopScope(
|
||||
onWillPop: () async {
|
||||
return PopScope(
|
||||
canPop: controller.selectMode == SelectMode.normal &&
|
||||
!controller.isSearchMode &&
|
||||
controller.activeFilter ==
|
||||
(AppConfig.separateChatTypes
|
||||
? ActiveFilter.messages
|
||||
: ActiveFilter.allChats),
|
||||
onPopInvoked: (pop) async {
|
||||
if (pop) return;
|
||||
final selMode = controller.selectMode;
|
||||
if (controller.isSearchMode) {
|
||||
controller.cancelSearch();
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
if (selMode != SelectMode.normal) {
|
||||
controller.cancelAction();
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
if (controller.activeFilter !=
|
||||
(AppConfig.separateChatTypes
|
||||
|
|
@ -115,9 +122,8 @@ class ChatListView extends StatelessWidget {
|
|||
: ActiveFilter.allChats)) {
|
||||
controller
|
||||
.onDestinationSelected(AppConfig.separateChatTypes ? 1 : 0);
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
child: Row(
|
||||
children: [
|
||||
|
|
|
|||
|
|
@ -395,13 +395,13 @@ class _SpaceViewState extends State<SpaceView> {
|
|||
// Pangea#
|
||||
|
||||
final canLoadMore = response.nextBatch != null;
|
||||
return WillPopScope(
|
||||
onWillPop: () async {
|
||||
return PopScope(
|
||||
canPop: parentSpace == null,
|
||||
onPopInvoked: (pop) async {
|
||||
if (pop) return;
|
||||
if (parentSpace != null) {
|
||||
widget.controller.setActiveSpace(parentSpace.id);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
child: CustomScrollView(
|
||||
controller: widget.scrollController,
|
||||
|
|
|
|||
|
|
@ -167,6 +167,7 @@ class _InviteContactListTile extends StatelessWidget {
|
|||
leading: Avatar(
|
||||
mxContent: avatarUrl,
|
||||
name: displayname,
|
||||
presenceUserId: userId,
|
||||
),
|
||||
title: Text(
|
||||
displayname,
|
||||
|
|
|
|||
|
|
@ -1,18 +1,16 @@
|
|||
import 'dart:developer';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
import 'package:fluffychat/pages/new_group/new_group_view.dart';
|
||||
import 'package:fluffychat/pangea/controllers/pangea_controller.dart';
|
||||
import 'package:fluffychat/pangea/models/chat_topic_model.dart';
|
||||
import 'package:fluffychat/pangea/models/lemma.dart';
|
||||
import 'package:fluffychat/pangea/utils/class_chat_power_levels.dart';
|
||||
import 'package:fluffychat/pangea/utils/error_handler.dart';
|
||||
import 'package:fluffychat/pangea/utils/firebase_analytics.dart';
|
||||
import 'package:fluffychat/pangea/widgets/class/add_space_toggles.dart';
|
||||
import 'package:fluffychat/widgets/matrix.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:future_loading_dialog/future_loading_dialog.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:matrix/matrix.dart' as sdk;
|
||||
|
||||
|
|
@ -24,25 +22,53 @@ class NewGroup extends StatefulWidget {
|
|||
}
|
||||
|
||||
class NewGroupController extends State<NewGroup> {
|
||||
TextEditingController controller = TextEditingController();
|
||||
bool publicGroup = false;
|
||||
TextEditingController nameController = TextEditingController();
|
||||
|
||||
//#Pangea
|
||||
TextEditingController topicController = TextEditingController();
|
||||
|
||||
bool publicGroup = false;
|
||||
bool groupCanBeFound = true;
|
||||
|
||||
Uint8List? avatar;
|
||||
|
||||
Uri? avatarUrl;
|
||||
|
||||
Object? error;
|
||||
|
||||
bool loading = false;
|
||||
|
||||
// #Pangea
|
||||
PangeaController pangeaController = MatrixState.pangeaController;
|
||||
final GlobalKey<AddToSpaceState> addToSpaceKey = GlobalKey<AddToSpaceState>();
|
||||
|
||||
ChatTopic chatTopic = ChatTopic.empty;
|
||||
|
||||
void setVocab(List<Lemma> vocab) => setState(() => chatTopic.vocab = vocab);
|
||||
|
||||
String? get activeSpaceId =>
|
||||
GoRouterState.of(context).pathParameters['spaceid'];
|
||||
// Pangea#
|
||||
|
||||
void setPublicGroup(bool b) => setState(() => publicGroup = b);
|
||||
|
||||
void setGroupCanBeFound(bool b) => setState(() => groupCanBeFound = b);
|
||||
|
||||
void selectPhoto() async {
|
||||
final photo = await FilePicker.platform.pickFiles(
|
||||
type: FileType.image,
|
||||
allowMultiple: false,
|
||||
withData: true,
|
||||
);
|
||||
|
||||
setState(() {
|
||||
avatarUrl = null;
|
||||
avatar = photo?.files.singleOrNull?.bytes;
|
||||
});
|
||||
}
|
||||
|
||||
void submitAction([_]) async {
|
||||
// #Pangea
|
||||
if (controller.text.isEmpty) {
|
||||
if (nameController.text.isEmpty) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(L10n.of(context)!.emptyChatNameWarning),
|
||||
|
|
@ -52,48 +78,68 @@ class NewGroupController extends State<NewGroup> {
|
|||
}
|
||||
// Pangea#
|
||||
final client = Matrix.of(context).client;
|
||||
final roomID = await showFutureLoadingDialog(
|
||||
context: context,
|
||||
future: () async {
|
||||
final roomId = await client.createGroupChat(
|
||||
// #Pangea
|
||||
// visibility:
|
||||
// publicGroup ? sdk.Visibility.public : sdk.Visibility.private,
|
||||
// preset: publicGroup
|
||||
// ? sdk.CreateRoomPreset.publicChat
|
||||
// : sdk.CreateRoomPreset.privateChat,
|
||||
preset: sdk.CreateRoomPreset.publicChat,
|
||||
groupName: controller.text.isNotEmpty ? controller.text : null,
|
||||
powerLevelContentOverride:
|
||||
await ClassChatPowerLevels.powerLevelOverrideForClassChat(
|
||||
context,
|
||||
addToSpaceKey.currentState!.parents
|
||||
.map((suggestionStatus) => suggestionStatus.room)
|
||||
.toList(),
|
||||
),
|
||||
// Pangea#
|
||||
|
||||
try {
|
||||
setState(() {
|
||||
loading = true;
|
||||
error = null;
|
||||
});
|
||||
|
||||
final avatar = this.avatar;
|
||||
avatarUrl ??= avatar == null ? null : await client.uploadContent(avatar);
|
||||
|
||||
if (!mounted) return;
|
||||
|
||||
final roomId = await client.createGroupChat(
|
||||
// #Pangea
|
||||
// visibility:
|
||||
// publicGroup ? sdk.Visibility.public : sdk.Visibility.private,
|
||||
// preset: publicGroup
|
||||
// ? sdk.CreateRoomPreset.publicChat
|
||||
// : sdk.CreateRoomPreset.privateChat,
|
||||
// groupName: nameController.text.isNotEmpty ? nameController.text : null,
|
||||
// initialState: [
|
||||
// if (topicController.text.isNotEmpty)
|
||||
// sdk.StateEvent(
|
||||
// type: sdk.EventTypes.RoomTopic,
|
||||
// content: {'topic': topicController.text},
|
||||
// ),
|
||||
// if (avatar != null)
|
||||
// sdk.StateEvent(
|
||||
// type: sdk.EventTypes.RoomAvatar,
|
||||
// content: {'url': avatarUrl.toString()},
|
||||
// ),
|
||||
// ],
|
||||
groupName: nameController.text,
|
||||
preset: sdk.CreateRoomPreset.publicChat,
|
||||
powerLevelContentOverride:
|
||||
await ClassChatPowerLevels.powerLevelOverrideForClassChat(
|
||||
context,
|
||||
addToSpaceKey.currentState!.parents
|
||||
.map((suggestionStatus) => suggestionStatus.room)
|
||||
.toList(),
|
||||
),
|
||||
// Pangea#
|
||||
);
|
||||
if (!mounted) return;
|
||||
if (publicGroup && groupCanBeFound) {
|
||||
await client.setRoomVisibilityOnDirectory(
|
||||
roomId,
|
||||
visibility: sdk.Visibility.public,
|
||||
);
|
||||
return roomId;
|
||||
},
|
||||
// #Pangea
|
||||
onError: (exception) {
|
||||
ErrorHandler.logError(e: exception, s: StackTrace.current);
|
||||
return exception.toString();
|
||||
},
|
||||
// Pangea#
|
||||
);
|
||||
if (roomID.error == null) {
|
||||
}
|
||||
//#Pangea
|
||||
GoogleAnalytics.createChat(roomID.result!);
|
||||
await addToSpaceKey.currentState!.addSpaces(roomID.result!);
|
||||
GoogleAnalytics.createChat(roomId);
|
||||
await addToSpaceKey.currentState!.addSpaces(roomId);
|
||||
//Pangea#
|
||||
context.go('/rooms/${roomID.result!}/invite');
|
||||
//#Pangea
|
||||
} else {
|
||||
debugger(when: kDebugMode);
|
||||
ErrorHandler.logError(e: roomID.error, s: StackTrace.current);
|
||||
context.go('/rooms/$roomId/invite');
|
||||
} catch (e, s) {
|
||||
sdk.Logs().d('Unable to create group', e, s);
|
||||
setState(() {
|
||||
error = e;
|
||||
loading = false;
|
||||
});
|
||||
}
|
||||
//Pangea#
|
||||
}
|
||||
|
||||
//#Pangea
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
import 'package:fluffychat/config/themes.dart';
|
||||
import 'package:fluffychat/pages/new_group/new_group.dart';
|
||||
import 'package:fluffychat/pangea/widgets/class/add_class_and_invite.dart';
|
||||
import 'package:fluffychat/pangea/widgets/class/add_space_toggles.dart';
|
||||
import 'package:fluffychat/utils/localized_exception_extension.dart';
|
||||
import 'package:fluffychat/widgets/avatar.dart';
|
||||
import 'package:fluffychat/widgets/layouts/max_width_body.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
|
|
@ -12,44 +15,73 @@ class NewGroupView extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final avatar = controller.avatar;
|
||||
final error = controller.error;
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
leading: Center(
|
||||
child: BackButton(
|
||||
onPressed: controller.loading ? null : Navigator.of(context).pop,
|
||||
),
|
||||
),
|
||||
title: Text(L10n.of(context)!.createGroup),
|
||||
),
|
||||
body: MaxWidthBody(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
const SizedBox(height: 16),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(12.0),
|
||||
child: TextField(
|
||||
controller: controller.controller,
|
||||
autofocus: true,
|
||||
autocorrect: false,
|
||||
textInputAction: TextInputAction.go,
|
||||
onSubmitted: controller.submitAction,
|
||||
decoration: InputDecoration(
|
||||
// #Pangea
|
||||
labelText: L10n.of(context)!.enterAGroupName,
|
||||
// labelText: L10n.of(context)!.optionalGroupName,
|
||||
prefixIcon: const Icon(Icons.people_outlined),
|
||||
// hintText: L10n.of(context)!.enterAGroupName,
|
||||
// Pangea#
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
||||
child: Row(
|
||||
children: [
|
||||
InkWell(
|
||||
borderRadius: BorderRadius.circular(90),
|
||||
onTap: controller.loading ? null : controller.selectPhoto,
|
||||
child: CircleAvatar(
|
||||
radius: Avatar.defaultSize / 2,
|
||||
child: avatar == null
|
||||
? const Icon(Icons.camera_alt_outlined)
|
||||
: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(90),
|
||||
child: Image.memory(
|
||||
avatar,
|
||||
width: Avatar.defaultSize,
|
||||
height: Avatar.defaultSize,
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 16),
|
||||
Expanded(
|
||||
child: TextField(
|
||||
controller: controller.nameController,
|
||||
autocorrect: false,
|
||||
readOnly: controller.loading,
|
||||
decoration: InputDecoration(
|
||||
prefixIcon: const Icon(Icons.people_outlined),
|
||||
hintText: L10n.of(context)!.groupName,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
// #Pangea
|
||||
// SwitchListTile.adaptive(
|
||||
// secondary: const Icon(Icons.public_outlined),
|
||||
// title: Text(L10n.of(context)!.groupIsPublic),
|
||||
// value: controller.publicGroup,
|
||||
// onChanged: controller.setPublicGroup,
|
||||
// ),
|
||||
// SwitchListTile.adaptive(
|
||||
// secondary: const Icon(Icons.lock_outlined),
|
||||
// title: Text(L10n.of(context)!.enableEncryption),
|
||||
// value: !controller.publicGroup,
|
||||
// onChanged: null,
|
||||
// Padding(
|
||||
// padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
||||
// child: TextField(
|
||||
// controller: controller.topicController,
|
||||
// minLines: 4,
|
||||
// maxLines: 4,
|
||||
// maxLength: 255,
|
||||
// readOnly: controller.loading,
|
||||
// decoration: InputDecoration(
|
||||
// hintText: L10n.of(context)!.addChatDescription,
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
AddToSpaceToggles(
|
||||
key: controller.addToSpaceKey,
|
||||
|
|
@ -57,17 +89,87 @@ class NewGroupView extends StatelessWidget {
|
|||
activeSpaceId: controller.activeSpaceId,
|
||||
mode: AddToClassMode.chat,
|
||||
),
|
||||
const SizedBox(
|
||||
height: 50,
|
||||
),
|
||||
// const SizedBox(height: 16),
|
||||
// SwitchListTile.adaptive(
|
||||
// secondary: const Icon(Icons.public_outlined),
|
||||
// title: Text(L10n.of(context)!.groupIsPublic),
|
||||
// value: controller.publicGroup,
|
||||
// onChanged: controller.loading ? null : controller.setPublicGroup,
|
||||
// ),
|
||||
// AnimatedSize(
|
||||
// duration: FluffyThemes.animationDuration,
|
||||
// child: controller.publicGroup
|
||||
// ? SwitchListTile.adaptive(
|
||||
// secondary: const Icon(Icons.search_outlined),
|
||||
// title: Text(L10n.of(context)!.groupCanBeFoundViaSearch),
|
||||
// value: controller.groupCanBeFound,
|
||||
// onChanged: controller.loading
|
||||
// ? null
|
||||
// : controller.setGroupCanBeFound,
|
||||
// )
|
||||
// : const SizedBox.shrink(),
|
||||
// ),
|
||||
// SwitchListTile.adaptive(
|
||||
// secondary: Icon(
|
||||
// Icons.lock_outlined,
|
||||
// color: Theme.of(context).colorScheme.onBackground,
|
||||
// ),
|
||||
// title: Text(
|
||||
// L10n.of(context)!.enableEncryption,
|
||||
// style: TextStyle(
|
||||
// color: Theme.of(context).colorScheme.onBackground,
|
||||
// ),
|
||||
// ),
|
||||
// value: !controller.publicGroup,
|
||||
// onChanged: null,
|
||||
// ),
|
||||
// Pangea#
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: SizedBox(
|
||||
width: double.infinity,
|
||||
child: ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
foregroundColor: Theme.of(context).colorScheme.onPrimary,
|
||||
backgroundColor: Theme.of(context).colorScheme.primary,
|
||||
),
|
||||
onPressed:
|
||||
controller.loading ? null : controller.submitAction,
|
||||
child: controller.loading
|
||||
? const LinearProgressIndicator()
|
||||
: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
L10n.of(context)!.createGroupAndInviteUsers,
|
||||
),
|
||||
),
|
||||
Icon(Icons.adaptive.arrow_forward_outlined),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
AnimatedSize(
|
||||
duration: FluffyThemes.animationDuration,
|
||||
child: error == null
|
||||
? const SizedBox.shrink()
|
||||
: ListTile(
|
||||
leading: Icon(
|
||||
Icons.warning_outlined,
|
||||
color: Theme.of(context).colorScheme.error,
|
||||
),
|
||||
title: Text(
|
||||
error.toLocalizedString(context),
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.error,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
floatingActionButton: FloatingActionButton(
|
||||
onPressed: controller.submitAction,
|
||||
child: const Icon(Icons.arrow_forward_outlined),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:device_info_plus/device_info_plus.dart';
|
||||
import 'package:fluffychat/pages/new_private_chat/new_private_chat_view.dart';
|
||||
import 'package:fluffychat/pages/new_private_chat/qr_scanner_modal.dart';
|
||||
import 'package:fluffychat/pages/user_bottom_sheet/user_bottom_sheet.dart';
|
||||
import 'package:fluffychat/utils/adaptive_bottom_sheet.dart';
|
||||
import 'package:fluffychat/utils/fluffy_share.dart';
|
||||
import 'package:fluffychat/utils/platform_infos.dart';
|
||||
|
|
@ -21,38 +24,43 @@ class NewPrivateChat extends StatefulWidget {
|
|||
class NewPrivateChatController extends State<NewPrivateChat> {
|
||||
final TextEditingController controller = TextEditingController();
|
||||
final FocusNode textFieldFocus = FocusNode();
|
||||
final formKey = GlobalKey<FormState>();
|
||||
bool loading = false;
|
||||
|
||||
// remove leading matrix.to from text field in order to simplify pasting
|
||||
final List<TextInputFormatter> removeMatrixToFormatters = [
|
||||
FilteringTextInputFormatter.deny(NewPrivateChatController.prefix),
|
||||
FilteringTextInputFormatter.deny(NewPrivateChatController.prefixNoProtocol),
|
||||
];
|
||||
Future<List<Profile>>? searchResponse;
|
||||
|
||||
static const Set<String> supportedSigils = {'@', '!', '#'};
|
||||
Timer? _searchCoolDown;
|
||||
|
||||
static const String prefix = 'https://matrix.to/#/';
|
||||
static const String prefixNoProtocol = 'matrix.to/#/';
|
||||
static const Duration _coolDown = Duration(milliseconds: 500);
|
||||
|
||||
void submitAction([_]) async {
|
||||
controller.text = controller.text.trim();
|
||||
if (!formKey.currentState!.validate()) return;
|
||||
UrlLauncher(context, '$prefix${controller.text}').openMatrixToUrl();
|
||||
void searchUsers([String? input]) async {
|
||||
final searchTerm = input ?? controller.text;
|
||||
if (searchTerm.isEmpty) {
|
||||
_searchCoolDown?.cancel();
|
||||
setState(() {
|
||||
searchResponse = _searchCoolDown = null;
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
_searchCoolDown?.cancel();
|
||||
_searchCoolDown = Timer(_coolDown, () {
|
||||
setState(() {
|
||||
searchResponse = _searchUser(searchTerm);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
String? validateForm(String? value) {
|
||||
if (value!.isEmpty) {
|
||||
return L10n.of(context)!.pleaseEnterAMatrixIdentifier;
|
||||
Future<List<Profile>> _searchUser(String searchTerm) async {
|
||||
final result =
|
||||
await Matrix.of(context).client.searchUserDirectory(searchTerm);
|
||||
final profiles = result.results;
|
||||
|
||||
if (searchTerm.isValidMatrixId &&
|
||||
searchTerm.sigil == '@' &&
|
||||
!profiles.any((profile) => profile.userId == searchTerm)) {
|
||||
profiles.add(Profile(userId: searchTerm));
|
||||
}
|
||||
if (!controller.text.isValidMatrixId ||
|
||||
!supportedSigils.contains(controller.text.sigil)) {
|
||||
return L10n.of(context)!.makeSureTheIdentifierIsValid;
|
||||
}
|
||||
if (controller.text == Matrix.of(context).client.userID) {
|
||||
return L10n.of(context)!.youCannotInviteYourself;
|
||||
}
|
||||
return null;
|
||||
|
||||
return profiles;
|
||||
}
|
||||
|
||||
void inviteAction() => FluffyShare.shareInviteLink(context);
|
||||
|
|
@ -79,6 +87,23 @@ class NewPrivateChatController extends State<NewPrivateChat> {
|
|||
);
|
||||
}
|
||||
|
||||
void copyUserId() async {
|
||||
await Clipboard.setData(
|
||||
ClipboardData(text: Matrix.of(context).client.userID!),
|
||||
);
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text(L10n.of(context)!.copiedToClipboard)),
|
||||
);
|
||||
}
|
||||
|
||||
void openUserModal(Profile profile) => showAdaptiveBottomSheet(
|
||||
context: context,
|
||||
builder: (c) => UserBottomSheet(
|
||||
profile: profile,
|
||||
outerContext: context,
|
||||
),
|
||||
);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => NewPrivateChatView(this);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,131 +1,254 @@
|
|||
import 'dart:math';
|
||||
|
||||
import 'package:fluffychat/config/app_config.dart';
|
||||
import 'package:fluffychat/config/themes.dart';
|
||||
import 'package:fluffychat/pages/new_private_chat/new_private_chat.dart';
|
||||
import 'package:fluffychat/utils/localized_exception_extension.dart';
|
||||
import 'package:fluffychat/utils/platform_infos.dart';
|
||||
import 'package:fluffychat/utils/url_launcher.dart';
|
||||
import 'package:fluffychat/widgets/avatar.dart';
|
||||
import 'package:fluffychat/widgets/layouts/max_width_body.dart';
|
||||
import 'package:fluffychat/widgets/matrix.dart';
|
||||
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';
|
||||
|
||||
class NewPrivateChatView extends StatelessWidget {
|
||||
final NewPrivateChatController controller;
|
||||
|
||||
const NewPrivateChatView(this.controller, {super.key});
|
||||
|
||||
static const double _qrCodePadding = 8;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final searchResponse = controller.searchResponse;
|
||||
final qrCodeSize =
|
||||
min(MediaQuery.of(context).size.width - 16, 256).toDouble();
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
scrolledUnderElevation: 0,
|
||||
leading: const Center(child: BackButton()),
|
||||
title: Text(L10n.of(context)!.newChat),
|
||||
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
|
||||
actions: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: TextButton(
|
||||
onPressed: () => context.go('/rooms/newgroup'),
|
||||
child: Text(
|
||||
L10n.of(context)!.createGroup,
|
||||
style:
|
||||
TextStyle(color: Theme.of(context).colorScheme.secondary),
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
onPressed:
|
||||
UrlLauncher(context, AppConfig.startChatTutorial).launchUrl,
|
||||
icon: const Icon(Icons.info_outlined),
|
||||
),
|
||||
],
|
||||
),
|
||||
body: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: MaxWidthBody(
|
||||
withFrame: false,
|
||||
child: Container(
|
||||
margin: const EdgeInsets.all(_qrCodePadding),
|
||||
alignment: Alignment.center,
|
||||
padding: const EdgeInsets.all(_qrCodePadding * 2),
|
||||
child: Material(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
elevation: 10,
|
||||
color: Colors.white,
|
||||
shadowColor: Theme.of(context).appBarTheme.shadowColor,
|
||||
clipBehavior: Clip.hardEdge,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
//#Pangea - commenting this out because it's not super important and is throwing an error
|
||||
// QrImageView(
|
||||
// data:
|
||||
// 'https://matrix.to/#/${Matrix.of(context).client.userID}',
|
||||
// version: QrVersions.auto,
|
||||
// size: qrCodeSize,
|
||||
// ),
|
||||
// Pangea#
|
||||
TextButton.icon(
|
||||
style: TextButton.styleFrom(
|
||||
fixedSize:
|
||||
Size.fromWidth(qrCodeSize - (2 * _qrCodePadding)),
|
||||
foregroundColor: Colors.black,
|
||||
body: MaxWidthBody(
|
||||
withScrolling: false,
|
||||
child: Column(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12.0),
|
||||
child: TextField(
|
||||
controller: controller.controller,
|
||||
onChanged: controller.searchUsers,
|
||||
decoration: InputDecoration(
|
||||
hintText: 'Search for @users...',
|
||||
prefixIcon: searchResponse == null
|
||||
? const Icon(Icons.search_outlined)
|
||||
: FutureBuilder(
|
||||
future: searchResponse,
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.connectionState !=
|
||||
ConnectionState.done) {
|
||||
return const Padding(
|
||||
padding: EdgeInsets.all(10.0),
|
||||
child: SizedBox.square(
|
||||
dimension: 24,
|
||||
child: CircularProgressIndicator.adaptive(
|
||||
strokeWidth: 1,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
return const Icon(Icons.search_outlined);
|
||||
},
|
||||
),
|
||||
suffixIcon: controller.controller.text.isEmpty
|
||||
? null
|
||||
: IconButton(
|
||||
icon: const Icon(Icons.clear_outlined),
|
||||
onPressed: () {
|
||||
controller.controller.clear();
|
||||
controller.searchUsers();
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: AnimatedCrossFade(
|
||||
duration: FluffyThemes.animationDuration,
|
||||
crossFadeState: searchResponse == null
|
||||
? CrossFadeState.showFirst
|
||||
: CrossFadeState.showSecond,
|
||||
firstChild: ListView(
|
||||
children: [
|
||||
ListTile(
|
||||
title: SelectableText.rich(
|
||||
TextSpan(
|
||||
children: [
|
||||
TextSpan(
|
||||
text: L10n.of(context)!.yourGlobalUserIdIs,
|
||||
),
|
||||
TextSpan(
|
||||
text: Matrix.of(context).client.userID,
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
style: TextStyle(
|
||||
color:
|
||||
Theme.of(context).colorScheme.onPrimaryContainer,
|
||||
fontSize: 14,
|
||||
),
|
||||
icon: Icon(Icons.adaptive.share_outlined),
|
||||
label: Text(L10n.of(context)!.shareInviteLink),
|
||||
onPressed: controller.inviteAction,
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
if (PlatformInfos.isMobile) ...[
|
||||
OutlinedButton.icon(
|
||||
style: OutlinedButton.styleFrom(
|
||||
backgroundColor:
|
||||
Theme.of(context).colorScheme.primaryContainer,
|
||||
fixedSize: Size.fromWidth(
|
||||
qrCodeSize - (2 * _qrCodePadding),
|
||||
trailing: IconButton(
|
||||
icon: Icon(
|
||||
Icons.copy_outlined,
|
||||
size: 16,
|
||||
color:
|
||||
Theme.of(context).colorScheme.onPrimaryContainer,
|
||||
),
|
||||
onPressed: controller.copyUserId,
|
||||
),
|
||||
),
|
||||
if (PlatformInfos.isMobile)
|
||||
ListTile(
|
||||
leading: CircleAvatar(
|
||||
backgroundColor:
|
||||
Theme.of(context).colorScheme.primaryContainer,
|
||||
foregroundColor:
|
||||
Theme.of(context).colorScheme.onPrimaryContainer,
|
||||
child: const Icon(Icons.qr_code_scanner_outlined),
|
||||
),
|
||||
title: Text(L10n.of(context)!.scanQrCode),
|
||||
onTap: controller.openScannerAction,
|
||||
),
|
||||
ListTile(
|
||||
leading: CircleAvatar(
|
||||
backgroundColor:
|
||||
Theme.of(context).colorScheme.secondaryContainer,
|
||||
foregroundColor:
|
||||
Theme.of(context).colorScheme.onSecondaryContainer,
|
||||
child: Icon(Icons.adaptive.share_outlined),
|
||||
),
|
||||
title: Text(L10n.of(context)!.shareInviteLink),
|
||||
onTap: controller.inviteAction,
|
||||
),
|
||||
ListTile(
|
||||
leading: CircleAvatar(
|
||||
backgroundColor:
|
||||
Theme.of(context).colorScheme.tertiaryContainer,
|
||||
foregroundColor:
|
||||
Theme.of(context).colorScheme.onTertiaryContainer,
|
||||
child: const Icon(Icons.group_add_outlined),
|
||||
),
|
||||
title: Text(L10n.of(context)!.createGroup),
|
||||
onTap: () => context.go('/rooms/newgroup'),
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
Center(
|
||||
child: Material(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
elevation: 10,
|
||||
color: Colors.white,
|
||||
shadowColor: Theme.of(context).appBarTheme.shadowColor,
|
||||
clipBehavior: Clip.hardEdge,
|
||||
// #Pangea - commenting this out because it's not super important and is throwing an error
|
||||
// child: QrImageView(
|
||||
// data:
|
||||
// 'https://matrix.to/#/${Matrix.of(context).client.userID}',
|
||||
// version: QrVersions.auto,
|
||||
// size: qrCodeSize,
|
||||
// ),
|
||||
// Pangea#
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
secondChild: FutureBuilder(
|
||||
future: searchResponse,
|
||||
builder: (context, snapshot) {
|
||||
final result = snapshot.data;
|
||||
final error = snapshot.error;
|
||||
if (error != null) {
|
||||
return Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
error.toLocalizedString(context),
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.error,
|
||||
),
|
||||
),
|
||||
icon: const Icon(Icons.qr_code_scanner_outlined),
|
||||
label: Text(L10n.of(context)!.scanQrCode),
|
||||
onPressed: controller.openScannerAction,
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
],
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
OutlinedButton.icon(
|
||||
onPressed: controller.searchUsers,
|
||||
icon: const Icon(Icons.refresh_outlined),
|
||||
label: Text(L10n.of(context)!.tryAgain),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
if (result == null) {
|
||||
return const Center(
|
||||
child: CircularProgressIndicator.adaptive(),
|
||||
);
|
||||
}
|
||||
if (result.isEmpty) {
|
||||
return Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
const Icon(Icons.search_outlined, size: 86),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Text(
|
||||
L10n.of(context)!.noUsersFoundWithQuery(
|
||||
controller.controller.text,
|
||||
),
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
return ListView.builder(
|
||||
itemCount: result.length,
|
||||
itemBuilder: (context, i) {
|
||||
final contact = result[i];
|
||||
final displayname = contact.displayName ??
|
||||
contact.userId.localpart ??
|
||||
contact.userId;
|
||||
return ListTile(
|
||||
leading: Avatar(
|
||||
name: displayname,
|
||||
mxContent: contact.avatarUrl,
|
||||
presenceUserId: contact.userId,
|
||||
),
|
||||
title: Text(displayname),
|
||||
subtitle: Text(contact.userId),
|
||||
onTap: () => controller.openUserModal(contact),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
MaxWidthBody(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(12.0),
|
||||
child: Form(
|
||||
key: controller.formKey,
|
||||
child: TextFormField(
|
||||
controller: controller.controller,
|
||||
autocorrect: false,
|
||||
textInputAction: TextInputAction.go,
|
||||
focusNode: controller.textFieldFocus,
|
||||
onFieldSubmitted: controller.submitAction,
|
||||
validator: controller.validateForm,
|
||||
inputFormatters: controller.removeMatrixToFormatters,
|
||||
decoration: InputDecoration(
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
horizontal: 12,
|
||||
vertical: 6,
|
||||
),
|
||||
labelText: L10n.of(context)!.enterInviteLinkOrMatrixId,
|
||||
hintText: '@username',
|
||||
prefixText: NewPrivateChatController.prefixNoProtocol,
|
||||
suffixIcon: IconButton(
|
||||
icon: const Icon(Icons.send_outlined),
|
||||
onPressed: controller.submitAction,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,8 @@ class _ImportEmoteArchiveDialogState extends State<ImportEmoteArchiveDialog> {
|
|||
|
||||
bool _loading = false;
|
||||
|
||||
double _progress = 0;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
_importFileMap();
|
||||
|
|
@ -44,7 +46,11 @@ class _ImportEmoteArchiveDialogState extends State<ImportEmoteArchiveDialog> {
|
|||
return AlertDialog(
|
||||
title: Text(L10n.of(context)!.importEmojis),
|
||||
content: _loading
|
||||
? const Center(child: CircularProgressIndicator())
|
||||
? Center(
|
||||
child: CircularProgressIndicator(
|
||||
value: _progress,
|
||||
),
|
||||
)
|
||||
: SingleChildScrollView(
|
||||
child: Wrap(
|
||||
alignment: WrapAlignment.spaceEvenly,
|
||||
|
|
@ -97,6 +103,7 @@ class _ImportEmoteArchiveDialogState extends State<ImportEmoteArchiveDialog> {
|
|||
Future<void> _addEmotePack() async {
|
||||
setState(() {
|
||||
_loading = true;
|
||||
_progress = 0;
|
||||
});
|
||||
final imports = _importMap;
|
||||
final successfulUploads = <String>{};
|
||||
|
|
@ -134,52 +141,56 @@ class _ImportEmoteArchiveDialogState extends State<ImportEmoteArchiveDialog> {
|
|||
}
|
||||
|
||||
for (final entry in imports.entries) {
|
||||
setState(() {
|
||||
_progress += 1 / imports.length;
|
||||
});
|
||||
final file = entry.key;
|
||||
final imageCode = entry.value;
|
||||
|
||||
// try {
|
||||
var mxcFile = MatrixImageFile(
|
||||
bytes: file.content,
|
||||
name: file.name,
|
||||
);
|
||||
try {
|
||||
mxcFile = (await mxcFile.generateThumbnail(
|
||||
var mxcFile = MatrixImageFile(
|
||||
bytes: file.content,
|
||||
name: file.name,
|
||||
);
|
||||
|
||||
final thumbnail = (await mxcFile.generateThumbnail(
|
||||
nativeImplementations: ClientManager.nativeImplementations,
|
||||
))!;
|
||||
} catch (e, s) {
|
||||
Logs().w('Unable to create thumbnail', e, s);
|
||||
}
|
||||
final uri = await Matrix.of(context).client.uploadContent(
|
||||
mxcFile.bytes,
|
||||
filename: mxcFile.name,
|
||||
contentType: mxcFile.mimeType,
|
||||
);
|
||||
|
||||
final info = <String, dynamic>{
|
||||
...mxcFile.info,
|
||||
};
|
||||
|
||||
// normalize width / height to 256, required for stickers
|
||||
if (info['w'] is int && info['h'] is int) {
|
||||
final ratio = info['w'] / info['h'];
|
||||
if (info['w'] > info['h']) {
|
||||
info['w'] = 256;
|
||||
info['h'] = (256.0 / ratio).round();
|
||||
));
|
||||
if (thumbnail == null) {
|
||||
Logs().w('Unable to create thumbnail');
|
||||
} else {
|
||||
info['h'] = 256;
|
||||
info['w'] = (ratio * 256.0).round();
|
||||
mxcFile = thumbnail;
|
||||
}
|
||||
}
|
||||
widget.controller.pack!.images[imageCode] =
|
||||
ImagePackImageContent.fromJson(<String, dynamic>{
|
||||
'url': uri.toString(),
|
||||
'info': info,
|
||||
});
|
||||
successfulUploads.add(file.name);
|
||||
/*} catch (e) {
|
||||
final uri = await Matrix.of(context).client.uploadContent(
|
||||
mxcFile.bytes,
|
||||
filename: mxcFile.name,
|
||||
contentType: mxcFile.mimeType,
|
||||
);
|
||||
|
||||
Logs().d('Could not upload emote $imageCode');
|
||||
}*/
|
||||
final info = <String, dynamic>{
|
||||
...mxcFile.info,
|
||||
};
|
||||
|
||||
// normalize width / height to 256, required for stickers
|
||||
if (info['w'] is int && info['h'] is int) {
|
||||
final ratio = info['w'] / info['h'];
|
||||
if (info['w'] > info['h']) {
|
||||
info['w'] = 256;
|
||||
info['h'] = (256.0 / ratio).round();
|
||||
} else {
|
||||
info['h'] = 256;
|
||||
info['w'] = (ratio * 256.0).round();
|
||||
}
|
||||
}
|
||||
widget.controller.pack!.images[imageCode] =
|
||||
ImagePackImageContent.fromJson(<String, dynamic>{
|
||||
'url': uri.toString(),
|
||||
'info': info,
|
||||
});
|
||||
successfulUploads.add(file.name);
|
||||
} catch (e) {
|
||||
Logs().d('Could not upload emote $imageCode');
|
||||
}
|
||||
}
|
||||
|
||||
await widget.controller.save(context);
|
||||
|
|
@ -188,6 +199,7 @@ class _ImportEmoteArchiveDialogState extends State<ImportEmoteArchiveDialog> {
|
|||
);
|
||||
|
||||
_loading = false;
|
||||
_progress = 0;
|
||||
|
||||
// in case we have unhandled / duplicated emotes left, don't pop
|
||||
if (mounted) setState(() {});
|
||||
|
|
|
|||
|
|
@ -307,6 +307,8 @@ class EmotesSettingsController extends State<EmotesSettings> {
|
|||
|
||||
await showDialog(
|
||||
context: context,
|
||||
// breaks [Matrix.of] calls otherwise
|
||||
useRootNavigator: false,
|
||||
builder: (context) => ImportEmoteArchiveDialog(
|
||||
controller: this,
|
||||
archive: archive,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
import 'package:fluffychat/utils/date_time_extension.dart';
|
||||
import 'package:fluffychat/utils/fluffy_share.dart';
|
||||
import 'package:fluffychat/widgets/avatar.dart';
|
||||
import 'package:fluffychat/widgets/presence_builder.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:matrix/matrix.dart';
|
||||
|
|
@ -29,7 +31,60 @@ class UserBottomSheetView extends StatelessWidget {
|
|||
leading: CloseButton(
|
||||
onPressed: Navigator.of(context, rootNavigator: false).pop,
|
||||
),
|
||||
title: Text(displayname.trim().split(' ').first),
|
||||
title: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(displayname),
|
||||
PresenceBuilder(
|
||||
userId: userId,
|
||||
client: client,
|
||||
builder: (context, presence) {
|
||||
if (presence == null ||
|
||||
(presence.presence == PresenceType.offline &&
|
||||
presence.lastActiveTimestamp == null)) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
|
||||
final dotColor = presence.presence.isOnline
|
||||
? Colors.green
|
||||
: presence.presence.isUnavailable
|
||||
? Colors.red
|
||||
: Colors.grey;
|
||||
|
||||
final lastActiveTimestamp = presence.lastActiveTimestamp;
|
||||
|
||||
return Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Container(
|
||||
width: 8,
|
||||
height: 8,
|
||||
margin: const EdgeInsets.only(right: 8),
|
||||
decoration: BoxDecoration(
|
||||
color: dotColor,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
),
|
||||
),
|
||||
if (presence.currentlyActive == true)
|
||||
Text(
|
||||
L10n.of(context)!.currentlyActive,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: Theme.of(context).textTheme.bodySmall,
|
||||
)
|
||||
else if (lastActiveTimestamp != null)
|
||||
Text(
|
||||
L10n.of(context)!.lastActiveAgo(
|
||||
lastActiveTimestamp.localizedTimeShort(context),
|
||||
),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: Theme.of(context).textTheme.bodySmall,
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
actions: [
|
||||
if (userId != client.userID &&
|
||||
!client.ignoredUsers.contains(userId))
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import 'package:fluffychat/utils/adaptive_bottom_sheet.dart';
|
|||
import 'package:fluffychat/widgets/matrix.dart';
|
||||
import 'package:fluffychat/widgets/public_room_bottom_sheet.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';
|
||||
|
|
@ -17,10 +16,16 @@ import 'package:url_launcher/url_launcher_string.dart';
|
|||
import 'platform_infos.dart';
|
||||
|
||||
class UrlLauncher {
|
||||
/// The url to open.
|
||||
final String? url;
|
||||
|
||||
/// The visible name in the GUI. For example the name of a markdown link
|
||||
/// which may differ from the actual url to open.
|
||||
final String? name;
|
||||
|
||||
final BuildContext context;
|
||||
|
||||
const UrlLauncher(this.context, this.url);
|
||||
const UrlLauncher(this.context, this.url, [this.name]);
|
||||
|
||||
void launchUrl() async {
|
||||
if (url!.toLowerCase().startsWith(AppConfig.deepLinkPrefix) ||
|
||||
|
|
@ -37,34 +42,19 @@ class UrlLauncher {
|
|||
);
|
||||
return;
|
||||
}
|
||||
final consent = await showModalActionSheet<_LaunchUrlResponse>(
|
||||
context: context,
|
||||
title: url,
|
||||
style: AdaptiveStyle.material,
|
||||
actions: [
|
||||
SheetAction(
|
||||
key: _LaunchUrlResponse.copy,
|
||||
icon: Icons.copy_outlined,
|
||||
label: L10n.of(context)!.copy,
|
||||
),
|
||||
SheetAction(
|
||||
key: _LaunchUrlResponse.launch,
|
||||
icon: Icons.launch_outlined,
|
||||
label: L10n.of(context)!.openLinkInBrowser,
|
||||
),
|
||||
],
|
||||
);
|
||||
if (consent == _LaunchUrlResponse.copy) {
|
||||
await Clipboard.setData(ClipboardData(text: uri.toString()));
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(L10n.of(context)!.copiedToClipboard),
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (consent != _LaunchUrlResponse.launch) return;
|
||||
if (name != null && url != name) {
|
||||
// If there is a name which differs from the url, we need to make sure
|
||||
// that the user can see the actual url before opening the browser.
|
||||
final consent = await showOkCancelAlertDialog(
|
||||
context: context,
|
||||
title: L10n.of(context)!.openLinkInBrowser,
|
||||
message: url,
|
||||
okLabel: L10n.of(context)!.yes,
|
||||
cancelLabel: L10n.of(context)!.cancel,
|
||||
);
|
||||
if (consent != OkCancelResult.ok) return;
|
||||
}
|
||||
|
||||
if (!{'https', 'http'}.contains(uri.scheme)) {
|
||||
// just launch non-https / non-http uris directly
|
||||
|
|
@ -240,8 +230,3 @@ class UrlLauncher {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum _LaunchUrlResponse {
|
||||
launch,
|
||||
copy,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ class Avatar extends StatelessWidget {
|
|||
static const double defaultSize = 44;
|
||||
final Client? client;
|
||||
final double fontSize;
|
||||
final String? presenceUserId;
|
||||
final Color? presenceBackgroundColor;
|
||||
//#Pangea
|
||||
final IconData? littleIcon;
|
||||
// Pangea#
|
||||
|
|
@ -22,6 +24,8 @@ class Avatar extends StatelessWidget {
|
|||
this.onTap,
|
||||
this.client,
|
||||
this.fontSize = 18,
|
||||
this.presenceUserId,
|
||||
this.presenceBackgroundColor,
|
||||
//#Pangea
|
||||
this.littleIcon,
|
||||
// Pangea#
|
||||
|
|
@ -53,27 +57,10 @@ class Avatar extends StatelessWidget {
|
|||
);
|
||||
final borderRadius = BorderRadius.circular(size / 2);
|
||||
// #Pangea
|
||||
// final container = ClipRRect(
|
||||
// borderRadius: borderRadius,
|
||||
// child: Container(
|
||||
// width: size,
|
||||
// height: size,
|
||||
// color: noPic
|
||||
// ? name?.lightColorAvatar
|
||||
// : Theme.of(context).secondaryHeaderColor,
|
||||
// child: noPic
|
||||
// ? textWidget
|
||||
// : MxcImage(
|
||||
// key: Key(mxContent.toString()),
|
||||
// uri: mxContent,
|
||||
// fit: BoxFit.cover,
|
||||
// width: size,
|
||||
// height: size,
|
||||
// placeholder: (_) => textWidget,
|
||||
// cacheKey: mxContent.toString(),
|
||||
// ),
|
||||
// ),
|
||||
// );
|
||||
// final presenceUserId = this.presenceUserId;
|
||||
// final color =
|
||||
// noPic ? name?.lightColorAvatar : Theme.of(context).secondaryHeaderColor;
|
||||
// Pangea#
|
||||
final container = Stack(
|
||||
children: [
|
||||
ClipRRect(
|
||||
|
|
@ -97,6 +84,7 @@ class Avatar extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
),
|
||||
// #Pangea
|
||||
if (littleIcon != null)
|
||||
Positioned(
|
||||
bottom: 0,
|
||||
|
|
@ -117,9 +105,47 @@ class Avatar extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
),
|
||||
// PresenceBuilder(
|
||||
// client: client,
|
||||
// userId: presenceUserId,
|
||||
// builder: (context, presence) {
|
||||
// if (presence == null ||
|
||||
// (presence.presence == PresenceType.offline &&
|
||||
// presence.lastActiveTimestamp == null)) {
|
||||
// return const SizedBox.shrink();
|
||||
// }
|
||||
// final dotColor = presence.presence.isOnline
|
||||
// ? Colors.green
|
||||
// : presence.presence.isUnavailable
|
||||
// ? Colors.red
|
||||
// : Colors.grey;
|
||||
// return Positioned(
|
||||
// bottom: -4,
|
||||
// right: -4,
|
||||
// child: Container(
|
||||
// width: 16,
|
||||
// height: 16,
|
||||
// decoration: BoxDecoration(
|
||||
// color: presenceBackgroundColor ??
|
||||
// Theme.of(context).colorScheme.background,
|
||||
// borderRadius: BorderRadius.circular(32),
|
||||
// ),
|
||||
// alignment: Alignment.center,
|
||||
// child: Container(
|
||||
// width: 8,
|
||||
// height: 8,
|
||||
// decoration: BoxDecoration(
|
||||
// color: dotColor,
|
||||
// borderRadius: BorderRadius.circular(16),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// );
|
||||
// },
|
||||
// ),
|
||||
// Pangea#
|
||||
],
|
||||
);
|
||||
// Pangea#
|
||||
if (onTap == null) return container;
|
||||
return InkWell(
|
||||
onTap: onTap,
|
||||
|
|
|
|||
|
|
@ -448,7 +448,6 @@ class MatrixState extends State<Matrix> with WidgetsBindingObserver {
|
|||
final foreground = state != AppLifecycleState.detached &&
|
||||
state != AppLifecycleState.paused;
|
||||
client.backgroundSync = foreground;
|
||||
client.syncPresence = foreground ? null : PresenceType.unavailable;
|
||||
client.requestHistoryOnLimitedTimeline = !foreground;
|
||||
}
|
||||
|
||||
|
|
|
|||
34
lib/widgets/presence_builder.dart
Normal file
34
lib/widgets/presence_builder.dart
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:matrix/matrix.dart';
|
||||
|
||||
import 'package:fluffychat/widgets/matrix.dart';
|
||||
|
||||
class PresenceBuilder extends StatelessWidget {
|
||||
final Widget Function(BuildContext context, CachedPresence? presence) builder;
|
||||
final String? userId;
|
||||
final Client? client;
|
||||
|
||||
const PresenceBuilder({
|
||||
required this.builder,
|
||||
this.userId,
|
||||
this.client,
|
||||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final userId = this.userId;
|
||||
if (userId == null) return builder(context, null);
|
||||
|
||||
final client = this.client ?? Matrix.of(context).client;
|
||||
return StreamBuilder(
|
||||
stream: client.onPresenceChanged.stream
|
||||
.where((cachedPresence) => cachedPresence.userid == userId),
|
||||
builder: (context, snapshot) => builder(
|
||||
context,
|
||||
snapshot.data ?? client.presences[userId],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -5,6 +5,7 @@
|
|||
import FlutterMacOS
|
||||
import Foundation
|
||||
|
||||
import appkit_ui_element_colors
|
||||
import audio_session
|
||||
import connectivity_plus
|
||||
import desktop_drop
|
||||
|
|
@ -37,10 +38,12 @@ import shared_preferences_foundation
|
|||
import sqflite
|
||||
import url_launcher_macos
|
||||
import video_compress
|
||||
import video_player_avfoundation
|
||||
import wakelock_plus
|
||||
import window_to_front
|
||||
|
||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||
AppkitUiElementColorsPlugin.register(with: registry.registrar(forPlugin: "AppkitUiElementColorsPlugin"))
|
||||
AudioSessionPlugin.register(with: registry.registrar(forPlugin: "AudioSessionPlugin"))
|
||||
ConnectivityPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlugin"))
|
||||
DesktopDropPlugin.register(with: registry.registrar(forPlugin: "DesktopDropPlugin"))
|
||||
|
|
@ -73,6 +76,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
|||
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
|
||||
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
|
||||
VideoCompressPlugin.register(with: registry.registrar(forPlugin: "VideoCompressPlugin"))
|
||||
FVPVideoPlayerPlugin.register(with: registry.registrar(forPlugin: "FVPVideoPlayerPlugin"))
|
||||
WakelockPlusMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockPlusMacosPlugin"))
|
||||
WindowToFrontPlugin.register(with: registry.registrar(forPlugin: "WindowToFrontPlugin"))
|
||||
}
|
||||
|
|
|
|||
10107
needed-translations.txt
10107
needed-translations.txt
File diff suppressed because it is too large
Load diff
560
pubspec.lock
560
pubspec.lock
File diff suppressed because it is too large
Load diff
58
pubspec.yaml
58
pubspec.yaml
|
|
@ -7,29 +7,29 @@ environment:
|
|||
sdk: ">=3.0.0 <4.0.0"
|
||||
|
||||
dependencies:
|
||||
adaptive_dialog: ^1.9.0+2
|
||||
animations: ^2.0.7
|
||||
archive: ^3.3.9
|
||||
adaptive_dialog: ^1.10.0
|
||||
animations: ^2.0.8
|
||||
archive: ^3.4.9
|
||||
async: ^2.11.0
|
||||
badges: ^3.1.1
|
||||
blurhash_dart: ^1.1.0
|
||||
badges: ^3.1.2
|
||||
blurhash_dart: ^1.2.1
|
||||
callkeep: ^0.3.2
|
||||
chewie: ^1.3.6
|
||||
collection: ^1.16.0
|
||||
chewie: ^1.7.1
|
||||
collection: ^1.17.2
|
||||
connectivity_plus: ^3.0.2
|
||||
country_picker: ^2.0.20
|
||||
csv: ^5.0.2
|
||||
cupertino_icons: any
|
||||
desktop_drop: ^0.4.0
|
||||
desktop_drop: ^0.4.4
|
||||
desktop_lifecycle: ^0.1.0
|
||||
desktop_notifications: ^0.6.3
|
||||
device_info_plus: ^9.0.2
|
||||
dynamic_color: ^1.6.0
|
||||
emoji_picker_flutter: ^1.5.1
|
||||
device_info_plus: ^9.1.0
|
||||
dynamic_color: ^1.6.8
|
||||
emoji_picker_flutter: ^1.6.3
|
||||
emoji_proposal: ^0.0.1
|
||||
emojis: ^0.9.9
|
||||
#fcm_shared_isolate: ^0.1.0
|
||||
file_picker: ^5.3.0
|
||||
file_picker: ^6.1.1
|
||||
fl_chart: ^0.61.0
|
||||
firebase_analytics: ^10.2.1
|
||||
firebase_core: ^2.10.0
|
||||
|
|
@ -56,15 +56,15 @@ dependencies:
|
|||
flutter_olm: ^1.2.0
|
||||
flutter_openssl_crypto: ^0.1.0
|
||||
flutter_ringtone_player: ^3.1.1
|
||||
flutter_secure_storage: ^8.0.0
|
||||
flutter_secure_storage: ^9.0.0
|
||||
flutter_svg: ^2.0.0+1
|
||||
flutter_typeahead: ^4.3.2
|
||||
flutter_typeahead: ^4.8.0
|
||||
flutter_web_auth_2: ^3.0.3
|
||||
flutter_webrtc: ^0.9.37
|
||||
flutter_webrtc: ^0.9.46
|
||||
future_loading_dialog: ^0.3.0
|
||||
geolocator: ^7.6.2
|
||||
get_storage: ^2.1.1
|
||||
go_router: ^12.0.1
|
||||
go_router: ^12.1.1
|
||||
hive: ^2.2.3
|
||||
hive_flutter: ^1.1.0
|
||||
http: ^0.13.4
|
||||
|
|
@ -92,22 +92,22 @@ dependencies:
|
|||
qr_code_scanner: ^1.0.0
|
||||
qr_flutter: ^4.0.0
|
||||
receive_sharing_intent: ^1.4.5
|
||||
record: ^4.4.4 # Upgrade to 5 currently breaks playing on iOS
|
||||
record: 4.4.4 # Upgrade to 5 currently breaks playing on iOS
|
||||
scroll_to_index: ^3.0.1
|
||||
sentry_flutter: ^7.4.0
|
||||
share_plus: ^7.0.0
|
||||
share_plus: ^7.2.1
|
||||
shared_preferences: ^2.2.0 # Pinned because https://github.com/flutter/flutter/issues/118401
|
||||
slugify: ^2.0.0
|
||||
swipe_to_action: ^0.2.0
|
||||
syncfusion_flutter_xlsio: ^22.2.9
|
||||
tor_detector_web: ^1.1.0
|
||||
uni_links: ^0.5.1
|
||||
unifiedpush: ^5.0.0
|
||||
universal_html: ^2.0.8
|
||||
url_launcher: ^6.0.20
|
||||
vibration: ^1.7.4-nullsafety.0
|
||||
unifiedpush: ^5.0.1
|
||||
universal_html: ^2.2.4
|
||||
url_launcher: ^6.2.1
|
||||
vibration: ^1.8.3
|
||||
video_compress: ^3.1.1
|
||||
video_player: ^2.2.18
|
||||
video_player: ^2.8.1
|
||||
wakelock_plus: ^1.1.3
|
||||
webrtc_interface: ^1.0.13
|
||||
|
||||
|
|
@ -179,6 +179,18 @@ msix_config:
|
|||
install_certificate: false
|
||||
|
||||
dependency_overrides:
|
||||
# https://github.com/fluttercommunity/flutter_blurhash/pull/58
|
||||
flutter_blurhash:
|
||||
git:
|
||||
url: https://github.com/Craftplacer/flutter_blurhash.git
|
||||
ref: eb9565f9d5731d4729bd7605510cec0f9e172e5f
|
||||
# https://github.com/simpleclub-extended/flutter_math_fork/pull/87
|
||||
flutter_math_fork:
|
||||
git:
|
||||
url: https://github.com/The-Redhat/flutter_math_fork.git
|
||||
ref: 3442b36a436880ce1c023e25c868d6f4004c4c24
|
||||
# Until https://github.com/mogol/flutter_secure_storage/issues/616 is fixed
|
||||
flutter_secure_storage_linux: 1.1.3
|
||||
geolocator_android:
|
||||
hosted:
|
||||
name: geolocator_android
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ diff --git a/android/app/build.gradle b/android/app/build.gradle
|
|||
index 001fbd72..339b35af 100644
|
||||
--- a/android/app/build.gradle
|
||||
+++ b/android/app/build.gradle
|
||||
@@ -68,6 +68,10 @@ android {
|
||||
@@ -70,6 +70,10 @@
|
||||
}
|
||||
release {
|
||||
signingConfig signingConfigs.release
|
||||
|
|
@ -12,7 +12,7 @@ index 001fbd72..339b35af 100644
|
|||
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
}
|
||||
// https://stackoverflow.com/a/77494454/8222484
|
||||
@@ -78,8 +82,11 @@ flutter {
|
||||
|
||||
dependencies {
|
||||
|
|
@ -149,11 +149,11 @@ index 6999d0b8..b2c9144f 100644
|
|||
--- a/pubspec.yaml
|
||||
+++ b/pubspec.yaml
|
||||
@@ -26,7 +26,7 @@ dependencies:
|
||||
emoji_picker_flutter: ^1.5.1
|
||||
emoji_picker_flutter: ^1.6.3
|
||||
emoji_proposal: ^0.0.1
|
||||
emojis: ^0.9.9
|
||||
- #fcm_shared_isolate: ^0.1.0
|
||||
+ fcm_shared_isolate: ^0.1.0
|
||||
file_picker: ^6.0.0
|
||||
file_picker: ^6.1.1
|
||||
flutter:
|
||||
sdk: flutter
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
#!/bin/sh -ve
|
||||
git apply ./scripts/enable-android-google-services.patch
|
||||
rm -rf fonts/NotoEmoji
|
||||
yq -i 'del( .flutter.fonts[] | select(.family == "NotoEmoji") )' pubspec.yaml
|
||||
flutter clean
|
||||
flutter pub get
|
||||
cd ios
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue