Compare commits
229 Commits
Author | SHA1 | Date |
---|---|---|
Krille-chan | b4fcb5b0d9 | |
Krille | 1911004d05 | |
Raatty | 5d67564445 | |
Krille | be04c5a46e | |
Farooq Karimi Zadeh | bd7a4c9dfb | |
Krille | 10ee57722e | |
Malin Errenst | ff5f7ab50e | |
Krille | 277885a61e | |
Malin Errenst | 6633ebc376 | |
Krille-chan | b2d9986cd3 | |
Krille-chan | a0b9bb277f | |
TheOneWithTheBraid | d381705cdd | |
Aminda Suomalainen | 3820d4264a | |
Milo Ivir | cf4e2d3fad | |
josé m | 002dc87577 | |
The one with the braid | 922e7ad0ff | |
Oğuz Ersen | 5d7be8a672 | |
Krille-chan | 431b357cfa | |
TheOneWithTheBraid | 2938acf152 | |
Krille | 4127f70e4d | |
xabirequejo | c07221cc12 | |
Rex_sa | 33b2f95e3f | |
Ihor Hordiichuk | 2a5cd9b218 | |
Linerly | a15fed034d | |
Riley | b9641ac021 | |
josé m | 2145bd8846 | |
Priit Jõerüüt | 672b97b310 | |
Umoya NgoLwesihlanu | 974da6ec90 | |
Krille | f19bbcd010 | |
Krille | a1468c92c8 | |
TheOneWithTheBraid | 6dd125a087 | |
Krille | 842ecc4235 | |
Krille | db66793d28 | |
Krille | 324da027e9 | |
DarkCoder15 | f2f45e53a8 | |
Krille | cacab45fe3 | |
Krille | 908d428220 | |
Krille | 8a6d726b8c | |
Krille | 40275d3d14 | |
Krille | 5039f1ba3b | |
Krille | 299aac134d | |
TheOneWithTheBraid | 044171c002 | |
Krille | ec9155d8f0 | |
Krille | 221fe3edcc | |
Krille | e166f17cae | |
Krille | 640fe0d476 | |
Krille | 3942de3222 | |
Krille | b00111381a | |
Krille | 715dca561f | |
Krille | 44d7f61788 | |
Krille | 518739e29f | |
Krille | 06e6e9c5b1 | |
Krille | 17cfff153b | |
Krille | 9f224b9839 | |
TheOneWithTheBraid | 56e1bb6bfd | |
lauren n. liberda | 6529ce0d0f | |
Rex_sa | 81c7f7decd | |
Krille | 85868cc0bd | |
Milo Ivir | 1d0c842bad | |
Krille | 02bcc98037 | |
Krille | 1a1c166ab0 | |
Krille | 692d6042c5 | |
Krille | fa2ed930eb | |
Krille | 9785b0023c | |
Malin Errenst | 313c94a4f1 | |
Krille | 2bb0dce7a1 | |
Krille | b1785d4b8a | |
Krille | 3f15fa365f | |
Krille | a56ebb245e | |
Malin Errenst | d300cdb58f | |
Krille | d88a1cd2d6 | |
Krille | 3070b38d2e | |
Krille | 38db3b35aa | |
Linerly | c4447adf8c | |
Riley | 0b91d3cecc | |
Eric | 3b3d20f250 | |
Ihor Hordiichuk | 0376e7f4b8 | |
josé m | 77f43fbde0 | |
Priit Jõerüüt | e203508c42 | |
José Muñoz | 8b6745763a | |
Krille | 8c4b2ade88 | |
TheOneWithTheBraid | 4e5f2ff05f | |
TheOneWithTheBraid | fd1b62fc8d | |
Krille | f53d17eab7 | |
TheOneWithTheBraid | c3b3f762eb | |
TheOneWithTheBraid | d288603c07 | |
TheOneWithTheBraid | e61682ef46 | |
TheOneWithTheBraid | 3b228bb58b | |
Krille | b62c41ce57 | |
Krille | a4397e9cec | |
Krille | 981d69706c | |
Krille | 0a4683d8a6 | |
Krille | 43f6284ada | |
Krille | 8cf6297560 | |
Krille | 1f42d7dff0 | |
Krille | abbf18e1dc | |
Krille | 102f3bba8e | |
Krille | 8faba7bdf2 | |
Krille | d41d21f8e1 | |
Krille | 298cd6245c | |
Tim Flink | 8bd88c4845 | |
Krille | e3bf76d8e2 | |
The one with the Braid | 3445d5be21 | |
Krille | a838ba3000 | |
Skying | 15b655413d | |
Krille | 2418c61498 | |
Krille | dfacbf9e32 | |
fbievan | 85f5b69d6e | |
Krille | 08797da53d | |
Krille | d3bd2c3a08 | |
Krille | 1086c0e5cd | |
Malin Errenst | 60df0761a5 | |
Malin Errenst | 650d878649 | |
Krille | 06f399c76d | |
Krille | 7c5b60474f | |
Krille | d81f92f2e2 | |
Krille | 1a8038e51d | |
Krille | 54a6ce8391 | |
lauren n. liberda | b1c38d766f | |
Krille | f44e24aec1 | |
Lauren N. Liberda | 325dcf901a | |
Krille | 77e1da8318 | |
Krille | b0a58d8524 | |
Krille | 623c3bfc2e | |
Krille | 5cd6cf79a2 | |
Krille | e1d54fa992 | |
Krille | b1c481c4d1 | |
Krille | 64821e4ec5 | |
Krille | 88585fb192 | |
JHansen | 25f5d5f4fd | |
JHansen | d0d33ce2c8 | |
Mæve Rey | 32d8791fe9 | |
Linerly | e76f42a706 | |
josé m | 32f4e471cf | |
Krille | dd86a0fb00 | |
Krille | a603597b20 | |
Jelv | 23b14e8730 | |
Ihor Hordiichuk | c4a7650e39 | |
Oğuz Ersen | c4bb5fa523 | |
Eryk Michalak | fa684d265d | |
Milo Ivir | 3eeaad17f0 | |
josé m | 8d2697ffc6 | |
Priit Jõerüüt | 150ba308e9 | |
Krille | ce18cfdf2a | |
MohammadSaleh Kamyab | 17bccc0dea | |
Milo Ivir | f8b7a6fef5 | |
Priit Jõerüüt | a68f7e8936 | |
Krille | 74ef50af49 | |
Krille | 70698cf4ec | |
Krille | 9bed679568 | |
Krille | 99595caee5 | |
Krille | b39018e454 | |
Linerly | 08bed5d668 | |
Jelv | b78868397c | |
Eryk Michalak | cbb4553fc0 | |
Ihor Hordiichuk | 3ddd661fb5 | |
Oğuz Ersen | 4e8f2c3040 | |
Krille | 52ee4b923a | |
Krille | 166fcce8ba | |
Krille | 92072904e6 | |
Krille | 9ace2fe07b | |
Krille | 8913b42803 | |
Krille | 253a3afbdd | |
Krille | af2907b946 | |
Jelv | 02a0c4760a | |
josé m | e9899fce8e | |
Krille | 63a9f9ca90 | |
Kristoffer Grundström | b5364e1619 | |
Krille | 742dcb8f41 | |
Siavash | dda90c85a4 | |
Siavash | 16455da39f | |
Parsa | b69e3969cb | |
Anne Onyme 017 | 14c904b214 | |
Krille | 0d12c31393 | |
Krille | d6b3482ce2 | |
Krille | f4eb6318cc | |
Linerly | c8b421d43e | |
Parsa | 87280a0e21 | |
Ihor Hordiichuk | 96d3f83933 | |
Oğuz Ersen | bb3eddb021 | |
Priit Jõerüüt | 59c403603b | |
Krille | fd7d732762 | |
Krille | fc8fe60613 | |
Krille | 2acf49a12b | |
Krille | 2f6799470c | |
Krille | 507cd1f17e | |
Linerly | f1a8716832 | |
Parsa | f99aad5a18 | |
Ihor Hordiichuk | caa816beec | |
Oğuz Ersen | 605ba186d6 | |
josé m | 8fa14659be | |
Priit Jõerüüt | e1fe8c2ed5 | |
Krille | 2e73051b81 | |
Krille | 1a61ed5d85 | |
noob_tea | 9ad8550449 | |
Krille | 8422c2bf3c | |
Linerly | bf2e6b2787 | |
Siavash | 9e01d51520 | |
Eric | 07b92bf876 | |
Ihor Hordiichuk | 4863c4a8f3 | |
Oğuz Ersen | 9def8de5a8 | |
josé m | f08968800e | |
Priit Jõerüüt | d8dee5905d | |
Krille | c2768ae40a | |
Krille | a4a852ede8 | |
Krille | ede1e289ce | |
Krille | d211dd4aeb | |
Krille | 20c1dbd00a | |
ShootingStarDragons | fa02384808 | |
Krille | dd4f2fcc35 | |
Krille | 1b2708f4b0 | |
Krille | 7c9e2bfe3c | |
Krille | 13365488b4 | |
Krille | 02f564f7ed | |
Krille | 0222e6ecd5 | |
Krille | df91290a18 | |
Krille | 57618417a1 | |
Krille | 5e3c47a433 | |
Krille | b30622c1b9 | |
Krille | eb651212e6 | |
Krille | 78aa686699 | |
Krille | 156217c3ae | |
Krille | 644ef388de | |
Krille | 71eac7078e | |
Krille | 511dd41d30 | |
Krille | f24b3ee09b | |
Christian Kußowski | 3b6321383e | |
Oğuz Ersen | 8888fd5884 | |
Luna | 0accfe4a26 |
110
.gitlab-ci.yml
110
.gitlab-ci.yml
|
@ -1,9 +1,7 @@
|
|||
variables:
|
||||
FLUTTER_VERSION: 3.7.7
|
||||
FLUTTER_VERSION: 3.10.0
|
||||
|
||||
image:
|
||||
name: cirrusci/flutter:${FLUTTER_VERSION}
|
||||
pull_policy: if-not-present
|
||||
image: ghcr.io/cirruslabs/flutter:${FLUTTER_VERSION}
|
||||
|
||||
.shared_windows_runners:
|
||||
tags:
|
||||
|
@ -18,23 +16,25 @@ stages:
|
|||
|
||||
code_analyze:
|
||||
stage: test
|
||||
script: [ ./scripts/code_analyze.sh ]
|
||||
script:
|
||||
- flutter pub get
|
||||
- dart run import_sorter:main --no-comments --exit-if-changed
|
||||
- dart format lib/ test/ --set-exit-if-changed
|
||||
- flutter analyze
|
||||
- git apply ./scripts/enable-android-google-services.patch
|
||||
- flutter pub get
|
||||
- flutter analyze
|
||||
- flutter pub run dart_code_metrics:metrics lib -r gitlab > code-quality-report.json || true
|
||||
artifacts:
|
||||
reports:
|
||||
codequality: code-quality-report.json
|
||||
tags:
|
||||
- docker
|
||||
- famedly
|
||||
|
||||
widget_test:
|
||||
stage: test
|
||||
script: [ flutter test ]
|
||||
tags:
|
||||
- docker
|
||||
- famedly
|
||||
script: [flutter test]
|
||||
|
||||
# the basic integration test configuration testing FLOSS builds on Synapse
|
||||
integration_test:
|
||||
.integration_test:
|
||||
image: registry.gitlab.com/famedly/company/frontend/flutter-dockerimages/integration/stable:${FLUTTER_VERSION}
|
||||
stage: test
|
||||
services:
|
||||
|
@ -74,9 +74,8 @@ integration_test:
|
|||
- ffmpeg -i video.mkv -vf scale=iw/2:-2 -crf 40 -b:v 2000k -preset fast video.mp4 || true
|
||||
timeout: 30m
|
||||
retry: 2
|
||||
rules:
|
||||
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
|
||||
when: always
|
||||
only:
|
||||
- tags
|
||||
artifacts:
|
||||
when: always
|
||||
paths:
|
||||
|
@ -85,12 +84,10 @@ integration_test:
|
|||
- docker
|
||||
- famedly
|
||||
|
||||
|
||||
# integration tests for Linux builds
|
||||
### disabled because of Linux headless issues
|
||||
.integration_test_linux:
|
||||
image: cirrusci/flutter:${FLUTTER_VERSION}
|
||||
extends: integration_test
|
||||
extends: .integration_test
|
||||
parallel:
|
||||
matrix:
|
||||
- HOMESERVER_IMPLEMENTATION:
|
||||
|
@ -100,12 +97,12 @@ integration_test:
|
|||
- apt-get install -y clang cmake ninja-build pkg-config libgtk-3-dev liblzma-dev libsecret-1-dev libjsoncpp-dev
|
||||
- flutter pub get
|
||||
- flutter test integration_test -d linux --dart-define=HOMESERVER=$HOMESERVER --dart-define=USER1_NAME=$USER1_NAME --dart-define=USER2_NAME=$USER2_NAME --dart-define=USER1_PW=$USER1_PW --dart-define=USER2_PW=$USER2_PW || ( sleep 10 && exit 1 )
|
||||
after_script: [ ]
|
||||
after_script: []
|
||||
artifacts:
|
||||
|
||||
# extending the default tests to test the Google-flavored builds
|
||||
integration_test_proprietary:
|
||||
extends: integration_test
|
||||
.integration_test_proprietary:
|
||||
extends: .integration_test
|
||||
parallel:
|
||||
matrix:
|
||||
- HOMESERVER_IMPLEMENTATION:
|
||||
|
@ -137,6 +134,8 @@ release_mode_launches:
|
|||
# generate temporary release build configuration and ensure app launches
|
||||
- scripts/integration-check-release-build.sh
|
||||
timeout: 20m
|
||||
only:
|
||||
- tags
|
||||
tags:
|
||||
- docker
|
||||
- famedly
|
||||
|
@ -144,14 +143,12 @@ release_mode_launches:
|
|||
build_web:
|
||||
stage: build
|
||||
before_script:
|
||||
[ sudo apt update && sudo apt install curl -y, ./scripts/prepare-web.sh ]
|
||||
script: [ ./scripts/build-web.sh ]
|
||||
[sudo apt update && sudo apt install curl -y, ./scripts/prepare-web.sh]
|
||||
script:
|
||||
- flutter build web --release --verbose --source-maps
|
||||
artifacts:
|
||||
paths:
|
||||
- build/web/
|
||||
tags:
|
||||
- docker
|
||||
- famedly
|
||||
|
||||
# yes, we *do* build a Windows DLL on Linux. More reliable.
|
||||
build_olm_windows:
|
||||
|
@ -197,28 +194,28 @@ build_windows:
|
|||
|
||||
build_android_debug:
|
||||
stage: build
|
||||
script: [ ./scripts/build-android-debug.sh ]
|
||||
script: [flutter build apk --debug]
|
||||
artifacts:
|
||||
when: on_success
|
||||
paths:
|
||||
- build/app/outputs/apk/debug/app-debug.apk
|
||||
except:
|
||||
- main
|
||||
- tags
|
||||
tags:
|
||||
- docker
|
||||
- famedly
|
||||
except:
|
||||
- main
|
||||
- tags
|
||||
|
||||
build_android_apk:
|
||||
stage: build
|
||||
before_script:
|
||||
- git apply ./scripts/enable-android-google-services.patch
|
||||
- ./scripts/prepare-android-release.sh
|
||||
script: [ ./scripts/build-android-apk.sh ]
|
||||
script: [flutter build apk --release]
|
||||
artifacts:
|
||||
when: on_success
|
||||
paths:
|
||||
- build/android/app-release.apk
|
||||
- build/app/outputs/apk/release/app-release.apk
|
||||
tags:
|
||||
- docker
|
||||
- famedly
|
||||
|
@ -231,7 +228,7 @@ deploy_playstore_internal:
|
|||
before_script:
|
||||
- git apply ./scripts/enable-android-google-services.patch
|
||||
- ./scripts/prepare-android-release.sh
|
||||
script: [ ./scripts/release-playstore-beta.sh ]
|
||||
script: [./scripts/release-playstore-beta.sh]
|
||||
artifacts:
|
||||
when: on_success
|
||||
paths:
|
||||
|
@ -258,9 +255,6 @@ fdroid_repo:
|
|||
needs:
|
||||
- "build_android_apk"
|
||||
resource_group: playstore_release
|
||||
tags:
|
||||
- docker
|
||||
- famedly
|
||||
allow_failure: true
|
||||
only:
|
||||
- main
|
||||
|
@ -289,12 +283,11 @@ pages:
|
|||
|
||||
build_linux_x86:
|
||||
stage: build
|
||||
image: registry.gitlab.com/famedly/company/frontend/flutter-dockerimages/flutter-linux/stable
|
||||
image: registry.gitlab.com/famedly/company/frontend/flutter-dockerimages/flutter-linux/stable:${FLUTTER_VERSION}
|
||||
before_script:
|
||||
[
|
||||
sudo apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install keyboard-configuration -y && sudo apt-get install curl clang cmake ninja-build pkg-config libgtk-3-dev libblkid-dev liblzma-dev libjsoncpp-dev cmake-data libsecret-1-dev libsecret-1-0 librhash0 -y,
|
||||
]
|
||||
script: [ ./scripts/build-linux.sh ]
|
||||
- sudo apt-get update
|
||||
- sudo apt-get install curl clang cmake ninja-build pkg-config libgtk-3-dev libblkid-dev liblzma-dev libjsoncpp-dev cmake-data libsecret-1-dev libsecret-1-0 librhash0 -y
|
||||
script: [flutter build linux --release]
|
||||
tags:
|
||||
- docker
|
||||
- famedly
|
||||
|
@ -305,9 +298,10 @@ build_linux_x86:
|
|||
|
||||
build_linux_arm64:
|
||||
stage: build
|
||||
before_script: [ flutter upgrade ]
|
||||
script: [ ./scripts/build-linux.sh ]
|
||||
tags: [ docker_arm64 ]
|
||||
before_script:
|
||||
- flutter upgrade $FLUTTER_VERSION --force
|
||||
script: [flutter build linux --release]
|
||||
tags: [docker_arm64]
|
||||
only:
|
||||
- main
|
||||
- tags
|
||||
|
@ -319,9 +313,7 @@ build_linux_arm64:
|
|||
|
||||
update_dependencies:
|
||||
stage: build
|
||||
needs: [ ]
|
||||
tags:
|
||||
- docker
|
||||
needs: []
|
||||
only:
|
||||
- schedules
|
||||
variables:
|
||||
|
@ -346,9 +338,6 @@ update_dependencies:
|
|||
.release:
|
||||
stage: deploy
|
||||
image: curlimages/curl:latest
|
||||
tags:
|
||||
- docker
|
||||
- famedly
|
||||
rules:
|
||||
- if: '$CI_COMMIT_TAG =~ /^v\d+\.\d+\.\d+$/'
|
||||
- if: '$CI_COMMIT_TAG =~ /^rc\d+\.\d+\.\d+-\d+$/'
|
||||
|
@ -361,29 +350,29 @@ upload_android:
|
|||
extends: .release
|
||||
script:
|
||||
- |
|
||||
curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --upload-file build/android/app-release.apk ${PACKAGE_REGISTRY_URL}/fluffychat.apk
|
||||
curl --fail-with-body --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --upload-file build/app/outputs/apk/release/app-release.apk ${PACKAGE_REGISTRY_URL}/fluffychat.apk
|
||||
|
||||
upload_web:
|
||||
extends: .release
|
||||
script:
|
||||
# workaround bug of Flutter engine
|
||||
- tar czf package.tar.gz --ignore-failed-read -C build/web/ .
|
||||
- tar czf package.tar.gz -C build/web/ .
|
||||
- |
|
||||
curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --upload-file package.tar.gz ${PACKAGE_REGISTRY_URL}/fluffychat-web.tar.gz
|
||||
curl --fail-with-body --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --upload-file package.tar.gz ${PACKAGE_REGISTRY_URL}/fluffychat-web.tar.gz
|
||||
|
||||
upload_linux_x86:
|
||||
extends: .release
|
||||
script:
|
||||
- tar czf package.tar.gz -C build/linux/x64/release/bundle/ .
|
||||
- |
|
||||
curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --upload-file package.tar.gz ${PACKAGE_REGISTRY_URL}/fluffychat-linux-x86.tar.gz
|
||||
curl --fail-with-body --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --upload-file package.tar.gz ${PACKAGE_REGISTRY_URL}/fluffychat-linux-x86.tar.gz
|
||||
|
||||
upload_linux_arm64:
|
||||
extends: .release
|
||||
script:
|
||||
- tar czf package.tar.gz -C build/linux/arm64/release/bundle/ .
|
||||
- |
|
||||
curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --upload-file package.tar.gz ${PACKAGE_REGISTRY_URL}/fluffychat-linux-arm64.tar.gz
|
||||
curl --fail-with-body --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --upload-file package.tar.gz ${PACKAGE_REGISTRY_URL}/fluffychat-linux-arm64.tar.gz
|
||||
allow_failure: true
|
||||
|
||||
upload_windows:
|
||||
extends: .release
|
||||
|
@ -393,15 +382,16 @@ upload_windows:
|
|||
- mv build/windows/runner/Release/fluffychat.msix fluffychat.msix
|
||||
- cd build/windows/runner/Release; zip -r ../../../../package.zip . ; cd -
|
||||
- |
|
||||
curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --upload-file package.zip ${PACKAGE_REGISTRY_URL}/fluffychat-windows.zip
|
||||
curl --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --upload-file fluffychat.msix ${PACKAGE_REGISTRY_URL}/fluffychat-windows.msix
|
||||
curl --fail-with-body --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --upload-file package.zip ${PACKAGE_REGISTRY_URL}/fluffychat-windows.zip
|
||||
curl --fail-with-body --header "JOB-TOKEN: ${CI_JOB_TOKEN}" --upload-file fluffychat.msix ${PACKAGE_REGISTRY_URL}/fluffychat-windows.msix
|
||||
allow_failure: true
|
||||
|
||||
deploy_playstore:
|
||||
stage: deploy
|
||||
before_script:
|
||||
- git apply ./scripts/enable-android-google-services.patch
|
||||
- ./scripts/prepare-android-release.sh
|
||||
script: [ ./scripts/release-playstore.sh ]
|
||||
script: [./scripts/release-playstore.sh]
|
||||
resource_group: playstore_release
|
||||
only:
|
||||
- tags
|
||||
|
|
25
.metadata
25
.metadata
|
@ -4,7 +4,7 @@
|
|||
# This file should be version controlled.
|
||||
|
||||
version:
|
||||
revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849
|
||||
revision: d3d8effc686d73e0114d71abdcccef63fa1f25d2
|
||||
channel: stable
|
||||
|
||||
project_type: app
|
||||
|
@ -13,26 +13,11 @@ project_type: app
|
|||
migration:
|
||||
platforms:
|
||||
- platform: root
|
||||
create_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849
|
||||
base_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849
|
||||
- platform: android
|
||||
create_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849
|
||||
base_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849
|
||||
- platform: ios
|
||||
create_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849
|
||||
base_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849
|
||||
- platform: linux
|
||||
create_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849
|
||||
base_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849
|
||||
create_revision: d3d8effc686d73e0114d71abdcccef63fa1f25d2
|
||||
base_revision: d3d8effc686d73e0114d71abdcccef63fa1f25d2
|
||||
- platform: macos
|
||||
create_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849
|
||||
base_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849
|
||||
- platform: web
|
||||
create_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849
|
||||
base_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849
|
||||
- platform: windows
|
||||
create_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849
|
||||
base_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849
|
||||
create_revision: d3d8effc686d73e0114d71abdcccef63fa1f25d2
|
||||
base_revision: d3d8effc686d73e0114d71abdcccef63fa1f25d2
|
||||
|
||||
# User provided section
|
||||
|
||||
|
|
108
CHANGELOG.md
108
CHANGELOG.md
|
@ -1,3 +1,111 @@
|
|||
## v1.12.0
|
||||
- Added translation using Weblate (Toki Pona) (Mæve Rey)
|
||||
- Translated using Weblate (Arabic) (Rex_sa)
|
||||
- Translated using Weblate (Chinese (Simplified)) (Eric)
|
||||
- Translated using Weblate (Croatian) (Milo Ivir)
|
||||
- Translated using Weblate (Estonian) (Priit Jõerüüt)
|
||||
- Translated using Weblate (Galician) (josé m)
|
||||
- Translated using Weblate (Indonesian) (Linerly)
|
||||
- Translated using Weblate (Polish) (lauren n. liberda)
|
||||
- Translated using Weblate (Romanian) (Riley)
|
||||
- Translated using Weblate (Russian) (DarkCoder15)
|
||||
- Translated using Weblate (Spanish) (José Muñoz)
|
||||
- Translated using Weblate (Ukrainian) (Ihor Hordiichuk)
|
||||
- build: Remove dependency overwrite for ffi (Krille)
|
||||
- build: Update dependencies (Krille)
|
||||
- builds: Change minsdkversion of Android from 16 to 19 (Krille)
|
||||
- builds: Do not allow failure for linux x86 (Krille)
|
||||
- builds: Do not use verbose mode on building linux (Krille)
|
||||
- builds: Linux with flutter 3.10 (Krille)
|
||||
- builds: Remove workaround for building linux arm64 (Krille)
|
||||
- builds: Update file_picker to 5.3.0 (Krille)
|
||||
- builds: Update flutter table html (Krille)
|
||||
- builds: Update flutter_html (Krille)
|
||||
- builds: migrate to dart 3.0/flutter 3.10 (lauren n. liberda)
|
||||
- chore: Add missing blockquote style (Krille)
|
||||
- chore: Allow failure in build linux for now (Krille)
|
||||
- chore: Ask for storage persistence (Krille)
|
||||
- chore: Clean unused translations (Malin Errenst)
|
||||
- chore: Enhance room pills (Krille)
|
||||
- chore: Minor code clean up (Krille)
|
||||
- chore: Update flutter webrtc (Krille)
|
||||
- chore: Upgrade to Flutter 3.10.1 (Malin Errenst)
|
||||
- chore: change release curl calls to use --fail-with-body (Tim Flink)
|
||||
- chore: update macOS icons and add build script (TheOneWithTheBraid)
|
||||
- design: Replace anime images with neutral cupertino icons (Krille)
|
||||
- feat: Add toggle to mute notifications from chat groups (fbievan)
|
||||
- feat: Allow ruby tags in html (Krille)
|
||||
- feat: Display progress value for initial sync (Krille)
|
||||
- feat: Implement new error reporting tool when critical features break like playing audio or video messages or opening a chat (Krille)
|
||||
- feat: clean up macOS build metadata (TheOneWithTheBraid)
|
||||
- feat: set display information correctly (TheOneWithTheBraid)
|
||||
- feat: update macOS build files (TheOneWithTheBraid)
|
||||
- feat: update macOS build information for macOS Ventura (TheOneWithTheBraid)
|
||||
- fix "Unhandled Exception: VRouter.of(context) was called with a context which does not contain a VRouter." (Lauren N. Liberda)
|
||||
- fix: Broken arb file (Krille)
|
||||
- fix: Do not unnecessary request all members in public rooms (Krille)
|
||||
- fix: Remove wrong rendered linebreak in html (Krille)
|
||||
- fix: Scroll down button (Krille)
|
||||
- fix: Scroll up and scroll down buttons in chat list (Krille)
|
||||
- fix: Scrolldown button (Krille)
|
||||
- fix: Too long file name cause a render overflow (Skying)
|
||||
- fix: Try to reload timeline on IOException (Krille)
|
||||
- fix: User pills (Krille)
|
||||
- fix: broken CI artifact uploads (TheOneWithTheBraid)
|
||||
- fix: custom emote placeholder (TheOneWithTheBraid)
|
||||
- fix: path of libolm (TheOneWithTheBraid)
|
||||
- fix: Quick account switching (JHansen)
|
||||
- fix: read reciepts (JHansen)
|
||||
- perf: Use valuenotifier to not rebuild chatlist (Krille)
|
||||
- refactor: Reimplement flutter matrix html locally (Krille)
|
||||
- refactor: Update Roboto and Noto Emoji (The one with the Braid)
|
||||
- refactor: Use AnimatedSize for FAB (Krille)
|
||||
- refactor: Use DateTime for weekday localization (Malin Errenst)
|
||||
|
||||
## v1.11.2
|
||||
- Translated using Weblate (Croatian) (Milo Ivir)
|
||||
- Translated using Weblate (Dutch) (Jelv)
|
||||
- Translated using Weblate (Estonian) (Priit Jõerüüt)
|
||||
- Translated using Weblate (Galician) (josé m)
|
||||
- Translated using Weblate (Polish) (Eryk Michalak)
|
||||
- Translated using Weblate (Turkish) (Oğuz Ersen)
|
||||
- Translated using Weblate (Ukrainian) (Ihor Hordiichuk)
|
||||
- feat: Permission dialog before open link in browser (Krille)
|
||||
- fix: Chats do not load (Krille)
|
||||
|
||||
## v1.11.1 - 2023-04-20
|
||||
- fix: Download files on web and iOS with correct mimetype
|
||||
|
||||
## v1.11.0 - 2023-04-14
|
||||
- feat: Add visual read marker (Krille)
|
||||
- feat: Jump to last read event (Krille)
|
||||
- feat: Use fragmented timeline to jump to event (Krille)
|
||||
- feat: change to flutterwebauth2 (ShootingStarDragons)
|
||||
- fix: Join public room (Krille)
|
||||
- fix: Set fcm priority to max on android (Krille)
|
||||
- refactor: CI scripts and old workarounds for build scripts (Krille)
|
||||
- refactor: Client in ChatPage (Krille)
|
||||
- refactor: Not nullable room in ChatPage (Krille)
|
||||
- refactor: Switch to file_picker package and get rid of some dependency overrides (Krille)
|
||||
- refactor: Use correct Matrix instance (Krille)
|
||||
- style: Make emptypage logo bigger (Krille)
|
||||
- style: Minor adjustments for modal bottom sheets (Krille)
|
||||
- style: Move chats to top (Krille)
|
||||
- style: Use SliverList for chatlist (Krille)
|
||||
- refactor: Container -> SizedBox.shrink() (noob_tea)
|
||||
- Translated using Weblate (Chinese (Simplified)) (Eric)
|
||||
- Translated using Weblate (Dutch) (Jelv)
|
||||
- Translated using Weblate (Estonian) (Priit Jõerüüt)
|
||||
- Translated using Weblate (French) (Anne Onyme 017)
|
||||
- Translated using Weblate (Galician) (josé m)
|
||||
- Translated using Weblate (Indonesian) (Linerly)
|
||||
- Translated using Weblate (Persian) (Parsa)
|
||||
- Translated using Weblate (Persian) (Siavash)
|
||||
- Translated using Weblate (Polish) (Luna)
|
||||
- Translated using Weblate (Swedish) (Kristoffer Grundström)
|
||||
- Translated using Weblate (Turkish) (Oğuz Ersen)
|
||||
- Translated using Weblate (Ukrainian) (Ihor Hordiichuk)
|
||||
|
||||
## v1.10.0 - 2023-02-25
|
||||
- Added translation using Weblate (Thai) (Wphaoka)
|
||||
- Added translation using Weblate (Tibetan) (Nathan Freitas)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
FROM cirrusci/flutter as builder
|
||||
FROM ghcr.io/cirruslabs/flutter as builder
|
||||
RUN sudo apt update && sudo apt install curl -y
|
||||
COPY . /app
|
||||
WORKDIR /app
|
||||
|
|
|
@ -44,7 +44,7 @@ android {
|
|||
|
||||
defaultConfig {
|
||||
applicationId "chat.fluffy.fluffychat"
|
||||
minSdkVersion 16
|
||||
minSdkVersion 19
|
||||
targetSdkVersion 31
|
||||
versionCode flutterVersionCode.toInteger()
|
||||
versionName flutterVersionName
|
||||
|
|
|
@ -93,8 +93,9 @@
|
|||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity android:name="com.linusu.flutter_web_auth.CallbackActivity"
|
||||
android:exported="true">
|
||||
<activity
|
||||
android:name="com.linusu.flutter_web_auth_2.CallbackActivity"
|
||||
android:exported="true">
|
||||
<intent-filter android:label="flutter_web_auth">
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
|
|
|
@ -27,6 +27,6 @@ subprojects {
|
|||
project.evaluationDependsOn(':app')
|
||||
}
|
||||
|
||||
task clean(type: Delete) {
|
||||
tasks.register("clean", Delete) {
|
||||
delete rootProject.buildDir
|
||||
}
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 51 KiB |
Binary file not shown.
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 44 KiB |
File diff suppressed because it is too large
Load Diff
|
@ -1 +1 @@
|
|||
{}
|
||||
{}
|
|
@ -71,11 +71,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"archivedRoom": "Sala arxivada",
|
||||
"@archivedRoom": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"areGuestsAllowedToJoin": "Accés dels usuaris convidats",
|
||||
"@areGuestsAllowedToJoin": {
|
||||
"type": "text",
|
||||
|
@ -400,11 +395,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"crossSigningEnabled": "Signatura creuada activada",
|
||||
"@crossSigningEnabled": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"currentlyActive": "Actiu actualment",
|
||||
"@currentlyActive": {
|
||||
"type": "text",
|
||||
|
@ -602,11 +592,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"friday": "divendres",
|
||||
"@friday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"fromJoining": "Des de la unió",
|
||||
"@fromJoining": {
|
||||
"type": "text",
|
||||
|
@ -772,11 +757,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"keysCached": "Les claus estan desades a la memòria cau",
|
||||
"@keysCached": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"kicked": "{username} ha expulsat a {targetName}",
|
||||
"@kicked": {
|
||||
"type": "text",
|
||||
|
@ -906,11 +886,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"monday": "dilluns",
|
||||
"@monday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"muteChat": "Silencia el xat",
|
||||
"@muteChat": {
|
||||
"type": "text",
|
||||
|
@ -1201,11 +1176,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"saturday": "dissabte",
|
||||
"@saturday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"security": "Seguretat",
|
||||
"@security": {
|
||||
"type": "text",
|
||||
|
@ -1394,11 +1364,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"sunday": "diumenge",
|
||||
"@sunday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"systemTheme": "Sistema",
|
||||
"@systemTheme": {
|
||||
"type": "text",
|
||||
|
@ -1414,16 +1379,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"thisRoomHasBeenArchived": "Aquesta sala ha estat arxivada.",
|
||||
"@thisRoomHasBeenArchived": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"thursday": "dijous",
|
||||
"@thursday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"title": "FluffyChat",
|
||||
"@title": {
|
||||
"description": "Title for the application",
|
||||
|
@ -1445,11 +1400,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"tuesday": "dimarts",
|
||||
"@tuesday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"unavailable": "No disponible",
|
||||
"@unavailable": {
|
||||
"type": "text",
|
||||
|
@ -1610,11 +1560,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"wednesday": "dimecres",
|
||||
"@wednesday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"weSentYouAnEmail": "Us hem enviat un missatge de correu electrònic",
|
||||
"@weSentYouAnEmail": {
|
||||
"type": "text",
|
||||
|
@ -1801,8 +1746,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"yourUserId": "El vostre id. d’usuari:",
|
||||
"@yourUserId": {},
|
||||
"enableEncryption": "Activa el xifratge",
|
||||
"@enableEncryption": {
|
||||
"type": "text",
|
||||
|
@ -2065,11 +2008,6 @@
|
|||
"supportedVersions": {}
|
||||
}
|
||||
},
|
||||
"discover": "Descobreix",
|
||||
"@discover": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"editChatPermissions": "Edita els permisos del xat",
|
||||
"@editChatPermissions": {
|
||||
"type": "text",
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1 @@
|
|||
{}
|
|
@ -134,11 +134,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"archivedRoom": "Archived Room",
|
||||
"@archivedRoom": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"areGuestsAllowedToJoin": "Are guest users allowed to join",
|
||||
"@areGuestsAllowedToJoin": {
|
||||
"type": "text",
|
||||
|
@ -388,8 +383,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"yourUserId": "Your user ID:",
|
||||
"@yourUserId": {},
|
||||
"yourChatBackupHasBeenSetUp": "Your chat backup has been set up.",
|
||||
"@yourChatBackupHasBeenSetUp": {},
|
||||
"chatBackup": "Chat backup",
|
||||
|
@ -633,11 +626,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"crossSigningEnabled": "Cross-signing on",
|
||||
"@crossSigningEnabled": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"currentlyActive": "Currently active",
|
||||
"@currentlyActive": {
|
||||
"type": "text",
|
||||
|
@ -723,6 +711,11 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"allRooms": "All Group Chats",
|
||||
"@allRooms": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"discover": "Discover",
|
||||
"@discover": {
|
||||
"type": "text",
|
||||
|
@ -896,11 +889,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"friday": "Friday",
|
||||
"@friday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"fromJoining": "From joining",
|
||||
"@fromJoining": {
|
||||
"type": "text",
|
||||
|
@ -1091,11 +1079,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"keysCached": "Keys are cached",
|
||||
"@keysCached": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"kicked": "👞 {username} kicked {targetName}",
|
||||
"@kicked": {
|
||||
"type": "text",
|
||||
|
@ -1160,8 +1143,6 @@
|
|||
"@dehydrate": {},
|
||||
"dehydrateWarning": "This action cannot be undone. Ensure you safely store the backup file.",
|
||||
"@dehydrateWarning": {},
|
||||
"dehydrateShare": "This is your private FluffyChat export. Ensure you don't lose it and keep it private.",
|
||||
"@dehydrateShare": {},
|
||||
"dehydrateTor": "TOR Users: Export session",
|
||||
"@dehydrateTor": {},
|
||||
"dehydrateTorLong": "For TOR users, it is recommended to export the session before closing the window.",
|
||||
|
@ -1236,17 +1217,11 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"noSearchResult": "No matching search results.",
|
||||
"moderator": "Moderator",
|
||||
"@moderator": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"monday": "Monday",
|
||||
"@monday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"muteChat": "Mute chat",
|
||||
"@muteChat": {
|
||||
"type": "text",
|
||||
|
@ -1312,8 +1287,6 @@
|
|||
},
|
||||
"shareYourInviteLink": "Share your invite link",
|
||||
"@shareYourInviteLink": {},
|
||||
"typeInInviteLinkManually": "Type in invite link manually...",
|
||||
"@typeInInviteLinkManually": {},
|
||||
"scanQrCode": "Scan QR code",
|
||||
"@scanQrCode": {},
|
||||
"none": "None",
|
||||
|
@ -1671,11 +1644,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"saturday": "Saturday",
|
||||
"@saturday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"saveFile": "Save file",
|
||||
"@saveFile": {
|
||||
"type": "text",
|
||||
|
@ -1929,11 +1897,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"sunday": "Sunday",
|
||||
"@sunday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"synchronizingPleaseWait": "Synchronizing… Please wait.",
|
||||
"@synchronizingPleaseWait": {
|
||||
"type": "text",
|
||||
|
@ -1954,16 +1917,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"thisRoomHasBeenArchived": "This room has been archived.",
|
||||
"@thisRoomHasBeenArchived": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"thursday": "Thursday",
|
||||
"@thursday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"title": "FluffyChat",
|
||||
"@title": {
|
||||
"description": "Title for the application",
|
||||
|
@ -2000,11 +1953,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"tuesday": "Tuesday",
|
||||
"@tuesday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"unavailable": "Unavailable",
|
||||
"@unavailable": {
|
||||
"type": "text",
|
||||
|
@ -2177,11 +2125,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"wednesday": "Wednesday",
|
||||
"@wednesday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"weSentYouAnEmail": "We sent you an email",
|
||||
"@weSentYouAnEmail": {
|
||||
"type": "text",
|
||||
|
@ -2436,8 +2379,6 @@
|
|||
"@stories": {},
|
||||
"users": "Users",
|
||||
"@users": {},
|
||||
"enableAutoBackups": "Enable auto backups",
|
||||
"@enableAutoBackups": {},
|
||||
"unlockOldMessages": "Unlock old messages",
|
||||
"@unlockOldMessages": {},
|
||||
"storeInSecureStorageDescription": "Store the recovery key in the secure storage of this device.",
|
||||
|
@ -2519,5 +2460,21 @@
|
|||
"reopenChat": "Reopen chat",
|
||||
"noBackupWarning": "Warning! Without enabling chat backup, you will lose access to your encrypted messages. It is highly recommended to enable the chat backup first before logging out.",
|
||||
"noOtherDevicesFound": "No other devices found",
|
||||
"fileIsTooBigForServer": "The server reports that the file is too large to be sent."
|
||||
"fileIsTooBigForServer": "The server reports that the file is too large to be sent.",
|
||||
"fileHasBeenSavedAt": "File has been saved at {path}",
|
||||
"@fileHasBeenSavedAt": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"path": {}
|
||||
}
|
||||
},
|
||||
"jumpToLastReadMessage": "Jump to last read message",
|
||||
"readUpToHere": "Read up to here",
|
||||
"jump": "Jump",
|
||||
"openLinkInBrowser": "Open link in browser",
|
||||
"reportErrorDescription": "Oh no. Something went wrong. Please try again later. If you want, you can report the bug to the developers.",
|
||||
"report": "report",
|
||||
"signInWithPassword": "Sign in with password",
|
||||
"continueWith": "Continue with:",
|
||||
"pleaseTryAgainLaterOrChooseDifferentServer": "Please try again later or choose a different server."
|
||||
}
|
||||
|
|
|
@ -81,11 +81,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"archivedRoom": "Arĥivita ĉambro",
|
||||
"@archivedRoom": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"areGuestsAllowedToJoin": "Ĉu gastoj rajtas aliĝi",
|
||||
"@areGuestsAllowedToJoin": {
|
||||
"type": "text",
|
||||
|
@ -533,11 +528,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"crossSigningEnabled": "Delegaj subskriboj estas ŝaltitaj",
|
||||
"@crossSigningEnabled": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"currentlyActive": "Nun aktiva",
|
||||
"@currentlyActive": {
|
||||
"type": "text",
|
||||
|
@ -623,11 +613,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"discover": "Trovi",
|
||||
"@discover": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"displaynameHasBeenChanged": "Prezenta nomo ŝanĝiĝis",
|
||||
"@displaynameHasBeenChanged": {
|
||||
"type": "text",
|
||||
|
@ -794,11 +779,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"friday": "Vendredo",
|
||||
"@friday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"fromJoining": "Ekde aliĝo",
|
||||
"@fromJoining": {
|
||||
"type": "text",
|
||||
|
@ -989,11 +969,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"keysCached": "Ŝlosiloj estas kaŝmemoritaj",
|
||||
"@keysCached": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"kicked": "{username} forpelis uzanton {targetName}",
|
||||
"@kicked": {
|
||||
"type": "text",
|
||||
|
@ -1118,11 +1093,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"monday": "Lundo",
|
||||
"@monday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"muteChat": "Silentigi babilon",
|
||||
"@muteChat": {
|
||||
"type": "text",
|
||||
|
@ -1503,11 +1473,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"saturday": "Sabato",
|
||||
"@saturday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"saveFile": "Konservi dosieron",
|
||||
"@saveFile": {
|
||||
"type": "text",
|
||||
|
@ -1742,11 +1707,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"sunday": "Dimanĉo",
|
||||
"@sunday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"synchronizingPleaseWait": "Spegulante… Bonvolu atendi.",
|
||||
"@synchronizingPleaseWait": {
|
||||
"type": "text",
|
||||
|
@ -1767,16 +1727,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"thisRoomHasBeenArchived": "Ĉi tiu ĉambro arĥiviĝis.",
|
||||
"@thisRoomHasBeenArchived": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"thursday": "Ĵaŭdo",
|
||||
"@thursday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"title": "FluffyChat",
|
||||
"@title": {
|
||||
"description": "Title for the application",
|
||||
|
@ -1813,11 +1763,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"tuesday": "Mardo",
|
||||
"@tuesday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"unavailable": "Nedisponeble",
|
||||
"@unavailable": {
|
||||
"type": "text",
|
||||
|
@ -1988,11 +1933,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"wednesday": "Merkredo",
|
||||
"@wednesday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"weSentYouAnEmail": "Ni sendis retleteron al vi",
|
||||
"@weSentYouAnEmail": {
|
||||
"type": "text",
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -82,11 +82,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"archivedRoom": "Arhiveeritud jututuba",
|
||||
"@archivedRoom": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"areGuestsAllowedToJoin": "Kas külalised võivad liituda",
|
||||
"@areGuestsAllowedToJoin": {
|
||||
"type": "text",
|
||||
|
@ -544,11 +539,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"crossSigningEnabled": "Risttunnustamine on kasutusel",
|
||||
"@crossSigningEnabled": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"currentlyActive": "Hetkel aktiivne",
|
||||
"@currentlyActive": {
|
||||
"type": "text",
|
||||
|
@ -634,11 +624,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"discover": "Avasta",
|
||||
"@discover": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"displaynameHasBeenChanged": "Kuvatav nimi on muudetud",
|
||||
"@displaynameHasBeenChanged": {
|
||||
"type": "text",
|
||||
|
@ -805,11 +790,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"friday": "Reede",
|
||||
"@friday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"fromJoining": "Alates liitumise hetkest",
|
||||
"@fromJoining": {
|
||||
"type": "text",
|
||||
|
@ -1000,11 +980,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"keysCached": "Krüptovõtmed on puhverdatud",
|
||||
"@keysCached": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"kicked": "👞 {username} müksas kasutaja {targetName} välja",
|
||||
"@kicked": {
|
||||
"type": "text",
|
||||
|
@ -1139,11 +1114,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"monday": "Esmaspäev",
|
||||
"@monday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"muteChat": "Summuta vestlus",
|
||||
"@muteChat": {
|
||||
"type": "text",
|
||||
|
@ -1537,11 +1507,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"saturday": "Laupäev",
|
||||
"@saturday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"saveFile": "Salvesta fail",
|
||||
"@saveFile": {
|
||||
"type": "text",
|
||||
|
@ -1780,11 +1745,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"sunday": "Pühapäev",
|
||||
"@sunday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"synchronizingPleaseWait": "Sünkroniseerin andmeid… Palun oota.",
|
||||
"@synchronizingPleaseWait": {
|
||||
"type": "text",
|
||||
|
@ -1805,16 +1765,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"thisRoomHasBeenArchived": "See jututuba on arhiveeritud.",
|
||||
"@thisRoomHasBeenArchived": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"thursday": "Neljapäev",
|
||||
"@thursday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"title": "FluffyChat",
|
||||
"@title": {
|
||||
"description": "Title for the application",
|
||||
|
@ -1851,11 +1801,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"tuesday": "Teisipäev",
|
||||
"@tuesday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"unavailable": "Eemal",
|
||||
"@unavailable": {
|
||||
"type": "text",
|
||||
|
@ -2026,11 +1971,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"wednesday": "Kolmapäev",
|
||||
"@wednesday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"weSentYouAnEmail": "Me saatsime sulle e-kirja",
|
||||
"@weSentYouAnEmail": {
|
||||
"type": "text",
|
||||
|
@ -2107,8 +2047,6 @@
|
|||
"@addToSpace": {},
|
||||
"scanQrCode": "Skaneeri QR-koodi",
|
||||
"@scanQrCode": {},
|
||||
"typeInInviteLinkManually": "Sisesta kutse link käsitsi...",
|
||||
"@typeInInviteLinkManually": {},
|
||||
"shareYourInviteLink": "Jaga oma kutselinki",
|
||||
"@shareYourInviteLink": {},
|
||||
"sendOnEnter": "Saada sõnum sisestusklahvi vajutusel",
|
||||
|
@ -2135,8 +2073,6 @@
|
|||
"@link": {},
|
||||
"yourChatBackupHasBeenSetUp": "Sinu vestluste varundus on seadistatud.",
|
||||
"@yourChatBackupHasBeenSetUp": {},
|
||||
"yourUserId": "Sinu kasutajatunnus:",
|
||||
"@yourUserId": {},
|
||||
"unverified": "Verifitseerimata",
|
||||
"@unverified": {},
|
||||
"repeatPassword": "Korda salasõna",
|
||||
|
@ -2374,8 +2310,6 @@
|
|||
"@recoveryKey": {},
|
||||
"users": "Kasutajad",
|
||||
"@users": {},
|
||||
"enableAutoBackups": "Võta kasutusele automaatne varundus",
|
||||
"@enableAutoBackups": {},
|
||||
"stories": "Jutustused",
|
||||
"@stories": {},
|
||||
"storeInSecureStorageDescription": "Salvesta taastevõti selle seadme turvahoidlas.",
|
||||
|
@ -2402,8 +2336,6 @@
|
|||
},
|
||||
"dehydrate": "Ekspordi sessiooni teave ja kustuta nutiseadmest rakenduse andmed",
|
||||
"@dehydrate": {},
|
||||
"dehydrateShare": "See on sinu FluffyChat'i privaatsete andmete eksport. Palun hoia teda turvaliselt ja vaata, et sa seda ei kaotaks.",
|
||||
"@dehydrateShare": {},
|
||||
"dehydrateTor": "TOR'i kasutajad: Ekspordi sessioon",
|
||||
"@dehydrateTor": {},
|
||||
"hydrateTor": "TOR'i kasutajatele: impordi viimati eksporditud sessiooni andmed",
|
||||
|
@ -2532,8 +2464,6 @@
|
|||
"@deviceKeys": {},
|
||||
"newSpaceDescription": "Kogukonnad võimaldavad sul koondada erinevaid vestlusi ning korraldada avalikku või privaatset ühistegevust.",
|
||||
"@newSpaceDescription": {},
|
||||
"noSearchResult": "Sobivaid otsingutulemusi ei leidu.",
|
||||
"@noSearchResult": {},
|
||||
"enterInviteLinkOrMatrixId": "Sisesta kutse link või Matrix ID...",
|
||||
"@enterInviteLinkOrMatrixId": {},
|
||||
"letsStart": "Sõidame!",
|
||||
|
@ -2545,5 +2475,40 @@
|
|||
"noBackupWarning": "Hoiatus! Kui sa ei lülita sisse vestluse varundust, siis sul puudub hiljem ligipääs krüptitud sõnumitele. Me tungivalt soovitame, et palun lülita vestluse varundamine sisse enne väljalogimist.",
|
||||
"@noBackupWarning": {},
|
||||
"fileIsTooBigForServer": "Serveri seadistuste alusel on see fail saatmiseks liiga suur.",
|
||||
"@fileIsTooBigForServer": {}
|
||||
"@fileIsTooBigForServer": {},
|
||||
"fileHasBeenSavedAt": "Fail on salvestatud kausta: {path}",
|
||||
"@fileHasBeenSavedAt": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"path": {}
|
||||
}
|
||||
},
|
||||
"jumpToLastReadMessage": "Liigu viimase loetud sõnumini",
|
||||
"@jumpToLastReadMessage": {},
|
||||
"readUpToHere": "Siiamaani on loetud",
|
||||
"@readUpToHere": {},
|
||||
"jump": "Hüppa",
|
||||
"@jump": {},
|
||||
"openLinkInBrowser": "Ava link veebibrauseris",
|
||||
"@openLinkInBrowser": {},
|
||||
"discover": "Otsi ja leia",
|
||||
"@discover": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"report": "teata",
|
||||
"@report": {},
|
||||
"allRooms": "Kõik vestlusrühmad",
|
||||
"@allRooms": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"reportErrorDescription": "Oh appike! Midagi läks valesti. Palun proovi hiljem uuesti. Kui soovid, võid sellest veast arendajatele teatada.",
|
||||
"@reportErrorDescription": {},
|
||||
"continueWith": "Jätkamiseks kasuta:",
|
||||
"@continueWith": {},
|
||||
"signInWithPassword": "Logi sisse salasõnaga",
|
||||
"@signInWithPassword": {},
|
||||
"pleaseTryAgainLaterOrChooseDifferentServer": "Palun proovi hiljem uuesti või muuda serveri nime.",
|
||||
"@pleaseTryAgainLaterOrChooseDifferentServer": {}
|
||||
}
|
||||
|
|
|
@ -62,11 +62,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"archivedRoom": "Artxibatutako gela",
|
||||
"@archivedRoom": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"areGuestsAllowedToJoin": "Ba al dute gonbidatutako erabiltzaileek bat egiteko baimenik?",
|
||||
"@areGuestsAllowedToJoin": {
|
||||
"type": "text",
|
||||
|
@ -271,12 +266,12 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"compareEmojiMatch": "Konparatu eta egiaztatu ondorengo emojiak beste gailukoarekin bat datozela:",
|
||||
"compareEmojiMatch": "Konparatu ondorengo emojiak:",
|
||||
"@compareEmojiMatch": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"compareNumbersMatch": "Konparatu eta egiaztatu ondorengo zenbakiak beste gailukoarekin bat datozela:",
|
||||
"compareNumbersMatch": "Konparatu ondorengo zenbakiak:",
|
||||
"@compareNumbersMatch": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
|
@ -337,11 +332,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"crossSigningEnabled": "Zeharkako sinadura gaituta dago",
|
||||
"@crossSigningEnabled": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"currentlyActive": "Unean aktibo",
|
||||
"@currentlyActive": {
|
||||
"type": "text",
|
||||
|
@ -494,17 +484,12 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"friday": "Ostirala",
|
||||
"@friday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"fromJoining": "sartzeaz",
|
||||
"fromJoining": "Bat egiteaz geroztik",
|
||||
"@fromJoining": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"fromTheInvitation": "gonbidapenaz",
|
||||
"fromTheInvitation": "Gonbidapenaz geroztik",
|
||||
"@fromTheInvitation": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
|
@ -629,11 +614,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"keysCached": "Gakoak katxean daude",
|
||||
"@keysCached": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"kicked": "👞 {username}(e)k {targetName} kaleratu du",
|
||||
"@kicked": {
|
||||
"type": "text",
|
||||
|
@ -736,11 +716,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"monday": "Astelehena",
|
||||
"@monday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"muteChat": "Mututu berriketa",
|
||||
"@muteChat": {
|
||||
"type": "text",
|
||||
|
@ -949,11 +924,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"saturday": "Larunbata",
|
||||
"@saturday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"seenByUser": "{username}(e)k ikusi du",
|
||||
"@seenByUser": {
|
||||
"type": "text",
|
||||
|
@ -1110,11 +1080,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"sunday": "Igandea",
|
||||
"@sunday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"systemTheme": "Sistemak darabilena",
|
||||
"@systemTheme": {
|
||||
"type": "text",
|
||||
|
@ -1130,16 +1095,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"thisRoomHasBeenArchived": "Gela hau artxibatu da.",
|
||||
"@thisRoomHasBeenArchived": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"thursday": "Osteguna",
|
||||
"@thursday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"title": "FluffyChat",
|
||||
"@title": {
|
||||
"description": "Title for the application",
|
||||
|
@ -1151,11 +1106,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"tuesday": "Asteartea",
|
||||
"@tuesday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"unbannedUser": "{username}(e)k {targetName} baimendu du",
|
||||
"@unbannedUser": {
|
||||
"type": "text",
|
||||
|
@ -1304,11 +1254,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"wednesday": "Asteazkena",
|
||||
"@wednesday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"whoIsAllowedToJoinThisGroup": "Nork duen baimena talde honetara batzeko",
|
||||
"@whoIsAllowedToJoinThisGroup": {
|
||||
"type": "text",
|
||||
|
@ -1525,7 +1470,7 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"unreadChats": "{unreadCount, plural, =1{irakurri gabeko txat 1} other {{unreadCount} txat irakurri gabe}}",
|
||||
"unreadChats": "{unreadCount, plural, =1{irakurri gabeko txat 1} other {irakurri gabeko {unreadCount} txat}}",
|
||||
"@unreadChats": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
|
@ -1740,8 +1685,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"yourUserId": "Zure erabiltzaile IDa:",
|
||||
"@yourUserId": {},
|
||||
"chatBackup": "Txataren babeskopia",
|
||||
"@chatBackup": {
|
||||
"type": "text",
|
||||
|
@ -1873,8 +1816,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"typeInInviteLinkManually": "Idatzi eskuz gonbidapen esteka…",
|
||||
"@typeInInviteLinkManually": {},
|
||||
"online": "Linean",
|
||||
"@online": {
|
||||
"type": "text",
|
||||
|
@ -2009,11 +1950,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"discover": "Deskubritu",
|
||||
"@discover": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"emotePacks": "Emote sortak gelarako",
|
||||
"@emotePacks": {
|
||||
"type": "text",
|
||||
|
@ -2064,7 +2000,7 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"noEncryptionForPublicRooms": "Zifraketa aktiba dezakezu soilik gela publikoa ez bada.",
|
||||
"noEncryptionForPublicRooms": "Zifraketa aktiba dezakezu soilik gelak publikoa izateari utzi badio.",
|
||||
"@noEncryptionForPublicRooms": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
|
@ -2296,7 +2232,7 @@
|
|||
"@widgetEtherpad": {},
|
||||
"widgetJitsi": "Jitsi Meet",
|
||||
"@widgetJitsi": {},
|
||||
"widgetCustom": "Neurrira egindakoa",
|
||||
"widgetCustom": "Norberak ezarritakoa",
|
||||
"@widgetCustom": {},
|
||||
"widgetName": "Izena",
|
||||
"@widgetName": {},
|
||||
|
@ -2407,10 +2343,6 @@
|
|||
"@hydrateTorLong": {},
|
||||
"noEmailWarning": "Sartu baliozko posta helbide bat. Bestela ezingo duzu pasahitza berrezarri. Hala ere nahi ez baduzu, sakatu berriro botoia aurrera egiteko.",
|
||||
"@noEmailWarning": {},
|
||||
"enableAutoBackups": "Gaitu babeskopia automatikoak",
|
||||
"@enableAutoBackups": {},
|
||||
"dehydrateShare": "Hau zure FluffyChaten esportazio pribatua da. Ez galdu eta ez partekatu inorekin.",
|
||||
"@dehydrateShare": {},
|
||||
"dehydrateTor": "TOR Erabiltzaileak: Esportatu saioa",
|
||||
"@dehydrateTor": {},
|
||||
"hydrateTor": "TOR Erabiltzaileak: Inportatu esportatutako saioa",
|
||||
|
@ -2498,7 +2430,7 @@
|
|||
"@startFirstChat": {},
|
||||
"newSpaceDescription": "Guneek txatak taldekatzea ahalbidetzen dute eta komunitate pribatu edo publikoak osatzea.",
|
||||
"@newSpaceDescription": {},
|
||||
"endToEndEncryption": "Puntuz puntuko zifraketa",
|
||||
"endToEndEncryption": "Ertzetik ertzerako zifratzea",
|
||||
"@endToEndEncryption": {},
|
||||
"disableEncryptionWarning": "Segurtasun arrazoiak direla-eta, ezin duzu lehendik zifratuta zegoen txat bateko zifraketa ezgaitu.",
|
||||
"@disableEncryptionWarning": {},
|
||||
|
@ -2519,6 +2451,57 @@
|
|||
"@sorryThatsNotPossible": {},
|
||||
"reopenChat": "Ireki txata berriro",
|
||||
"@reopenChat": {},
|
||||
"noSearchResult": "Ez da emaitzarik aurkitu.",
|
||||
"@noSearchResult": {}
|
||||
"commandHint_googly": "Bidali begi dibertigarri batzuk",
|
||||
"@commandHint_googly": {},
|
||||
"commandHint_cuddle": "Bidali besarkada goxoa",
|
||||
"@commandHint_cuddle": {},
|
||||
"googlyEyesContent": "{senderName}(e)k begi dibertigarri batzuk bidali dizkizu",
|
||||
"@googlyEyesContent": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"senderName": {}
|
||||
}
|
||||
},
|
||||
"allRooms": "Talde-txat guztiak",
|
||||
"@allRooms": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"jumpToLastReadMessage": "Joan irakurritako azken mezura",
|
||||
"@jumpToLastReadMessage": {},
|
||||
"reportErrorDescription": "Ez! Zerbaitek huts egin du. Saiatu berriro geroago. Nahi izanez gero, eman garatzaileei errorearen berri.",
|
||||
"@reportErrorDescription": {},
|
||||
"cuddleContent": "{senderName}(e)k samurki besarkatu zaitu",
|
||||
"@cuddleContent": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"senderName": {}
|
||||
}
|
||||
},
|
||||
"readUpToHere": "Honaino irakurrita",
|
||||
"@readUpToHere": {},
|
||||
"discover": "Deskubritu",
|
||||
"@discover": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"fileHasBeenSavedAt": "Fitxategia {path}(e)n gorde da",
|
||||
"@fileHasBeenSavedAt": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"path": {}
|
||||
}
|
||||
},
|
||||
"jump": "Joan",
|
||||
"@jump": {},
|
||||
"openLinkInBrowser": "Ireki esteka nabigatzailean",
|
||||
"@openLinkInBrowser": {},
|
||||
"report": "eman berri",
|
||||
"@report": {},
|
||||
"signInWithPassword": "Hasi saioa pasahitzarekin",
|
||||
"@signInWithPassword": {},
|
||||
"continueWith": "Jarraitu honekin:",
|
||||
"@continueWith": {},
|
||||
"pleaseTryAgainLaterOrChooseDifferentServer": "Saiatu geroago edo hautatu beste zerbitzari bat.",
|
||||
"@pleaseTryAgainLaterOrChooseDifferentServer": {}
|
||||
}
|
||||
|
|
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
|
@ -9,11 +9,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"wednesday": "Dé Céadaoin",
|
||||
"@wednesday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"warning": "Rabhadh!",
|
||||
"@warning": {
|
||||
"type": "text",
|
||||
|
@ -49,32 +44,17 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"tuesday": "Dé Máirt",
|
||||
"@tuesday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"title": "FluffyChat",
|
||||
"@title": {
|
||||
"description": "Title for the application",
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"thursday": "Déardaoin",
|
||||
"@thursday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"systemTheme": "Córas",
|
||||
"@systemTheme": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"sunday": "Dé Domhnaigh",
|
||||
"@sunday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"submit": "Cuir isteach",
|
||||
"@submit": {
|
||||
"type": "text",
|
||||
|
@ -120,11 +100,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"saturday": "Dé Sathairn",
|
||||
"@saturday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"reply": "Freagair",
|
||||
"@reply": {
|
||||
"type": "text",
|
||||
|
@ -205,11 +180,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"crossSigningEnabled": "Tá cros-shíniú tosaithe",
|
||||
"@crossSigningEnabled": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"createNewSpace": "Spás nua",
|
||||
"@createNewSpace": {
|
||||
"type": "text",
|
||||
|
@ -267,11 +237,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"monday": "Dé Luain",
|
||||
"@monday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"moderator": "Modhnóir",
|
||||
"@moderator": {
|
||||
"type": "text",
|
||||
|
@ -352,11 +317,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"friday": "Dé hAoine",
|
||||
"@friday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"forward": "Seol ar aghaidh",
|
||||
"@forward": {
|
||||
"type": "text",
|
||||
|
@ -384,11 +344,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"discover": "Tar ar",
|
||||
"@discover": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"devices": "Gléasanna",
|
||||
"@devices": {
|
||||
"type": "text",
|
||||
|
@ -534,11 +489,6 @@
|
|||
},
|
||||
"sendOnEnter": "Seol ar iontráil",
|
||||
"@sendOnEnter": {},
|
||||
"archivedRoom": "Seomra cartlainne",
|
||||
"@archivedRoom": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"archive": "Cartlann",
|
||||
"@archive": {
|
||||
"type": "text",
|
||||
|
@ -1312,8 +1262,6 @@
|
|||
},
|
||||
"scanQrCode": "Scan cód QR",
|
||||
"@scanQrCode": {},
|
||||
"typeInInviteLinkManually": "Clóscríobh an nasc cuiridh de láimh...",
|
||||
"@typeInInviteLinkManually": {},
|
||||
"inviteText": "Thug {username} cuireadh duit chuig FluffyChat.\n1. Suiteáil FluffyChat: https://fluffychat.im\n2. Cláraigh nó sínigh isteach\n3. Oscail an nasc cuiridh: {link}",
|
||||
"@inviteText": {
|
||||
"type": "text",
|
||||
|
@ -1451,11 +1399,6 @@
|
|||
"targetName": {}
|
||||
}
|
||||
},
|
||||
"keysCached": "Cuirtear eochracha i dtaisce",
|
||||
"@keysCached": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinedTheChat": "Tháinig {username} isteach sa chomhrá",
|
||||
"@joinedTheChat": {
|
||||
"type": "text",
|
||||
|
@ -1740,11 +1683,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"thisRoomHasBeenArchived": "Tá an seomra seo curtha i gcartlann.",
|
||||
"@thisRoomHasBeenArchived": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"theyDontMatch": "Níl siad céanna",
|
||||
"@theyDontMatch": {
|
||||
"type": "text",
|
||||
|
@ -2153,8 +2091,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"yourUserId": "D'aitheantas úsáideora:",
|
||||
"@yourUserId": {},
|
||||
"yourChatBackupHasBeenSetUp": "Bunaíodh do chúltaca comhrá.",
|
||||
"@yourChatBackupHasBeenSetUp": {},
|
||||
"openVideoCamera": "Oscail físcheamara",
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"activatedEndToEndEncryption": "🔐 {username} activou o cifrado extremo-a-extremo",
|
||||
"activatedEndToEndEncryption": "🔐 {username} activou a cifraxe extremo-a-extremo",
|
||||
"@activatedEndToEndEncryption": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
|
@ -82,11 +82,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"archivedRoom": "Sala arquivada",
|
||||
"@archivedRoom": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"areGuestsAllowedToJoin": "Permitir o acceso de convidadas",
|
||||
"@areGuestsAllowedToJoin": {
|
||||
"type": "text",
|
||||
|
@ -319,7 +314,7 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"channelCorruptedDecryptError": "O cifrado está corrompido",
|
||||
"channelCorruptedDecryptError": "A cifraxe está estragada",
|
||||
"@channelCorruptedDecryptError": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
|
@ -544,11 +539,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"crossSigningEnabled": "Sinatura-Cruzada activada",
|
||||
"@crossSigningEnabled": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"currentlyActive": "Actualmente activo",
|
||||
"@currentlyActive": {
|
||||
"type": "text",
|
||||
|
@ -634,11 +624,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"discover": "Descubrir",
|
||||
"@discover": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"displaynameHasBeenChanged": "O nome público mudou",
|
||||
"@displaynameHasBeenChanged": {
|
||||
"type": "text",
|
||||
|
@ -719,12 +704,12 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"enableEncryption": "Activar cifrado",
|
||||
"enableEncryption": "Activar cifraxe",
|
||||
"@enableEncryption": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"enableEncryptionWarning": "Non poderás desactivar o cifrado posteriormente, tes certeza?",
|
||||
"enableEncryptionWarning": "Non poderás desactivar a cifraxe posteriormente, tes certeza?",
|
||||
"@enableEncryptionWarning": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
|
@ -734,12 +719,12 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"encryption": "Cifrado",
|
||||
"encryption": "Cifraxe",
|
||||
"@encryption": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"encryptionNotEnabled": "O cifrado non está activado",
|
||||
"encryptionNotEnabled": "A cifraxe non está activada",
|
||||
"@encryptionNotEnabled": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
|
@ -805,11 +790,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"friday": "Venres",
|
||||
"@friday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"fromJoining": "Desde que se una",
|
||||
"@fromJoining": {
|
||||
"type": "text",
|
||||
|
@ -1000,11 +980,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"keysCached": "Chaves almacenadas",
|
||||
"@keysCached": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"kicked": "👞 {username} expulsou a {targetName}",
|
||||
"@kicked": {
|
||||
"type": "text",
|
||||
|
@ -1139,17 +1114,12 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"monday": "Luns",
|
||||
"@monday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"muteChat": "Acalar chat",
|
||||
"@muteChat": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"needPantalaimonWarning": "Ten en conta que polo de agora precisas Pantalaimon para o cifrado extremo-a-extremo.",
|
||||
"needPantalaimonWarning": "Ten en conta que polo de agora precisas Pantalaimon para a cifraxe extremo-a-extremo.",
|
||||
"@needPantalaimonWarning": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
|
@ -1189,7 +1159,7 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"noEncryptionForPublicRooms": "Só podes activar o cifrado tan pronto como a sala non sexa públicamente accesible.",
|
||||
"noEncryptionForPublicRooms": "Só podes activar a cifraxe tan pronto como a sala non sexa públicamente accesible.",
|
||||
"@noEncryptionForPublicRooms": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
|
@ -1537,11 +1507,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"saturday": "Sábado",
|
||||
"@saturday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"saveFile": "Gardar ficheiro",
|
||||
"@saveFile": {
|
||||
"type": "text",
|
||||
|
@ -1780,11 +1745,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"sunday": "Domingo",
|
||||
"@sunday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"synchronizingPleaseWait": "Sincronizando... Agarda.",
|
||||
"@synchronizingPleaseWait": {
|
||||
"type": "text",
|
||||
|
@ -1805,16 +1765,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"thisRoomHasBeenArchived": "A sala foi arquivada.",
|
||||
"@thisRoomHasBeenArchived": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"thursday": "Xoves",
|
||||
"@thursday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"title": "FluffyChat",
|
||||
"@title": {
|
||||
"description": "Title for the application",
|
||||
|
@ -1851,11 +1801,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"tuesday": "Martes",
|
||||
"@tuesday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"unavailable": "Non dispoñible",
|
||||
"@unavailable": {
|
||||
"type": "text",
|
||||
|
@ -1879,7 +1824,7 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"unknownEncryptionAlgorithm": "Algoritmo de cifrado descoñecido",
|
||||
"unknownEncryptionAlgorithm": "Algoritmo de cifraxe descoñecido",
|
||||
"@unknownEncryptionAlgorithm": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
|
@ -2026,11 +1971,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"wednesday": "Mércores",
|
||||
"@wednesday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"weSentYouAnEmail": "Enviamosche un email",
|
||||
"@weSentYouAnEmail": {
|
||||
"type": "text",
|
||||
|
@ -2107,8 +2047,6 @@
|
|||
"@addToSpace": {},
|
||||
"scanQrCode": "Escanear código QR",
|
||||
"@scanQrCode": {},
|
||||
"typeInInviteLinkManually": "Escribe manualmente a ligazón do convite...",
|
||||
"@typeInInviteLinkManually": {},
|
||||
"shareYourInviteLink": "Comparte a túa ligazón de convite",
|
||||
"@shareYourInviteLink": {},
|
||||
"sendOnEnter": "Enter para enviar",
|
||||
|
@ -2129,8 +2067,6 @@
|
|||
"@yourChatBackupHasBeenSetUp": {},
|
||||
"unverified": "Sen verificar",
|
||||
"@unverified": {},
|
||||
"yourUserId": "O teu ID:",
|
||||
"@yourUserId": {},
|
||||
"pleaseEnterValidEmail": "Escribe un enderezo de email válido.",
|
||||
"@pleaseEnterValidEmail": {},
|
||||
"passwordsDoNotMatch": "Os contrasinais non concordan!",
|
||||
|
@ -2167,7 +2103,7 @@
|
|||
"type": "text",
|
||||
"description": "Usage hint for the command /discardsession"
|
||||
},
|
||||
"commandHint_create": "Crear un grupo de conversa baleiro\nUsa --no-encryption para desactivar o cifrado",
|
||||
"commandHint_create": "Crear un grupo de conversa baleiro\nUsa --no-encryption para desactivar a cifraxe",
|
||||
"@commandHint_create": {
|
||||
"type": "text",
|
||||
"description": "Usage hint for the command /create"
|
||||
|
@ -2177,7 +2113,7 @@
|
|||
"type": "text",
|
||||
"description": "Usage hint for the command /clearcache"
|
||||
},
|
||||
"commandHint_dm": "Iniciar un chat directo\nUsa --no-encryption para desactivar o cifrado",
|
||||
"commandHint_dm": "Iniciar un chat directo\nUsa --no-encryption para desactivar a cifraxe",
|
||||
"@commandHint_dm": {
|
||||
"type": "text",
|
||||
"description": "Usage hint for the command /dm"
|
||||
|
@ -2388,8 +2324,6 @@
|
|||
"@pleaseEnterRecoveryKeyDescription": {},
|
||||
"users": "Usuarias",
|
||||
"@users": {},
|
||||
"enableAutoBackups": "Activar copia automática",
|
||||
"@enableAutoBackups": {},
|
||||
"storeInSecureStorageDescription": "Gardar a chave de recuperación na almacenaxe segura deste dispositivo.",
|
||||
"@storeInSecureStorageDescription": {},
|
||||
"countFiles": "{count} ficheiros",
|
||||
|
@ -2400,8 +2334,6 @@
|
|||
},
|
||||
"unlockOldMessages": "Desbloquear mensaxes antigas",
|
||||
"@unlockOldMessages": {},
|
||||
"dehydrateShare": "Esta é a copia de apoio privada de FluffyChat. Pon coidado en non perdela e mantela segura.",
|
||||
"@dehydrateShare": {},
|
||||
"dehydrateTorLong": "Para usuarias de TOR, é recomendable exportar a sesión antes de pechar a ventál.",
|
||||
"@dehydrateTorLong": {},
|
||||
"hydrateTor": "Usuarias TOR: Importar a sesión exportada",
|
||||
|
@ -2511,15 +2443,13 @@
|
|||
"senderName": {}
|
||||
}
|
||||
},
|
||||
"noSearchResult": "Non hai resultados para a busca.",
|
||||
"@noSearchResult": {},
|
||||
"enterInviteLinkOrMatrixId": "Escribe a ligazón de convite ou ID Matrix...",
|
||||
"@enterInviteLinkOrMatrixId": {},
|
||||
"encryptThisChat": "Cifrar esta conversa",
|
||||
"@encryptThisChat": {},
|
||||
"endToEndEncryption": "Cifrado de extremo a extremo",
|
||||
"endToEndEncryption": "Cifraxe de extremo a extremo",
|
||||
"@endToEndEncryption": {},
|
||||
"disableEncryptionWarning": "Por razóns de seguridade non podes desactivar o cifrado dunha conversa onde foi activado previamente.",
|
||||
"disableEncryptionWarning": "Por razóns de seguridade non podes desactivar a cifraxe dunha conversa onde foi activada previamente.",
|
||||
"@disableEncryptionWarning": {},
|
||||
"sorryThatsNotPossible": "Lamentámolo... iso non é posible",
|
||||
"@sorryThatsNotPossible": {},
|
||||
|
@ -2545,5 +2475,40 @@
|
|||
"noBackupWarning": "Aviso! Se non activas a copia de apoio do chat, perderás o acceso ás túas mensaxes cifradas. É totalmente recomendable activar a copia de apoio do chat antes de pechar a sesión.",
|
||||
"@noBackupWarning": {},
|
||||
"fileIsTooBigForServer": "O servidor informa de que o ficheiro é demasiado grande para envialo.",
|
||||
"@fileIsTooBigForServer": {}
|
||||
"@fileIsTooBigForServer": {},
|
||||
"fileHasBeenSavedAt": "Gardouse o ficheiro en {path}",
|
||||
"@fileHasBeenSavedAt": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"path": {}
|
||||
}
|
||||
},
|
||||
"jumpToLastReadMessage": "Ir á última mensaxe lida",
|
||||
"@jumpToLastReadMessage": {},
|
||||
"readUpToHere": "Lin ate aquí",
|
||||
"@readUpToHere": {},
|
||||
"openLinkInBrowser": "Abrir ligazón no navegador",
|
||||
"@openLinkInBrowser": {},
|
||||
"jump": "Ir alá",
|
||||
"@jump": {},
|
||||
"report": "informar",
|
||||
"@report": {},
|
||||
"allRooms": "Todas as Conversas en grupo",
|
||||
"@allRooms": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"reportErrorDescription": "Vaia! Algo fallou. Inténtao máis tarde. Se queres, podes informar do problema aos desenvolvedores.",
|
||||
"@reportErrorDescription": {},
|
||||
"discover": "Descubrir",
|
||||
"@discover": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"signInWithPassword": "Accede con contrasinal",
|
||||
"@signInWithPassword": {},
|
||||
"continueWith": "Continuar con:",
|
||||
"@continueWith": {},
|
||||
"pleaseTryAgainLaterOrChooseDifferentServer": "Inténtao máis tarde ou elixe un servidor diferente.",
|
||||
"@pleaseTryAgainLaterOrChooseDifferentServer": {}
|
||||
}
|
||||
|
|
|
@ -61,11 +61,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"archivedRoom": "חדר בארכיון",
|
||||
"@archivedRoom": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"areGuestsAllowedToJoin": "האם משתמשים אורחים מורשים להצטרף",
|
||||
"@areGuestsAllowedToJoin": {
|
||||
"type": "text",
|
||||
|
@ -343,8 +338,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"yourUserId": "מזהה המשתמש שלך:",
|
||||
"@yourUserId": {},
|
||||
"yourChatBackupHasBeenSetUp": "גיבוי הצ'אט שלך הוגדר.",
|
||||
"@yourChatBackupHasBeenSetUp": {},
|
||||
"chatBackup": "גיבוי צ'אט",
|
||||
|
@ -477,11 +470,6 @@
|
|||
"username": {}
|
||||
}
|
||||
},
|
||||
"crossSigningEnabled": "חתימה צולבת על",
|
||||
"@crossSigningEnabled": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"currentlyActive": "פעיל כעת",
|
||||
"@currentlyActive": {
|
||||
"type": "text",
|
||||
|
@ -543,11 +531,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"discover": "לגלות",
|
||||
"@discover": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"downloadFile": "הורד קובץ",
|
||||
"@downloadFile": {
|
||||
"type": "text",
|
||||
|
@ -630,11 +613,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"friday": "יום שישי",
|
||||
"@friday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"fromJoining": "מהצטרפות",
|
||||
"@fromJoining": {
|
||||
"type": "text",
|
||||
|
@ -755,11 +733,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"keysCached": "המפתחות נשמרים במטמון",
|
||||
"@keysCached": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"kicked": "{username} בעט ב {targetName}",
|
||||
"@kicked": {
|
||||
"type": "text",
|
||||
|
@ -1146,8 +1119,6 @@
|
|||
},
|
||||
"shareYourInviteLink": "שתף את קישור ההזמנה שלך",
|
||||
"@shareYourInviteLink": {},
|
||||
"typeInInviteLinkManually": "הקלד את קישור ההזמנה באופן ידני...",
|
||||
"@typeInInviteLinkManually": {},
|
||||
"noRoomsFound": "לא נמצאו חדרים…",
|
||||
"@noRoomsFound": {
|
||||
"type": "text",
|
||||
|
@ -1312,11 +1283,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"monday": "יום שני",
|
||||
"@monday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"noGoogleServicesWarning": "נראה שאין לך שירותי גוגל בטלפון שלך. זו החלטה טובה לפרטיות שלך! כדי לקבל התרעות ב- FluffyChat אנו ממליצים להשתמש https://microg.org/ או https://unifiedpush.org/.",
|
||||
"@noGoogleServicesWarning": {
|
||||
"type": "text",
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -247,11 +247,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"friday": "Jumat",
|
||||
"@friday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"forward": "Teruskan",
|
||||
"@forward": {
|
||||
"type": "text",
|
||||
|
@ -449,11 +444,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"crossSigningEnabled": "Tanda tangan silang dinyalakan",
|
||||
"@crossSigningEnabled": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"createNewGroup": "Buat grup baru",
|
||||
"@createNewGroup": {
|
||||
"type": "text",
|
||||
|
@ -729,11 +719,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"archivedRoom": "Ruangan yang Diarsipkan",
|
||||
"@archivedRoom": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"appLock": "Kunci aplikasi",
|
||||
"@appLock": {
|
||||
"type": "text",
|
||||
|
@ -885,11 +870,6 @@
|
|||
"targetName": {}
|
||||
}
|
||||
},
|
||||
"keysCached": "Kunci telah ditembolok",
|
||||
"@keysCached": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinRoom": "Bergabung dengan ruangan",
|
||||
"@joinRoom": {
|
||||
"type": "text",
|
||||
|
@ -967,11 +947,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"monday": "Senin",
|
||||
"@monday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"moderator": "Moderator",
|
||||
"@moderator": {
|
||||
"type": "text",
|
||||
|
@ -1176,11 +1151,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"wednesday": "Rabu",
|
||||
"@wednesday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"warning": "Peringatan!",
|
||||
"@warning": {
|
||||
"type": "text",
|
||||
|
@ -1334,11 +1304,6 @@
|
|||
"targetName": {}
|
||||
}
|
||||
},
|
||||
"tuesday": "Selasa",
|
||||
"@tuesday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"tryToSendAgain": "Coba kirim lagi",
|
||||
"@tryToSendAgain": {
|
||||
"type": "text",
|
||||
|
@ -1370,16 +1335,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"thursday": "Kamis",
|
||||
"@thursday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"thisRoomHasBeenArchived": "Ruangan ini telah diarsipkan.",
|
||||
"@thisRoomHasBeenArchived": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"theyMatch": "Cocok",
|
||||
"@theyMatch": {
|
||||
"type": "text",
|
||||
|
@ -1400,11 +1355,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"sunday": "Minggu",
|
||||
"@sunday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"submit": "Kirim",
|
||||
"@submit": {
|
||||
"type": "text",
|
||||
|
@ -1775,8 +1725,6 @@
|
|||
},
|
||||
"scanQrCode": "Pindai kode QR",
|
||||
"@scanQrCode": {},
|
||||
"typeInInviteLinkManually": "Masukkan tautan undangan secara manual...",
|
||||
"@typeInInviteLinkManually": {},
|
||||
"shareYourInviteLink": "Bagikan tautan undanganmu",
|
||||
"@shareYourInviteLink": {},
|
||||
"noMatrixServer": "{server1} itu bukan server Matrix, gunakan {server2} saja?",
|
||||
|
@ -1885,11 +1833,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"discover": "Temukan",
|
||||
"@discover": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"defaultPermissionLevel": "Level izin default",
|
||||
"@defaultPermissionLevel": {
|
||||
"type": "text",
|
||||
|
@ -2068,11 +2011,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"saturday": "Sabtu",
|
||||
"@saturday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"removeDevice": "Hapus perangkat",
|
||||
"@removeDevice": {
|
||||
"type": "text",
|
||||
|
@ -2134,8 +2072,6 @@
|
|||
"@link": {},
|
||||
"yourChatBackupHasBeenSetUp": "Cadangan obrolanmu telah disiapkan.",
|
||||
"@yourChatBackupHasBeenSetUp": {},
|
||||
"yourUserId": "ID penggunamu:",
|
||||
"@yourUserId": {},
|
||||
"unverified": "Tidak terverifikasi",
|
||||
"@unverified": {},
|
||||
"pleaseEnterValidEmail": "Mohon masukkan alamat email yang valid.",
|
||||
|
@ -2389,8 +2325,6 @@
|
|||
"@recoveryKeyLost": {},
|
||||
"storeInAndroidKeystore": "Simpan di Android KeyStore",
|
||||
"@storeInAndroidKeystore": {},
|
||||
"enableAutoBackups": "Aktifkan cadangan otomatis",
|
||||
"@enableAutoBackups": {},
|
||||
"storeSecurlyOnThisDevice": "Simpan secara aman di perangkat ini",
|
||||
"@storeSecurlyOnThisDevice": {},
|
||||
"countFiles": "{count} file",
|
||||
|
@ -2399,8 +2333,6 @@
|
|||
"count": {}
|
||||
}
|
||||
},
|
||||
"dehydrateShare": "Ini adalah ekspor FluffyChat privat kamu. Pastikan kamu tidak menghilangkannya dan tetap rahasia.",
|
||||
"@dehydrateShare": {},
|
||||
"hydrate": "Pulihkan dari file cadangan",
|
||||
"@hydrate": {},
|
||||
"indexedDbErrorTitle": "Masalah dengan mode privat",
|
||||
|
@ -2531,8 +2463,6 @@
|
|||
"@endToEndEncryption": {},
|
||||
"disableEncryptionWarning": "Demi keamanan kamu tidak bisa menonaktifkan enkripsi dalam sebuah obrolan di mana sebelumbya sudah diaktifkan.",
|
||||
"@disableEncryptionWarning": {},
|
||||
"noSearchResult": "Tidak ada hasil pencarian yang cocok.",
|
||||
"@noSearchResult": {},
|
||||
"letsStart": "Mari kita mulai",
|
||||
"@letsStart": {},
|
||||
"enterInviteLinkOrMatrixId": "Masukkan tautan undangan atau ID Matrix...",
|
||||
|
@ -2544,5 +2474,40 @@
|
|||
"noOtherDevicesFound": "Tidak ada perangkat lain yang ditemukan",
|
||||
"@noOtherDevicesFound": {},
|
||||
"fileIsTooBigForServer": "Server melaporkan bahwa file terlalu besar untuk dikirim.",
|
||||
"@fileIsTooBigForServer": {}
|
||||
"@fileIsTooBigForServer": {},
|
||||
"fileHasBeenSavedAt": "Berkas telah disimpan di {path}",
|
||||
"@fileHasBeenSavedAt": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"path": {}
|
||||
}
|
||||
},
|
||||
"jumpToLastReadMessage": "Pergi ke pesan terakhir dibaca",
|
||||
"@jumpToLastReadMessage": {},
|
||||
"readUpToHere": "Baca sampai sini",
|
||||
"@readUpToHere": {},
|
||||
"jump": "Lompat",
|
||||
"@jump": {},
|
||||
"openLinkInBrowser": "Buka tautan dalam peramban",
|
||||
"@openLinkInBrowser": {},
|
||||
"discover": "Jelajahi",
|
||||
"@discover": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"allRooms": "Semua Percakapan Grup",
|
||||
"@allRooms": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"report": "laporkan",
|
||||
"@report": {},
|
||||
"reportErrorDescription": "Aduh. Ada yang salah. Silakan coba lahi nanti. Jika kamu mau, kamu bisa melaporkan kutu ini kepada para pengembang.",
|
||||
"@reportErrorDescription": {},
|
||||
"signInWithPassword": "Masuk dengan kata sandi",
|
||||
"@signInWithPassword": {},
|
||||
"continueWith": "Lanjutkan dengan:",
|
||||
"@continueWith": {},
|
||||
"pleaseTryAgainLaterOrChooseDifferentServer": "Silakan coba lagi nanti atau pilih server yang lain.",
|
||||
"@pleaseTryAgainLaterOrChooseDifferentServer": {}
|
||||
}
|
||||
|
|
|
@ -34,11 +34,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"discover": "Decovrir",
|
||||
"@discover": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"containsUserName": "Contene li nómine",
|
||||
"@containsUserName": {
|
||||
"type": "text",
|
||||
|
@ -189,11 +184,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"keysCached": "Claves es in cache",
|
||||
"@keysCached": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"lastActiveAgo": "Ultim activité: {localizedTimeShort}",
|
||||
"@lastActiveAgo": {
|
||||
"type": "text",
|
||||
|
@ -340,11 +330,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"tuesday": "Mardí",
|
||||
"@tuesday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"unavailable": "Índisponibil",
|
||||
"@unavailable": {
|
||||
"type": "text",
|
||||
|
@ -465,11 +450,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"saturday": "Saturdí",
|
||||
"@saturday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"dateWithYear": "{day}.{month}.{year}",
|
||||
"@dateWithYear": {
|
||||
"type": "text",
|
||||
|
@ -494,11 +474,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"friday": "Venerdí",
|
||||
"@friday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"lightTheme": "Lucid",
|
||||
"@lightTheme": {
|
||||
"type": "text",
|
||||
|
@ -529,11 +504,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"thursday": "Jovedí",
|
||||
"@thursday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"username": "Nómine de usator",
|
||||
"@username": {
|
||||
"type": "text",
|
||||
|
@ -544,11 +514,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"wednesday": "Mercurdí",
|
||||
"@wednesday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"submit": "Inviar",
|
||||
"@submit": {
|
||||
"type": "text",
|
||||
|
@ -683,11 +648,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"archivedRoom": "Archivat chambre",
|
||||
"@archivedRoom": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"changePassword": "Cambiar li contrasigne",
|
||||
"@changePassword": {
|
||||
"type": "text",
|
||||
|
@ -970,8 +930,6 @@
|
|||
},
|
||||
"updateAvailable": "Un actualisament de FluffyChat es disponibil",
|
||||
"@updateAvailable": {},
|
||||
"yourUserId": "Vor ID de usator:",
|
||||
"@yourUserId": {},
|
||||
"editWidgets": "Modificar li widgets",
|
||||
"@editWidgets": {},
|
||||
"widgetEtherpad": "Textual nota",
|
||||
|
@ -1165,11 +1123,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"monday": "Lunedí",
|
||||
"@monday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"newGroup": "Crear un gruppe",
|
||||
"@newGroup": {},
|
||||
"newSpace": "Crear un spacie",
|
||||
|
@ -1218,11 +1171,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"sunday": "Soledí",
|
||||
"@sunday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"unverified": "Ínverificat",
|
||||
"@unverified": {},
|
||||
"deviceId": "ID de aparate",
|
||||
|
|
|
@ -76,11 +76,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"archivedRoom": "Stanza archiviata",
|
||||
"@archivedRoom": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"areGuestsAllowedToJoin": "Gli utenti ospiti possono partecipare",
|
||||
"@areGuestsAllowedToJoin": {
|
||||
"type": "text",
|
||||
|
@ -432,11 +427,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"crossSigningEnabled": "Firma incrociata abilitata",
|
||||
"@crossSigningEnabled": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"currentlyActive": "Attualmente attivo",
|
||||
"@currentlyActive": {
|
||||
"type": "text",
|
||||
|
@ -522,11 +512,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"discover": "Scopri",
|
||||
"@discover": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"displaynameHasBeenChanged": "Il nominativo è stato cambiato",
|
||||
"@displaynameHasBeenChanged": {
|
||||
"type": "text",
|
||||
|
@ -679,11 +664,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"friday": "venerdì",
|
||||
"@friday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"fromJoining": "Dall'adesione",
|
||||
"@fromJoining": {
|
||||
"type": "text",
|
||||
|
@ -874,11 +854,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"keysCached": "Le chiave sono memorizzate nella cache",
|
||||
"@keysCached": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"kicked": "{username} ha espulso {targetName}",
|
||||
"@kicked": {
|
||||
"type": "text",
|
||||
|
@ -996,11 +971,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"monday": "lunedì",
|
||||
"@monday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"muteChat": "Silenzia discussione",
|
||||
"@muteChat": {
|
||||
"type": "text",
|
||||
|
@ -1346,11 +1316,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"saturday": "sabato",
|
||||
"@saturday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"search": "Cerca",
|
||||
"@search": {
|
||||
"type": "text",
|
||||
|
@ -1550,11 +1515,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"sunday": "domenica",
|
||||
"@sunday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"systemTheme": "Sistema",
|
||||
"@systemTheme": {
|
||||
"type": "text",
|
||||
|
@ -1570,16 +1530,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"thisRoomHasBeenArchived": "Questa stanza è stata archiviata.",
|
||||
"@thisRoomHasBeenArchived": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"thursday": "giovedì",
|
||||
"@thursday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"title": "FluffyChat",
|
||||
"@title": {
|
||||
"description": "Title for the application",
|
||||
|
@ -1616,11 +1566,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"tuesday": "martedì",
|
||||
"@tuesday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"unavailable": "Non disponibile",
|
||||
"@unavailable": {
|
||||
"type": "text",
|
||||
|
@ -1791,11 +1736,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"wednesday": "mercoledì",
|
||||
"@wednesday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"weSentYouAnEmail": "Ti abbiamo inviato un'e-mail",
|
||||
"@weSentYouAnEmail": {
|
||||
"type": "text",
|
||||
|
@ -1936,8 +1876,6 @@
|
|||
"@passwordsDoNotMatch": {},
|
||||
"pleaseEnterValidEmail": "Inserire un indirizzo email valido.",
|
||||
"@pleaseEnterValidEmail": {},
|
||||
"yourUserId": "Il tuo ID utente:",
|
||||
"@yourUserId": {},
|
||||
"commandHint_leave": "Lascia questa stanza",
|
||||
"@commandHint_leave": {
|
||||
"type": "text",
|
||||
|
|
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
|
@ -71,11 +71,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"archivedRoom": "Arkivert rom",
|
||||
"@archivedRoom": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"areGuestsAllowedToJoin": "Skal gjester tillates å ta del",
|
||||
"@areGuestsAllowedToJoin": {
|
||||
"type": "text",
|
||||
|
@ -401,11 +396,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"crossSigningEnabled": "Videreformidling av tillit på",
|
||||
"@crossSigningEnabled": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"currentlyActive": "Aktiv nå",
|
||||
"@currentlyActive": {
|
||||
"type": "text",
|
||||
|
@ -491,11 +481,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"discover": "Oppdag",
|
||||
"@discover": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"displaynameHasBeenChanged": "Visningsnavn endret",
|
||||
"@displaynameHasBeenChanged": {
|
||||
"type": "text",
|
||||
|
@ -648,11 +633,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"friday": "Fredag",
|
||||
"@friday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"fromJoining": "Fra å ta del",
|
||||
"@fromJoining": {
|
||||
"type": "text",
|
||||
|
@ -838,11 +818,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"keysCached": "Nøkler hurtiglagret",
|
||||
"@keysCached": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"kicked": "{username} kastet ut {targetName}",
|
||||
"@kicked": {
|
||||
"type": "text",
|
||||
|
@ -960,11 +935,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"monday": "Mandag",
|
||||
"@monday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"muteChat": "Forstum sludring",
|
||||
"@muteChat": {
|
||||
"type": "text",
|
||||
|
@ -1275,11 +1245,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"saturday": "Lørdag",
|
||||
"@saturday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"search": "Søk",
|
||||
"@search": {
|
||||
"type": "text",
|
||||
|
@ -1474,11 +1439,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"sunday": "Søndag",
|
||||
"@sunday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"systemTheme": "System",
|
||||
"@systemTheme": {
|
||||
"type": "text",
|
||||
|
@ -1494,16 +1454,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"thisRoomHasBeenArchived": "Dette rommet har blitt arkivert.",
|
||||
"@thisRoomHasBeenArchived": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"thursday": "Torsdag",
|
||||
"@thursday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"title": "FluffyChat",
|
||||
"@title": {
|
||||
"description": "Title for the application",
|
||||
|
@ -1525,11 +1475,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"tuesday": "Tirsdag",
|
||||
"@tuesday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"unavailable": "Utilgjengelig",
|
||||
"@unavailable": {
|
||||
"type": "text",
|
||||
|
@ -1685,11 +1630,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"wednesday": "Onsdag",
|
||||
"@wednesday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"weSentYouAnEmail": "Du har fått en e-post",
|
||||
"@weSentYouAnEmail": {
|
||||
"type": "text",
|
||||
|
@ -1839,7 +1779,5 @@
|
|||
"@changeYourAvatar": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"yourUserId": "Din bruker ID:",
|
||||
"@yourUserId": {}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"@@locale": "pl",
|
||||
"@@last_modified": "2021-08-14 12:41:09.943634",
|
||||
"about": "O nas",
|
||||
"about": "O aplikacji",
|
||||
"@about": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
|
@ -67,11 +67,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"archivedRoom": "Zarchiwizowane pokoje",
|
||||
"@archivedRoom": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"areGuestsAllowedToJoin": "Czy użytkownicy-goście mogą dołączyć",
|
||||
"@areGuestsAllowedToJoin": {
|
||||
"type": "text",
|
||||
|
@ -188,7 +183,7 @@
|
|||
"username": {}
|
||||
}
|
||||
},
|
||||
"changedTheDisplaynameTo": "{username} zmienił/-a swój nick na: {displayname}",
|
||||
"changedTheDisplaynameTo": "{username} zmienił/-a swój nick na: '{displayname}'",
|
||||
"@changedTheDisplaynameTo": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
|
@ -523,7 +518,7 @@
|
|||
"day": {}
|
||||
}
|
||||
},
|
||||
"dateWithYear": "{day}-{month}-{year}",
|
||||
"dateWithYear": "{day}.{month}.{year}",
|
||||
"@dateWithYear": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
|
@ -532,7 +527,7 @@
|
|||
"day": {}
|
||||
}
|
||||
},
|
||||
"deactivateAccountWarning": "To dezaktywuje twoje konto. To jest nieodwracalne ! Czy jesteś pewien?",
|
||||
"deactivateAccountWarning": "To zdezaktywuje twoje konto. To jest nieodwracalne! Na pewno chcesz to zrobić?",
|
||||
"@deactivateAccountWarning": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
|
@ -704,11 +699,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"friday": "Piątek",
|
||||
"@friday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"fromJoining": "Od dołączenia",
|
||||
"@fromJoining": {
|
||||
"type": "text",
|
||||
|
@ -879,11 +869,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"keysCached": "Klucze są załadowane",
|
||||
"@keysCached": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"kicked": "👞 {username} wyrzucił/-a {targetName}",
|
||||
"@kicked": {
|
||||
"type": "text",
|
||||
|
@ -996,11 +981,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"monday": "Poniedziałek",
|
||||
"@monday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"muteChat": "Wycisz czat",
|
||||
"@muteChat": {
|
||||
"type": "text",
|
||||
|
@ -1229,11 +1209,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"saturday": "Sobota",
|
||||
"@saturday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"seenByUser": "Zobaczone przez {username}",
|
||||
"@seenByUser": {
|
||||
"type": "text",
|
||||
|
@ -1369,11 +1344,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"sunday": "Niedziela",
|
||||
"@sunday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"synchronizingPleaseWait": "Synchronizacja… Proszę czekać.",
|
||||
"@synchronizingPleaseWait": {
|
||||
"type": "text",
|
||||
|
@ -1384,16 +1354,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"thisRoomHasBeenArchived": "Ten pokój został przeniesiony do archiwum.",
|
||||
"@thisRoomHasBeenArchived": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"thursday": "Czwartek",
|
||||
"@thursday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"title": "FluffyChat",
|
||||
"@title": {
|
||||
"description": "Title for the application",
|
||||
|
@ -1410,11 +1370,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"tuesday": "Wtorek",
|
||||
"@tuesday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"unbannedUser": "{username} odbanował/-a {targetName}",
|
||||
"@unbannedUser": {
|
||||
"type": "text",
|
||||
|
@ -1540,11 +1495,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"wednesday": "Środa",
|
||||
"@wednesday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"whoIsAllowedToJoinThisGroup": "Kto może dołączyć do tej grupy",
|
||||
"@whoIsAllowedToJoinThisGroup": {
|
||||
"type": "text",
|
||||
|
@ -1748,7 +1698,7 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"whatIsGoingOn": "Co u Ciebie słychać?",
|
||||
"whatIsGoingOn": "Co u ciebie słychać?",
|
||||
"@whatIsGoingOn": {},
|
||||
"pleaseEnterValidEmail": "Proszę podaj poprawny adres email.",
|
||||
"@pleaseEnterValidEmail": {},
|
||||
|
@ -1821,8 +1771,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"yourUserId": "Twoja nazwa użytkownika:",
|
||||
"@yourUserId": {},
|
||||
"yourChatBackupHasBeenSetUp": "Twoja kopia zapasowa chatu została ustawiona.",
|
||||
"@yourChatBackupHasBeenSetUp": {},
|
||||
"chatHasBeenAddedToThisSpace": "Chat został dodany do tej przestrzeni",
|
||||
|
@ -1832,11 +1780,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"discover": "Odkrywaj",
|
||||
"@discover": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"editRoomAvatar": "Edytuj zdjęcie pokoju",
|
||||
"@editRoomAvatar": {
|
||||
"type": "text",
|
||||
|
@ -1947,8 +1890,6 @@
|
|||
"@scanQrCode": {},
|
||||
"addToStory": "Dodaj do relacji",
|
||||
"@addToStory": {},
|
||||
"typeInInviteLinkManually": "Wpisz link ręcznie...",
|
||||
"@typeInInviteLinkManually": {},
|
||||
"createNewSpace": "Nowa przestrzeń",
|
||||
"@createNewSpace": {
|
||||
"type": "text",
|
||||
|
@ -2183,12 +2124,8 @@
|
|||
"@unsubscribeStories": {},
|
||||
"updateNow": "Rozpocznij aktualizację w tle",
|
||||
"@updateNow": {},
|
||||
"dehydrateShare": "To jest twój prywatny eksport FluffyChat. Upewnij się, że nie zgubisz go i zachowaj go dla siebie.",
|
||||
"@dehydrateShare": {},
|
||||
"hydrateTorLong": "Czy ostatnio eksportowałeś/-aś swoją sesję na TOR? Szybko ją zaimportuj i kontynuuj rozmowy.",
|
||||
"@hydrateTorLong": {},
|
||||
"noSearchResult": "Brak pasujących wyników wyszukiwania.",
|
||||
"@noSearchResult": {},
|
||||
"dehydrateTorLong": "W przypadku użytkowników sieci TOR zaleca się eksportowanie sesji przed zamknięciem okna.",
|
||||
"@dehydrateTorLong": {},
|
||||
"hydrate": "Przywracanie z pliku kopii zapasowej",
|
||||
|
@ -2267,11 +2204,6 @@
|
|||
},
|
||||
"commandHint_markasdm": "Oznacz jako pokój wiadomości bezpośrednich",
|
||||
"@commandHint_markasdm": {},
|
||||
"crossSigningEnabled": "Weryfikacja krzyżowa jest włączona",
|
||||
"@crossSigningEnabled": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"confirmMatrixId": "Potwierdź swój identyfikator Matrix w celu usunięcia konta.",
|
||||
"@confirmMatrixId": {},
|
||||
"commandHint_markasgroup": "Oznacz jako grupę",
|
||||
|
@ -2288,5 +2220,268 @@
|
|||
"dehydrateTor": "Użytkownicy TOR-a: Eksportuj sesję",
|
||||
"@dehydrateTor": {},
|
||||
"matrixWidgets": "Widżety Matrix",
|
||||
"@matrixWidgets": {}
|
||||
"@matrixWidgets": {},
|
||||
"unsupportedAndroidVersion": "Nieobsługiwana wersja systemu Android",
|
||||
"@unsupportedAndroidVersion": {},
|
||||
"widgetCustom": "Własny",
|
||||
"@widgetCustom": {},
|
||||
"widgetEtherpad": "Notatka",
|
||||
"@widgetEtherpad": {},
|
||||
"widgetJitsi": "Jitsi Meet",
|
||||
"@widgetJitsi": {},
|
||||
"pinMessage": "Przypnij do pokoju",
|
||||
"@pinMessage": {},
|
||||
"confirmEventUnpin": "Czy na pewno chcesz trwale odpiąć wydarzenie?",
|
||||
"@confirmEventUnpin": {},
|
||||
"youJoinedTheChat": "Dołączono do czatu",
|
||||
"@youJoinedTheChat": {},
|
||||
"noEmailWarning": "Wprowadź prawidłowy adres e-mail. W przeciwnym razie resetowanie hasła nie będzie możliwe. Jeśli nie chcesz, dotknij ponownie przycisku, aby kontynuować.",
|
||||
"@noEmailWarning": {},
|
||||
"user": "Użytkownik",
|
||||
"@user": {},
|
||||
"custom": "Własne",
|
||||
"@custom": {},
|
||||
"newGroup": "Nowa grupa",
|
||||
"@newGroup": {},
|
||||
"newSpace": "Nowa przestrzeń",
|
||||
"@newSpace": {},
|
||||
"enterInviteLinkOrMatrixId": "Wprowadź link zaproszenia lub identyfikator Matrix...",
|
||||
"@enterInviteLinkOrMatrixId": {},
|
||||
"fileIsTooBigForServer": "Serwer zgłasza, że plik jest zbyt duży, aby go wysłać.",
|
||||
"@fileIsTooBigForServer": {},
|
||||
"youBannedUser": "Zbanowałeś/-aś {user}",
|
||||
"@youBannedUser": {
|
||||
"placeholders": {
|
||||
"user": {}
|
||||
}
|
||||
},
|
||||
"users": "Użytkownicy",
|
||||
"@users": {},
|
||||
"countFiles": "{count} plików",
|
||||
"@countFiles": {
|
||||
"placeholders": {
|
||||
"count": {}
|
||||
}
|
||||
},
|
||||
"noOtherDevicesFound": "Nie znaleziono innych urządzeń",
|
||||
"@noOtherDevicesFound": {},
|
||||
"widgetUrlError": "Niepoprawny URL.",
|
||||
"@widgetUrlError": {},
|
||||
"widgetNameError": "Podaj nazwę wyświetlaną.",
|
||||
"@widgetNameError": {},
|
||||
"encryptThisChat": "Zaszyfruj ten czat",
|
||||
"@encryptThisChat": {},
|
||||
"endToEndEncryption": "Szyfrowanie od końca do końca",
|
||||
"@endToEndEncryption": {},
|
||||
"disableEncryptionWarning": "Ze względów bezpieczeństwa nie można wyłączyć szyfrowania w czacie, w którym zostało ono wcześniej włączone.",
|
||||
"@disableEncryptionWarning": {},
|
||||
"deviceKeys": "Klucze urządzenia:",
|
||||
"@deviceKeys": {},
|
||||
"emailOrUsername": "Adres e-mail lub nazwa użytkownika",
|
||||
"@emailOrUsername": {},
|
||||
"indexedDbErrorLong": "Przechowywanie wiadomości niestety nie jest domyślnie włączone w trybie prywatnym.\nOdwiedź\n - about:config\n - ustaw dom.indexedDB.privateBrowsing.enabled na true\nW przeciwnym razie nie jest możliwe uruchomienie FluffyChat.",
|
||||
"@indexedDbErrorLong": {},
|
||||
"saveKeyManuallyDescription": "Zapisz ten klucz ręcznie, uruchamiając systemowe okno dialogowe udostępniania lub schowek.",
|
||||
"@saveKeyManuallyDescription": {},
|
||||
"screenSharingTitle": "udostępnianie ekranu",
|
||||
"@screenSharingTitle": {},
|
||||
"appearOnTopDetails": "Umożliwia wyświetlanie aplikacji nad innymi (nie jest to konieczne, jeśli FluffyChat jest już ustawiony jako konto do dzwonienia)",
|
||||
"@appearOnTopDetails": {},
|
||||
"noKeyForThisMessage": "Może się to zdarzyć, jeśli wiadomość została wysłana przed zalogowaniem się na to konto na tym urządzeniu.\n\nMożliwe jest również, że nadawca zablokował Twoje urządzenie lub coś poszło nie tak z połączeniem internetowym.\n\nJesteś w stanie odczytać wiadomość na innej sesji? W takim razie możesz przenieść z niej wiadomość! Wejdź w Ustawienia > Urządzenia i upewnij się, że Twoje urządzenia zweryfikowały się wzajemnie. Gdy następnym razem otworzysz pokój i obie sesje będą włączone, klucze zostaną przekazane automatycznie.\n\nNie chcesz stracić kluczy podczas wylogowania lub przełączania urządzeń? Upewnij się, że w ustawieniach masz włączoną kopię zapasową czatu.",
|
||||
"@noKeyForThisMessage": {},
|
||||
"sorryThatsNotPossible": "Przepraszamy... to nie jest możliwe",
|
||||
"@sorryThatsNotPossible": {},
|
||||
"noBackupWarning": "Uwaga! Bez włączenia kopii zapasowej czatu, stracisz dostęp do swoich zaszyfrowanych wiadomości. Zaleca się włączenie kopii zapasowej czatu przed wylogowaniem.",
|
||||
"@noBackupWarning": {},
|
||||
"commandHint_googly": "Wyślij kręcące się oczka",
|
||||
"@commandHint_googly": {},
|
||||
"callingPermissions": "Uprawnienia połączeń",
|
||||
"@callingPermissions": {},
|
||||
"storeInAndroidKeystore": "Przechowaj w Android KeyStore",
|
||||
"@storeInAndroidKeystore": {},
|
||||
"commandHint_cuddle": "Wyślij przytulenie",
|
||||
"@commandHint_cuddle": {},
|
||||
"googlyEyesContent": "{senderName} wysyła ci kręcące się oczka",
|
||||
"@googlyEyesContent": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"senderName": {}
|
||||
}
|
||||
},
|
||||
"cuddleContent": "{senderName} przytula cię",
|
||||
"@cuddleContent": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"senderName": {}
|
||||
}
|
||||
},
|
||||
"hugContent": "{senderName} uściska cię",
|
||||
"@hugContent": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"senderName": {}
|
||||
}
|
||||
},
|
||||
"commandHint_hug": "Wyślij uścisk",
|
||||
"@commandHint_hug": {},
|
||||
"letsStart": "Zacznijmy",
|
||||
"@letsStart": {},
|
||||
"reactedWith": "{sender} zareagował/-a z {reaction}",
|
||||
"@reactedWith": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"sender": {},
|
||||
"reaction": {}
|
||||
}
|
||||
},
|
||||
"emojis": "Emoji",
|
||||
"@emojis": {},
|
||||
"placeCall": "Zadzwoń",
|
||||
"@placeCall": {},
|
||||
"voiceCall": "Połączenie głosowe",
|
||||
"@voiceCall": {},
|
||||
"unsupportedAndroidVersionLong": "Ta funkcja wymaga nowszej wersji systemu Android. Sprawdź aktualizacje lub wsparcie Lineage OS.",
|
||||
"@unsupportedAndroidVersionLong": {},
|
||||
"videoCallsBetaWarning": "Należy pamiętać, że połączenia wideo są obecnie w fazie beta. Mogą nie działać zgodnie z oczekiwaniami lub nie działać w ogóle na wszystkich platformach.",
|
||||
"@videoCallsBetaWarning": {},
|
||||
"experimentalVideoCalls": "Eksperymentalne połączenia wideo",
|
||||
"@experimentalVideoCalls": {},
|
||||
"indexedDbErrorTitle": "Problemy związane z trybem prywatnym",
|
||||
"@indexedDbErrorTitle": {},
|
||||
"switchToAccount": "Przełącz na konto {number}",
|
||||
"@switchToAccount": {
|
||||
"type": "number",
|
||||
"placeholders": {
|
||||
"number": {}
|
||||
}
|
||||
},
|
||||
"nextAccount": "Następne konto",
|
||||
"@nextAccount": {},
|
||||
"previousAccount": "Poprzednie konto",
|
||||
"@previousAccount": {},
|
||||
"editWidgets": "Edytuj widżety",
|
||||
"@editWidgets": {},
|
||||
"addWidget": "Dodaj widżet",
|
||||
"@addWidget": {},
|
||||
"widgetVideo": "Film",
|
||||
"@widgetVideo": {},
|
||||
"widgetName": "Nazwa",
|
||||
"@widgetName": {},
|
||||
"errorAddingWidget": "Błąd podczas dodawania widżetu.",
|
||||
"@errorAddingWidget": {},
|
||||
"youRejectedTheInvitation": "Odrzucono zaproszenie",
|
||||
"@youRejectedTheInvitation": {},
|
||||
"youAcceptedTheInvitation": "👍 Zaakceptowałeś/-aś zaproszenie",
|
||||
"@youAcceptedTheInvitation": {},
|
||||
"youHaveWithdrawnTheInvitationFor": "Wycofano zaproszenie dla {user}",
|
||||
"@youHaveWithdrawnTheInvitationFor": {
|
||||
"placeholders": {
|
||||
"user": {}
|
||||
}
|
||||
},
|
||||
"youInvitedBy": "📩 Zostałeś/-aś zaproszony/-a przez {user}",
|
||||
"@youInvitedBy": {
|
||||
"placeholders": {
|
||||
"user": {}
|
||||
}
|
||||
},
|
||||
"youInvitedUser": "📩 Zaprosiłeś/-aś {user}",
|
||||
"@youInvitedUser": {
|
||||
"placeholders": {
|
||||
"user": {}
|
||||
}
|
||||
},
|
||||
"youKicked": "👞 Wyrzuciłeś/-aś {user}",
|
||||
"@youKicked": {
|
||||
"placeholders": {
|
||||
"user": {}
|
||||
}
|
||||
},
|
||||
"youKickedAndBanned": "🙅 Wyrzuciłeś/-aś i zbanowałeś/-aś {user}",
|
||||
"@youKickedAndBanned": {
|
||||
"placeholders": {
|
||||
"user": {}
|
||||
}
|
||||
},
|
||||
"youUnbannedUser": "Odbanowałeś/-aś {user}",
|
||||
"@youUnbannedUser": {
|
||||
"placeholders": {
|
||||
"user": {}
|
||||
}
|
||||
},
|
||||
"stories": "Relacje",
|
||||
"@stories": {},
|
||||
"unlockOldMessages": "Odblokuj stare wiadomości",
|
||||
"@unlockOldMessages": {},
|
||||
"storeInSecureStorageDescription": "Przechowaj klucz odzyskiwania w bezpiecznym magazynie tego urządzenia.",
|
||||
"@storeInSecureStorageDescription": {},
|
||||
"storeInAppleKeyChain": "Przechowaj w pęku kluczy Apple",
|
||||
"@storeInAppleKeyChain": {},
|
||||
"storeSecurlyOnThisDevice": "Przechowaj bezpiecznie na tym urządzeniu",
|
||||
"@storeSecurlyOnThisDevice": {},
|
||||
"foregroundServiceRunning": "To powiadomienie pojawia się, gdy usługa w tle jest uruchomiona.",
|
||||
"@foregroundServiceRunning": {},
|
||||
"screenSharingDetail": "Udostępniasz swój ekran w FluffyChat",
|
||||
"@screenSharingDetail": {},
|
||||
"callingAccount": "Konto połączeń",
|
||||
"@callingAccount": {},
|
||||
"callingAccountDetails": "Pozwala FluffyChat używać natywnej aplikacji do wykonywania połączeń w Androidzie.",
|
||||
"@callingAccountDetails": {},
|
||||
"appearOnTop": "Wyświetlaj nad innymi",
|
||||
"@appearOnTop": {},
|
||||
"otherCallingPermissions": "Mikrofon, kamera i inne uprawnienia FluffyChat",
|
||||
"@otherCallingPermissions": {},
|
||||
"whyIsThisMessageEncrypted": "Dlaczego nie można odczytać tej wiadomości?",
|
||||
"@whyIsThisMessageEncrypted": {},
|
||||
"enterSpace": "Wejdź do przestrzeni",
|
||||
"@enterSpace": {},
|
||||
"enterRoom": "Wejdź do pokoju",
|
||||
"@enterRoom": {},
|
||||
"allSpaces": "Wszystkie przestrzenie",
|
||||
"@allSpaces": {},
|
||||
"numChats": "{number} czatów",
|
||||
"@numChats": {
|
||||
"type": "number",
|
||||
"placeholders": {
|
||||
"number": {}
|
||||
}
|
||||
},
|
||||
"hideUnimportantStateEvents": "Ukryj nieistotne wydarzenia stanu",
|
||||
"@hideUnimportantStateEvents": {},
|
||||
"doNotShowAgain": "Nie pokazuj ponownie",
|
||||
"@doNotShowAgain": {},
|
||||
"wasDirectChatDisplayName": "Pusty czat (wcześniej {oldDisplayName})",
|
||||
"@wasDirectChatDisplayName": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"oldDisplayName": {}
|
||||
}
|
||||
},
|
||||
"newSpaceDescription": "Przestrzenie pozwalają na konsolidację czatów i budowanie prywatnych lub publicznych społeczności.",
|
||||
"@newSpaceDescription": {},
|
||||
"reopenChat": "Otwórz ponownie czat",
|
||||
"@reopenChat": {},
|
||||
"fileHasBeenSavedAt": "Plik został zapisany w ścieżce {path}",
|
||||
"@fileHasBeenSavedAt": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"path": {}
|
||||
}
|
||||
},
|
||||
"addToBundle": "Dodaj do pakietu",
|
||||
"@addToBundle": {},
|
||||
"bundleName": "Nazwa pakietu",
|
||||
"@bundleName": {},
|
||||
"editBundlesForAccount": "Edytuj paczki dla tego konta",
|
||||
"@editBundlesForAccount": {},
|
||||
"jumpToLastReadMessage": "Przejdź do ostatnio przeczytanej wiadomości",
|
||||
"@jumpToLastReadMessage": {},
|
||||
"readUpToHere": "Czytaj do tego miejsca",
|
||||
"@readUpToHere": {},
|
||||
"jump": "Przejdź",
|
||||
"@jump": {},
|
||||
"removeFromBundle": "Usuń z tej paczki",
|
||||
"@removeFromBundle": {},
|
||||
"openLinkInBrowser": "Otwórz link w przeglądarce",
|
||||
"@openLinkInBrowser": {}
|
||||
}
|
||||
|
|
|
@ -10,21 +10,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"monday": "segunda-feira",
|
||||
"@monday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"saturday": "sábado",
|
||||
"@saturday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"wednesday": "quarta-feira",
|
||||
"@wednesday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"about": "Sobre",
|
||||
"@about": {
|
||||
"type": "text",
|
||||
|
@ -107,11 +92,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"tuesday": "terça-feira",
|
||||
"@tuesday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"logout": "Terminar sessão",
|
||||
"@logout": {
|
||||
"type": "text",
|
||||
|
@ -122,11 +102,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"sunday": "domingo",
|
||||
"@sunday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"users": "Utilizadores",
|
||||
"@users": {},
|
||||
"close": "Fechar",
|
||||
|
@ -141,15 +116,5 @@
|
|||
"month": {},
|
||||
"day": {}
|
||||
}
|
||||
},
|
||||
"friday": "sexta-feira",
|
||||
"@friday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"thursday": "quinta-feira",
|
||||
"@thursday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
|
@ -81,11 +81,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"archivedRoom": "Sala arquivada",
|
||||
"@archivedRoom": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"areGuestsAllowedToJoin": "Usuários convidados podem participar",
|
||||
"@areGuestsAllowedToJoin": {
|
||||
"type": "text",
|
||||
|
@ -543,11 +538,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"crossSigningEnabled": "Assinatura cruzada ativada",
|
||||
"@crossSigningEnabled": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"currentlyActive": "Ativo",
|
||||
"@currentlyActive": {
|
||||
"type": "text",
|
||||
|
@ -633,11 +623,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"discover": "Desvendar",
|
||||
"@discover": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"displaynameHasBeenChanged": "O nome de exibição foi alterado",
|
||||
"@displaynameHasBeenChanged": {
|
||||
"type": "text",
|
||||
|
@ -804,11 +789,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"friday": "Sexta-feira",
|
||||
"@friday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"fromJoining": "Desde que entrou",
|
||||
"@fromJoining": {
|
||||
"type": "text",
|
||||
|
@ -999,11 +979,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"keysCached": "Chaves guardadas",
|
||||
"@keysCached": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"kicked": "👞 {username} enxotou {targetName}",
|
||||
"@kicked": {
|
||||
"type": "text",
|
||||
|
@ -1138,11 +1113,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"monday": "Segunda-feira",
|
||||
"@monday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"muteChat": "Silenciar",
|
||||
"@muteChat": {
|
||||
"type": "text",
|
||||
|
@ -1536,11 +1506,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"saturday": "Sábado",
|
||||
"@saturday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"saveFile": "Salvar arquivo",
|
||||
"@saveFile": {
|
||||
"type": "text",
|
||||
|
@ -1779,11 +1744,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"sunday": "Domingo",
|
||||
"@sunday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"synchronizingPleaseWait": "Sincronizando… Por favor, aguarde.",
|
||||
"@synchronizingPleaseWait": {
|
||||
"type": "text",
|
||||
|
@ -1804,16 +1764,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"thisRoomHasBeenArchived": "Esta sala foi arquivada.",
|
||||
"@thisRoomHasBeenArchived": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"thursday": "Quinta-feira",
|
||||
"@thursday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"title": "FluffyChat",
|
||||
"@title": {
|
||||
"description": "Title for the application",
|
||||
|
@ -1850,11 +1800,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"tuesday": "Terça-feira",
|
||||
"@tuesday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"unavailable": "Indisponível",
|
||||
"@unavailable": {
|
||||
"type": "text",
|
||||
|
@ -2025,11 +1970,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"wednesday": "Quarta-feira",
|
||||
"@wednesday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"weSentYouAnEmail": "Enviamos um e-mail para você",
|
||||
"@weSentYouAnEmail": {
|
||||
"type": "text",
|
||||
|
@ -2102,8 +2042,6 @@
|
|||
},
|
||||
"shareYourInviteLink": "Compartilhar o link do convite",
|
||||
"@shareYourInviteLink": {},
|
||||
"typeInInviteLinkManually": "Digitar o link do convite manualmente...",
|
||||
"@typeInInviteLinkManually": {},
|
||||
"oneClientLoggedOut": "Um dos seus clientes foi desvinculado",
|
||||
"@oneClientLoggedOut": {},
|
||||
"addAccount": "Adicionar conta",
|
||||
|
@ -2176,8 +2114,6 @@
|
|||
"@sendOnEnter": {},
|
||||
"homeserver": "Servidor matriz",
|
||||
"@homeserver": {},
|
||||
"yourUserId": "Seu ID de usuário:",
|
||||
"@yourUserId": {},
|
||||
"chatHasBeenAddedToThisSpace": "A conversa foi adicionada a este espaço",
|
||||
"@chatHasBeenAddedToThisSpace": {},
|
||||
"commandHint_clearcache": "Limpar dados temporários",
|
||||
|
@ -2419,8 +2355,6 @@
|
|||
"@commandHint_markasdm": {},
|
||||
"commandHint_markasgroup": "Marcar como grupo",
|
||||
"@commandHint_markasgroup": {},
|
||||
"dehydrateShare": "Este é seu extrato FluffyChat. Cuidado para não perdê-lo e o mantenha privado.",
|
||||
"@dehydrateShare": {},
|
||||
"hydrateTor": "Usuários TOR: Importar sessão",
|
||||
"@hydrateTor": {},
|
||||
"hydrateTorLong": "Você exportou sua última sessão no TOR? Importe ela rapidamente e continue conversando.",
|
||||
|
@ -2491,8 +2425,6 @@
|
|||
"@dehydrateWarning": {},
|
||||
"dehydrateTorLong": "Para usuários TOR, é recomendado exportar a sessão antes de fechar a janela.",
|
||||
"@dehydrateTorLong": {},
|
||||
"enableAutoBackups": "Habilitar backups automáticos",
|
||||
"@enableAutoBackups": {},
|
||||
"whyIsThisMessageEncrypted": "Por que esta mensagem está ilegível?",
|
||||
"@whyIsThisMessageEncrypted": {},
|
||||
"screenSharingTitle": "Compartilhar tela",
|
||||
|
|
|
@ -90,11 +90,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"archivedRoom": "Sala arquivada",
|
||||
"@archivedRoom": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"areGuestsAllowedToJoin": "Todos os visitantes podem entrar",
|
||||
"@areGuestsAllowedToJoin": {
|
||||
"type": "text",
|
||||
|
@ -294,8 +289,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"yourUserId": "O teu ID de utilizador:",
|
||||
"@yourUserId": {},
|
||||
"yourChatBackupHasBeenSetUp": "A cópia de segurança foi configurada.",
|
||||
"@yourChatBackupHasBeenSetUp": {},
|
||||
"chatBackup": "Cópia de segurança de conversas",
|
||||
|
@ -515,11 +508,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"crossSigningEnabled": "Assinatura cruzada ativada",
|
||||
"@crossSigningEnabled": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"currentlyActive": "Ativo(a) agora",
|
||||
"@currentlyActive": {
|
||||
"type": "text",
|
||||
|
@ -605,11 +593,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"discover": "Descobrir",
|
||||
"@discover": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"displaynameHasBeenChanged": "Nome de exibição alterado",
|
||||
"@displaynameHasBeenChanged": {
|
||||
"type": "text",
|
||||
|
@ -778,11 +761,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"friday": "Sexta-feira",
|
||||
"@friday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"goToTheNewRoom": "Ir para a nova sala",
|
||||
"@goToTheNewRoom": {
|
||||
"type": "text",
|
||||
|
@ -963,11 +941,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"keysCached": "Chaves estão armazenadas em cache",
|
||||
"@keysCached": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"kicked": "{username} expulsou {targetName}",
|
||||
"@kicked": {
|
||||
"type": "text",
|
||||
|
@ -1097,11 +1070,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"monday": "Segunda-feira",
|
||||
"@monday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"muteChat": "Silenciar conversa",
|
||||
"@muteChat": {
|
||||
"type": "text",
|
||||
|
@ -1167,8 +1135,6 @@
|
|||
},
|
||||
"shareYourInviteLink": "Partilhar a ligação de convite",
|
||||
"@shareYourInviteLink": {},
|
||||
"typeInInviteLinkManually": "Escrever a ligação de convite manualmente...",
|
||||
"@typeInInviteLinkManually": {},
|
||||
"none": "Nenhum",
|
||||
"@none": {
|
||||
"type": "text",
|
||||
|
@ -1581,11 +1547,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"saturday": "Sábado",
|
||||
"@saturday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"saveFile": "Guardar ficheiro",
|
||||
"@saveFile": {
|
||||
"type": "text",
|
||||
|
@ -1709,8 +1670,6 @@
|
|||
"@dehydrate": {},
|
||||
"dehydrateWarning": "Esta ação não pode ser revertida. Assegura-te que guardas bem a cópia de segurança.",
|
||||
"@dehydrateWarning": {},
|
||||
"dehydrateShare": "Esta é a tua exportação privada do FluffyChat. Assegura-te que não a perdes e que a manténs privada.",
|
||||
"@dehydrateShare": {},
|
||||
"hydrateTorLong": "Exportaste a tua sessão na última vez que estiveste no TOR? Importa-a rapidamente e continua a conversar.",
|
||||
"@hydrateTorLong": {},
|
||||
"dehydrateTor": "Utilizadores do TOR: Exportar sessão",
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -55,11 +55,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"archivedRoom": "Archivovaná miestnosť",
|
||||
"@archivedRoom": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"areGuestsAllowedToJoin": "Môžu sa pripojiť hostia",
|
||||
"@areGuestsAllowedToJoin": {
|
||||
"type": "text",
|
||||
|
@ -330,11 +325,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"crossSigningEnabled": "Vzájomné overenie je zapnuté",
|
||||
"@crossSigningEnabled": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"currentlyActive": "Momentálne prítomní",
|
||||
"@currentlyActive": {
|
||||
"type": "text",
|
||||
|
@ -480,11 +470,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"friday": "Piatok",
|
||||
"@friday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"fromJoining": "Od pripojenia",
|
||||
"@fromJoining": {
|
||||
"type": "text",
|
||||
|
@ -610,11 +595,6 @@
|
|||
"username": {}
|
||||
}
|
||||
},
|
||||
"keysCached": "Kľúče sú uložené",
|
||||
"@keysCached": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"kicked": "{username} vyhodili {targetName}",
|
||||
"@kicked": {
|
||||
"type": "text",
|
||||
|
@ -717,11 +697,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"monday": "Pondelok",
|
||||
"@monday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"muteChat": "Stlmiť chat",
|
||||
"@muteChat": {
|
||||
"type": "text",
|
||||
|
@ -920,11 +895,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"saturday": "Sobota",
|
||||
"@saturday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"seenByUser": "Videné užívateľom {username}",
|
||||
"@seenByUser": {
|
||||
"type": "text",
|
||||
|
@ -1060,11 +1030,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"sunday": "Nedeľa",
|
||||
"@sunday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"systemTheme": "Systémová farba",
|
||||
"@systemTheme": {
|
||||
"type": "text",
|
||||
|
@ -1080,16 +1045,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"thisRoomHasBeenArchived": "Táto miestnosť bola archivovaná.",
|
||||
"@thisRoomHasBeenArchived": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"thursday": "Štvrtok",
|
||||
"@thursday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"title": "FluffyChat",
|
||||
"@title": {
|
||||
"description": "Title for the application",
|
||||
|
@ -1101,11 +1056,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"tuesday": "Utorok",
|
||||
"@tuesday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"unbannedUser": "{username} odbanovali {targetName}",
|
||||
"@unbannedUser": {
|
||||
"type": "text",
|
||||
|
@ -1256,11 +1206,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"wednesday": "Streda",
|
||||
"@wednesday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"whoIsAllowedToJoinThisGroup": "Kto môže vstúpiť do tejto skupiny",
|
||||
"@whoIsAllowedToJoinThisGroup": {
|
||||
"type": "text",
|
||||
|
@ -1440,8 +1385,6 @@
|
|||
},
|
||||
"sendOnEnter": "Odoslať pri vstupe",
|
||||
"@sendOnEnter": {},
|
||||
"yourUserId": "Vaše užívateľské ID:",
|
||||
"@yourUserId": {},
|
||||
"ignoredUsers": "Ignorovaní užívatelia",
|
||||
"@ignoredUsers": {
|
||||
"type": "text",
|
||||
|
|
|
@ -71,11 +71,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"archivedRoom": "Arhivirana soba",
|
||||
"@archivedRoom": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"askSSSSSign": "Če želite podpisati drugo osebo, vnesite geslo za varno trgovino ali obnovitveni ključ.",
|
||||
"@askSSSSSign": {
|
||||
"type": "text",
|
||||
|
@ -259,8 +254,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"yourUserId": "Vaš ID uporabnika:",
|
||||
"@yourUserId": {},
|
||||
"yourChatBackupHasBeenSetUp": "Varnostna kopija klepeta je nastavljena.",
|
||||
"@yourChatBackupHasBeenSetUp": {},
|
||||
"chatBackup": "Varnostno kopiranje klepeta",
|
||||
|
@ -558,11 +551,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"crossSigningEnabled": "Navzkrižno podpisovanje DA",
|
||||
"@crossSigningEnabled": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"currentlyActive": "Trenutno aktiven",
|
||||
"@currentlyActive": {
|
||||
"type": "text",
|
||||
|
|
|
@ -76,11 +76,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"archivedRoom": "Архивирана соба",
|
||||
"@archivedRoom": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"areGuestsAllowedToJoin": "Да ли је гостима дозвољен приступ",
|
||||
"@areGuestsAllowedToJoin": {
|
||||
"type": "text",
|
||||
|
@ -504,11 +499,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"crossSigningEnabled": "Међу-потписивање укључено",
|
||||
"@crossSigningEnabled": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"currentlyActive": "Тренутно активно",
|
||||
"@currentlyActive": {
|
||||
"type": "text",
|
||||
|
@ -594,11 +584,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"discover": "Истражи",
|
||||
"@discover": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"displaynameHasBeenChanged": "Име за приказ је измењено",
|
||||
"@displaynameHasBeenChanged": {
|
||||
"type": "text",
|
||||
|
@ -756,11 +741,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"friday": "петак",
|
||||
"@friday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"fromJoining": "од приступања",
|
||||
"@fromJoining": {
|
||||
"type": "text",
|
||||
|
@ -951,11 +931,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"keysCached": "Кључеви су кеширани",
|
||||
"@keysCached": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"kicked": "{username} избаци корисника {targetName}",
|
||||
"@kicked": {
|
||||
"type": "text",
|
||||
|
@ -1080,11 +1055,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"monday": "понедељак",
|
||||
"@monday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"muteChat": "Ућуткај ћаскање",
|
||||
"@muteChat": {
|
||||
"type": "text",
|
||||
|
@ -1460,11 +1430,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"saturday": "субота",
|
||||
"@saturday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"search": "Претражи",
|
||||
"@search": {
|
||||
"type": "text",
|
||||
|
@ -1674,11 +1639,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"sunday": "недеља",
|
||||
"@sunday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"systemTheme": "системски",
|
||||
"@systemTheme": {
|
||||
"type": "text",
|
||||
|
@ -1694,16 +1654,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"thisRoomHasBeenArchived": "Ова соба је архивирана.",
|
||||
"@thisRoomHasBeenArchived": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"thursday": "четвртак",
|
||||
"@thursday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"title": "FluffyChat",
|
||||
"@title": {
|
||||
"description": "Title for the application",
|
||||
|
@ -1740,11 +1690,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"tuesday": "уторак",
|
||||
"@tuesday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"unavailable": "Недоступно",
|
||||
"@unavailable": {
|
||||
"type": "text",
|
||||
|
@ -1915,11 +1860,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"wednesday": "среда",
|
||||
"@wednesday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"weSentYouAnEmail": "Послали смо вам е-пошту",
|
||||
"@weSentYouAnEmail": {
|
||||
"type": "text",
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1 +1 @@
|
|||
{}
|
||||
{}
|
|
@ -84,11 +84,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"archivedRoom": "Arşivlenmiş Oda",
|
||||
"@archivedRoom": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"areGuestsAllowedToJoin": "Misafir kullanıcıların katılmasına izin veriliyor mu",
|
||||
"@areGuestsAllowedToJoin": {
|
||||
"type": "text",
|
||||
|
@ -548,11 +543,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"crossSigningEnabled": "Çapraz imzalama açık",
|
||||
"@crossSigningEnabled": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"currentlyActive": "Şu anda etkin",
|
||||
"@currentlyActive": {
|
||||
"type": "text",
|
||||
|
@ -638,11 +628,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"discover": "Keşfet",
|
||||
"@discover": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"displaynameHasBeenChanged": "Görünen ad değiştirildi",
|
||||
"@displaynameHasBeenChanged": {
|
||||
"type": "text",
|
||||
|
@ -809,11 +794,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"friday": "Cuma",
|
||||
"@friday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"fromJoining": "Katılmadan",
|
||||
"@fromJoining": {
|
||||
"type": "text",
|
||||
|
@ -1004,11 +984,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"keysCached": "Anahtarlar önbelleğe alındı",
|
||||
"@keysCached": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"kicked": "👞 {username}, {targetName} kişisini attı",
|
||||
"@kicked": {
|
||||
"type": "text",
|
||||
|
@ -1143,11 +1118,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"monday": "Pazartesi",
|
||||
"@monday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"muteChat": "Sohbeti sessize al",
|
||||
"@muteChat": {
|
||||
"type": "text",
|
||||
|
@ -1541,11 +1511,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"saturday": "Cumartesi",
|
||||
"@saturday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"saveFile": "Dosyayı kaydet",
|
||||
"@saveFile": {
|
||||
"type": "text",
|
||||
|
@ -1784,11 +1749,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"sunday": "Pazar",
|
||||
"@sunday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"synchronizingPleaseWait": "Eşzamanlanıyor… Lütfen bekleyin.",
|
||||
"@synchronizingPleaseWait": {
|
||||
"type": "text",
|
||||
|
@ -1809,16 +1769,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"thisRoomHasBeenArchived": "Bu oda arşivlendi.",
|
||||
"@thisRoomHasBeenArchived": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"thursday": "Perşembe",
|
||||
"@thursday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"title": "FluffyChat",
|
||||
"@title": {
|
||||
"description": "Title for the application",
|
||||
|
@ -1855,11 +1805,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"tuesday": "Salı",
|
||||
"@tuesday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"unavailable": "Yok",
|
||||
"@unavailable": {
|
||||
"type": "text",
|
||||
|
@ -2030,11 +1975,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"wednesday": "Çarşamba",
|
||||
"@wednesday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"weSentYouAnEmail": "Size bir e-posta gönderdik",
|
||||
"@weSentYouAnEmail": {
|
||||
"type": "text",
|
||||
|
@ -2107,8 +2047,6 @@
|
|||
},
|
||||
"scanQrCode": "QR kodunu tarayın",
|
||||
"@scanQrCode": {},
|
||||
"typeInInviteLinkManually": "Davet bağlantısını el ile yazın...",
|
||||
"@typeInInviteLinkManually": {},
|
||||
"shareYourInviteLink": "Davet bağlantınızı paylaşın",
|
||||
"@shareYourInviteLink": {},
|
||||
"sendOnEnter": "Enter tuşu ile gönder",
|
||||
|
@ -2137,8 +2075,6 @@
|
|||
"@yourChatBackupHasBeenSetUp": {},
|
||||
"unverified": "Doğrulanmadı",
|
||||
"@unverified": {},
|
||||
"yourUserId": "Kullanıcı kimliğiniz:",
|
||||
"@yourUserId": {},
|
||||
"repeatPassword": "Parolayı tekrarlayın",
|
||||
"@repeatPassword": {},
|
||||
"passwordsDoNotMatch": "Parolalar eşleşmiyor!",
|
||||
|
@ -2380,8 +2316,6 @@
|
|||
"@users": {},
|
||||
"storeInSecureStorageDescription": "Kurtarma anahtarını bu aygıtın güvenli deposunda saklayın.",
|
||||
"@storeInSecureStorageDescription": {},
|
||||
"enableAutoBackups": "Otomatik yedeklemeleri etkinleştir",
|
||||
"@enableAutoBackups": {},
|
||||
"recoveryKey": "Kurtarma anahtarı",
|
||||
"@recoveryKey": {},
|
||||
"stories": "Hikayeler",
|
||||
|
@ -2414,8 +2348,6 @@
|
|||
"@indexedDbErrorTitle": {},
|
||||
"dehydrateWarning": "Bu eylem geri alınamaz. Yedekleme dosyasını güvenli bir şekilde sakladığınızdan emin olun.",
|
||||
"@dehydrateWarning": {},
|
||||
"dehydrateShare": "Bu sizin özel FluffyChat dışa aktarımınızdır. Kaybetmediğinizden ve gizli tuttuğunuzdan emin olun.",
|
||||
"@dehydrateShare": {},
|
||||
"hydrateTorLong": "TOR'da en son oturumunuzu dışa aktardınız mı? Hızlıca içe aktarın ve sohbete devam edin.",
|
||||
"@hydrateTorLong": {},
|
||||
"indexedDbErrorLong": "Mesaj saklama özelliği ne yazık ki öntanımlı olarak gizli modda etkin değildir.\nLütfen\n - about:config sayfasına gidin ve\n - dom.indexedDB.privateBrowsing.enabled seçeneğini true olarak ayarlayın\nAksi takdirde FluffyChat çalıştırılamaz.",
|
||||
|
@ -2443,7 +2375,7 @@
|
|||
"@commandHint_markasdm": {},
|
||||
"whyIsThisMessageEncrypted": "Bu mesaj neden okunamıyor?",
|
||||
"@whyIsThisMessageEncrypted": {},
|
||||
"noKeyForThisMessage": "Bu durum, mesaj siz bu aygıtta hesabınızda oturum açmadan önce gönderildiyse meydana gelebilir. \n \nGönderenin aygıtınızı engellemiş olması veya internet bağlantısında bir sorun olması da mümkündür. \n \nMesajı başka bir oturumda okuyabiliyor musunuz? O zaman mesajı oradan aktarabilirsiniz! Ayarlar > Aygıtlar bölümüne gidin ve aygıtlarınızın birbirini doğruladığından emin olun. Odayı bir sonraki sefer açtığınızda ve her iki oturum da ön planda olduğunda, anahtarlar otomatik olarak iletilecektir. \n \nOturumu kapatırken veya aygıt değiştirirken anahtarları kaybetmek istemiyor musunuz? Ayarlarda sohbet yedeklemesini etkinleştirdiğinizden emin olun.",
|
||||
"noKeyForThisMessage": "Bu durum, mesaj siz bu aygıtta hesabınızda oturum açmadan önce gönderildiyse meydana gelebilir.\n\nGönderenin aygıtınızı engellemiş olması veya internet bağlantısında bir sorun olması da mümkündür.\n\nMesajı başka bir oturumda okuyabiliyor musunuz? O zaman mesajı oradan aktarabilirsiniz! Ayarlar > Aygıtlar bölümüne gidin ve aygıtlarınızın birbirini doğruladığından emin olun. Odayı bir sonraki sefer açtığınızda ve her iki oturum da ön planda olduğunda, anahtarlar otomatik olarak iletilecektir.\n\nOturumu kapatırken veya aygıt değiştirirken anahtarları kaybetmek istemiyor musunuz? Ayarlarda sohbet yedeklemesini etkinleştirdiğinizden emin olun.",
|
||||
"@noKeyForThisMessage": {},
|
||||
"screenSharingTitle": "ekran paylaşımı",
|
||||
"@screenSharingTitle": {},
|
||||
|
@ -2532,8 +2464,6 @@
|
|||
"@sorryThatsNotPossible": {},
|
||||
"deviceKeys": "Aygıt anahtarları:",
|
||||
"@deviceKeys": {},
|
||||
"noSearchResult": "Eşleşen arama sonucu yok.",
|
||||
"@noSearchResult": {},
|
||||
"letsStart": "Başlayalım",
|
||||
"@letsStart": {},
|
||||
"enterInviteLinkOrMatrixId": "Davet bağlantısını veya Matris kimliğini girin...",
|
||||
|
@ -2545,5 +2475,40 @@
|
|||
"noOtherDevicesFound": "Başka aygıt bulunamadı",
|
||||
"@noOtherDevicesFound": {},
|
||||
"fileIsTooBigForServer": "Sunucu, dosyanın gönderilemeyecek kadar büyük olduğunu bildiriyor.",
|
||||
"@fileIsTooBigForServer": {}
|
||||
"@fileIsTooBigForServer": {},
|
||||
"fileHasBeenSavedAt": "Dosya {path} konumuna kaydedildi",
|
||||
"@fileHasBeenSavedAt": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"path": {}
|
||||
}
|
||||
},
|
||||
"jumpToLastReadMessage": "Son okunan mesaja atla",
|
||||
"@jumpToLastReadMessage": {},
|
||||
"readUpToHere": "Buraya kadar oku",
|
||||
"@readUpToHere": {},
|
||||
"jump": "Atla",
|
||||
"@jump": {},
|
||||
"openLinkInBrowser": "Bağlantıyı tarayıcıda aç",
|
||||
"@openLinkInBrowser": {},
|
||||
"allRooms": "Tüm Grup Sohbetleri",
|
||||
"@allRooms": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"discover": "Keşfet",
|
||||
"@discover": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"reportErrorDescription": "Olamaz. Bir şeyler yanlış gitti. Lütfen daha sonra tekrar deneyin. İsterseniz hatayı geliştiricilere bildirebilirsiniz.",
|
||||
"@reportErrorDescription": {},
|
||||
"report": "bildir",
|
||||
"@report": {},
|
||||
"signInWithPassword": "Parola ile oturum aç",
|
||||
"@signInWithPassword": {},
|
||||
"continueWith": "Devam et:",
|
||||
"@continueWith": {},
|
||||
"pleaseTryAgainLaterOrChooseDifferentServer": "Lütfen daha sonra tekrar deneyin veya farklı bir sunucu seçin.",
|
||||
"@pleaseTryAgainLaterOrChooseDifferentServer": {}
|
||||
}
|
||||
|
|
|
@ -62,11 +62,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"archivedRoom": "Заархівована кімната",
|
||||
"@archivedRoom": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"areGuestsAllowedToJoin": "Чи дозволено гостям приєднуватись",
|
||||
"@areGuestsAllowedToJoin": {
|
||||
"type": "text",
|
||||
|
@ -337,11 +332,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"crossSigningEnabled": "Перехресне підписування увімкнено",
|
||||
"@crossSigningEnabled": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"currentlyActive": "Зараз у мережі",
|
||||
"@currentlyActive": {
|
||||
"type": "text",
|
||||
|
@ -494,11 +484,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"friday": "П'ятниця",
|
||||
"@friday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"fromJoining": "З моменту приєднання",
|
||||
"@fromJoining": {
|
||||
"type": "text",
|
||||
|
@ -624,11 +609,6 @@
|
|||
"username": {}
|
||||
}
|
||||
},
|
||||
"keysCached": "Ключі кешовано",
|
||||
"@keysCached": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"kicked": "👞 {username} вилучає {targetName}",
|
||||
"@kicked": {
|
||||
"type": "text",
|
||||
|
@ -731,11 +711,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"monday": "Понеділок",
|
||||
"@monday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"muteChat": "Вимкнути сповіщення",
|
||||
"@muteChat": {
|
||||
"type": "text",
|
||||
|
@ -934,11 +909,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"saturday": "Субота",
|
||||
"@saturday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"seenByUser": "Переглянуто {username}",
|
||||
"@seenByUser": {
|
||||
"type": "text",
|
||||
|
@ -1066,11 +1036,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"sunday": "Неділя",
|
||||
"@sunday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"systemTheme": "Системна",
|
||||
"@systemTheme": {
|
||||
"type": "text",
|
||||
|
@ -1086,16 +1051,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"thisRoomHasBeenArchived": "Цю кімнату було заархівовано.",
|
||||
"@thisRoomHasBeenArchived": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"thursday": "Четвер",
|
||||
"@thursday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"title": "FluffyChat",
|
||||
"@title": {
|
||||
"description": "Title for the application",
|
||||
|
@ -1107,11 +1062,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"tuesday": "Вівторок",
|
||||
"@tuesday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"unbannedUser": "{username} розблоковує {targetName}",
|
||||
"@unbannedUser": {
|
||||
"type": "text",
|
||||
|
@ -1255,11 +1205,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"wednesday": "Середа",
|
||||
"@wednesday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"whoIsAllowedToJoinThisGroup": "Кому дозволено приєднуватися до цієї групи",
|
||||
"@whoIsAllowedToJoinThisGroup": {
|
||||
"type": "text",
|
||||
|
@ -1494,8 +1439,6 @@
|
|||
},
|
||||
"shareYourInviteLink": "Поділіться своїм посиланням запрошення",
|
||||
"@shareYourInviteLink": {},
|
||||
"typeInInviteLinkManually": "Введіть посилання запрошення власноруч...",
|
||||
"@typeInInviteLinkManually": {},
|
||||
"scanQrCode": "Сканувати QR-код",
|
||||
"@scanQrCode": {},
|
||||
"noPasswordRecoveryDescription": "Ви ще не додали спосіб відновлення пароля.",
|
||||
|
@ -1851,8 +1794,6 @@
|
|||
"type": "text",
|
||||
"description": "Usage hint for the command /html"
|
||||
},
|
||||
"yourUserId": "Ваш ID користувача:",
|
||||
"@yourUserId": {},
|
||||
"commandHint_invite": "Запросіть цього користувача до цієї кімнати",
|
||||
"@commandHint_invite": {
|
||||
"type": "text",
|
||||
|
@ -1990,11 +1931,6 @@
|
|||
"senderName": {}
|
||||
}
|
||||
},
|
||||
"discover": "Огляд",
|
||||
"@discover": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"cantOpenUri": "Не вдалося відкрити URI {uri}",
|
||||
"@cantOpenUri": {
|
||||
"type": "text",
|
||||
|
@ -2384,8 +2320,6 @@
|
|||
"@recoveryKey": {},
|
||||
"recoveryKeyLost": "Ключ відновлення втрачено?",
|
||||
"@recoveryKeyLost": {},
|
||||
"enableAutoBackups": "Увімкнути автоматичне резервне копіювання",
|
||||
"@enableAutoBackups": {},
|
||||
"users": "Користувачі",
|
||||
"@users": {},
|
||||
"stories": "Історії",
|
||||
|
@ -2412,8 +2346,6 @@
|
|||
"@dehydrate": {},
|
||||
"dehydrateWarning": "Цю дію не можна скасувати. Переконайтеся, що ви безпечно зберігаєте файл резервної копії.",
|
||||
"@dehydrateWarning": {},
|
||||
"dehydrateShare": "Це ваш приватний експорт FluffyChat. Переконайтеся, що ви не втратите його та зберігайте його приватно.",
|
||||
"@dehydrateShare": {},
|
||||
"dehydrateTor": "Користувачі TOR: експорт сеансу",
|
||||
"@dehydrateTor": {},
|
||||
"dehydrateTorLong": "Для користувачів TOR рекомендується експортувати сеанс перед закриттям вікна.",
|
||||
|
@ -2532,8 +2464,6 @@
|
|||
"@sorryThatsNotPossible": {},
|
||||
"deviceKeys": "Ключі пристрою:",
|
||||
"@deviceKeys": {},
|
||||
"noSearchResult": "Немає відповідних результатів пошуку.",
|
||||
"@noSearchResult": {},
|
||||
"letsStart": "Розпочнімо",
|
||||
"@letsStart": {},
|
||||
"enterInviteLinkOrMatrixId": "Введіть запрошувальне посилання або Matrix ID...",
|
||||
|
@ -2545,5 +2475,40 @@
|
|||
"noBackupWarning": "Увага! Якщо ви не ввімкнете резервне копіювання бесіди, ви втратите доступ до своїх зашифрованих повідомлень. Наполегливо радимо ввімкнути резервне копіювання бесіди перед виходом.",
|
||||
"@noBackupWarning": {},
|
||||
"fileIsTooBigForServer": "Сервер повідомляє, що файл завеликий для надсилання.",
|
||||
"@fileIsTooBigForServer": {}
|
||||
"@fileIsTooBigForServer": {},
|
||||
"fileHasBeenSavedAt": "Файл збережено в {path}",
|
||||
"@fileHasBeenSavedAt": {
|
||||
"type": "text",
|
||||
"placeholders": {
|
||||
"path": {}
|
||||
}
|
||||
},
|
||||
"jumpToLastReadMessage": "Перейти до останнього прочитаного повідомлення",
|
||||
"@jumpToLastReadMessage": {},
|
||||
"readUpToHere": "Читати тут",
|
||||
"@readUpToHere": {},
|
||||
"jump": "Перейти",
|
||||
"@jump": {},
|
||||
"openLinkInBrowser": "Відкрити посилання у браузері",
|
||||
"@openLinkInBrowser": {},
|
||||
"allRooms": "Усі групові бесіди",
|
||||
"@allRooms": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"reportErrorDescription": "О, ні. Щось пішло не так. Повторіть спробу пізніше. Якщо хочете, можете повідомити про помилку розробникам.",
|
||||
"@reportErrorDescription": {},
|
||||
"report": "повідомити",
|
||||
"@report": {},
|
||||
"discover": "Огляд",
|
||||
"@discover": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"pleaseTryAgainLaterOrChooseDifferentServer": "Спробуйте пізніше або виберіть інший сервер.",
|
||||
"@pleaseTryAgainLaterOrChooseDifferentServer": {},
|
||||
"signInWithPassword": "Увійти за допомогою пароля",
|
||||
"@signInWithPassword": {},
|
||||
"continueWith": "Продовжити за допомогою:",
|
||||
"@continueWith": {}
|
||||
}
|
||||
|
|
|
@ -61,11 +61,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"archivedRoom": "Phòng hội thảo đã lưu trữ",
|
||||
"@archivedRoom": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"areGuestsAllowedToJoin": "Khách vãng lai có được tham gia không",
|
||||
"@areGuestsAllowedToJoin": {
|
||||
"type": "text",
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -76,11 +76,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"archivedRoom": "已封存的對話",
|
||||
"@archivedRoom": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"areGuestsAllowedToJoin": "是否允許訪客加入",
|
||||
"@areGuestsAllowedToJoin": {
|
||||
"type": "text",
|
||||
|
@ -427,11 +422,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"crossSigningEnabled": "第三方登入已啟用",
|
||||
"@crossSigningEnabled": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"currentlyActive": "目前活躍",
|
||||
"@currentlyActive": {
|
||||
"type": "text",
|
||||
|
@ -517,11 +507,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"discover": "探索",
|
||||
"@discover": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"displaynameHasBeenChanged": "顯示名稱已被變更",
|
||||
"@displaynameHasBeenChanged": {
|
||||
"type": "text",
|
||||
|
@ -674,11 +659,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"friday": "星期五",
|
||||
"@friday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"fromJoining": "自加入起",
|
||||
"@fromJoining": {
|
||||
"type": "text",
|
||||
|
@ -864,11 +844,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"keysCached": "金鑰已被快取",
|
||||
"@keysCached": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"kicked": "{username}踢了{targetName}",
|
||||
"@kicked": {
|
||||
"type": "text",
|
||||
|
@ -986,11 +961,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"monday": "星期一",
|
||||
"@monday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"muteChat": "將該聊天室靜音",
|
||||
"@muteChat": {
|
||||
"type": "text",
|
||||
|
@ -1326,11 +1296,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"saturday": "星期六",
|
||||
"@saturday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"search": "搜尋",
|
||||
"@search": {
|
||||
"type": "text",
|
||||
|
@ -1530,11 +1495,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"sunday": "星期日",
|
||||
"@sunday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"systemTheme": "自動",
|
||||
"@systemTheme": {
|
||||
"type": "text",
|
||||
|
@ -1550,16 +1510,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"thisRoomHasBeenArchived": "這個聊天室已被封存。",
|
||||
"@thisRoomHasBeenArchived": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"thursday": "星期四",
|
||||
"@thursday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"title": "FluffyChat",
|
||||
"@title": {
|
||||
"description": "Title for the application",
|
||||
|
@ -1596,11 +1546,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"tuesday": "星期二",
|
||||
"@tuesday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"unavailable": "無法取得",
|
||||
"@unavailable": {
|
||||
"type": "text",
|
||||
|
@ -1771,11 +1716,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"wednesday": "星期三",
|
||||
"@wednesday": {
|
||||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"weSentYouAnEmail": "我們向您傳送了一封電子郵件",
|
||||
"@weSentYouAnEmail": {
|
||||
"type": "text",
|
||||
|
@ -1972,8 +1912,6 @@
|
|||
"type": "text",
|
||||
"placeholders": {}
|
||||
},
|
||||
"yourUserId": "您的ID:",
|
||||
"@yourUserId": {},
|
||||
"chatHasBeenAddedToThisSpace": "聊天室已添加到此空間",
|
||||
"@chatHasBeenAddedToThisSpace": {},
|
||||
"clearArchive": "清除存檔",
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 212 KiB After Width: | Height: | Size: 146 KiB |
Binary file not shown.
Before Width: | Height: | Size: 52 KiB |
|
@ -55,7 +55,7 @@
|
|||
<div class="flex mb-8 justify-center content-center">
|
||||
<a rel="me"
|
||||
class="inline-block text-indigo-500 no-underline hover:text-indigo-900 hover:scale-105 transition-all text-center h-auto p-4"
|
||||
rel="me" href="https://metalhead.club/@krille">
|
||||
rel="me" href="https://mastodon.art/@krille">
|
||||
<svg class="fill-current h-6" viewBox="0 0 1000 1000" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve"
|
||||
style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;">
|
||||
|
@ -116,4 +116,4 @@
|
|||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -291,6 +291,7 @@
|
|||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${TARGET_BUILD_DIR}/${INFOPLIST_PATH}",
|
||||
);
|
||||
name = "Thin Binary";
|
||||
outputPaths = (
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
app_identifier("im.fluffychat.app") # The bundle identifier of your app
|
||||
apple_id("christian.pauly@wtal.de") # Your Apple email address
|
||||
apple_id("christian-kussowski@posteo.de") # Your Apple email address
|
||||
|
||||
itc_team_id("122628977") # App Store Connect Team ID
|
||||
team_id("4NXF6Z997G") # Developer Portal Team ID
|
||||
|
|
|
@ -16,7 +16,7 @@ abstract class AppConfig {
|
|||
static const double messageFontSize = 15.75;
|
||||
static const bool allowOtherHomeservers = true;
|
||||
static const bool enableRegistration = true;
|
||||
static const Color primaryColor = Color.fromARGB(255, 135, 103, 172);
|
||||
static const Color primaryColor = Color(0xFF5625BA);
|
||||
static const Color primaryColorLight = Color(0xFFCCBDEA);
|
||||
static const Color secondaryColor = Color(0xFF41a2bc);
|
||||
static String _privacyUrl =
|
||||
|
@ -33,6 +33,11 @@ abstract class AppConfig {
|
|||
static const String sourceCodeUrl = 'https://gitlab.com/famedly/fluffychat';
|
||||
static const String supportUrl =
|
||||
'https://gitlab.com/famedly/fluffychat/issues';
|
||||
static final Uri newIssueUrl = Uri(
|
||||
scheme: 'https',
|
||||
host: 'gitlab.com',
|
||||
path: '/famedly/fluffychat/-/issues/new',
|
||||
);
|
||||
static const bool enableSentry = true;
|
||||
static const String sentryDns =
|
||||
'https://8591d0d863b646feb4f3dda7e5dcab38@o256755.ingest.sentry.io/5243143';
|
||||
|
|
|
@ -9,7 +9,6 @@ import 'package:fluffychat/pages/chat_details/chat_details.dart';
|
|||
import 'package:fluffychat/pages/chat_encryption_settings/chat_encryption_settings.dart';
|
||||
import 'package:fluffychat/pages/chat_list/chat_list.dart';
|
||||
import 'package:fluffychat/pages/chat_permissions_settings/chat_permissions_settings.dart';
|
||||
import 'package:fluffychat/pages/connect/connect_page.dart';
|
||||
import 'package:fluffychat/pages/device_settings/device_settings.dart';
|
||||
import 'package:fluffychat/pages/homeserver_picker/homeserver_picker.dart';
|
||||
import 'package:fluffychat/pages/invitation_selection/invitation_selection.dart';
|
||||
|
@ -27,7 +26,6 @@ import 'package:fluffychat/pages/settings_notifications/settings_notifications.d
|
|||
import 'package:fluffychat/pages/settings_security/settings_security.dart';
|
||||
import 'package:fluffychat/pages/settings_stories/settings_stories.dart';
|
||||
import 'package:fluffychat/pages/settings_style/settings_style.dart';
|
||||
import 'package:fluffychat/pages/sign_up/signup.dart';
|
||||
import 'package:fluffychat/pages/story/story_page.dart';
|
||||
import 'package:fluffychat/widgets/layouts/empty_page.dart';
|
||||
import 'package:fluffychat/widgets/layouts/loading_view.dart';
|
||||
|
@ -72,7 +70,7 @@ class AppRoutes {
|
|||
),
|
||||
VWidget(
|
||||
path: ':roomid',
|
||||
widget: const Chat(),
|
||||
widget: const ChatPage(),
|
||||
stackedRoutes: [
|
||||
VWidget(
|
||||
path: 'encryption',
|
||||
|
@ -100,7 +98,7 @@ class AppRoutes {
|
|||
stackedRoutes: [
|
||||
VWidget(
|
||||
path: ':roomid',
|
||||
widget: const Chat(),
|
||||
widget: const ChatPage(),
|
||||
buildTransition: _dynamicTransition,
|
||||
),
|
||||
],
|
||||
|
@ -174,14 +172,14 @@ class AppRoutes {
|
|||
VNester(
|
||||
path: ':roomid',
|
||||
widgetBuilder: (child) => SideViewLayout(
|
||||
mainView: const Chat(),
|
||||
mainView: const ChatPage(),
|
||||
sideView: child,
|
||||
),
|
||||
buildTransition: _fadeTransition,
|
||||
nestedRoutes: [
|
||||
VWidget(
|
||||
path: '',
|
||||
widget: const Chat(),
|
||||
widget: const ChatPage(),
|
||||
buildTransition: _fadeTransition,
|
||||
),
|
||||
VWidget(
|
||||
|
@ -245,7 +243,7 @@ class AppRoutes {
|
|||
),
|
||||
VWidget(
|
||||
path: ':roomid',
|
||||
widget: const Chat(),
|
||||
widget: const ChatPage(),
|
||||
buildTransition: _dynamicTransition,
|
||||
),
|
||||
],
|
||||
|
@ -266,23 +264,6 @@ class AppRoutes {
|
|||
widget: const Login(),
|
||||
buildTransition: _fadeTransition,
|
||||
),
|
||||
VWidget(
|
||||
path: 'connect',
|
||||
widget: const ConnectPage(),
|
||||
buildTransition: _fadeTransition,
|
||||
stackedRoutes: [
|
||||
VWidget(
|
||||
path: 'login',
|
||||
widget: const Login(),
|
||||
buildTransition: _fadeTransition,
|
||||
),
|
||||
VWidget(
|
||||
path: 'signup',
|
||||
widget: const SignupPage(),
|
||||
buildTransition: _fadeTransition,
|
||||
),
|
||||
],
|
||||
),
|
||||
VWidget(
|
||||
path: 'logs',
|
||||
widget: const LogViewer(),
|
||||
|
@ -358,23 +339,6 @@ class AppRoutes {
|
|||
widget: const Login(),
|
||||
buildTransition: _fadeTransition,
|
||||
),
|
||||
VWidget(
|
||||
path: 'connect',
|
||||
widget: const ConnectPage(),
|
||||
buildTransition: _fadeTransition,
|
||||
stackedRoutes: [
|
||||
VWidget(
|
||||
path: 'login',
|
||||
widget: const Login(),
|
||||
buildTransition: _fadeTransition,
|
||||
),
|
||||
VWidget(
|
||||
path: 'signup',
|
||||
widget: const SignupPage(),
|
||||
buildTransition: _fadeTransition,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
VWidget(
|
||||
|
|
|
@ -9,7 +9,10 @@ import 'app_config.dart';
|
|||
abstract class FluffyThemes {
|
||||
static const double columnWidth = 360.0;
|
||||
|
||||
static bool isColumnModeByWidth(double width) => width > columnWidth * 2 + 64;
|
||||
static const double navRailWidth = 64.0;
|
||||
|
||||
static bool isColumnModeByWidth(double width) =>
|
||||
width > columnWidth * 2 + navRailWidth;
|
||||
|
||||
static bool isColumnMode(BuildContext context) =>
|
||||
isColumnModeByWidth(MediaQuery.of(context).size.width);
|
||||
|
@ -38,6 +41,22 @@ abstract class FluffyThemes {
|
|||
titleSmall: fallbackTextStyle,
|
||||
);
|
||||
|
||||
static LinearGradient backgroundGradient(
|
||||
BuildContext context,
|
||||
int alpha,
|
||||
) {
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
return LinearGradient(
|
||||
begin: Alignment.topCenter,
|
||||
colors: [
|
||||
colorScheme.primaryContainer.withAlpha(alpha),
|
||||
colorScheme.secondaryContainer.withAlpha(alpha),
|
||||
colorScheme.tertiaryContainer.withAlpha(alpha),
|
||||
colorScheme.primaryContainer.withAlpha(alpha),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
static const Duration animationDuration = Duration(milliseconds: 250);
|
||||
static const Curve animationCurve = Curves.easeInOut;
|
||||
|
||||
|
|
|
@ -3,7 +3,8 @@ import 'dart:math';
|
|||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:file_picker_cross/file_picker_cross.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
import 'package:future_loading_dialog/future_loading_dialog.dart';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
import 'package:matrix/matrix.dart';
|
||||
|
@ -68,14 +69,15 @@ class AddStoryController extends State<AddStoryPage> {
|
|||
}
|
||||
|
||||
void importMedia() async {
|
||||
final picked = await FilePickerCross.importFromStorage(
|
||||
type: FileTypeCross.image,
|
||||
final picked = await FilePicker.platform.pickFiles(
|
||||
type: FileType.image,
|
||||
withData: true,
|
||||
);
|
||||
final fileName = picked.fileName;
|
||||
if (fileName == null) return;
|
||||
final file = picked?.files.firstOrNull;
|
||||
if (file == null) return;
|
||||
final matrixFile = MatrixImageFile(
|
||||
bytes: picked.toUint8List(),
|
||||
name: fileName,
|
||||
bytes: file.bytes!,
|
||||
name: file.name,
|
||||
);
|
||||
setState(() {
|
||||
image = matrixFile;
|
||||
|
|
|
@ -9,7 +9,7 @@ import 'package:adaptive_dialog/adaptive_dialog.dart';
|
|||
import 'package:desktop_drop/desktop_drop.dart';
|
||||
import 'package:device_info_plus/device_info_plus.dart';
|
||||
import 'package:emoji_picker_flutter/emoji_picker_flutter.dart';
|
||||
import 'package:file_picker_cross/file_picker_cross.dart';
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:future_loading_dialog/future_loading_dialog.dart';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
|
@ -23,6 +23,7 @@ import 'package:fluffychat/pages/chat/chat_view.dart';
|
|||
import 'package:fluffychat/pages/chat/event_info_dialog.dart';
|
||||
import 'package:fluffychat/pages/chat/recording_dialog.dart';
|
||||
import 'package:fluffychat/utils/adaptive_bottom_sheet.dart';
|
||||
import 'package:fluffychat/utils/error_reporter.dart';
|
||||
import 'package:fluffychat/utils/matrix_sdk_extensions/event_extension.dart';
|
||||
import 'package:fluffychat/utils/matrix_sdk_extensions/ios_badge_client_extension.dart';
|
||||
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
|
||||
|
@ -35,25 +36,56 @@ import 'send_file_dialog.dart';
|
|||
import 'send_location_dialog.dart';
|
||||
import 'sticker_picker_dialog.dart';
|
||||
|
||||
class Chat extends StatefulWidget {
|
||||
class ChatPage extends StatelessWidget {
|
||||
final Widget? sideView;
|
||||
|
||||
const Chat({Key? key, this.sideView}) : super(key: key);
|
||||
const ChatPage({Key? key, this.sideView}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final roomId = context.vRouter.pathParameters['roomid'];
|
||||
final room =
|
||||
roomId == null ? null : Matrix.of(context).client.getRoomById(roomId);
|
||||
if (room == null) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: Text(L10n.of(context)!.oopsSomethingWentWrong)),
|
||||
body: Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child:
|
||||
Text(L10n.of(context)!.youAreNoLongerParticipatingInThisChat),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
return ChatPageWithRoom(sideView: sideView, room: room);
|
||||
}
|
||||
}
|
||||
|
||||
class ChatPageWithRoom extends StatefulWidget {
|
||||
final Widget? sideView;
|
||||
final Room room;
|
||||
|
||||
const ChatPageWithRoom({
|
||||
Key? key,
|
||||
required this.sideView,
|
||||
required this.room,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
ChatController createState() => ChatController();
|
||||
}
|
||||
|
||||
class ChatController extends State<Chat> {
|
||||
Room? room;
|
||||
class ChatController extends State<ChatPageWithRoom> {
|
||||
Room get room => sendingClient.getRoomById(roomId) ?? widget.room;
|
||||
|
||||
Client? sendingClient;
|
||||
late Client sendingClient;
|
||||
|
||||
Timeline? timeline;
|
||||
|
||||
MatrixState? matrix;
|
||||
String? readMarkerEventId;
|
||||
|
||||
String? get roomId => context.vRouter.pathParameters['roomid'];
|
||||
String get roomId => widget.room.id;
|
||||
|
||||
final AutoScrollController scrollController = AutoScrollController();
|
||||
|
||||
|
@ -95,7 +127,7 @@ class ChatController extends State<Chat> {
|
|||
useRootNavigator: false,
|
||||
builder: (c) => SendFileDialog(
|
||||
files: matrixFiles,
|
||||
room: room!,
|
||||
room: room,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -120,7 +152,10 @@ class ChatController extends State<Chat> {
|
|||
|
||||
Event? editEvent;
|
||||
|
||||
bool showScrollDownButton = false;
|
||||
bool _scrolledUp = false;
|
||||
|
||||
bool get showScrollDownButton =>
|
||||
_scrolledUp || timeline?.allowNewEvent == false;
|
||||
|
||||
bool get selectMode => selectedEvents.isNotEmpty;
|
||||
|
||||
|
@ -130,16 +165,12 @@ class ChatController extends State<Chat> {
|
|||
|
||||
String pendingText = '';
|
||||
|
||||
bool get canLoadMore =>
|
||||
timeline!.events.isEmpty ||
|
||||
timeline!.events.last.type != EventTypes.RoomCreate;
|
||||
|
||||
bool showEmojiPicker = false;
|
||||
|
||||
void recreateChat() async {
|
||||
final room = this.room;
|
||||
final userId = room?.directChatMatrixID;
|
||||
if (room == null || userId == null) {
|
||||
final userId = room.directChatMatrixID;
|
||||
if (userId == null) {
|
||||
throw Exception(
|
||||
'Try to recreate a room with is not a DM room. This should not be possible from the UI!',
|
||||
);
|
||||
|
@ -161,12 +192,6 @@ class ChatController extends State<Chat> {
|
|||
}
|
||||
|
||||
void leaveChat() async {
|
||||
final room = this.room;
|
||||
if (room == null) {
|
||||
throw Exception(
|
||||
'Leave room button clicked while room is null. This should not be possible from the UI!',
|
||||
);
|
||||
}
|
||||
final success = await showFutureLoadingDialog(
|
||||
context: context,
|
||||
future: room.leave,
|
||||
|
@ -178,19 +203,40 @@ class ChatController extends State<Chat> {
|
|||
EmojiPickerType emojiPickerType = EmojiPickerType.keyboard;
|
||||
|
||||
void requestHistory() async {
|
||||
if (canLoadMore) {
|
||||
try {
|
||||
await timeline!.requestHistory(historyCount: _loadHistoryCount);
|
||||
} catch (err) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(
|
||||
(err).toLocalizedString(context),
|
||||
),
|
||||
if (!timeline!.canRequestHistory) return;
|
||||
Logs().v('Requesting history...');
|
||||
try {
|
||||
await timeline!.requestHistory(historyCount: _loadHistoryCount);
|
||||
} catch (err) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(
|
||||
(err).toLocalizedString(context),
|
||||
),
|
||||
);
|
||||
rethrow;
|
||||
}
|
||||
),
|
||||
);
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
void requestFuture() async {
|
||||
final timeline = this.timeline;
|
||||
if (timeline == null) return;
|
||||
if (!timeline.canRequestFuture) return;
|
||||
Logs().v('Requesting future...');
|
||||
try {
|
||||
final mostRecentEventId = timeline.events.first.eventId;
|
||||
await timeline.requestFuture(historyCount: _loadHistoryCount);
|
||||
setReadMarker(eventId: mostRecentEventId);
|
||||
} catch (err) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(
|
||||
(err).toLocalizedString(context),
|
||||
),
|
||||
),
|
||||
);
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -200,18 +246,11 @@ class ChatController extends State<Chat> {
|
|||
}
|
||||
setReadMarker();
|
||||
if (!scrollController.hasClients) return;
|
||||
if (scrollController.position.pixels ==
|
||||
scrollController.position.maxScrollExtent &&
|
||||
timeline!.events.isNotEmpty &&
|
||||
timeline!.events[timeline!.events.length - 1].type !=
|
||||
EventTypes.RoomCreate) {
|
||||
requestHistory();
|
||||
}
|
||||
if (scrollController.position.pixels > 0 && showScrollDownButton == false) {
|
||||
setState(() => showScrollDownButton = true);
|
||||
} else if (scrollController.position.pixels == 0 &&
|
||||
showScrollDownButton == true) {
|
||||
setState(() => showScrollDownButton = false);
|
||||
if (timeline?.allowNewEvent == false ||
|
||||
scrollController.position.pixels > 0 && _scrolledUp == false) {
|
||||
setState(() => _scrolledUp = true);
|
||||
} else if (scrollController.position.pixels == 0 && _scrolledUp == true) {
|
||||
setState(() => _scrolledUp = false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -230,6 +269,12 @@ class ChatController extends State<Chat> {
|
|||
inputFocus.addListener(_inputFocusListener);
|
||||
_loadDraft();
|
||||
super.initState();
|
||||
sendingClient = Matrix.of(context).client;
|
||||
readMarkerEventId = room.fullyRead;
|
||||
loadTimelineFuture =
|
||||
_getTimeline(eventContextId: readMarkerEventId).onError(
|
||||
ErrorReporter(context, 'Unable to load timeline').onErrorCallback,
|
||||
);
|
||||
}
|
||||
|
||||
void updateView() {
|
||||
|
@ -237,48 +282,84 @@ class ChatController extends State<Chat> {
|
|||
setState(() {});
|
||||
}
|
||||
|
||||
Future<bool> getTimeline() async {
|
||||
if (timeline == null) {
|
||||
await Matrix.of(context).client.roomsLoading;
|
||||
await Matrix.of(context).client.accountDataLoading;
|
||||
timeline = await room!.getTimeline(onUpdate: updateView);
|
||||
if (timeline!.events.isNotEmpty) {
|
||||
if (room!.markedUnread) room!.markUnread(false);
|
||||
setReadMarker();
|
||||
}
|
||||
Future<void>? loadTimelineFuture;
|
||||
|
||||
// when the scroll controller is attached we want to scroll to an event id, if specified
|
||||
// and update the scroll controller...which will trigger a request history, if the
|
||||
// "load more" button is visible on the screen
|
||||
SchedulerBinding.instance.addPostFrameCallback((_) async {
|
||||
if (mounted) {
|
||||
final event = VRouter.of(context).queryParameters['event'];
|
||||
if (event != null) {
|
||||
scrollToEventId(event);
|
||||
}
|
||||
_updateScrollController();
|
||||
}
|
||||
});
|
||||
Future<void> _getTimeline({
|
||||
String? eventContextId,
|
||||
Duration timeout = const Duration(seconds: 7),
|
||||
}) async {
|
||||
await Matrix.of(context).client.roomsLoading;
|
||||
await Matrix.of(context).client.accountDataLoading;
|
||||
if (eventContextId != null &&
|
||||
(!eventContextId.isValidMatrixId || eventContextId.sigil != '\$')) {
|
||||
eventContextId = null;
|
||||
}
|
||||
try {
|
||||
timeline = await room
|
||||
.getTimeline(
|
||||
onUpdate: updateView,
|
||||
eventContextId: eventContextId,
|
||||
)
|
||||
.timeout(timeout);
|
||||
} catch (e, s) {
|
||||
Logs().w('Unable to load timeline on event ID $eventContextId', e, s);
|
||||
if (!mounted) return;
|
||||
timeline = await room.getTimeline(onUpdate: updateView);
|
||||
if (!mounted) return;
|
||||
if (e is TimeoutException || e is IOException) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(L10n.of(context)!.jumpToLastReadMessage),
|
||||
action: SnackBarAction(
|
||||
label: L10n.of(context)!.jump,
|
||||
onPressed: () => scrollToEventId(eventContextId!),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
timeline!.requestKeys(onlineKeyBackupOnly: false);
|
||||
return true;
|
||||
if (timeline!.events.isNotEmpty) {
|
||||
if (room.markedUnread) room.markUnread(false);
|
||||
setReadMarker();
|
||||
}
|
||||
|
||||
// when the scroll controller is attached we want to scroll to an event id, if specified
|
||||
// and update the scroll controller...which will trigger a request history, if the
|
||||
// "load more" button is visible on the screen
|
||||
SchedulerBinding.instance.addPostFrameCallback((_) async {
|
||||
if (mounted) {
|
||||
final event = VRouter.of(context).queryParameters['event'];
|
||||
if (event != null) {
|
||||
scrollToEventId(event);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Future<void>? _setReadMarkerFuture;
|
||||
|
||||
void setReadMarker([_]) {
|
||||
if (_setReadMarkerFuture == null &&
|
||||
(room!.hasNewMessages || room!.notificationCount > 0) &&
|
||||
timeline != null &&
|
||||
timeline!.events.isNotEmpty &&
|
||||
Matrix.of(context).webHasFocus) {
|
||||
Logs().v('Set read marker...');
|
||||
// ignore: unawaited_futures
|
||||
_setReadMarkerFuture = timeline!.setReadMarker().then((_) {
|
||||
_setReadMarkerFuture = null;
|
||||
});
|
||||
room!.client.updateIosBadge();
|
||||
void setReadMarker({String? eventId}) {
|
||||
if (_setReadMarkerFuture != null) return;
|
||||
if (eventId == null &&
|
||||
!room.hasNewMessages &&
|
||||
room.notificationCount == 0) {
|
||||
return;
|
||||
}
|
||||
if (!Matrix.of(context).webHasFocus) return;
|
||||
|
||||
final timeline = this.timeline;
|
||||
if (timeline == null || timeline.events.isEmpty) return;
|
||||
|
||||
eventId ??= timeline.events.first.eventId;
|
||||
Logs().v('Set read marker...', eventId);
|
||||
// ignore: unawaited_futures
|
||||
_setReadMarkerFuture = timeline.setReadMarker(eventId: eventId).then((_) {
|
||||
_setReadMarkerFuture = null;
|
||||
});
|
||||
room.client.updateIosBadge();
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -291,15 +372,24 @@ class ChatController extends State<Chat> {
|
|||
|
||||
TextEditingController sendController = TextEditingController();
|
||||
|
||||
void setSendingClient(Client? c) {
|
||||
// first cancle typing with the old sending client
|
||||
void setSendingClient(Client c) {
|
||||
// first cancel typing with the old sending client
|
||||
if (currentlyTyping) {
|
||||
// no need to have the setting typing to false be blocking
|
||||
typingCoolDown?.cancel();
|
||||
typingCoolDown = null;
|
||||
room!.setTyping(false);
|
||||
room.setTyping(false);
|
||||
currentlyTyping = false;
|
||||
}
|
||||
// then cancel the old timeline
|
||||
// fixes bug with read reciepts and quick switching
|
||||
loadTimelineFuture = _getTimeline(eventContextId: room.fullyRead).onError(
|
||||
ErrorReporter(
|
||||
context,
|
||||
'Unable to load timeline after changing sending Client',
|
||||
).onErrorCallback,
|
||||
);
|
||||
|
||||
// then set the new sending client
|
||||
setState(() => sendingClient = c);
|
||||
}
|
||||
|
@ -317,7 +407,7 @@ class ChatController extends State<Chat> {
|
|||
|
||||
final commandMatch = RegExp(r'^\/(\w+)').firstMatch(sendController.text);
|
||||
if (commandMatch != null &&
|
||||
!room!.client.commands.keys.contains(commandMatch[1]!.toLowerCase())) {
|
||||
!sendingClient.commands.keys.contains(commandMatch[1]!.toLowerCase())) {
|
||||
final l10n = L10n.of(context)!;
|
||||
final dialogResult = await showOkCancelAlertDialog(
|
||||
context: context,
|
||||
|
@ -332,7 +422,7 @@ class ChatController extends State<Chat> {
|
|||
}
|
||||
|
||||
// ignore: unawaited_futures
|
||||
room!.sendTextEvent(
|
||||
room.sendTextEvent(
|
||||
sendController.text,
|
||||
inReplyTo: replyEvent,
|
||||
editEventId: editEvent?.eventId,
|
||||
|
@ -352,46 +442,49 @@ class ChatController extends State<Chat> {
|
|||
}
|
||||
|
||||
void sendFileAction() async {
|
||||
final result = await FilePickerCross.importMultipleFromStorage(
|
||||
type: FileTypeCross.any,
|
||||
final result = await FilePicker.platform.pickFiles(
|
||||
allowMultiple: true,
|
||||
withData: true,
|
||||
);
|
||||
if (result.isEmpty) return;
|
||||
if (result == null || result.files.isEmpty) return;
|
||||
await showDialog(
|
||||
context: context,
|
||||
useRootNavigator: false,
|
||||
builder: (c) => SendFileDialog(
|
||||
files: result
|
||||
files: result.files
|
||||
.map(
|
||||
(xfile) => MatrixFile(
|
||||
bytes: xfile.toUint8List(),
|
||||
name: xfile.fileName!,
|
||||
bytes: xfile.bytes!,
|
||||
name: xfile.name,
|
||||
).detectFileType,
|
||||
)
|
||||
.toList(),
|
||||
room: room!,
|
||||
room: room,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void sendImageAction() async {
|
||||
final result = await FilePickerCross.importMultipleFromStorage(
|
||||
type: FileTypeCross.image,
|
||||
final result = await FilePicker.platform.pickFiles(
|
||||
type: FileType.image,
|
||||
withData: true,
|
||||
allowMultiple: true,
|
||||
);
|
||||
if (result.isEmpty) return;
|
||||
if (result == null || result.files.isEmpty) return;
|
||||
|
||||
await showDialog(
|
||||
context: context,
|
||||
useRootNavigator: false,
|
||||
builder: (c) => SendFileDialog(
|
||||
files: result
|
||||
files: result.files
|
||||
.map(
|
||||
(xfile) => MatrixFile(
|
||||
bytes: xfile.toUint8List(),
|
||||
name: xfile.fileName!,
|
||||
bytes: xfile.bytes!,
|
||||
name: xfile.name,
|
||||
).detectFileType,
|
||||
)
|
||||
.toList(),
|
||||
room: room!,
|
||||
room: room,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -412,7 +505,7 @@ class ChatController extends State<Chat> {
|
|||
name: file.path,
|
||||
)
|
||||
],
|
||||
room: room!,
|
||||
room: room,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -433,7 +526,7 @@ class ChatController extends State<Chat> {
|
|||
name: file.path,
|
||||
)
|
||||
],
|
||||
room: room!,
|
||||
room: room,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
@ -441,7 +534,7 @@ class ChatController extends State<Chat> {
|
|||
void sendStickerAction() async {
|
||||
final sticker = await showAdaptiveBottomSheet<ImagePackImageContent>(
|
||||
context: context,
|
||||
builder: (c) => StickerPickerDialog(room: room!),
|
||||
builder: (c) => StickerPickerDialog(room: room),
|
||||
);
|
||||
if (sticker == null) return;
|
||||
final eventContent = <String, dynamic>{
|
||||
|
@ -450,7 +543,7 @@ class ChatController extends State<Chat> {
|
|||
'url': sticker.url.toString(),
|
||||
};
|
||||
// send the sticker
|
||||
await room!.sendEvent(
|
||||
await room.sendEvent(
|
||||
eventContent,
|
||||
type: EventTypes.Sticker,
|
||||
);
|
||||
|
@ -484,7 +577,7 @@ class ChatController extends State<Chat> {
|
|||
bytes: audioFile.readAsBytesSync(),
|
||||
name: audioFile.path,
|
||||
);
|
||||
await room!.sendFileEvent(
|
||||
await room.sendFileEvent(
|
||||
file,
|
||||
inReplyTo: replyEvent,
|
||||
extraContent: {
|
||||
|
@ -534,7 +627,7 @@ class ChatController extends State<Chat> {
|
|||
await showDialog(
|
||||
context: context,
|
||||
useRootNavigator: false,
|
||||
builder: (c) => SendLocationDialog(room: room!),
|
||||
builder: (c) => SendLocationDialog(room: room),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -640,7 +733,7 @@ class ChatController extends State<Chat> {
|
|||
if (client == null) {
|
||||
return;
|
||||
}
|
||||
final room = client.getRoomById(roomId!)!;
|
||||
final room = client.getRoomById(roomId)!;
|
||||
await Event.fromJson(event.toJson(), room).redactEvent();
|
||||
}
|
||||
} else {
|
||||
|
@ -656,14 +749,14 @@ class ChatController extends State<Chat> {
|
|||
}
|
||||
|
||||
List<Client?> get currentRoomBundle {
|
||||
final clients = matrix!.currentBundle!;
|
||||
clients.removeWhere((c) => c!.getRoomById(roomId!) == null);
|
||||
final clients = Matrix.of(context).currentBundle!;
|
||||
clients.removeWhere((c) => c!.getRoomById(roomId) == null);
|
||||
return clients;
|
||||
}
|
||||
|
||||
bool get canRedactSelectedEvents {
|
||||
if (isArchived) return false;
|
||||
final clients = matrix!.currentBundle;
|
||||
final clients = Matrix.of(context).currentBundle;
|
||||
for (final event in selectedEvents) {
|
||||
if (event.canRedact == false &&
|
||||
!(clients!.any((cl) => event.senderId == cl!.userID))) return false;
|
||||
|
@ -718,49 +811,23 @@ class ChatController extends State<Chat> {
|
|||
}
|
||||
|
||||
void scrollToEventId(String eventId) async {
|
||||
var eventIndex = timeline!.events.indexWhere((e) => e.eventId == eventId);
|
||||
final eventIndex = timeline!.events.indexWhere((e) => e.eventId == eventId);
|
||||
if (eventIndex == -1) {
|
||||
// event id not found...maybe we can fetch it?
|
||||
// the try...finally is here to start and close the loading dialog reliably
|
||||
await showFutureLoadingDialog(
|
||||
context: context,
|
||||
future: () async {
|
||||
// okay, we first have to fetch if the event is in the room
|
||||
try {
|
||||
final event = await timeline!.getEventById(eventId);
|
||||
if (event == null) {
|
||||
// event is null...meaning something is off
|
||||
return;
|
||||
}
|
||||
} catch (err) {
|
||||
if (err is MatrixException && err.errcode == 'M_NOT_FOUND') {
|
||||
// event wasn't found, as the server gave a 404 or something
|
||||
return;
|
||||
}
|
||||
rethrow;
|
||||
}
|
||||
// okay, we know that the event *is* in the room
|
||||
while (eventIndex == -1) {
|
||||
if (!canLoadMore) {
|
||||
// we can't load any more events but still haven't found ours yet...better stop here
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await timeline!.requestHistory(historyCount: _loadHistoryCount);
|
||||
} catch (err) {
|
||||
if (err is TimeoutException) {
|
||||
// loading the history timed out...so let's do nothing
|
||||
return;
|
||||
}
|
||||
rethrow;
|
||||
}
|
||||
eventIndex =
|
||||
timeline!.events.indexWhere((e) => e.eventId == eventId);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
if (!mounted) {
|
||||
setState(() {
|
||||
timeline = null;
|
||||
_scrolledUp = false;
|
||||
loadTimelineFuture = _getTimeline(
|
||||
eventContextId: eventId,
|
||||
timeout: const Duration(seconds: 30),
|
||||
).onError(
|
||||
ErrorReporter(context, 'Unable to load timeline after scroll to ID')
|
||||
.onErrorCallback,
|
||||
);
|
||||
});
|
||||
await loadTimelineFuture;
|
||||
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
|
||||
scrollToEventId(eventId);
|
||||
});
|
||||
return;
|
||||
}
|
||||
await scrollController.scrollToIndex(
|
||||
|
@ -770,7 +837,21 @@ class ChatController extends State<Chat> {
|
|||
_updateScrollController();
|
||||
}
|
||||
|
||||
void scrollDown() => scrollController.jumpTo(0);
|
||||
void scrollDown() async {
|
||||
if (!timeline!.allowNewEvent) {
|
||||
setState(() {
|
||||
timeline = null;
|
||||
_scrolledUp = false;
|
||||
loadTimelineFuture = _getTimeline().onError(
|
||||
ErrorReporter(context, 'Unable to load timeline after scroll down')
|
||||
.onErrorCallback,
|
||||
);
|
||||
});
|
||||
await loadTimelineFuture;
|
||||
setReadMarker(eventId: timeline!.events.first.eventId);
|
||||
}
|
||||
scrollController.jumpTo(0);
|
||||
}
|
||||
|
||||
void onEmojiSelected(_, Emoji? emoji) {
|
||||
switch (emojiPickerType) {
|
||||
|
@ -788,15 +869,18 @@ class ChatController extends State<Chat> {
|
|||
setState(() => showEmojiPicker = false);
|
||||
if (emoji == null) return;
|
||||
// make sure we don't send the same emoji twice
|
||||
if (_allReactionEvents
|
||||
.any((e) => e.content['m.relates_to']['key'] == emoji.emoji)) return;
|
||||
if (_allReactionEvents.any(
|
||||
(e) => e.content.tryGetMap('m.relates_to')?['key'] == emoji.emoji,
|
||||
)) {
|
||||
return;
|
||||
}
|
||||
return sendEmojiAction(emoji.emoji);
|
||||
}
|
||||
|
||||
void forgetRoom() async {
|
||||
final result = await showFutureLoadingDialog(
|
||||
context: context,
|
||||
future: room!.forget,
|
||||
future: room.forget,
|
||||
);
|
||||
if (result.error != null) return;
|
||||
VRouter.of(context).to('/archive');
|
||||
|
@ -845,7 +929,7 @@ class ChatController extends State<Chat> {
|
|||
final events = List<Event>.from(selectedEvents);
|
||||
setState(() => selectedEvents.clear());
|
||||
for (final event in events) {
|
||||
await room!.sendReaction(
|
||||
await room.sendReaction(
|
||||
event.eventId,
|
||||
emoji!,
|
||||
);
|
||||
|
@ -892,7 +976,7 @@ class ChatController extends State<Chat> {
|
|||
useRootNavigator: false,
|
||||
context: context,
|
||||
title: L10n.of(context)!.goToTheNewRoom,
|
||||
message: room!
|
||||
message: room
|
||||
.getState(EventTypes.RoomTombstone)!
|
||||
.parsedTombstoneContent
|
||||
.body,
|
||||
|
@ -903,8 +987,8 @@ class ChatController extends State<Chat> {
|
|||
}
|
||||
final result = await showFutureLoadingDialog(
|
||||
context: context,
|
||||
future: () => room!.client.joinRoom(
|
||||
room!
|
||||
future: () => room.client.joinRoom(
|
||||
room
|
||||
.getState(EventTypes.RoomTombstone)!
|
||||
.parsedTombstoneContent
|
||||
.replacementRoom,
|
||||
|
@ -912,7 +996,7 @@ class ChatController extends State<Chat> {
|
|||
);
|
||||
await showFutureLoadingDialog(
|
||||
context: context,
|
||||
future: room!.leave,
|
||||
future: room.leave,
|
||||
);
|
||||
if (result.error == null) {
|
||||
VRouter.of(context).toSegments(['rooms', result.result!]);
|
||||
|
@ -989,18 +1073,16 @@ class ChatController extends State<Chat> {
|
|||
cancelLabel: L10n.of(context)!.cancel,
|
||||
);
|
||||
if (response == OkCancelResult.ok) {
|
||||
final events = room!.pinnedEventIds
|
||||
final events = room.pinnedEventIds
|
||||
..removeWhere((oldEvent) => oldEvent == eventId);
|
||||
showFutureLoadingDialog(
|
||||
context: context,
|
||||
future: () => room!.setPinnedEvents(events),
|
||||
future: () => room.setPinnedEvents(events),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void pinEvent() {
|
||||
final room = this.room;
|
||||
if (room == null) return;
|
||||
final pinnedEventIds = room.pinnedEventIds;
|
||||
final selectedEventIds = selectedEvents.map((e) => e.eventId).toSet();
|
||||
final unpin = selectedEventIds.length == 1 &&
|
||||
|
@ -1026,7 +1108,7 @@ class ChatController extends State<Chat> {
|
|||
await prefs.setString('draft_$roomId', text);
|
||||
});
|
||||
setReadMarker();
|
||||
if (text.endsWith(' ') && matrix!.hasComplexBundles) {
|
||||
if (text.endsWith(' ') && Matrix.of(context).hasComplexBundles) {
|
||||
final clients = currentRoomBundle;
|
||||
for (final client in clients) {
|
||||
final prefix = client!.sendPrefix;
|
||||
|
@ -1045,7 +1127,7 @@ class ChatController extends State<Chat> {
|
|||
typingCoolDown = Timer(const Duration(seconds: 2), () {
|
||||
typingCoolDown = null;
|
||||
currentlyTyping = false;
|
||||
room!.setTyping(false);
|
||||
room.setTyping(false);
|
||||
});
|
||||
typingTimeout ??= Timer(const Duration(seconds: 30), () {
|
||||
typingTimeout = null;
|
||||
|
@ -1053,14 +1135,13 @@ class ChatController extends State<Chat> {
|
|||
});
|
||||
if (!currentlyTyping) {
|
||||
currentlyTyping = true;
|
||||
room!
|
||||
.setTyping(true, timeout: const Duration(seconds: 30).inMilliseconds);
|
||||
room.setTyping(true, timeout: const Duration(seconds: 30).inMilliseconds);
|
||||
}
|
||||
setState(() => inputText = text);
|
||||
}
|
||||
|
||||
bool get isArchived =>
|
||||
{Membership.leave, Membership.ban}.contains(room?.membership);
|
||||
{Membership.leave, Membership.ban}.contains(room.membership);
|
||||
|
||||
void showEventInfo([Event? event]) =>
|
||||
(event ?? selectedEvents.single).showInfoDialog(context);
|
||||
|
@ -1108,7 +1189,7 @@ class ChatController extends State<Chat> {
|
|||
if (success.result != null) {
|
||||
final voipPlugin = Matrix.of(context).voipPlugin;
|
||||
try {
|
||||
await voipPlugin!.voip.inviteToCall(room!.id, callType);
|
||||
await voipPlugin!.voip.inviteToCall(room.id, callType);
|
||||
} catch (e) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text(e.toLocalizedString(context))),
|
||||
|
|
|
@ -16,9 +16,6 @@ class ChatAppBarTitle extends StatelessWidget {
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final room = controller.room;
|
||||
if (room == null) {
|
||||
return Container();
|
||||
}
|
||||
if (controller.selectedEvents.isNotEmpty) {
|
||||
return Text(controller.selectedEvents.length.toString());
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:matrix/matrix.dart';
|
||||
import 'package:scroll_to_index/scroll_to_index.dart';
|
||||
|
||||
|
@ -48,6 +47,26 @@ class ChatEventList extends StatelessWidget {
|
|||
(BuildContext context, int i) {
|
||||
// Footer to display typing indicator and read receipts:
|
||||
if (i == 0) {
|
||||
if (controller.timeline!.isRequestingFuture) {
|
||||
return const Center(
|
||||
child: CircularProgressIndicator.adaptive(strokeWidth: 2),
|
||||
);
|
||||
}
|
||||
if (controller.timeline!.canRequestFuture) {
|
||||
return Builder(
|
||||
builder: (context) {
|
||||
WidgetsBinding.instance.addPostFrameCallback(
|
||||
(_) => controller.requestFuture(),
|
||||
);
|
||||
return Center(
|
||||
child: IconButton(
|
||||
onPressed: controller.requestFuture,
|
||||
icon: const Icon(Icons.refresh_outlined),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
|
@ -64,18 +83,22 @@ class ChatEventList extends StatelessWidget {
|
|||
child: CircularProgressIndicator.adaptive(strokeWidth: 2),
|
||||
);
|
||||
}
|
||||
if (controller.canLoadMore) {
|
||||
Center(
|
||||
child: OutlinedButton(
|
||||
style: OutlinedButton.styleFrom(
|
||||
backgroundColor: Theme.of(context).scaffoldBackgroundColor,
|
||||
),
|
||||
onPressed: controller.requestHistory,
|
||||
child: Text(L10n.of(context)!.loadMore),
|
||||
),
|
||||
if (controller.timeline!.canRequestHistory) {
|
||||
return Builder(
|
||||
builder: (context) {
|
||||
WidgetsBinding.instance.addPostFrameCallback(
|
||||
(_) => controller.requestHistory(),
|
||||
);
|
||||
return Center(
|
||||
child: IconButton(
|
||||
onPressed: controller.requestHistory,
|
||||
icon: const Icon(Icons.refresh_outlined),
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
return Container();
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
|
||||
// The message at this index:
|
||||
|
@ -107,11 +130,14 @@ class ChatEventList extends StatelessWidget {
|
|||
selected: controller.selectedEvents
|
||||
.any((e) => e.eventId == event.eventId),
|
||||
timeline: controller.timeline!,
|
||||
displayReadMarker:
|
||||
controller.readMarkerEventId == event.eventId &&
|
||||
controller.timeline?.allowNewEvent == false,
|
||||
nextEvent: i < controller.timeline!.events.length
|
||||
? controller.timeline!.events[i]
|
||||
: null,
|
||||
)
|
||||
: Container(),
|
||||
: const SizedBox.shrink(),
|
||||
);
|
||||
},
|
||||
childCount: controller.timeline!.events.length + 2,
|
||||
|
|
|
@ -23,7 +23,7 @@ class ChatInputRow extends StatelessWidget {
|
|||
Widget build(BuildContext context) {
|
||||
if (controller.showEmojiPicker &&
|
||||
controller.emojiPickerType == EmojiPickerType.reaction) {
|
||||
return Container();
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
return Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
|
@ -72,7 +72,7 @@ class ChatInputRow extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
)
|
||||
: Container(),
|
||||
: const SizedBox.shrink(),
|
||||
]
|
||||
: <Widget>[
|
||||
KeyBoardShortcuts(
|
||||
|
@ -146,7 +146,7 @@ class ChatInputRow extends StatelessWidget {
|
|||
contentPadding: const EdgeInsets.all(0),
|
||||
),
|
||||
),
|
||||
if (controller.room!
|
||||
if (controller.room
|
||||
.getImagePacks(ImagePackUsage.sticker)
|
||||
.isNotEmpty)
|
||||
PopupMenuItem<String>(
|
||||
|
@ -215,9 +215,9 @@ class ChatInputRow extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
),
|
||||
if (controller.matrix!.isMultiAccount &&
|
||||
controller.matrix!.hasComplexBundles &&
|
||||
controller.matrix!.currentBundle!.length > 1)
|
||||
if (Matrix.of(context).isMultiAccount &&
|
||||
Matrix.of(context).hasComplexBundles &&
|
||||
Matrix.of(context).currentBundle!.length > 1)
|
||||
Container(
|
||||
height: 56,
|
||||
alignment: Alignment.center,
|
||||
|
@ -227,7 +227,7 @@ class ChatInputRow extends StatelessWidget {
|
|||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 4.0),
|
||||
child: InputBar(
|
||||
room: controller.room!,
|
||||
room: controller.room,
|
||||
minLines: 1,
|
||||
maxLines: 8,
|
||||
autofocus: !PlatformInfos.isMobile,
|
||||
|
@ -279,8 +279,9 @@ class _ChatAccountPicker extends StatelessWidget {
|
|||
|
||||
const _ChatAccountPicker(this.controller, {Key? key}) : super(key: key);
|
||||
|
||||
void _popupMenuButtonSelected(String mxid) {
|
||||
final client = controller.matrix!.currentBundle!
|
||||
void _popupMenuButtonSelected(String mxid, BuildContext context) {
|
||||
final client = Matrix.of(context)
|
||||
.currentBundle!
|
||||
.firstWhere((cl) => cl!.userID == mxid, orElse: () => null);
|
||||
if (client == null) {
|
||||
Logs().w('Attempted to switch to a non-existing client $mxid');
|
||||
|
@ -291,14 +292,13 @@ class _ChatAccountPicker extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
controller.matrix ??= Matrix.of(context);
|
||||
final clients = controller.currentRoomBundle;
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: FutureBuilder<Profile>(
|
||||
future: controller.sendingClient!.fetchOwnProfile(),
|
||||
future: controller.sendingClient.fetchOwnProfile(),
|
||||
builder: (context, snapshot) => PopupMenuButton<String>(
|
||||
onSelected: _popupMenuButtonSelected,
|
||||
onSelected: (mxid) => _popupMenuButtonSelected(mxid, context),
|
||||
itemBuilder: (BuildContext context) => clients
|
||||
.map(
|
||||
(client) => PopupMenuItem<String>(
|
||||
|
@ -322,7 +322,7 @@ class _ChatAccountPicker extends StatelessWidget {
|
|||
child: Avatar(
|
||||
mxContent: snapshot.data?.avatarUrl,
|
||||
name: snapshot.data?.displayName ??
|
||||
controller.matrix!.client.userID!.localpart,
|
||||
Matrix.of(context).client.userID!.localpart,
|
||||
size: 20,
|
||||
),
|
||||
),
|
||||
|
|
|
@ -125,43 +125,27 @@ class ChatView extends StatelessWidget {
|
|||
} else {
|
||||
return [
|
||||
if (Matrix.of(context).voipPlugin != null &&
|
||||
controller.room!.isDirectChat)
|
||||
controller.room.isDirectChat)
|
||||
IconButton(
|
||||
onPressed: controller.onPhoneButtonTap,
|
||||
icon: const Icon(Icons.call_outlined),
|
||||
tooltip: L10n.of(context)!.placeCall,
|
||||
),
|
||||
EncryptionButton(controller.room!),
|
||||
ChatSettingsPopupMenu(controller.room!, !controller.room!.isDirectChat),
|
||||
EncryptionButton(controller.room),
|
||||
ChatSettingsPopupMenu(controller.room, !controller.room.isDirectChat),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
controller.matrix ??= Matrix.of(context);
|
||||
final client = controller.matrix!.client;
|
||||
controller.sendingClient ??= client;
|
||||
controller.room = controller.sendingClient!.getRoomById(controller.roomId!);
|
||||
if (controller.room == null) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(L10n.of(context)!.oopsSomethingWentWrong),
|
||||
),
|
||||
body: Center(
|
||||
child: Text(L10n.of(context)!.youAreNoLongerParticipatingInThisChat),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
if (controller.room!.membership == Membership.invite) {
|
||||
if (controller.room.membership == Membership.invite) {
|
||||
showFutureLoadingDialog(
|
||||
context: context,
|
||||
future: () => controller.room!.join(),
|
||||
future: () => controller.room.join(),
|
||||
);
|
||||
}
|
||||
final bottomSheetPadding = FluffyThemes.isColumnMode(context) ? 16.0 : 8.0;
|
||||
final colorScheme = Theme.of(context).colorScheme;
|
||||
|
||||
return VWidgetGuard(
|
||||
onSystemPop: (redirector) async {
|
||||
|
@ -174,13 +158,13 @@ class ChatView extends StatelessWidget {
|
|||
}
|
||||
},
|
||||
child: GestureDetector(
|
||||
onTapDown: controller.setReadMarker,
|
||||
onTapDown: (_) => controller.setReadMarker(),
|
||||
behavior: HitTestBehavior.opaque,
|
||||
child: StreamBuilder(
|
||||
stream: controller.room!.onUpdate.stream
|
||||
stream: controller.room.onUpdate.stream
|
||||
.rateLimit(const Duration(seconds: 1)),
|
||||
builder: (context, snapshot) => FutureBuilder<bool>(
|
||||
future: controller.getTimeline(),
|
||||
builder: (context, snapshot) => FutureBuilder(
|
||||
future: controller.loadTimelineFuture,
|
||||
builder: (BuildContext context, snapshot) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
|
@ -198,7 +182,7 @@ class ChatView extends StatelessWidget {
|
|||
color: Theme.of(context).colorScheme.primary,
|
||||
)
|
||||
: UnreadRoomsBadge(
|
||||
filter: (r) => r.id != controller.roomId!,
|
||||
filter: (r) => r.id != controller.roomId,
|
||||
badgePosition: BadgePosition.topEnd(end: 8, top: 4),
|
||||
child: const Center(child: BackButton()),
|
||||
),
|
||||
|
@ -212,6 +196,7 @@ class ChatView extends StatelessWidget {
|
|||
padding: const EdgeInsets.only(bottom: 56.0),
|
||||
child: FloatingActionButton(
|
||||
onPressed: controller.scrollDown,
|
||||
heroTag: null,
|
||||
mini: true,
|
||||
child: const Icon(Icons.arrow_downward_outlined),
|
||||
),
|
||||
|
@ -234,14 +219,9 @@ class ChatView extends StatelessWidget {
|
|||
else
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.topCenter,
|
||||
colors: [
|
||||
colorScheme.primaryContainer.withAlpha(64),
|
||||
colorScheme.secondaryContainer.withAlpha(64),
|
||||
colorScheme.tertiaryContainer.withAlpha(64),
|
||||
colorScheme.primaryContainer.withAlpha(64),
|
||||
],
|
||||
gradient: FluffyThemes.backgroundGradient(
|
||||
context,
|
||||
64,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -271,8 +251,8 @@ class ChatView extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
),
|
||||
if (controller.room!.canSendDefaultMessages &&
|
||||
controller.room!.membership == Membership.join)
|
||||
if (controller.room.canSendDefaultMessages &&
|
||||
controller.room.membership == Membership.join)
|
||||
Container(
|
||||
margin: EdgeInsets.only(
|
||||
bottom: bottomSheetPadding,
|
||||
|
@ -297,7 +277,7 @@ class ChatView extends StatelessWidget {
|
|||
Brightness.light
|
||||
? Colors.white
|
||||
: Colors.black,
|
||||
child: controller.room?.isAbandonedDMRoom ==
|
||||
child: controller.room.isAbandonedDMRoom ==
|
||||
true
|
||||
? Row(
|
||||
mainAxisAlignment:
|
||||
|
@ -326,7 +306,7 @@ class ChatView extends StatelessWidget {
|
|||
const EdgeInsets.all(16),
|
||||
),
|
||||
icon: const Icon(
|
||||
Icons.chat_outlined,
|
||||
Icons.forum_outlined,
|
||||
),
|
||||
onPressed:
|
||||
controller.recreateChat,
|
||||
|
|
|
@ -20,7 +20,9 @@ class EncryptionButton extends StatelessWidget {
|
|||
.where((s) => s.deviceLists != null),
|
||||
builder: (context, snapshot) {
|
||||
return FutureBuilder<EncryptionHealthState>(
|
||||
future: room.calcEncryptionHealthState(),
|
||||
future: room.encrypted
|
||||
? room.calcEncryptionHealthState()
|
||||
: Future.value(EncryptionHealthState.allVerified),
|
||||
builder: (BuildContext context, snapshot) => IconButton(
|
||||
tooltip: room.encrypted
|
||||
? L10n.of(context)!.encrypted
|
||||
|
|
|
@ -4,12 +4,12 @@ import 'dart:io';
|
|||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:just_audio/just_audio.dart';
|
||||
import 'package:matrix/matrix.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
|
||||
import 'package:fluffychat/config/app_config.dart';
|
||||
import 'package:fluffychat/utils/error_reporter.dart';
|
||||
import 'package:fluffychat/utils/localized_exception_extension.dart';
|
||||
import '../../../utils/matrix_sdk_extensions/event_extension.dart';
|
||||
|
||||
|
@ -132,14 +132,10 @@ class AudioPlayerState extends State<AudioPlayerWidget> {
|
|||
} else {
|
||||
await audioPlayer.setAudioSource(MatrixFileAudioSource(matrixFile!));
|
||||
}
|
||||
audioPlayer.play().catchError((e, s) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(L10n.of(context)!.oopsSomethingWentWrong),
|
||||
),
|
||||
);
|
||||
Logs().w('Error while playing audio', e, s);
|
||||
});
|
||||
audioPlayer.play().onError(
|
||||
ErrorReporter(context, 'Unable to play audio message')
|
||||
.onErrorCallback,
|
||||
);
|
||||
}
|
||||
|
||||
static const double buttonSize = 36;
|
||||
|
|
|
@ -36,19 +36,16 @@ class _CuteContentState extends State<CuteContent> {
|
|||
|
||||
return GestureDetector(
|
||||
onTap: addOverlay,
|
||||
child: SizedBox.square(
|
||||
dimension: 300,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
widget.event.text,
|
||||
style: const TextStyle(fontSize: 150),
|
||||
),
|
||||
if (label != null) Text(label)
|
||||
],
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
widget.event.text,
|
||||
style: const TextStyle(fontSize: 150),
|
||||
),
|
||||
if (label != null) Text(label)
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
|
@ -144,24 +141,26 @@ class _CuteEventOverlayState extends State<CuteEventOverlay>
|
|||
return SizedBox(
|
||||
height: constraints.maxHeight,
|
||||
width: constraints.maxWidth,
|
||||
child: Stack(
|
||||
alignment: Alignment.bottomLeft,
|
||||
fit: StackFit.expand,
|
||||
children: items
|
||||
.map(
|
||||
(position) => Positioned(
|
||||
left: position.width * width,
|
||||
bottom: (height *
|
||||
.25 *
|
||||
position.height *
|
||||
(controller?.value ?? 0)) -
|
||||
_CuteOverlayContent.size,
|
||||
child: _CuteOverlayContent(
|
||||
emoji: widget.emoji,
|
||||
child: OverflowBox(
|
||||
child: Stack(
|
||||
alignment: Alignment.bottomLeft,
|
||||
fit: StackFit.expand,
|
||||
children: items
|
||||
.map(
|
||||
(position) => Positioned(
|
||||
left: position.width * width,
|
||||
bottom: (height *
|
||||
.25 *
|
||||
position.height *
|
||||
(controller?.value ?? 0)) -
|
||||
_CuteOverlayContent.size,
|
||||
child: _CuteOverlayContent(
|
||||
emoji: widget.emoji,
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
)
|
||||
.toList(),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
|
|
|
@ -1,32 +1,29 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:flutter_matrix_html/flutter_html.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:flutter_highlighter/flutter_highlighter.dart';
|
||||
import 'package:flutter_highlighter/themes/shades-of-purple.dart';
|
||||
import 'package:flutter_html/flutter_html.dart';
|
||||
import 'package:flutter_html_table/flutter_html_table.dart';
|
||||
import 'package:flutter_math_fork/flutter_math.dart';
|
||||
import 'package:linkify/linkify.dart';
|
||||
import 'package:matrix/matrix.dart';
|
||||
|
||||
import 'package:fluffychat/widgets/matrix.dart';
|
||||
import '../../../config/app_config.dart';
|
||||
import '../../../config/setting_keys.dart';
|
||||
import '../../../pages/image_viewer/image_viewer.dart';
|
||||
import '../../../utils/matrix_sdk_extensions/matrix_locals.dart';
|
||||
import 'package:fluffychat/config/app_config.dart';
|
||||
import 'package:fluffychat/widgets/avatar.dart';
|
||||
import 'package:fluffychat/widgets/mxc_image.dart';
|
||||
import '../../../utils/url_launcher.dart';
|
||||
|
||||
class HtmlMessage extends StatelessWidget {
|
||||
final String html;
|
||||
final int? maxLines;
|
||||
final Room room;
|
||||
final TextStyle? defaultTextStyle;
|
||||
final TextStyle? linkStyle;
|
||||
final double? emoteSize;
|
||||
final Color textColor;
|
||||
|
||||
const HtmlMessage({
|
||||
Key? key,
|
||||
required this.html,
|
||||
this.maxLines,
|
||||
required this.room,
|
||||
this.defaultTextStyle,
|
||||
this.linkStyle,
|
||||
this.emoteSize,
|
||||
this.textColor = Colors.black,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
|
@ -47,118 +44,461 @@ class HtmlMessage extends StatelessWidget {
|
|||
'',
|
||||
);
|
||||
|
||||
// there is no need to pre-validate the html, as we validate it while rendering
|
||||
final fontSize = AppConfig.messageFontSize * AppConfig.fontSizeFactor;
|
||||
|
||||
final matrix = Matrix.of(context);
|
||||
|
||||
final themeData = Theme.of(context);
|
||||
return Html(
|
||||
data: renderHtml,
|
||||
defaultTextStyle: defaultTextStyle,
|
||||
emoteSize: emoteSize,
|
||||
linkStyle: linkStyle ??
|
||||
themeData.textTheme.bodyMedium!.copyWith(
|
||||
color: themeData.colorScheme.secondary,
|
||||
decoration: TextDecoration.underline,
|
||||
decorationColor: themeData.colorScheme.secondary,
|
||||
),
|
||||
shrinkToFit: true,
|
||||
maxLines: maxLines,
|
||||
onLinkTap: (url) => UrlLauncher(context, url).launchUrl(),
|
||||
onPillTap: (url) => UrlLauncher(context, url).launchUrl(),
|
||||
getMxcUrl: (
|
||||
String mxc,
|
||||
double? width,
|
||||
double? height, {
|
||||
bool? animated = false,
|
||||
}) {
|
||||
final ratio = MediaQuery.of(context).devicePixelRatio;
|
||||
return Uri.parse(mxc)
|
||||
.getThumbnail(
|
||||
matrix.client,
|
||||
width: (width ?? 800) * ratio,
|
||||
height: (height ?? 800) * ratio,
|
||||
method: ThumbnailMethod.scale,
|
||||
animated: AppConfig.autoplayImages ? animated : false,
|
||||
)
|
||||
.toString();
|
||||
},
|
||||
onImageTap: (String mxc) => showDialog(
|
||||
context: Matrix.of(context).navigatorContext,
|
||||
useRootNavigator: false,
|
||||
builder: (_) => ImageViewer(
|
||||
Event(
|
||||
type: EventTypes.Message,
|
||||
content: <String, dynamic>{
|
||||
'body': mxc,
|
||||
'url': mxc,
|
||||
'msgtype': MessageTypes.Image,
|
||||
},
|
||||
senderId: room.client.userID!,
|
||||
originServerTs: DateTime.now(),
|
||||
eventId: 'fake_event',
|
||||
room: room,
|
||||
),
|
||||
),
|
||||
),
|
||||
setCodeLanguage: (String key, String value) async {
|
||||
await matrix.store.setItem('${SettingKeys.codeLanguage}.$key', value);
|
||||
},
|
||||
getCodeLanguage: (String key) async {
|
||||
return await matrix.store.getItem('${SettingKeys.codeLanguage}.$key');
|
||||
},
|
||||
getPillInfo: (String url) async {
|
||||
final identityParts = url.parseIdentifierIntoParts();
|
||||
final identifier = identityParts?.primaryIdentifier;
|
||||
if (identifier == null) {
|
||||
return {};
|
||||
}
|
||||
if (identifier.sigil == '@') {
|
||||
// we have a user pill
|
||||
final user = room.getState('m.room.member', identifier);
|
||||
if (user != null) {
|
||||
return user.content;
|
||||
}
|
||||
// there might still be a profile...
|
||||
final profile = await room.client.getProfileFromUserId(identifier);
|
||||
return {
|
||||
'displayname': profile.displayName,
|
||||
'avatar_url': profile.avatarUrl.toString(),
|
||||
};
|
||||
}
|
||||
if (identifier.sigil == '#') {
|
||||
// we have an alias pill
|
||||
for (final r in room.client.rooms) {
|
||||
final state = r.getState('m.room.canonical_alias');
|
||||
if (state != null &&
|
||||
((state.content['alias'] is String &&
|
||||
state.content['alias'] == identifier) ||
|
||||
(state.content['alt_aliases'] is List &&
|
||||
state.content['alt_aliases'].contains(identifier)))) {
|
||||
// we have a room!
|
||||
return {
|
||||
'displayname':
|
||||
r.getLocalizedDisplayname(MatrixLocals(L10n.of(context)!)),
|
||||
'avatar_url': r.getState('m.room.avatar')?.content['url'],
|
||||
};
|
||||
final linkifiedRenderHtml = linkify(
|
||||
renderHtml,
|
||||
options: const LinkifyOptions(humanize: false),
|
||||
)
|
||||
.map(
|
||||
(element) {
|
||||
if (element is! UrlElement ||
|
||||
element.text.contains('<') ||
|
||||
element.text.contains('>') ||
|
||||
element.text.contains('"')) {
|
||||
return element.text;
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
if (identifier.sigil == '!') {
|
||||
// we have a room ID pill
|
||||
final r = room.client.getRoomById(identifier);
|
||||
if (r == null) {
|
||||
return {};
|
||||
}
|
||||
return {
|
||||
'displayname':
|
||||
r.getLocalizedDisplayname(MatrixLocals(L10n.of(context)!)),
|
||||
'avatar_url': r.getState('m.room.avatar')?.content['url'],
|
||||
};
|
||||
}
|
||||
return {};
|
||||
return '<a href="${element.url}">${element.text}</a>';
|
||||
},
|
||||
)
|
||||
.join('')
|
||||
.replaceAll('\n', '');
|
||||
|
||||
final linkColor = textColor.withAlpha(150);
|
||||
|
||||
// there is no need to pre-validate the html, as we validate it while rendering
|
||||
return Html(
|
||||
data: linkifiedRenderHtml,
|
||||
style: {
|
||||
'*': Style(
|
||||
color: textColor,
|
||||
margin: Margins.all(0),
|
||||
fontSize: FontSize(fontSize),
|
||||
),
|
||||
'a': Style(color: linkColor, textDecorationColor: linkColor),
|
||||
'h1': Style(
|
||||
fontSize: FontSize(fontSize * 2),
|
||||
lineHeight: LineHeight.number(1.5),
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
'h2': Style(
|
||||
fontSize: FontSize(fontSize * 1.75),
|
||||
lineHeight: LineHeight.number(1.5),
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
'h3': Style(
|
||||
fontSize: FontSize(fontSize * 1.5),
|
||||
lineHeight: LineHeight.number(1.5),
|
||||
),
|
||||
'h4': Style(
|
||||
fontSize: FontSize(fontSize * 1.25),
|
||||
lineHeight: LineHeight.number(1.5),
|
||||
),
|
||||
'h5': Style(
|
||||
fontSize: FontSize(fontSize * 1.25),
|
||||
lineHeight: LineHeight.number(1.5),
|
||||
),
|
||||
'h6': Style(
|
||||
fontSize: FontSize(fontSize),
|
||||
lineHeight: LineHeight.number(1.5),
|
||||
),
|
||||
'blockquote': Style(
|
||||
border: Border(
|
||||
left: BorderSide(
|
||||
width: 3,
|
||||
color: textColor,
|
||||
),
|
||||
),
|
||||
padding: HtmlPaddings.only(left: 6, bottom: 0),
|
||||
),
|
||||
'hr': Style(
|
||||
border: Border.all(color: textColor, width: 0.5),
|
||||
),
|
||||
'table': Style(
|
||||
border: Border.all(color: textColor, width: 0.5),
|
||||
),
|
||||
'tr': Style(
|
||||
border: Border.all(color: textColor, width: 0.5),
|
||||
),
|
||||
'td': Style(
|
||||
border: Border.all(color: textColor, width: 0.5),
|
||||
padding: HtmlPaddings.all(2),
|
||||
),
|
||||
'th': Style(
|
||||
border: Border.all(color: textColor, width: 0.5),
|
||||
),
|
||||
},
|
||||
extensions: [
|
||||
RoomPillExtension(context, room),
|
||||
CodeExtension(fontSize: fontSize),
|
||||
MatrixMathExtension(
|
||||
style: TextStyle(fontSize: fontSize, color: textColor),
|
||||
),
|
||||
const TableHtmlExtension(),
|
||||
SpoilerExtension(textColor: textColor),
|
||||
const ImageExtension(),
|
||||
FontColorExtension(),
|
||||
],
|
||||
onLinkTap: (url, _, __) => UrlLauncher(context, url).launchUrl(),
|
||||
onlyRenderTheseTags: const {
|
||||
...allowedHtmlTags,
|
||||
// Needed to make it work properly
|
||||
'body',
|
||||
'html',
|
||||
},
|
||||
shrinkWrap: true,
|
||||
);
|
||||
}
|
||||
|
||||
/// Keep in sync with: https://spec.matrix.org/v1.6/client-server-api/#mroommessage-msgtypes
|
||||
static const Set<String> allowedHtmlTags = {
|
||||
'font',
|
||||
'del',
|
||||
'h1',
|
||||
'h2',
|
||||
'h3',
|
||||
'h4',
|
||||
'h5',
|
||||
'h6',
|
||||
'blockquote',
|
||||
'p',
|
||||
'a',
|
||||
'ul',
|
||||
'ol',
|
||||
'sup',
|
||||
'sub',
|
||||
'li',
|
||||
'b',
|
||||
'i',
|
||||
'u',
|
||||
'strong',
|
||||
'em',
|
||||
'strike',
|
||||
'code',
|
||||
'hr',
|
||||
'br',
|
||||
'div',
|
||||
'table',
|
||||
'thead',
|
||||
'tbody',
|
||||
'tr',
|
||||
'th',
|
||||
'td',
|
||||
'caption',
|
||||
'pre',
|
||||
'span',
|
||||
'img',
|
||||
'details',
|
||||
'summary',
|
||||
// Not in the allowlist of the matrix spec yet but should be harmless:
|
||||
'ruby',
|
||||
'rp',
|
||||
'rt',
|
||||
};
|
||||
}
|
||||
|
||||
class FontColorExtension extends HtmlExtension {
|
||||
static const String colorAttribute = 'color';
|
||||
static const String mxColorAttribute = 'data-mx-color';
|
||||
static const String bgColorAttribute = 'data-mx-bg-color';
|
||||
|
||||
@override
|
||||
Set<String> get supportedTags => {'font', 'span'};
|
||||
|
||||
@override
|
||||
bool matches(ExtensionContext context) {
|
||||
if (!supportedTags.contains(context.elementName)) return false;
|
||||
return context.element?.attributes.keys.any(
|
||||
{
|
||||
colorAttribute,
|
||||
mxColorAttribute,
|
||||
bgColorAttribute,
|
||||
}.contains,
|
||||
) ??
|
||||
false;
|
||||
}
|
||||
|
||||
Color? hexToColor(String? hexCode) {
|
||||
if (hexCode == null) return null;
|
||||
if (hexCode.startsWith('#')) hexCode = hexCode.substring(1);
|
||||
if (hexCode.length == 6) hexCode = 'FF$hexCode';
|
||||
final colorValue = int.tryParse(hexCode, radix: 16);
|
||||
return colorValue == null ? null : Color(colorValue);
|
||||
}
|
||||
|
||||
@override
|
||||
InlineSpan build(
|
||||
ExtensionContext context,
|
||||
) {
|
||||
final colorText = context.element?.attributes[colorAttribute] ??
|
||||
context.element?.attributes[mxColorAttribute];
|
||||
final bgColor = context.element?.attributes[bgColorAttribute];
|
||||
return TextSpan(
|
||||
style: TextStyle(
|
||||
color: hexToColor(colorText),
|
||||
backgroundColor: hexToColor(bgColor),
|
||||
),
|
||||
text: context.innerHtml,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ImageExtension extends HtmlExtension {
|
||||
final double defaultDimension;
|
||||
|
||||
const ImageExtension({this.defaultDimension = 64});
|
||||
|
||||
@override
|
||||
Set<String> get supportedTags => {'img'};
|
||||
|
||||
@override
|
||||
InlineSpan build(ExtensionContext context) {
|
||||
final mxcUrl = Uri.tryParse(context.attributes['src'] ?? '');
|
||||
if (mxcUrl == null || mxcUrl.scheme != 'mxc') {
|
||||
return TextSpan(text: context.attributes['alt']);
|
||||
}
|
||||
|
||||
final width = double.tryParse(context.attributes['width'] ?? '');
|
||||
final height = double.tryParse(context.attributes['height'] ?? '');
|
||||
|
||||
return WidgetSpan(
|
||||
child: SizedBox(
|
||||
width: width ?? height ?? defaultDimension,
|
||||
height: height ?? width ?? defaultDimension,
|
||||
child: MxcImage(
|
||||
uri: mxcUrl,
|
||||
width: width ?? height ?? defaultDimension,
|
||||
height: height ?? width ?? defaultDimension,
|
||||
cacheKey: mxcUrl.toString(),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class SpoilerExtension extends HtmlExtension {
|
||||
final Color textColor;
|
||||
|
||||
const SpoilerExtension({required this.textColor});
|
||||
|
||||
@override
|
||||
Set<String> get supportedTags => {'span'};
|
||||
|
||||
static const String customDataAttribute = 'data-mx-spoiler';
|
||||
|
||||
@override
|
||||
bool matches(ExtensionContext context) {
|
||||
if (context.elementName != 'span') return false;
|
||||
return context.element?.attributes.containsKey(customDataAttribute) ??
|
||||
false;
|
||||
}
|
||||
|
||||
@override
|
||||
InlineSpan build(ExtensionContext context) {
|
||||
var obscure = true;
|
||||
final children = context.inlineSpanChildren;
|
||||
return WidgetSpan(
|
||||
child: StatefulBuilder(
|
||||
builder: (context, setState) {
|
||||
return InkWell(
|
||||
onTap: () => setState(() {
|
||||
obscure = !obscure;
|
||||
}),
|
||||
child: RichText(
|
||||
text: TextSpan(
|
||||
style: obscure ? TextStyle(backgroundColor: textColor) : null,
|
||||
children: children,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class MatrixMathExtension extends HtmlExtension {
|
||||
final TextStyle? style;
|
||||
|
||||
MatrixMathExtension({this.style});
|
||||
@override
|
||||
Set<String> get supportedTags => {'div'};
|
||||
|
||||
@override
|
||||
bool matches(ExtensionContext context) {
|
||||
if (context.elementName != 'div') return false;
|
||||
final mathData = context.element?.attributes['data-mx-maths'];
|
||||
return mathData != null;
|
||||
}
|
||||
|
||||
@override
|
||||
InlineSpan build(ExtensionContext context) {
|
||||
final data = context.element?.attributes['data-mx-maths'] ?? '';
|
||||
return WidgetSpan(
|
||||
child: Math.tex(
|
||||
data,
|
||||
textStyle: style,
|
||||
onErrorFallback: (e) {
|
||||
Logs().d('Flutter math parse error', e);
|
||||
return Text(
|
||||
data,
|
||||
style: style,
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class CodeExtension extends HtmlExtension {
|
||||
final double fontSize;
|
||||
|
||||
CodeExtension({required this.fontSize});
|
||||
@override
|
||||
Set<String> get supportedTags => {'code'};
|
||||
|
||||
@override
|
||||
InlineSpan build(ExtensionContext context) => WidgetSpan(
|
||||
child: Material(
|
||||
clipBehavior: Clip.hardEdge,
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
child: SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: HighlightView(
|
||||
context.element?.text ?? '',
|
||||
language: context.element?.className
|
||||
.split(' ')
|
||||
.singleWhereOrNull(
|
||||
(className) => className.startsWith('language-'),
|
||||
)
|
||||
?.split('language-')
|
||||
.last ??
|
||||
'md',
|
||||
theme: shadesOfPurpleTheme,
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 6,
|
||||
vertical: context.element?.parent?.localName == 'pre' ? 6 : 0,
|
||||
),
|
||||
textStyle: TextStyle(fontSize: fontSize),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
class RoomPillExtension extends HtmlExtension {
|
||||
final Room room;
|
||||
final BuildContext context;
|
||||
|
||||
RoomPillExtension(this.context, this.room);
|
||||
@override
|
||||
Set<String> get supportedTags => {'a'};
|
||||
|
||||
@override
|
||||
bool matches(ExtensionContext context) {
|
||||
if (context.elementName != 'a') return false;
|
||||
final userId = context.element?.attributes['href']
|
||||
?.parseIdentifierIntoParts()
|
||||
?.primaryIdentifier;
|
||||
return userId != null;
|
||||
}
|
||||
|
||||
static final _cachedUsers = <String, User?>{};
|
||||
|
||||
Future<User?> _fetchUser(String matrixId) async =>
|
||||
_cachedUsers[room.id + matrixId] ??= await room.requestUser(matrixId);
|
||||
|
||||
@override
|
||||
InlineSpan build(ExtensionContext context) {
|
||||
final href = context.element?.attributes['href'];
|
||||
final matrixId = href?.parseIdentifierIntoParts()?.primaryIdentifier;
|
||||
if (href == null || matrixId == null) {
|
||||
return TextSpan(text: context.innerHtml);
|
||||
}
|
||||
if (matrixId.sigil == '@') {
|
||||
return WidgetSpan(
|
||||
child: FutureBuilder<User?>(
|
||||
future: _fetchUser(matrixId),
|
||||
builder: (context, snapshot) => MatrixPill(
|
||||
key: Key('user_pill_$matrixId'),
|
||||
name: _cachedUsers[room.id + matrixId]?.calcDisplayname() ??
|
||||
matrixId.localpart ??
|
||||
matrixId,
|
||||
avatar: _cachedUsers[room.id + matrixId]?.avatarUrl,
|
||||
uri: href,
|
||||
outerContext: this.context,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
if (matrixId.sigil == '#' || matrixId.sigil == '!') {
|
||||
final room = matrixId.sigil == '!'
|
||||
? this.room.client.getRoomById(matrixId)
|
||||
: this.room.client.getRoomByAlias(matrixId);
|
||||
if (room != null) {
|
||||
return WidgetSpan(
|
||||
child: MatrixPill(
|
||||
name: room.getLocalizedDisplayname(),
|
||||
avatar: room.avatar,
|
||||
uri: href,
|
||||
outerContext: this.context,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return TextSpan(text: context.innerHtml);
|
||||
}
|
||||
}
|
||||
|
||||
class MatrixPill extends StatelessWidget {
|
||||
final String name;
|
||||
final BuildContext outerContext;
|
||||
final Uri? avatar;
|
||||
final String uri;
|
||||
|
||||
const MatrixPill({
|
||||
super.key,
|
||||
required this.name,
|
||||
required this.outerContext,
|
||||
this.avatar,
|
||||
required this.uri,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return InkWell(
|
||||
onTap: UrlLauncher(outerContext, uri).launchUrl,
|
||||
child: Material(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(AppConfig.borderRadius),
|
||||
side: BorderSide(
|
||||
color: Theme.of(outerContext).colorScheme.onPrimaryContainer,
|
||||
width: 0.5,
|
||||
),
|
||||
),
|
||||
color: Theme.of(outerContext).colorScheme.primaryContainer,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 6.0),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Avatar(
|
||||
mxContent: avatar,
|
||||
name: name,
|
||||
size: 16,
|
||||
),
|
||||
const SizedBox(width: 6),
|
||||
Text(
|
||||
name,
|
||||
style: TextStyle(
|
||||
color: Theme.of(outerContext).colorScheme.onPrimaryContainer,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:matrix/matrix.dart';
|
||||
import 'package:swipe_to_action/swipe_to_action.dart';
|
||||
|
||||
|
@ -18,6 +19,7 @@ import 'verification_request_content.dart';
|
|||
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;
|
||||
|
@ -30,6 +32,7 @@ class Message extends StatelessWidget {
|
|||
const Message(
|
||||
this.event, {
|
||||
this.nextEvent,
|
||||
this.displayReadMarker = false,
|
||||
this.longPressSelect = false,
|
||||
this.onSelect,
|
||||
this.onInfoTab,
|
||||
|
@ -54,7 +57,7 @@ class Message extends StatelessWidget {
|
|||
EventTypes.CallInvite
|
||||
}.contains(event.type)) {
|
||||
if (event.type.startsWith('m.call.')) {
|
||||
return Container();
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
return StateMessage(event);
|
||||
}
|
||||
|
@ -303,7 +306,8 @@ class Message extends StatelessWidget {
|
|||
Widget container;
|
||||
if (event.hasAggregatedEvents(timeline, RelationshipTypes.reaction) ||
|
||||
displayTime ||
|
||||
selected) {
|
||||
selected ||
|
||||
displayReadMarker) {
|
||||
container = Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment:
|
||||
|
@ -347,6 +351,35 @@ class Message extends StatelessWidget {
|
|||
),
|
||||
child: MessageReactions(event, timeline),
|
||||
),
|
||||
if (displayReadMarker)
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Divider(color: Theme.of(context).colorScheme.primary),
|
||||
),
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
),
|
||||
color: Theme.of(context).colorScheme.primaryContainer,
|
||||
borderRadius: BorderRadius.circular(4),
|
||||
),
|
||||
margin: const EdgeInsets.all(8.0),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 8,
|
||||
),
|
||||
child: Text(
|
||||
L10n.of(context)!.readUpToHere,
|
||||
style:
|
||||
TextStyle(color: Theme.of(context).colorScheme.primary),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Divider(color: Theme.of(context).colorScheme.primary),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
} else {
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:flutter_linkify/flutter_linkify.dart';
|
||||
import 'package:matrix/matrix.dart';
|
||||
import 'package:matrix_link_text/link_text.dart';
|
||||
|
||||
import 'package:fluffychat/pages/chat/events/video_player.dart';
|
||||
import 'package:fluffychat/utils/adaptive_bottom_sheet.dart';
|
||||
|
@ -150,23 +150,10 @@ class MessageContent extends StatelessWidget {
|
|||
if (event.messageType == MessageTypes.Emote) {
|
||||
html = '* $html';
|
||||
}
|
||||
final bigEmotes = event.onlyEmotes &&
|
||||
event.numberEmotes > 0 &&
|
||||
event.numberEmotes <= 10;
|
||||
return HtmlMessage(
|
||||
html: html,
|
||||
defaultTextStyle: TextStyle(
|
||||
color: textColor,
|
||||
fontSize: bigEmotes ? fontSize * 3 : fontSize,
|
||||
),
|
||||
linkStyle: TextStyle(
|
||||
color: textColor.withAlpha(150),
|
||||
fontSize: bigEmotes ? fontSize * 3 : fontSize,
|
||||
decoration: TextDecoration.underline,
|
||||
decorationColor: textColor.withAlpha(150),
|
||||
),
|
||||
textColor: textColor,
|
||||
room: event.room,
|
||||
emoteSize: bigEmotes ? fontSize * 3 : fontSize * 1.5,
|
||||
);
|
||||
}
|
||||
// else we fall through to the normal message rendering
|
||||
|
@ -242,25 +229,26 @@ class MessageContent extends StatelessWidget {
|
|||
hideReply: true,
|
||||
),
|
||||
builder: (context, snapshot) {
|
||||
return LinkText(
|
||||
return Linkify(
|
||||
text: snapshot.data ??
|
||||
event.calcLocalizedBodyFallback(
|
||||
MatrixLocals(L10n.of(context)!),
|
||||
hideReply: true,
|
||||
),
|
||||
textStyle: TextStyle(
|
||||
style: TextStyle(
|
||||
color: textColor,
|
||||
fontSize: bigEmotes ? fontSize * 3 : fontSize,
|
||||
decoration:
|
||||
event.redacted ? TextDecoration.lineThrough : null,
|
||||
),
|
||||
options: const LinkifyOptions(humanize: false),
|
||||
linkStyle: TextStyle(
|
||||
color: textColor.withAlpha(150),
|
||||
fontSize: bigEmotes ? fontSize * 3 : fontSize,
|
||||
decoration: TextDecoration.underline,
|
||||
decorationColor: textColor.withAlpha(150),
|
||||
),
|
||||
onLinkTap: (url) => UrlLauncher(context, url).launchUrl(),
|
||||
onOpen: (url) => UrlLauncher(context, url.url).launchUrl(),
|
||||
);
|
||||
},
|
||||
);
|
||||
|
|
|
@ -37,14 +37,17 @@ class MessageDownloadContent extends StatelessWidget {
|
|||
color: textColor,
|
||||
),
|
||||
const SizedBox(width: 16),
|
||||
Text(
|
||||
filename,
|
||||
maxLines: 1,
|
||||
style: TextStyle(
|
||||
color: textColor,
|
||||
fontWeight: FontWeight.bold,
|
||||
Flexible(
|
||||
child: Text(
|
||||
filename,
|
||||
maxLines: 1,
|
||||
style: TextStyle(
|
||||
color: textColor,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
|
@ -61,7 +61,7 @@ class MessageReactions extends StatelessWidget {
|
|||
final evt = allReactionEvents.firstWhereOrNull(
|
||||
(e) =>
|
||||
e.senderId == e.room.client.userID &&
|
||||
e.content['m.relates_to']['key'] == r.key,
|
||||
e.content.tryGetMap('m.relates_to')?['key'] == r.key,
|
||||
);
|
||||
if (evt != null) {
|
||||
showFutureLoadingDialog(
|
||||
|
|
|
@ -5,7 +5,6 @@ import 'package:matrix/matrix.dart';
|
|||
|
||||
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
|
||||
import '../../../config/app_config.dart';
|
||||
import 'html_message.dart';
|
||||
|
||||
class ReplyContent extends StatelessWidget {
|
||||
final Event replyEvent;
|
||||
|
@ -26,47 +25,23 @@ class ReplyContent extends StatelessWidget {
|
|||
final displayEvent =
|
||||
timeline != null ? replyEvent.getDisplayEvent(timeline) : replyEvent;
|
||||
final fontSize = AppConfig.messageFontSize * AppConfig.fontSizeFactor;
|
||||
if (AppConfig.renderHtml &&
|
||||
[EventTypes.Message, EventTypes.Encrypted]
|
||||
.contains(displayEvent.type) &&
|
||||
[MessageTypes.Text, MessageTypes.Notice, MessageTypes.Emote]
|
||||
.contains(displayEvent.messageType) &&
|
||||
!displayEvent.redacted &&
|
||||
displayEvent.content['format'] == 'org.matrix.custom.html' &&
|
||||
displayEvent.content['formatted_body'] is String) {
|
||||
String? html = displayEvent.content['formatted_body'];
|
||||
if (displayEvent.messageType == MessageTypes.Emote) {
|
||||
html = '* $html';
|
||||
}
|
||||
replyBody = HtmlMessage(
|
||||
html: html!,
|
||||
defaultTextStyle: TextStyle(
|
||||
color: ownMessage
|
||||
? Theme.of(context).colorScheme.onPrimary
|
||||
: Theme.of(context).colorScheme.onBackground,
|
||||
fontSize: fontSize,
|
||||
),
|
||||
maxLines: 1,
|
||||
room: displayEvent.room,
|
||||
emoteSize: fontSize * 1.5,
|
||||
);
|
||||
} else {
|
||||
replyBody = Text(
|
||||
displayEvent.calcLocalizedBodyFallback(
|
||||
MatrixLocals(L10n.of(context)!),
|
||||
withSenderNamePrefix: false,
|
||||
hideReply: true,
|
||||
),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: 1,
|
||||
style: TextStyle(
|
||||
color: ownMessage
|
||||
? Theme.of(context).colorScheme.onPrimary
|
||||
: Theme.of(context).colorScheme.onBackground,
|
||||
fontSize: fontSize,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
replyBody = Text(
|
||||
displayEvent.calcLocalizedBodyFallback(
|
||||
MatrixLocals(L10n.of(context)!),
|
||||
withSenderNamePrefix: false,
|
||||
hideReply: true,
|
||||
),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
maxLines: 1,
|
||||
style: TextStyle(
|
||||
color: ownMessage
|
||||
? Theme.of(context).colorScheme.onPrimary
|
||||
: Theme.of(context).colorScheme.onBackground,
|
||||
fontSize: fontSize,
|
||||
),
|
||||
);
|
||||
|
||||
return Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
|
|
|
@ -14,6 +14,7 @@ import 'package:video_player/video_player.dart';
|
|||
import 'package:fluffychat/pages/chat/events/image_bubble.dart';
|
||||
import 'package:fluffychat/utils/localized_exception_extension.dart';
|
||||
import 'package:fluffychat/utils/matrix_sdk_extensions/event_extension.dart';
|
||||
import '../../../utils/error_reporter.dart';
|
||||
|
||||
class EventVideoPlayer extends StatefulWidget {
|
||||
final Event event;
|
||||
|
@ -51,7 +52,8 @@ class EventVideoPlayerState extends State<EventVideoPlayer> {
|
|||
final networkUri = _networkUri;
|
||||
if (kIsWeb && networkUri != null && _chewieManager == null) {
|
||||
_chewieManager ??= ChewieController(
|
||||
videoPlayerController: VideoPlayerController.network(networkUri),
|
||||
videoPlayerController:
|
||||
VideoPlayerController.networkUrl(Uri.parse(networkUri)),
|
||||
autoPlay: true,
|
||||
autoInitialize: true,
|
||||
);
|
||||
|
@ -69,12 +71,7 @@ class EventVideoPlayerState extends State<EventVideoPlayer> {
|
|||
),
|
||||
);
|
||||
} catch (e, s) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(e.toLocalizedString(context)),
|
||||
),
|
||||
);
|
||||
Logs().w('Error while playing video', e, s);
|
||||
ErrorReporter(context, 'Unable to play video').onErrorCallback(e, s);
|
||||
} finally {
|
||||
// Workaround for Chewie needs time to get the aspectRatio
|
||||
await Future.delayed(const Duration(milliseconds: 100));
|
||||
|
|
|
@ -183,12 +183,13 @@ class InputBar extends StatelessWidget {
|
|||
final state = r.getState(EventTypes.RoomCanonicalAlias);
|
||||
if ((state != null &&
|
||||
((state.content['alias'] is String &&
|
||||
state.content['alias']
|
||||
state.content
|
||||
.tryGet<String>('alias')!
|
||||
.split(':')[0]
|
||||
.toLowerCase()
|
||||
.contains(roomSearch)) ||
|
||||
(state.content['alt_aliases'] is List &&
|
||||
state.content['alt_aliases'].any(
|
||||
(state.content['alt_aliases'] as List).any(
|
||||
(l) =>
|
||||
l is String &&
|
||||
l
|
||||
|
@ -263,6 +264,8 @@ class InputBar extends StatelessWidget {
|
|||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
MxcImage(
|
||||
// ensure proper ordering ...
|
||||
key: ValueKey(suggestion['name']),
|
||||
uri: suggestion['mxc'] is String
|
||||
? Uri.parse(suggestion['mxc'] ?? '')
|
||||
: null,
|
||||
|
@ -313,7 +316,7 @@ class InputBar extends StatelessWidget {
|
|||
),
|
||||
);
|
||||
}
|
||||
return Container();
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
|
||||
void insertSuggestion(_, Map<String, String?> suggestion) {
|
||||
|
@ -458,11 +461,12 @@ class InputBar extends StatelessWidget {
|
|||
buildSuggestion(c, s, Matrix.of(context).client),
|
||||
onSuggestionSelected: (Map<String, String?> suggestion) =>
|
||||
insertSuggestion(context, suggestion),
|
||||
errorBuilder: (BuildContext context, Object? error) => Container(),
|
||||
loadingBuilder: (BuildContext context) => Container(),
|
||||
errorBuilder: (BuildContext context, Object? error) =>
|
||||
const SizedBox.shrink(),
|
||||
loadingBuilder: (BuildContext context) => const SizedBox.shrink(),
|
||||
// fix loading briefly flickering a dark box
|
||||
noItemsFoundBuilder: (BuildContext context) =>
|
||||
Container(), // fix loading briefly showing no suggestions
|
||||
noItemsFoundBuilder: (BuildContext context) => const SizedBox
|
||||
.shrink(), // fix loading briefly showing no suggestions
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
|
@ -4,8 +4,8 @@ import 'package:flutter/material.dart';
|
|||
|
||||
import 'package:adaptive_dialog/adaptive_dialog.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:flutter_linkify/flutter_linkify.dart';
|
||||
import 'package:matrix/matrix.dart';
|
||||
import 'package:matrix_link_text/link_text.dart';
|
||||
|
||||
import 'package:fluffychat/config/app_config.dart';
|
||||
import 'package:fluffychat/pages/chat/chat.dart';
|
||||
|
@ -46,14 +46,14 @@ class PinnedEvents extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final pinnedEventIds = controller.room!.pinnedEventIds;
|
||||
final pinnedEventIds = controller.room.pinnedEventIds;
|
||||
|
||||
if (pinnedEventIds.isEmpty) {
|
||||
return Container();
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
final completers = pinnedEventIds.map<Completer<Event?>>((e) {
|
||||
final completer = Completer<Event?>();
|
||||
controller.room!
|
||||
controller.room
|
||||
.getEventById(e)
|
||||
.then((value) => completer.complete(value));
|
||||
return completer;
|
||||
|
@ -86,11 +86,10 @@ class PinnedEvents extends StatelessWidget {
|
|||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||
icon: const Icon(Icons.push_pin),
|
||||
tooltip: L10n.of(context)!.unpin,
|
||||
onPressed: controller.room
|
||||
?.canSendEvent(EventTypes.RoomPinnedEvents) ??
|
||||
false
|
||||
? () => controller.unpinEvent(event.eventId)
|
||||
: null,
|
||||
onPressed:
|
||||
controller.room.canSendEvent(EventTypes.RoomPinnedEvents)
|
||||
? () => controller.unpinEvent(event.eventId)
|
||||
: null,
|
||||
),
|
||||
Expanded(
|
||||
child: Padding(
|
||||
|
@ -102,15 +101,16 @@ class PinnedEvents extends StatelessWidget {
|
|||
hideReply: true,
|
||||
),
|
||||
builder: (context, snapshot) {
|
||||
return LinkText(
|
||||
return Linkify(
|
||||
text: snapshot.data ??
|
||||
event.calcLocalizedBodyFallback(
|
||||
MatrixLocals(L10n.of(context)!),
|
||||
withSenderNamePrefix: true,
|
||||
hideReply: true,
|
||||
),
|
||||
options: const LinkifyOptions(humanize: false),
|
||||
maxLines: 2,
|
||||
textStyle: TextStyle(
|
||||
style: TextStyle(
|
||||
color:
|
||||
Theme.of(context).colorScheme.onSurfaceVariant,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
|
@ -127,8 +127,8 @@ class PinnedEvents extends StatelessWidget {
|
|||
decorationColor:
|
||||
Theme.of(context).colorScheme.onSurfaceVariant,
|
||||
),
|
||||
onLinkTap: (url) =>
|
||||
UrlLauncher(context, url).launchUrl(),
|
||||
onOpen: (url) =>
|
||||
UrlLauncher(context, url.url).launchUrl(),
|
||||
);
|
||||
},
|
||||
),
|
||||
|
|
|
@ -15,10 +15,10 @@ class ReactionsPicker extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (controller.showEmojiPicker) return Container();
|
||||
if (controller.showEmojiPicker) return const SizedBox.shrink();
|
||||
final display = controller.editEvent == null &&
|
||||
controller.replyEvent == null &&
|
||||
controller.room!.canSendDefaultMessages &&
|
||||
controller.room.canSendDefaultMessages &&
|
||||
controller.selectedEvents.isNotEmpty;
|
||||
return AnimatedContainer(
|
||||
duration: FluffyThemes.animationDuration,
|
||||
|
@ -29,7 +29,7 @@ class ReactionsPicker extends StatelessWidget {
|
|||
child: Builder(
|
||||
builder: (context) {
|
||||
if (!display) {
|
||||
return Container();
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
final proposals = proposeEmojis(
|
||||
controller.selectedEvents.first.plaintextBody,
|
||||
|
@ -52,7 +52,7 @@ class ReactionsPicker extends StatelessWidget {
|
|||
|
||||
for (final event in allReactionEvents) {
|
||||
try {
|
||||
emojis.remove(event.content['m.relates_to']['key']);
|
||||
emojis.remove(event.content.tryGetMap('m.relates_to')!['key']);
|
||||
} catch (_) {}
|
||||
}
|
||||
return Row(
|
||||
|
|
|
@ -58,7 +58,7 @@ class _EditContent extends StatelessWidget {
|
|||
Widget build(BuildContext context) {
|
||||
final event = this.event;
|
||||
if (event == null) {
|
||||
return Container();
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
return Row(
|
||||
children: <Widget>[
|
||||
|
|
|
@ -12,7 +12,7 @@ class SeenByRow extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final seenByUsers = controller.room!.getSeenByUsers(controller.timeline!);
|
||||
final seenByUsers = controller.room.getSeenByUsers(controller.timeline!);
|
||||
const maxAvatars = 7;
|
||||
return Container(
|
||||
width: double.infinity,
|
||||
|
|
|
@ -39,7 +39,7 @@ class StickerPickerDialogState extends State<StickerPickerDialog> {
|
|||
final imageKeys =
|
||||
filteredImagePackImageEntried.map((e) => e.key).toList();
|
||||
if (imageKeys.isEmpty) {
|
||||
return Container();
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
final packName = pack.pack.displayName ?? packSlugs[packIndex];
|
||||
return Column(
|
||||
|
|
|
@ -11,8 +11,8 @@ class TombstoneDisplay extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (controller.room!.getState(EventTypes.RoomTombstone) == null) {
|
||||
return Container();
|
||||
if (controller.room.getState(EventTypes.RoomTombstone) == null) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
return SizedBox(
|
||||
height: 72,
|
||||
|
@ -26,7 +26,7 @@ class TombstoneDisplay extends StatelessWidget {
|
|||
child: const Icon(Icons.upgrade_outlined),
|
||||
),
|
||||
title: Text(
|
||||
controller.room!
|
||||
controller.room
|
||||
.getState(EventTypes.RoomTombstone)!
|
||||
.parsedTombstoneContent
|
||||
.body,
|
||||
|
|
|
@ -12,7 +12,7 @@ class TypingIndicators extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final typingUsers = controller.room!.typingUsers
|
||||
final typingUsers = controller.room.typingUsers
|
||||
..removeWhere((u) => u.stateKey == Matrix.of(context).client.userID);
|
||||
const topPadding = 20.0;
|
||||
const bottomPadding = 4.0;
|
||||
|
|
|
@ -2,7 +2,8 @@ import 'package:flutter/material.dart';
|
|||
import 'package:flutter/services.dart';
|
||||
|
||||
import 'package:adaptive_dialog/adaptive_dialog.dart';
|
||||
import 'package:file_picker_cross/file_picker_cross.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:future_loading_dialog/future_loading_dialog.dart';
|
||||
import 'package:image_picker/image_picker.dart';
|
||||
|
@ -82,7 +83,9 @@ class ChatDetailsController extends State<ChatDetails> {
|
|||
RequestType.GET,
|
||||
'/client/unstable/org.matrix.msc2432/rooms/${Uri.encodeComponent(room.id)}/aliases',
|
||||
)
|
||||
.then((response) => List<String>.from(response['aliases'])),
|
||||
.then(
|
||||
(response) => List<String>.from(response['aliases'] as Iterable),
|
||||
),
|
||||
);
|
||||
// Switch to the stable api once it is implemented.
|
||||
|
||||
|
@ -312,12 +315,15 @@ class ChatDetailsController extends State<ChatDetails> {
|
|||
name: result.path,
|
||||
);
|
||||
} else {
|
||||
final result =
|
||||
await FilePickerCross.importFromStorage(type: FileTypeCross.image);
|
||||
if (result.fileName == null) return;
|
||||
final picked = await FilePicker.platform.pickFiles(
|
||||
type: FileType.image,
|
||||
withData: true,
|
||||
);
|
||||
final pickedFile = picked?.files.firstOrNull;
|
||||
if (pickedFile == null) return;
|
||||
file = MatrixFile(
|
||||
bytes: result.toUint8List(),
|
||||
name: result.fileName!,
|
||||
bytes: pickedFile.bytes!,
|
||||
name: pickedFile.name,
|
||||
);
|
||||
}
|
||||
await showFutureLoadingDialog(
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:flutter_gen/gen_l10n/l10n.dart';
|
||||
import 'package:flutter_linkify/flutter_linkify.dart';
|
||||
import 'package:matrix/matrix.dart';
|
||||
import 'package:matrix_link_text/link_text.dart';
|
||||
import 'package:vrouter/vrouter.dart';
|
||||
|
||||
import 'package:fluffychat/config/app_config.dart';
|
||||
|
@ -125,13 +125,14 @@ class ChatDetailsView extends StatelessWidget {
|
|||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 16.0,
|
||||
),
|
||||
child: LinkText(
|
||||
child: Linkify(
|
||||
text: room.topic.isEmpty
|
||||
? L10n.of(context)!.addGroupDescription
|
||||
: room.topic,
|
||||
options: const LinkifyOptions(humanize: false),
|
||||
linkStyle:
|
||||
const TextStyle(color: Colors.blueAccent),
|
||||
textStyle: TextStyle(
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
color: Theme.of(context)
|
||||
.textTheme
|
||||
|
@ -142,8 +143,8 @@ class ChatDetailsView extends StatelessWidget {
|
|||
.bodyMedium!
|
||||
.color,
|
||||
),
|
||||
onLinkTap: (url) =>
|
||||
UrlLauncher(context, url).launchUrl(),
|
||||
onOpen: (url) =>
|
||||
UrlLauncher(context, url.url).launchUrl(),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
|
@ -409,7 +410,7 @@ class ChatDetailsView extends StatelessWidget {
|
|||
),
|
||||
onTap: () => VRouter.of(context).to('invite'),
|
||||
)
|
||||
: Container(),
|
||||
: const SizedBox.shrink(),
|
||||
],
|
||||
)
|
||||
: i < controller.members!.length + 1
|
||||
|
|
|
@ -62,7 +62,7 @@ class ParticipantListItem extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
membershipBatch[user.membership]!.isEmpty
|
||||
? Container()
|
||||
? const SizedBox.shrink()
|
||||
: Container(
|
||||
padding: const EdgeInsets.all(4),
|
||||
margin: const EdgeInsets.symmetric(horizontal: 8),
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue